From 1eee8fbd76f03307eb8e7aa6a43943f13068bd7a Mon Sep 17 00:00:00 2001 From: Alex Ladda Date: Fri, 19 Mar 2021 14:32:22 +0800 Subject: [PATCH] cleaned up ./.idea, ./venv, renamed branch to main --- venv/bin/Activate.ps1 | 231 - venv/bin/activate | 76 - venv/bin/activate.csh | 37 - venv/bin/activate.fish | 75 - venv/bin/easy_install | 12 - venv/bin/easy_install-3.8 | 12 - venv/bin/pip | 12 - venv/bin/pip3 | 12 - venv/bin/pip3.8 | 12 - venv/bin/python | Bin 9604 -> 0 bytes venv/bin/python3 | Bin 9604 -> 0 bytes venv/bin/python3.8 | Bin 9604 -> 0 bytes .../python3.8/site-packages/easy-install.pth | 2 - .../pip-19.0.3-py3.8.egg/EGG-INFO/PKG-INFO | 73 - .../pip-19.0.3-py3.8.egg/EGG-INFO/SOURCES.txt | 391 - .../EGG-INFO/dependency_links.txt | 1 - .../EGG-INFO/entry_points.txt | 5 - .../EGG-INFO/not-zip-safe | 1 - .../EGG-INFO/top_level.txt | 1 - .../pip-19.0.3-py3.8.egg/pip/__init__.py | 1 - .../pip-19.0.3-py3.8.egg/pip/__main__.py | 19 - .../pip/_internal/__init__.py | 78 - .../pip/_internal/build_env.py | 215 - .../pip/_internal/cache.py | 224 - .../pip/_internal/cli/__init__.py | 4 - .../pip/_internal/cli/autocompletion.py | 152 - .../pip/_internal/cli/base_command.py | 341 - .../pip/_internal/cli/cmdoptions.py | 809 -- .../pip/_internal/cli/main_parser.py | 104 - .../pip/_internal/cli/parser.py | 261 - .../pip/_internal/cli/status_codes.py | 8 - .../pip/_internal/commands/__init__.py | 79 - .../pip/_internal/commands/check.py | 41 - .../pip/_internal/commands/completion.py | 94 - .../pip/_internal/commands/configuration.py | 227 - .../pip/_internal/commands/download.py | 176 - .../pip/_internal/commands/freeze.py | 96 - .../pip/_internal/commands/hash.py | 57 - .../pip/_internal/commands/help.py | 37 - .../pip/_internal/commands/install.py | 566 -- .../pip/_internal/commands/list.py | 301 - .../pip/_internal/commands/search.py | 135 - .../pip/_internal/commands/show.py | 168 - .../pip/_internal/commands/uninstall.py | 78 - .../pip/_internal/commands/wheel.py | 186 - .../pip/_internal/configuration.py | 387 - .../pip/_internal/download.py | 971 -- .../pip/_internal/exceptions.py | 274 - .../pip/_internal/index.py | 990 -- .../pip/_internal/locations.py | 211 - .../pip/_internal/models/__init__.py | 2 - .../pip/_internal/models/candidate.py | 31 - .../pip/_internal/models/format_control.py | 73 - .../pip/_internal/models/index.py | 31 - .../pip/_internal/models/link.py | 163 - .../pip/_internal/operations/__init__.py | 0 .../pip/_internal/operations/check.py | 155 - .../pip/_internal/operations/freeze.py | 247 - .../pip/_internal/operations/prepare.py | 413 - .../pip/_internal/pep425tags.py | 381 - .../pip/_internal/pyproject.py | 171 - .../pip/_internal/req/__init__.py | 77 - .../pip/_internal/req/constructors.py | 339 - .../pip/_internal/req/req_file.py | 382 - .../pip/_internal/req/req_install.py | 1021 -- .../pip/_internal/req/req_set.py | 197 - .../pip/_internal/req/req_tracker.py | 88 - .../pip/_internal/req/req_uninstall.py | 596 -- .../pip/_internal/resolve.py | 393 - .../pip/_internal/utils/__init__.py | 0 .../pip/_internal/utils/appdirs.py | 270 - .../pip/_internal/utils/compat.py | 264 - .../pip/_internal/utils/deprecation.py | 90 - .../pip/_internal/utils/encoding.py | 39 - .../pip/_internal/utils/filesystem.py | 30 - .../pip/_internal/utils/glibc.py | 93 - .../pip/_internal/utils/hashes.py | 115 - .../pip/_internal/utils/logging.py | 318 - .../pip/_internal/utils/misc.py | 1040 --- .../pip/_internal/utils/models.py | 40 - .../pip/_internal/utils/outdated.py | 164 - .../pip/_internal/utils/packaging.py | 85 - .../pip/_internal/utils/setuptools_build.py | 8 - .../pip/_internal/utils/temp_dir.py | 155 - .../pip/_internal/utils/typing.py | 29 - .../pip/_internal/utils/ui.py | 441 - .../pip/_internal/vcs/__init__.py | 534 -- .../pip/_internal/vcs/bazaar.py | 114 - .../pip/_internal/vcs/git.py | 369 - .../pip/_internal/vcs/mercurial.py | 103 - .../pip/_internal/vcs/subversion.py | 200 - .../pip/_internal/wheel.py | 1095 --- .../pip/_vendor/__init__.py | 111 - .../pip/_vendor/appdirs.py | 604 -- .../pip/_vendor/cachecontrol/__init__.py | 11 - .../pip/_vendor/cachecontrol/_cmd.py | 57 - .../pip/_vendor/cachecontrol/adapter.py | 133 - .../pip/_vendor/cachecontrol/cache.py | 39 - .../_vendor/cachecontrol/caches/__init__.py | 2 - .../_vendor/cachecontrol/caches/file_cache.py | 146 - .../cachecontrol/caches/redis_cache.py | 33 - .../pip/_vendor/cachecontrol/compat.py | 29 - .../pip/_vendor/cachecontrol/controller.py | 367 - .../pip/_vendor/cachecontrol/filewrapper.py | 80 - .../pip/_vendor/cachecontrol/heuristics.py | 135 - .../pip/_vendor/cachecontrol/serialize.py | 186 - .../pip/_vendor/cachecontrol/wrapper.py | 29 - .../pip/_vendor/certifi/__init__.py | 3 - .../pip/_vendor/certifi/__main__.py | 2 - .../pip/_vendor/certifi/cacert.pem | 4512 --------- .../pip/_vendor/certifi/core.py | 20 - .../pip/_vendor/chardet/__init__.py | 39 - .../pip/_vendor/chardet/big5freq.py | 386 - .../pip/_vendor/chardet/big5prober.py | 47 - .../pip/_vendor/chardet/chardistribution.py | 233 - .../pip/_vendor/chardet/charsetgroupprober.py | 106 - .../pip/_vendor/chardet/charsetprober.py | 145 - .../pip/_vendor/chardet/cli/__init__.py | 1 - .../pip/_vendor/chardet/cli/chardetect.py | 85 - .../pip/_vendor/chardet/codingstatemachine.py | 88 - .../pip/_vendor/chardet/compat.py | 34 - .../pip/_vendor/chardet/cp949prober.py | 49 - .../pip/_vendor/chardet/enums.py | 76 - .../pip/_vendor/chardet/escprober.py | 101 - .../pip/_vendor/chardet/escsm.py | 246 - .../pip/_vendor/chardet/eucjpprober.py | 92 - .../pip/_vendor/chardet/euckrfreq.py | 195 - .../pip/_vendor/chardet/euckrprober.py | 47 - .../pip/_vendor/chardet/euctwfreq.py | 387 - .../pip/_vendor/chardet/euctwprober.py | 46 - .../pip/_vendor/chardet/gb2312freq.py | 283 - .../pip/_vendor/chardet/gb2312prober.py | 46 - .../pip/_vendor/chardet/hebrewprober.py | 292 - .../pip/_vendor/chardet/jisfreq.py | 325 - .../pip/_vendor/chardet/jpcntx.py | 233 - .../pip/_vendor/chardet/langbulgarianmodel.py | 228 - .../pip/_vendor/chardet/langcyrillicmodel.py | 333 - .../pip/_vendor/chardet/langgreekmodel.py | 225 - .../pip/_vendor/chardet/langhebrewmodel.py | 200 - .../pip/_vendor/chardet/langhungarianmodel.py | 225 - .../pip/_vendor/chardet/langthaimodel.py | 199 - .../pip/_vendor/chardet/langturkishmodel.py | 193 - .../pip/_vendor/chardet/latin1prober.py | 145 - .../pip/_vendor/chardet/mbcharsetprober.py | 91 - .../pip/_vendor/chardet/mbcsgroupprober.py | 54 - .../pip/_vendor/chardet/mbcssm.py | 572 -- .../pip/_vendor/chardet/sbcharsetprober.py | 132 - .../pip/_vendor/chardet/sbcsgroupprober.py | 73 - .../pip/_vendor/chardet/sjisprober.py | 92 - .../pip/_vendor/chardet/universaldetector.py | 286 - .../pip/_vendor/chardet/utf8prober.py | 82 - .../pip/_vendor/chardet/version.py | 9 - .../pip/_vendor/colorama/__init__.py | 6 - .../pip/_vendor/colorama/ansi.py | 102 - .../pip/_vendor/colorama/ansitowin32.py | 257 - .../pip/_vendor/colorama/initialise.py | 80 - .../pip/_vendor/colorama/win32.py | 152 - .../pip/_vendor/colorama/winterm.py | 169 - .../pip/_vendor/distlib/__init__.py | 23 - .../pip/_vendor/distlib/_backport/__init__.py | 6 - .../pip/_vendor/distlib/_backport/misc.py | 41 - .../pip/_vendor/distlib/_backport/shutil.py | 761 -- .../_vendor/distlib/_backport/sysconfig.cfg | 84 - .../_vendor/distlib/_backport/sysconfig.py | 788 -- .../pip/_vendor/distlib/_backport/tarfile.py | 2607 ------ .../pip/_vendor/distlib/compat.py | 1120 --- .../pip/_vendor/distlib/database.py | 1339 --- .../pip/_vendor/distlib/index.py | 516 -- .../pip/_vendor/distlib/locators.py | 1295 --- .../pip/_vendor/distlib/manifest.py | 393 - .../pip/_vendor/distlib/markers.py | 131 - .../pip/_vendor/distlib/metadata.py | 1094 --- .../pip/_vendor/distlib/resources.py | 355 - .../pip/_vendor/distlib/scripts.py | 417 - .../pip/_vendor/distlib/t32.exe | Bin 92672 -> 0 bytes .../pip/_vendor/distlib/t64.exe | Bin 102400 -> 0 bytes .../pip/_vendor/distlib/util.py | 1756 ---- .../pip/_vendor/distlib/version.py | 736 -- .../pip/_vendor/distlib/w32.exe | Bin 89088 -> 0 bytes .../pip/_vendor/distlib/w64.exe | Bin 99328 -> 0 bytes .../pip/_vendor/distlib/wheel.py | 988 -- .../pip/_vendor/distro.py | 1197 --- .../pip/_vendor/html5lib/__init__.py | 35 - .../pip/_vendor/html5lib/_ihatexml.py | 288 - .../pip/_vendor/html5lib/_inputstream.py | 923 -- .../pip/_vendor/html5lib/_tokenizer.py | 1721 ---- .../pip/_vendor/html5lib/_trie/__init__.py | 14 - .../pip/_vendor/html5lib/_trie/_base.py | 37 - .../pip/_vendor/html5lib/_trie/datrie.py | 44 - .../pip/_vendor/html5lib/_trie/py.py | 67 - .../pip/_vendor/html5lib/_utils.py | 124 - .../pip/_vendor/html5lib/constants.py | 2947 ------ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../filters/alphabeticalattributes.py | 29 - .../pip/_vendor/html5lib/filters/base.py | 12 - .../html5lib/filters/inject_meta_charset.py | 73 - .../pip/_vendor/html5lib/filters/lint.py | 93 - .../_vendor/html5lib/filters/optionaltags.py | 207 - .../pip/_vendor/html5lib/filters/sanitizer.py | 896 -- .../_vendor/html5lib/filters/whitespace.py | 38 - .../pip/_vendor/html5lib/html5parser.py | 2791 ------ .../pip/_vendor/html5lib/serializer.py | 409 - .../_vendor/html5lib/treeadapters/__init__.py | 30 - .../_vendor/html5lib/treeadapters/genshi.py | 54 - .../pip/_vendor/html5lib/treeadapters/sax.py | 50 - .../_vendor/html5lib/treebuilders/__init__.py | 88 - .../pip/_vendor/html5lib/treebuilders/base.py | 417 - .../pip/_vendor/html5lib/treebuilders/dom.py | 236 - .../_vendor/html5lib/treebuilders/etree.py | 340 - .../html5lib/treebuilders/etree_lxml.py | 366 - .../_vendor/html5lib/treewalkers/__init__.py | 154 - .../pip/_vendor/html5lib/treewalkers/base.py | 252 - .../pip/_vendor/html5lib/treewalkers/dom.py | 43 - .../pip/_vendor/html5lib/treewalkers/etree.py | 130 - .../html5lib/treewalkers/etree_lxml.py | 213 - .../_vendor/html5lib/treewalkers/genshi.py | 69 - .../pip/_vendor/idna/__init__.py | 2 - .../pip/_vendor/idna/codec.py | 118 - .../pip/_vendor/idna/compat.py | 12 - .../pip/_vendor/idna/core.py | 396 - .../pip/_vendor/idna/idnadata.py | 1979 ---- .../pip/_vendor/idna/intranges.py | 53 - .../pip/_vendor/idna/package_data.py | 2 - .../pip/_vendor/idna/uts46data.py | 8205 ----------------- .../pip/_vendor/ipaddress.py | 2419 ----- .../pip/_vendor/lockfile/__init__.py | 347 - .../pip/_vendor/lockfile/linklockfile.py | 73 - .../pip/_vendor/lockfile/mkdirlockfile.py | 84 - .../pip/_vendor/lockfile/pidlockfile.py | 190 - .../pip/_vendor/lockfile/sqlitelockfile.py | 156 - .../pip/_vendor/lockfile/symlinklockfile.py | 70 - .../pip/_vendor/msgpack/__init__.py | 66 - .../pip/_vendor/msgpack/_version.py | 1 - .../pip/_vendor/msgpack/exceptions.py | 41 - .../pip/_vendor/msgpack/fallback.py | 977 -- .../pip/_vendor/packaging/__about__.py | 27 - .../pip/_vendor/packaging/__init__.py | 26 - .../pip/_vendor/packaging/_compat.py | 31 - .../pip/_vendor/packaging/_structures.py | 68 - .../pip/_vendor/packaging/markers.py | 296 - .../pip/_vendor/packaging/requirements.py | 138 - .../pip/_vendor/packaging/specifiers.py | 749 -- .../pip/_vendor/packaging/utils.py | 57 - .../pip/_vendor/packaging/version.py | 420 - .../pip/_vendor/pep517/__init__.py | 4 - .../pip/_vendor/pep517/_in_process.py | 207 - .../pip/_vendor/pep517/build.py | 108 - .../pip/_vendor/pep517/check.py | 202 - .../pip/_vendor/pep517/colorlog.py | 115 - .../pip/_vendor/pep517/compat.py | 23 - .../pip/_vendor/pep517/envbuild.py | 158 - .../pip/_vendor/pep517/wrappers.py | 163 - .../pip/_vendor/pkg_resources/__init__.py | 3171 ------- .../pip/_vendor/pkg_resources/py31compat.py | 23 - .../pip/_vendor/progress/__init__.py | 127 - .../pip/_vendor/progress/bar.py | 94 - .../pip/_vendor/progress/counter.py | 48 - .../pip/_vendor/progress/helpers.py | 91 - .../pip/_vendor/progress/spinner.py | 44 - .../pip/_vendor/pyparsing.py | 6452 ------------- .../pip/_vendor/pytoml/__init__.py | 4 - .../pip/_vendor/pytoml/core.py | 13 - .../pip/_vendor/pytoml/parser.py | 341 - .../pip/_vendor/pytoml/test.py | 30 - .../pip/_vendor/pytoml/utils.py | 67 - .../pip/_vendor/pytoml/writer.py | 106 - .../pip/_vendor/requests/__init__.py | 133 - .../pip/_vendor/requests/__version__.py | 14 - .../pip/_vendor/requests/_internal_utils.py | 42 - .../pip/_vendor/requests/adapters.py | 533 -- .../pip/_vendor/requests/api.py | 158 - .../pip/_vendor/requests/auth.py | 305 - .../pip/_vendor/requests/certs.py | 18 - .../pip/_vendor/requests/compat.py | 74 - .../pip/_vendor/requests/cookies.py | 549 -- .../pip/_vendor/requests/exceptions.py | 126 - .../pip/_vendor/requests/help.py | 119 - .../pip/_vendor/requests/hooks.py | 34 - .../pip/_vendor/requests/models.py | 953 -- .../pip/_vendor/requests/packages.py | 16 - .../pip/_vendor/requests/sessions.py | 770 -- .../pip/_vendor/requests/status_codes.py | 120 - .../pip/_vendor/requests/structures.py | 103 - .../pip/_vendor/requests/utils.py | 977 -- .../pip/_vendor/retrying.py | 267 - .../pip-19.0.3-py3.8.egg/pip/_vendor/six.py | 952 -- .../pip/_vendor/urllib3/__init__.py | 92 - .../pip/_vendor/urllib3/_collections.py | 329 - .../pip/_vendor/urllib3/connection.py | 391 - .../pip/_vendor/urllib3/connectionpool.py | 896 -- .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../urllib3/contrib/_appengine_environ.py | 30 - .../contrib/_securetransport/__init__.py | 0 .../contrib/_securetransport/bindings.py | 593 -- .../contrib/_securetransport/low_level.py | 346 - .../pip/_vendor/urllib3/contrib/appengine.py | 289 - .../pip/_vendor/urllib3/contrib/ntlmpool.py | 111 - .../pip/_vendor/urllib3/contrib/pyopenssl.py | 466 - .../urllib3/contrib/securetransport.py | 804 -- .../pip/_vendor/urllib3/contrib/socks.py | 192 - .../pip/_vendor/urllib3/exceptions.py | 246 - .../pip/_vendor/urllib3/fields.py | 178 - .../pip/_vendor/urllib3/filepost.py | 98 - .../pip/_vendor/urllib3/packages/__init__.py | 5 - .../urllib3/packages/backports/__init__.py | 0 .../urllib3/packages/backports/makefile.py | 53 - .../pip/_vendor/urllib3/packages/six.py | 868 -- .../packages/ssl_match_hostname/__init__.py | 19 - .../ssl_match_hostname/_implementation.py | 156 - .../pip/_vendor/urllib3/poolmanager.py | 450 - .../pip/_vendor/urllib3/request.py | 150 - .../pip/_vendor/urllib3/response.py | 705 -- .../pip/_vendor/urllib3/util/__init__.py | 54 - .../pip/_vendor/urllib3/util/connection.py | 134 - .../pip/_vendor/urllib3/util/queue.py | 21 - .../pip/_vendor/urllib3/util/request.py | 118 - .../pip/_vendor/urllib3/util/response.py | 87 - .../pip/_vendor/urllib3/util/retry.py | 411 - .../pip/_vendor/urllib3/util/ssl_.py | 381 - .../pip/_vendor/urllib3/util/timeout.py | 242 - .../pip/_vendor/urllib3/util/url.py | 230 - .../pip/_vendor/urllib3/util/wait.py | 150 - .../pip/_vendor/webencodings/__init__.py | 342 - .../pip/_vendor/webencodings/labels.py | 231 - .../pip/_vendor/webencodings/mklabels.py | 59 - .../pip/_vendor/webencodings/tests.py | 153 - .../_vendor/webencodings/x_user_defined.py | 325 - .../site-packages/setuptools-40.8.0-py3.8.egg | Bin 571890 -> 0 bytes .../python3.8/site-packages/setuptools.pth | 1 - venv/pyvenv.cfg | 3 - 330 files changed, 106688 deletions(-) delete mode 100644 venv/bin/Activate.ps1 delete mode 100644 venv/bin/activate delete mode 100644 venv/bin/activate.csh delete mode 100644 venv/bin/activate.fish delete mode 100755 venv/bin/easy_install delete mode 100755 venv/bin/easy_install-3.8 delete mode 100755 venv/bin/pip delete mode 100755 venv/bin/pip3 delete mode 100755 venv/bin/pip3.8 delete mode 100755 venv/bin/python delete mode 100755 venv/bin/python3 delete mode 100755 venv/bin/python3.8 delete mode 100644 venv/lib/python3.8/site-packages/easy-install.pth delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/PKG-INFO delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/SOURCES.txt delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/dependency_links.txt delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/entry_points.txt delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/not-zip-safe delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/top_level.txt delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/__main__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/build_env.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cache.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/autocompletion.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/base_command.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/cmdoptions.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/main_parser.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/parser.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/status_codes.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/check.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/completion.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/configuration.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/download.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/freeze.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/hash.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/help.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/install.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/list.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/search.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/show.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/uninstall.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/wheel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/configuration.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/download.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/exceptions.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/index.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/locations.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/candidate.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/format_control.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/index.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/link.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/check.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/freeze.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/prepare.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/pep425tags.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/pyproject.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/constructors.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_file.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_install.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_set.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_tracker.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_uninstall.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/resolve.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/appdirs.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/deprecation.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/encoding.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/filesystem.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/glibc.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/hashes.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/logging.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/misc.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/models.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/outdated.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/packaging.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/setuptools_build.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/temp_dir.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/typing.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/ui.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/bazaar.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/git.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/mercurial.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/subversion.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/wheel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/appdirs.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/_cmd.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/adapter.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/cache.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/file_cache.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/redis_cache.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/controller.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/filewrapper.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/heuristics.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/serialize.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/wrapper.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/__main__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/cacert.pem delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/core.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/big5freq.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/big5prober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/chardistribution.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/charsetgroupprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/charsetprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cli/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cli/chardetect.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/codingstatemachine.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cp949prober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/enums.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/escprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/escsm.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/eucjpprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euckrfreq.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euckrprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euctwfreq.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euctwprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/gb2312freq.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/gb2312prober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/hebrewprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/jisfreq.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/jpcntx.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langbulgarianmodel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langcyrillicmodel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langgreekmodel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langhebrewmodel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langhungarianmodel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langthaimodel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langturkishmodel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/latin1prober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcharsetprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcsgroupprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcssm.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sbcharsetprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sbcsgroupprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sjisprober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/universaldetector.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/utf8prober.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/version.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/ansi.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/ansitowin32.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/initialise.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/win32.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/winterm.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/misc.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/shutil.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/sysconfig.cfg delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/sysconfig.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/tarfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/database.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/index.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/locators.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/manifest.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/markers.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/metadata.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/resources.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/scripts.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/t32.exe delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/t64.exe delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/util.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/version.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/w32.exe delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/w64.exe delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/wheel.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distro.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_ihatexml.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_inputstream.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_tokenizer.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/_base.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/datrie.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/py.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_utils.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/constants.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/base.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/lint.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/optionaltags.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/sanitizer.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/whitespace.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/html5parser.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/serializer.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/genshi.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/sax.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/base.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/dom.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/etree.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/base.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/dom.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/etree.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/genshi.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/codec.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/core.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/idnadata.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/intranges.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/package_data.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/uts46data.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/ipaddress.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/linklockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/mkdirlockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/pidlockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/sqlitelockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/symlinklockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/_version.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/exceptions.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/fallback.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/__about__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/_compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/_structures.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/markers.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/requirements.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/specifiers.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/utils.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/version.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/_in_process.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/build.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/check.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/colorlog.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/envbuild.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/wrappers.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pkg_resources/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pkg_resources/py31compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/bar.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/counter.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/helpers.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/spinner.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pyparsing.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/core.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/parser.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/test.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/utils.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/writer.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/__version__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/_internal_utils.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/adapters.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/api.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/auth.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/certs.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/cookies.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/exceptions.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/help.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/hooks.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/models.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/packages.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/sessions.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/status_codes.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/structures.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/utils.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/retrying.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/six.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/_collections.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/connection.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/connectionpool.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_appengine_environ.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/appengine.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/ntlmpool.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/pyopenssl.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/securetransport.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/socks.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/exceptions.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/fields.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/filepost.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/backports/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/backports/makefile.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/six.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/poolmanager.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/request.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/response.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/connection.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/queue.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/request.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/response.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/retry.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/ssl_.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/timeout.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/url.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/wait.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/labels.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/mklabels.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/tests.py delete mode 100644 venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/x_user_defined.py delete mode 100644 venv/lib/python3.8/site-packages/setuptools-40.8.0-py3.8.egg delete mode 100644 venv/lib/python3.8/site-packages/setuptools.pth delete mode 100644 venv/pyvenv.cfg diff --git a/venv/bin/Activate.ps1 b/venv/bin/Activate.ps1 deleted file mode 100644 index 5b9adb2..0000000 --- a/venv/bin/Activate.ps1 +++ /dev/null @@ -1,231 +0,0 @@ -<# -.Synopsis -Activate a Python virtual environment for the current Powershell session. - -.Description -Pushes the python executable for a virtual environment to the front of the -$Env:PATH environment variable and sets the prompt to signify that you are -in a Python virtual environment. Makes use of the command line switches as -well as the `pyvenv.cfg` file values present in the virtual environment. - -.Parameter VenvDir -Path to the directory that contains the virtual environment to activate. The -default value for this is the parent of the directory that the Activate.ps1 -script is located within. - -.Parameter Prompt -The prompt prefix to display when this virtual environment is activated. By -default, this prompt is the name of the virtual environment folder (VenvDir) -surrounded by parentheses and followed by a single space (ie. '(.venv) '). - -.Example -Activate.ps1 -Activates the Python virtual environment that contains the Activate.ps1 script. - -.Example -Activate.ps1 -Verbose -Activates the Python virtual environment that contains the Activate.ps1 script, -and shows extra information about the activation as it executes. - -.Example -Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv -Activates the Python virtual environment located in the specified location. - -.Example -Activate.ps1 -Prompt "MyPython" -Activates the Python virtual environment that contains the Activate.ps1 script, -and prefixes the current prompt with the specified string (surrounded in -parentheses) while the virtual environment is active. - - -#> -Param( - [Parameter(Mandatory = $false)] - [String] - $VenvDir, - [Parameter(Mandatory = $false)] - [String] - $Prompt -) - -<# Function declarations --------------------------------------------------- #> - -<# -.Synopsis -Remove all shell session elements added by the Activate script, including the -addition of the virtual environment's Python executable from the beginning of -the PATH variable. - -.Parameter NonDestructive -If present, do not remove this function from the global namespace for the -session. - -#> -function global:deactivate ([switch]$NonDestructive) { - # Revert to original values - - # The prior prompt: - if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { - Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt - Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT - } - - # The prior PYTHONHOME: - if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { - Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME - Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME - } - - # The prior PATH: - if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { - Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH - Remove-Item -Path Env:_OLD_VIRTUAL_PATH - } - - # Just remove the VIRTUAL_ENV altogether: - if (Test-Path -Path Env:VIRTUAL_ENV) { - Remove-Item -Path env:VIRTUAL_ENV - } - - # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: - if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { - Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force - } - - # Leave deactivate function in the global namespace if requested: - if (-not $NonDestructive) { - Remove-Item -Path function:deactivate - } -} - -<# -.Description -Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the -given folder, and returns them in a map. - -For each line in the pyvenv.cfg file, if that line can be parsed into exactly -two strings separated by `=` (with any amount of whitespace surrounding the =) -then it is considered a `key = value` line. The left hand string is the key, -the right hand is the value. - -If the value starts with a `'` or a `"` then the first and last character is -stripped from the value before being captured. - -.Parameter ConfigDir -Path to the directory that contains the `pyvenv.cfg` file. -#> -function Get-PyVenvConfig( - [String] - $ConfigDir -) { - Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" - - # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). - $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue - - # An empty map will be returned if no config file is found. - $pyvenvConfig = @{ } - - if ($pyvenvConfigPath) { - - Write-Verbose "File exists, parse `key = value` lines" - $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath - - $pyvenvConfigContent | ForEach-Object { - $keyval = $PSItem -split "\s*=\s*", 2 - if ($keyval[0] -and $keyval[1]) { - $val = $keyval[1] - - # Remove extraneous quotations around a string value. - if ("'""".Contains($val.Substring(0,1))) { - $val = $val.Substring(1, $val.Length - 2) - } - - $pyvenvConfig[$keyval[0]] = $val - Write-Verbose "Adding Key: '$($keyval[0])'='$val'" - } - } - } - return $pyvenvConfig -} - - -<# Begin Activate script --------------------------------------------------- #> - -# Determine the containing directory of this script -$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition -$VenvExecDir = Get-Item -Path $VenvExecPath - -Write-Verbose "Activation script is located in path: '$VenvExecPath'" -Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" -Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" - -# Set values required in priority: CmdLine, ConfigFile, Default -# First, get the location of the virtual environment, it might not be -# VenvExecDir if specified on the command line. -if ($VenvDir) { - Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" -} else { - Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." - $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") - $VenvDir = $VenvDir.Insert($VenvDir.Length, "/") - Write-Verbose "VenvDir=$VenvDir" -} - -# Next, read the `pyvenv.cfg` file to determine any required value such -# as `prompt`. -$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir - -# Next, set the prompt from the command line, or the config file, or -# just use the name of the virtual environment folder. -if ($Prompt) { - Write-Verbose "Prompt specified as argument, using '$Prompt'" -} else { - Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" - if ($pyvenvCfg -and $pyvenvCfg['prompt']) { - Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" - $Prompt = $pyvenvCfg['prompt']; - } - else { - Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" - Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" - $Prompt = Split-Path -Path $venvDir -Leaf - } -} - -Write-Verbose "Prompt = '$Prompt'" -Write-Verbose "VenvDir='$VenvDir'" - -# Deactivate any currently active virtual environment, but leave the -# deactivate function in place. -deactivate -nondestructive - -# Now set the environment variable VIRTUAL_ENV, used by many tools to determine -# that there is an activated venv. -$env:VIRTUAL_ENV = $VenvDir - -if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { - - Write-Verbose "Setting prompt to '$Prompt'" - - # Set the prompt to include the env name - # Make sure _OLD_VIRTUAL_PROMPT is global - function global:_OLD_VIRTUAL_PROMPT { "" } - Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT - New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt - - function global:prompt { - Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " - _OLD_VIRTUAL_PROMPT - } -} - -# Clear PYTHONHOME -if (Test-Path -Path Env:PYTHONHOME) { - Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME - Remove-Item -Path Env:PYTHONHOME -} - -# Add the venv to the PATH -Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH -$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/venv/bin/activate b/venv/bin/activate deleted file mode 100644 index 4eff59b..0000000 --- a/venv/bin/activate +++ /dev/null @@ -1,76 +0,0 @@ -# This file must be used with "source bin/activate" *from bash* -# you cannot run it directly - -deactivate () { - # reset old environment variables - if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then - PATH="${_OLD_VIRTUAL_PATH:-}" - export PATH - unset _OLD_VIRTUAL_PATH - fi - if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then - PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" - export PYTHONHOME - unset _OLD_VIRTUAL_PYTHONHOME - fi - - # This should detect bash and zsh, which have a hash command that must - # be called to get it to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected - if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r - fi - - if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then - PS1="${_OLD_VIRTUAL_PS1:-}" - export PS1 - unset _OLD_VIRTUAL_PS1 - fi - - unset VIRTUAL_ENV - if [ ! "${1:-}" = "nondestructive" ] ; then - # Self destruct! - unset -f deactivate - fi -} - -# unset irrelevant variables -deactivate nondestructive - -VIRTUAL_ENV="/Users/imtiazahmad/PycharmProjects/Assignments/venv" -export VIRTUAL_ENV - -_OLD_VIRTUAL_PATH="$PATH" -PATH="$VIRTUAL_ENV/bin:$PATH" -export PATH - -# unset PYTHONHOME if set -# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) -# could use `if (set -u; : $PYTHONHOME) ;` in bash -if [ -n "${PYTHONHOME:-}" ] ; then - _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" - unset PYTHONHOME -fi - -if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then - _OLD_VIRTUAL_PS1="${PS1:-}" - if [ "x(venv) " != x ] ; then - PS1="(venv) ${PS1:-}" - else - if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" - else - PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" - fi - fi - export PS1 -fi - -# This should detect bash and zsh, which have a hash command that must -# be called to get it to forget past commands. Without forgetting -# past commands the $PATH changes we made may not be respected -if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r -fi diff --git a/venv/bin/activate.csh b/venv/bin/activate.csh deleted file mode 100644 index 3a5f21e..0000000 --- a/venv/bin/activate.csh +++ /dev/null @@ -1,37 +0,0 @@ -# This file must be used with "source bin/activate.csh" *from csh*. -# You cannot run it directly. -# Created by Davide Di Blasi . -# Ported to Python 3.3 venv by Andrew Svetlov - -alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' - -# Unset irrelevant variables. -deactivate nondestructive - -setenv VIRTUAL_ENV "/Users/imtiazahmad/PycharmProjects/Assignments/venv" - -set _OLD_VIRTUAL_PATH="$PATH" -setenv PATH "$VIRTUAL_ENV/bin:$PATH" - - -set _OLD_VIRTUAL_PROMPT="$prompt" - -if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then - if ("venv" != "") then - set env_name = "venv" - else - if (`basename "VIRTUAL_ENV"` == "__") then - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` - else - set env_name = `basename "$VIRTUAL_ENV"` - endif - endif - set prompt = "[$env_name] $prompt" - unset env_name -endif - -alias pydoc python -m pydoc - -rehash diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish deleted file mode 100644 index 1e68fdd..0000000 --- a/venv/bin/activate.fish +++ /dev/null @@ -1,75 +0,0 @@ -# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) -# you cannot run it directly - -function deactivate -d "Exit virtualenv and return to normal shell environment" - # reset old environment variables - if test -n "$_OLD_VIRTUAL_PATH" - set -gx PATH $_OLD_VIRTUAL_PATH - set -e _OLD_VIRTUAL_PATH - end - if test -n "$_OLD_VIRTUAL_PYTHONHOME" - set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME - set -e _OLD_VIRTUAL_PYTHONHOME - end - - if test -n "$_OLD_FISH_PROMPT_OVERRIDE" - functions -e fish_prompt - set -e _OLD_FISH_PROMPT_OVERRIDE - functions -c _old_fish_prompt fish_prompt - functions -e _old_fish_prompt - end - - set -e VIRTUAL_ENV - if test "$argv[1]" != "nondestructive" - # Self destruct! - functions -e deactivate - end -end - -# unset irrelevant variables -deactivate nondestructive - -set -gx VIRTUAL_ENV "/Users/imtiazahmad/PycharmProjects/Assignments/venv" - -set -gx _OLD_VIRTUAL_PATH $PATH -set -gx PATH "$VIRTUAL_ENV/bin" $PATH - -# unset PYTHONHOME if set -if set -q PYTHONHOME - set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME - set -e PYTHONHOME -end - -if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" - # fish uses a function instead of an env var to generate the prompt. - - # save the current fish_prompt function as the function _old_fish_prompt - functions -c fish_prompt _old_fish_prompt - - # with the original prompt function renamed, we can override with our own. - function fish_prompt - # Save the return status of the last command - set -l old_status $status - - # Prompt override? - if test -n "(venv) " - printf "%s%s" "(venv) " (set_color normal) - else - # ...Otherwise, prepend env - set -l _checkbase (basename "$VIRTUAL_ENV") - if test $_checkbase = "__" - # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ - printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) - else - printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) - end - end - - # Restore the return status of the previous command. - echo "exit $old_status" | . - _old_fish_prompt - end - - set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" -end diff --git a/venv/bin/easy_install b/venv/bin/easy_install deleted file mode 100755 index 620ffe3..0000000 --- a/venv/bin/easy_install +++ /dev/null @@ -1,12 +0,0 @@ -#!/Users/imtiazahmad/PycharmProjects/Assignments/venv/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==40.8.0','console_scripts','easy_install' -__requires__ = 'setuptools==40.8.0' -import re -import sys -from pkg_resources import load_entry_point - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit( - load_entry_point('setuptools==40.8.0', 'console_scripts', 'easy_install')() - ) diff --git a/venv/bin/easy_install-3.8 b/venv/bin/easy_install-3.8 deleted file mode 100755 index ba5512f..0000000 --- a/venv/bin/easy_install-3.8 +++ /dev/null @@ -1,12 +0,0 @@ -#!/Users/imtiazahmad/PycharmProjects/Assignments/venv/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==40.8.0','console_scripts','easy_install-3.8' -__requires__ = 'setuptools==40.8.0' -import re -import sys -from pkg_resources import load_entry_point - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit( - load_entry_point('setuptools==40.8.0', 'console_scripts', 'easy_install-3.8')() - ) diff --git a/venv/bin/pip b/venv/bin/pip deleted file mode 100755 index 433e6a5..0000000 --- a/venv/bin/pip +++ /dev/null @@ -1,12 +0,0 @@ -#!/Users/imtiazahmad/PycharmProjects/Assignments/venv/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip' -__requires__ = 'pip==19.0.3' -import re -import sys -from pkg_resources import load_entry_point - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit( - load_entry_point('pip==19.0.3', 'console_scripts', 'pip')() - ) diff --git a/venv/bin/pip3 b/venv/bin/pip3 deleted file mode 100755 index 3a6e169..0000000 --- a/venv/bin/pip3 +++ /dev/null @@ -1,12 +0,0 @@ -#!/Users/imtiazahmad/PycharmProjects/Assignments/venv/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip3' -__requires__ = 'pip==19.0.3' -import re -import sys -from pkg_resources import load_entry_point - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit( - load_entry_point('pip==19.0.3', 'console_scripts', 'pip3')() - ) diff --git a/venv/bin/pip3.8 b/venv/bin/pip3.8 deleted file mode 100755 index 186186a..0000000 --- a/venv/bin/pip3.8 +++ /dev/null @@ -1,12 +0,0 @@ -#!/Users/imtiazahmad/PycharmProjects/Assignments/venv/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip3.8' -__requires__ = 'pip==19.0.3' -import re -import sys -from pkg_resources import load_entry_point - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit( - load_entry_point('pip==19.0.3', 'console_scripts', 'pip3.8')() - ) diff --git a/venv/bin/python b/venv/bin/python deleted file mode 100755 index b63a1a6c704d3534300c6c4f5428d363a0fe1909..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9604 zcmeHNZEPGz8J;6Cb<-s0l%|E!2KOVx1mSbr7(x;YyUC^-uw6HagA-A0&c40)l=I!O zx7XM~2B)!$&liJLN>m_%@S!RM6-B6Oq976{4cI?W8vzoQ_)wIl)mo)s@gYJ54bL+> zd)`~yRe$hyzk8WKJ(5y^Ukej{K{KzzI~Grp+!OryhjMJ0=e?NLJWy&P(pkF zSw}XEwx&n4J=*q1*;<-HrR=;MacVGtVeHg8c9x1r{i@P7p?KIPDv)84Oom~by|!Xd z1@Xo!F&VV~Zm}yvUXgCYVlm(nZfO`lHU;sHEpzeWO2Xqkg-V4tYaj89ZZnxN zEeHki7B6@4&ME-%^m{SQv9Bv@TZz;@B@o0rr|^EQ`pNrK2{t+mBbPdmNX3jqDxQ{n z>3Td9cJ1SuGm#HsxIJ!Z7-qK-x1v3!$Cu(=QF!lHO60NE7EIhH!&pGW*wVDK$tQ;W zAooeNYV-DsZ=Vp?TWiBeC5>!fPiH!5WNd3eJP(HZ&2Jaild<3>!`PShZM!*mRnVt> z-aN?%@!scwp*D>z`Zsalr8<7t;4>t38IP?2&7MNwHTL>qaPI;w@}fWoPJgrFSv z8huy?#XC@Mx*z8c`fma4=@H+{lwXOwP&$5}5Nqb?WSCSVFGY^zvQ{LS=#0erk}>d1 zA4H}dYySGxoj;2|^z@JSe`D0S_~J&G=gTG>Q8m5n@9yI%DYf{D26kv-f{ z=y@z_Xm(DR*N(odZT8eYT#NZ7I;kbZhmot0uiOJOP=7@64tS=IBD0^o&W3U-d*J`j z1MPbLHU03P8Yi@W)4F{Bbv>V(aZJRRKHBgyjw5|EcSX-@&V+V_JKcE>@sZcA9qPYE zh49cTAu0NOh@Oj}#d!?^P?*vW^-oEW!5^Ul+JHo>@54`+UeKmS^w4n2Z%O^4F(jO0 zRBMn5LwBM&4_s)~ci^PdM^|o!@+skLrPOFcJu%M6$b-}fVcMsLKONEwxhXw=QO{p+ zs$4vn9DZswgq*+O#PC2DxuAc>&(wtc9RTzj=%0RF4%#pyhpB%V$DFfh0mIHqnUyDj z0qy6Z4a1H>14jRZeMS3}MPH;y1C3S|MST{1-bMSI-=f_vrtV@kp=%E2+92jKALiXI zCcj6Ev#db>G$u)7m&^Wo2j6IC>1}5fI`i5keYAfP>*DBzmKi-C(kHY@YB=BFQlBBo zq>r{hs^Lz$vXFC{3))O`A*|;oFkR6iiPwfdG$=vT{@be; zDlSNCa+iVN?1qrq3ouT=g6kBYUP22B{g<7C5WpszftfRU#U{!?ZG+o7j;%LN`S4JQ z_Ae=R_J&Hp8HeGQohuTweOzDEKBFJH$ZkE~J_-0Ur!X33xv^z@SUVjaG3|-y6)ui8IenUd(9$dDWWdt7E=DaehOoX8)+aDp z&mXuFV<(+Yc!uWN5vJM+z+Bf4U)uZlOYwj|>vTkNd_ucQ;Qs5*$DoOjbpC>o3N2H4 zm=8+0Gdd5ians(18VmHQ^pvut>U#ffjrLh~UpTb}_Ru9W^M3zTn`4w4? z$?|DgJ|oMcvV2yS-<0JsS$LjT?QpZURlR8T3D5)c)en{#`Qa>lv zOX>|$DN;*e$8?O;T2gyReUelgDSi-6Zv|zU(PSoScWf}X{9BZXG=dG^f+2jfQClWS+~zR{w~J73Rj6v|O_gIs5!LxFs@o9bR9mI$8dX22 z>P@QNs_HgX?@@J3)hSi?s`^P)A5ryDRUcRNNmaj~>UUvkS)}ZNvIoi@D0`snfwBk6 z9w>XD?18ce${r|tpzMLN2Lc{gac|9DzH_ci+~9xd>deo00z)xPZZh>)hQKI7#L|25_>t2Y~O0 zk!0}{aJgdqdy!u}g=Fx%VP6b*FVstd+|SI0_ng+!xSp@u4d?|T*$ZJDi!ydu%b=Ze WR$9@RwILFz|M&yz>eoFe#D4(=^&-;% diff --git a/venv/bin/python3 b/venv/bin/python3 deleted file mode 100755 index b63a1a6c704d3534300c6c4f5428d363a0fe1909..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9604 zcmeHNZEPGz8J;6Cb<-s0l%|E!2KOVx1mSbr7(x;YyUC^-uw6HagA-A0&c40)l=I!O zx7XM~2B)!$&liJLN>m_%@S!RM6-B6Oq976{4cI?W8vzoQ_)wIl)mo)s@gYJ54bL+> zd)`~yRe$hyzk8WKJ(5y^Ukej{K{KzzI~Grp+!OryhjMJ0=e?NLJWy&P(pkF zSw}XEwx&n4J=*q1*;<-HrR=;MacVGtVeHg8c9x1r{i@P7p?KIPDv)84Oom~by|!Xd z1@Xo!F&VV~Zm}yvUXgCYVlm(nZfO`lHU;sHEpzeWO2Xqkg-V4tYaj89ZZnxN zEeHki7B6@4&ME-%^m{SQv9Bv@TZz;@B@o0rr|^EQ`pNrK2{t+mBbPdmNX3jqDxQ{n z>3Td9cJ1SuGm#HsxIJ!Z7-qK-x1v3!$Cu(=QF!lHO60NE7EIhH!&pGW*wVDK$tQ;W zAooeNYV-DsZ=Vp?TWiBeC5>!fPiH!5WNd3eJP(HZ&2Jaild<3>!`PShZM!*mRnVt> z-aN?%@!scwp*D>z`Zsalr8<7t;4>t38IP?2&7MNwHTL>qaPI;w@}fWoPJgrFSv z8huy?#XC@Mx*z8c`fma4=@H+{lwXOwP&$5}5Nqb?WSCSVFGY^zvQ{LS=#0erk}>d1 zA4H}dYySGxoj;2|^z@JSe`D0S_~J&G=gTG>Q8m5n@9yI%DYf{D26kv-f{ z=y@z_Xm(DR*N(odZT8eYT#NZ7I;kbZhmot0uiOJOP=7@64tS=IBD0^o&W3U-d*J`j z1MPbLHU03P8Yi@W)4F{Bbv>V(aZJRRKHBgyjw5|EcSX-@&V+V_JKcE>@sZcA9qPYE zh49cTAu0NOh@Oj}#d!?^P?*vW^-oEW!5^Ul+JHo>@54`+UeKmS^w4n2Z%O^4F(jO0 zRBMn5LwBM&4_s)~ci^PdM^|o!@+skLrPOFcJu%M6$b-}fVcMsLKONEwxhXw=QO{p+ zs$4vn9DZswgq*+O#PC2DxuAc>&(wtc9RTzj=%0RF4%#pyhpB%V$DFfh0mIHqnUyDj z0qy6Z4a1H>14jRZeMS3}MPH;y1C3S|MST{1-bMSI-=f_vrtV@kp=%E2+92jKALiXI zCcj6Ev#db>G$u)7m&^Wo2j6IC>1}5fI`i5keYAfP>*DBzmKi-C(kHY@YB=BFQlBBo zq>r{hs^Lz$vXFC{3))O`A*|;oFkR6iiPwfdG$=vT{@be; zDlSNCa+iVN?1qrq3ouT=g6kBYUP22B{g<7C5WpszftfRU#U{!?ZG+o7j;%LN`S4JQ z_Ae=R_J&Hp8HeGQohuTweOzDEKBFJH$ZkE~J_-0Ur!X33xv^z@SUVjaG3|-y6)ui8IenUd(9$dDWWdt7E=DaehOoX8)+aDp z&mXuFV<(+Yc!uWN5vJM+z+Bf4U)uZlOYwj|>vTkNd_ucQ;Qs5*$DoOjbpC>o3N2H4 zm=8+0Gdd5ians(18VmHQ^pvut>U#ffjrLh~UpTb}_Ru9W^M3zTn`4w4? z$?|DgJ|oMcvV2yS-<0JsS$LjT?QpZURlR8T3D5)c)en{#`Qa>lv zOX>|$DN;*e$8?O;T2gyReUelgDSi-6Zv|zU(PSoScWf}X{9BZXG=dG^f+2jfQClWS+~zR{w~J73Rj6v|O_gIs5!LxFs@o9bR9mI$8dX22 z>P@QNs_HgX?@@J3)hSi?s`^P)A5ryDRUcRNNmaj~>UUvkS)}ZNvIoi@D0`snfwBk6 z9w>XD?18ce${r|tpzMLN2Lc{gac|9DzH_ci+~9xd>deo00z)xPZZh>)hQKI7#L|25_>t2Y~O0 zk!0}{aJgdqdy!u}g=Fx%VP6b*FVstd+|SI0_ng+!xSp@u4d?|T*$ZJDi!ydu%b=Ze WR$9@RwILFz|M&yz>eoFe#D4(=^&-;% diff --git a/venv/bin/python3.8 b/venv/bin/python3.8 deleted file mode 100755 index b63a1a6c704d3534300c6c4f5428d363a0fe1909..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9604 zcmeHNZEPGz8J;6Cb<-s0l%|E!2KOVx1mSbr7(x;YyUC^-uw6HagA-A0&c40)l=I!O zx7XM~2B)!$&liJLN>m_%@S!RM6-B6Oq976{4cI?W8vzoQ_)wIl)mo)s@gYJ54bL+> zd)`~yRe$hyzk8WKJ(5y^Ukej{K{KzzI~Grp+!OryhjMJ0=e?NLJWy&P(pkF zSw}XEwx&n4J=*q1*;<-HrR=;MacVGtVeHg8c9x1r{i@P7p?KIPDv)84Oom~by|!Xd z1@Xo!F&VV~Zm}yvUXgCYVlm(nZfO`lHU;sHEpzeWO2Xqkg-V4tYaj89ZZnxN zEeHki7B6@4&ME-%^m{SQv9Bv@TZz;@B@o0rr|^EQ`pNrK2{t+mBbPdmNX3jqDxQ{n z>3Td9cJ1SuGm#HsxIJ!Z7-qK-x1v3!$Cu(=QF!lHO60NE7EIhH!&pGW*wVDK$tQ;W zAooeNYV-DsZ=Vp?TWiBeC5>!fPiH!5WNd3eJP(HZ&2Jaild<3>!`PShZM!*mRnVt> z-aN?%@!scwp*D>z`Zsalr8<7t;4>t38IP?2&7MNwHTL>qaPI;w@}fWoPJgrFSv z8huy?#XC@Mx*z8c`fma4=@H+{lwXOwP&$5}5Nqb?WSCSVFGY^zvQ{LS=#0erk}>d1 zA4H}dYySGxoj;2|^z@JSe`D0S_~J&G=gTG>Q8m5n@9yI%DYf{D26kv-f{ z=y@z_Xm(DR*N(odZT8eYT#NZ7I;kbZhmot0uiOJOP=7@64tS=IBD0^o&W3U-d*J`j z1MPbLHU03P8Yi@W)4F{Bbv>V(aZJRRKHBgyjw5|EcSX-@&V+V_JKcE>@sZcA9qPYE zh49cTAu0NOh@Oj}#d!?^P?*vW^-oEW!5^Ul+JHo>@54`+UeKmS^w4n2Z%O^4F(jO0 zRBMn5LwBM&4_s)~ci^PdM^|o!@+skLrPOFcJu%M6$b-}fVcMsLKONEwxhXw=QO{p+ zs$4vn9DZswgq*+O#PC2DxuAc>&(wtc9RTzj=%0RF4%#pyhpB%V$DFfh0mIHqnUyDj z0qy6Z4a1H>14jRZeMS3}MPH;y1C3S|MST{1-bMSI-=f_vrtV@kp=%E2+92jKALiXI zCcj6Ev#db>G$u)7m&^Wo2j6IC>1}5fI`i5keYAfP>*DBzmKi-C(kHY@YB=BFQlBBo zq>r{hs^Lz$vXFC{3))O`A*|;oFkR6iiPwfdG$=vT{@be; zDlSNCa+iVN?1qrq3ouT=g6kBYUP22B{g<7C5WpszftfRU#U{!?ZG+o7j;%LN`S4JQ z_Ae=R_J&Hp8HeGQohuTweOzDEKBFJH$ZkE~J_-0Ur!X33xv^z@SUVjaG3|-y6)ui8IenUd(9$dDWWdt7E=DaehOoX8)+aDp z&mXuFV<(+Yc!uWN5vJM+z+Bf4U)uZlOYwj|>vTkNd_ucQ;Qs5*$DoOjbpC>o3N2H4 zm=8+0Gdd5ians(18VmHQ^pvut>U#ffjrLh~UpTb}_Ru9W^M3zTn`4w4? z$?|DgJ|oMcvV2yS-<0JsS$LjT?QpZURlR8T3D5)c)en{#`Qa>lv zOX>|$DN;*e$8?O;T2gyReUelgDSi-6Zv|zU(PSoScWf}X{9BZXG=dG^f+2jfQClWS+~zR{w~J73Rj6v|O_gIs5!LxFs@o9bR9mI$8dX22 z>P@QNs_HgX?@@J3)hSi?s`^P)A5ryDRUcRNNmaj~>UUvkS)}ZNvIoi@D0`snfwBk6 z9w>XD?18ce${r|tpzMLN2Lc{gac|9DzH_ci+~9xd>deo00z)xPZZh>)hQKI7#L|25_>t2Y~O0 zk!0}{aJgdqdy!u}g=Fx%VP6b*FVstd+|SI0_ng+!xSp@u4d?|T*$ZJDi!ydu%b=Ze WR$9@RwILFz|M&yz>eoFe#D4(=^&-;% diff --git a/venv/lib/python3.8/site-packages/easy-install.pth b/venv/lib/python3.8/site-packages/easy-install.pth deleted file mode 100644 index c5c7346..0000000 --- a/venv/lib/python3.8/site-packages/easy-install.pth +++ /dev/null @@ -1,2 +0,0 @@ -./setuptools-40.8.0-py3.8.egg -./pip-19.0.3-py3.8.egg diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/PKG-INFO b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/PKG-INFO deleted file mode 100644 index 0b410a2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/PKG-INFO +++ /dev/null @@ -1,73 +0,0 @@ -Metadata-Version: 1.2 -Name: pip -Version: 19.0.3 -Summary: The PyPA recommended tool for installing Python packages. -Home-page: https://pip.pypa.io/ -Author: The pip developers -Author-email: pypa-dev@groups.google.com -License: MIT -Description: pip - The Python Package Installer - ================================== - - .. image:: https://img.shields.io/pypi/v/pip.svg - :target: https://pypi.org/project/pip/ - - .. image:: https://readthedocs.org/projects/pip/badge/?version=latest - :target: https://pip.pypa.io/en/latest - - pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. - - Please take a look at our documentation for how to install and use pip: - - * `Installation`_ - * `Usage`_ - * `Release notes`_ - - If you find bugs, need help, or want to talk to the developers please use our mailing lists or chat rooms: - - * `Issue tracking`_ - * `Discourse channel`_ - * `User IRC`_ - - If you want to get involved head over to GitHub to get the source code and feel free to jump on the developer mailing lists and chat rooms: - - * `GitHub page`_ - * `Dev mailing list`_ - * `Dev IRC`_ - - Code of Conduct - --------------- - - Everyone interacting in the pip project's codebases, issue trackers, chat - rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. - - .. _package installer: https://packaging.python.org/en/latest/current/ - .. _Python Package Index: https://pypi.org - .. _Installation: https://pip.pypa.io/en/stable/installing.html - .. _Usage: https://pip.pypa.io/en/stable/ - .. _Release notes: https://pip.pypa.io/en/stable/news.html - .. _GitHub page: https://github.com/pypa/pip - .. _Issue tracking: https://github.com/pypa/pip/issues - .. _Discourse channel: https://discuss.python.org/c/packaging - .. _Dev mailing list: https://groups.google.com/forum/#!forum/pypa-dev - .. _User IRC: https://webchat.freenode.net/?channels=%23pypa - .. _Dev IRC: https://webchat.freenode.net/?channels=%23pypa-dev - .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ - -Keywords: distutils easy_install egg setuptools wheel virtualenv -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Topic :: Software Development :: Build Tools -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/SOURCES.txt b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/SOURCES.txt deleted file mode 100644 index eb4810d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/SOURCES.txt +++ /dev/null @@ -1,391 +0,0 @@ -AUTHORS.txt -LICENSE.txt -MANIFEST.in -NEWS.rst -README.rst -pyproject.toml -setup.cfg -setup.py -docs/pip_sphinxext.py -docs/html/conf.py -docs/html/cookbook.rst -docs/html/index.rst -docs/html/installing.rst -docs/html/logic.rst -docs/html/news.rst -docs/html/quickstart.rst -docs/html/usage.rst -docs/html/user_guide.rst -docs/html/development/configuration.rst -docs/html/development/contributing.rst -docs/html/development/getting-started.rst -docs/html/development/index.rst -docs/html/development/release-process.rst -docs/html/development/vendoring-policy.rst -docs/html/reference/index.rst -docs/html/reference/pip.rst -docs/html/reference/pip_check.rst -docs/html/reference/pip_config.rst -docs/html/reference/pip_download.rst -docs/html/reference/pip_freeze.rst -docs/html/reference/pip_hash.rst -docs/html/reference/pip_install.rst -docs/html/reference/pip_list.rst -docs/html/reference/pip_search.rst -docs/html/reference/pip_show.rst -docs/html/reference/pip_uninstall.rst -docs/html/reference/pip_wheel.rst -docs/man/index.rst -docs/man/commands/check.rst -docs/man/commands/config.rst -docs/man/commands/download.rst -docs/man/commands/freeze.rst -docs/man/commands/hash.rst -docs/man/commands/help.rst -docs/man/commands/install.rst -docs/man/commands/list.rst -docs/man/commands/search.rst -docs/man/commands/show.rst -docs/man/commands/uninstall.rst -docs/man/commands/wheel.rst -src/pip/__init__.py -src/pip/__main__.py -src/pip.egg-info/PKG-INFO -src/pip.egg-info/SOURCES.txt -src/pip.egg-info/dependency_links.txt -src/pip.egg-info/entry_points.txt -src/pip.egg-info/not-zip-safe -src/pip.egg-info/top_level.txt -src/pip/_internal/__init__.py -src/pip/_internal/build_env.py -src/pip/_internal/cache.py -src/pip/_internal/configuration.py -src/pip/_internal/download.py -src/pip/_internal/exceptions.py -src/pip/_internal/index.py -src/pip/_internal/locations.py -src/pip/_internal/pep425tags.py -src/pip/_internal/pyproject.py -src/pip/_internal/resolve.py -src/pip/_internal/wheel.py -src/pip/_internal/cli/__init__.py -src/pip/_internal/cli/autocompletion.py -src/pip/_internal/cli/base_command.py -src/pip/_internal/cli/cmdoptions.py -src/pip/_internal/cli/main_parser.py -src/pip/_internal/cli/parser.py -src/pip/_internal/cli/status_codes.py -src/pip/_internal/commands/__init__.py -src/pip/_internal/commands/check.py -src/pip/_internal/commands/completion.py -src/pip/_internal/commands/configuration.py -src/pip/_internal/commands/download.py -src/pip/_internal/commands/freeze.py -src/pip/_internal/commands/hash.py -src/pip/_internal/commands/help.py -src/pip/_internal/commands/install.py -src/pip/_internal/commands/list.py -src/pip/_internal/commands/search.py -src/pip/_internal/commands/show.py -src/pip/_internal/commands/uninstall.py -src/pip/_internal/commands/wheel.py -src/pip/_internal/models/__init__.py -src/pip/_internal/models/candidate.py -src/pip/_internal/models/format_control.py -src/pip/_internal/models/index.py -src/pip/_internal/models/link.py -src/pip/_internal/operations/__init__.py -src/pip/_internal/operations/check.py -src/pip/_internal/operations/freeze.py -src/pip/_internal/operations/prepare.py -src/pip/_internal/req/__init__.py -src/pip/_internal/req/constructors.py -src/pip/_internal/req/req_file.py -src/pip/_internal/req/req_install.py -src/pip/_internal/req/req_set.py -src/pip/_internal/req/req_tracker.py -src/pip/_internal/req/req_uninstall.py -src/pip/_internal/utils/__init__.py -src/pip/_internal/utils/appdirs.py -src/pip/_internal/utils/compat.py -src/pip/_internal/utils/deprecation.py -src/pip/_internal/utils/encoding.py -src/pip/_internal/utils/filesystem.py -src/pip/_internal/utils/glibc.py -src/pip/_internal/utils/hashes.py -src/pip/_internal/utils/logging.py -src/pip/_internal/utils/misc.py -src/pip/_internal/utils/models.py -src/pip/_internal/utils/outdated.py -src/pip/_internal/utils/packaging.py -src/pip/_internal/utils/setuptools_build.py -src/pip/_internal/utils/temp_dir.py -src/pip/_internal/utils/typing.py -src/pip/_internal/utils/ui.py -src/pip/_internal/vcs/__init__.py -src/pip/_internal/vcs/bazaar.py -src/pip/_internal/vcs/git.py -src/pip/_internal/vcs/mercurial.py -src/pip/_internal/vcs/subversion.py -src/pip/_vendor/README.rst -src/pip/_vendor/__init__.py -src/pip/_vendor/appdirs.LICENSE.txt -src/pip/_vendor/appdirs.py -src/pip/_vendor/distro.LICENSE -src/pip/_vendor/distro.py -src/pip/_vendor/ipaddress.LICENSE -src/pip/_vendor/ipaddress.py -src/pip/_vendor/pyparsing.LICENSE -src/pip/_vendor/pyparsing.py -src/pip/_vendor/retrying.LICENSE -src/pip/_vendor/retrying.py -src/pip/_vendor/six.LICENSE -src/pip/_vendor/six.py -src/pip/_vendor/vendor.txt -src/pip/_vendor/cachecontrol/LICENSE.txt -src/pip/_vendor/cachecontrol/__init__.py -src/pip/_vendor/cachecontrol/_cmd.py -src/pip/_vendor/cachecontrol/adapter.py -src/pip/_vendor/cachecontrol/cache.py -src/pip/_vendor/cachecontrol/compat.py -src/pip/_vendor/cachecontrol/controller.py -src/pip/_vendor/cachecontrol/filewrapper.py -src/pip/_vendor/cachecontrol/heuristics.py -src/pip/_vendor/cachecontrol/serialize.py -src/pip/_vendor/cachecontrol/wrapper.py -src/pip/_vendor/cachecontrol/caches/__init__.py -src/pip/_vendor/cachecontrol/caches/file_cache.py -src/pip/_vendor/cachecontrol/caches/redis_cache.py -src/pip/_vendor/certifi/LICENSE -src/pip/_vendor/certifi/__init__.py -src/pip/_vendor/certifi/__main__.py -src/pip/_vendor/certifi/cacert.pem -src/pip/_vendor/certifi/core.py -src/pip/_vendor/chardet/LICENSE -src/pip/_vendor/chardet/__init__.py -src/pip/_vendor/chardet/big5freq.py -src/pip/_vendor/chardet/big5prober.py -src/pip/_vendor/chardet/chardistribution.py -src/pip/_vendor/chardet/charsetgroupprober.py -src/pip/_vendor/chardet/charsetprober.py -src/pip/_vendor/chardet/codingstatemachine.py -src/pip/_vendor/chardet/compat.py -src/pip/_vendor/chardet/cp949prober.py -src/pip/_vendor/chardet/enums.py -src/pip/_vendor/chardet/escprober.py -src/pip/_vendor/chardet/escsm.py -src/pip/_vendor/chardet/eucjpprober.py -src/pip/_vendor/chardet/euckrfreq.py -src/pip/_vendor/chardet/euckrprober.py -src/pip/_vendor/chardet/euctwfreq.py -src/pip/_vendor/chardet/euctwprober.py -src/pip/_vendor/chardet/gb2312freq.py -src/pip/_vendor/chardet/gb2312prober.py -src/pip/_vendor/chardet/hebrewprober.py -src/pip/_vendor/chardet/jisfreq.py -src/pip/_vendor/chardet/jpcntx.py -src/pip/_vendor/chardet/langbulgarianmodel.py -src/pip/_vendor/chardet/langcyrillicmodel.py -src/pip/_vendor/chardet/langgreekmodel.py -src/pip/_vendor/chardet/langhebrewmodel.py -src/pip/_vendor/chardet/langhungarianmodel.py -src/pip/_vendor/chardet/langthaimodel.py -src/pip/_vendor/chardet/langturkishmodel.py -src/pip/_vendor/chardet/latin1prober.py -src/pip/_vendor/chardet/mbcharsetprober.py -src/pip/_vendor/chardet/mbcsgroupprober.py -src/pip/_vendor/chardet/mbcssm.py -src/pip/_vendor/chardet/sbcharsetprober.py -src/pip/_vendor/chardet/sbcsgroupprober.py -src/pip/_vendor/chardet/sjisprober.py -src/pip/_vendor/chardet/universaldetector.py -src/pip/_vendor/chardet/utf8prober.py -src/pip/_vendor/chardet/version.py -src/pip/_vendor/chardet/cli/__init__.py -src/pip/_vendor/chardet/cli/chardetect.py -src/pip/_vendor/colorama/LICENSE.txt -src/pip/_vendor/colorama/__init__.py -src/pip/_vendor/colorama/ansi.py -src/pip/_vendor/colorama/ansitowin32.py -src/pip/_vendor/colorama/initialise.py -src/pip/_vendor/colorama/win32.py -src/pip/_vendor/colorama/winterm.py -src/pip/_vendor/distlib/LICENSE.txt -src/pip/_vendor/distlib/__init__.py -src/pip/_vendor/distlib/compat.py -src/pip/_vendor/distlib/database.py -src/pip/_vendor/distlib/index.py -src/pip/_vendor/distlib/locators.py -src/pip/_vendor/distlib/manifest.py -src/pip/_vendor/distlib/markers.py -src/pip/_vendor/distlib/metadata.py -src/pip/_vendor/distlib/resources.py -src/pip/_vendor/distlib/scripts.py -src/pip/_vendor/distlib/t32.exe -src/pip/_vendor/distlib/t64.exe -src/pip/_vendor/distlib/util.py -src/pip/_vendor/distlib/version.py -src/pip/_vendor/distlib/w32.exe -src/pip/_vendor/distlib/w64.exe -src/pip/_vendor/distlib/wheel.py -src/pip/_vendor/distlib/_backport/__init__.py -src/pip/_vendor/distlib/_backport/misc.py -src/pip/_vendor/distlib/_backport/shutil.py -src/pip/_vendor/distlib/_backport/sysconfig.cfg -src/pip/_vendor/distlib/_backport/sysconfig.py -src/pip/_vendor/distlib/_backport/tarfile.py -src/pip/_vendor/html5lib/LICENSE -src/pip/_vendor/html5lib/__init__.py -src/pip/_vendor/html5lib/_ihatexml.py -src/pip/_vendor/html5lib/_inputstream.py -src/pip/_vendor/html5lib/_tokenizer.py -src/pip/_vendor/html5lib/_utils.py -src/pip/_vendor/html5lib/constants.py -src/pip/_vendor/html5lib/html5parser.py -src/pip/_vendor/html5lib/serializer.py -src/pip/_vendor/html5lib/_trie/__init__.py -src/pip/_vendor/html5lib/_trie/_base.py -src/pip/_vendor/html5lib/_trie/datrie.py -src/pip/_vendor/html5lib/_trie/py.py -src/pip/_vendor/html5lib/filters/__init__.py -src/pip/_vendor/html5lib/filters/alphabeticalattributes.py -src/pip/_vendor/html5lib/filters/base.py -src/pip/_vendor/html5lib/filters/inject_meta_charset.py -src/pip/_vendor/html5lib/filters/lint.py -src/pip/_vendor/html5lib/filters/optionaltags.py -src/pip/_vendor/html5lib/filters/sanitizer.py -src/pip/_vendor/html5lib/filters/whitespace.py -src/pip/_vendor/html5lib/treeadapters/__init__.py -src/pip/_vendor/html5lib/treeadapters/genshi.py -src/pip/_vendor/html5lib/treeadapters/sax.py -src/pip/_vendor/html5lib/treebuilders/__init__.py -src/pip/_vendor/html5lib/treebuilders/base.py -src/pip/_vendor/html5lib/treebuilders/dom.py -src/pip/_vendor/html5lib/treebuilders/etree.py -src/pip/_vendor/html5lib/treebuilders/etree_lxml.py -src/pip/_vendor/html5lib/treewalkers/__init__.py -src/pip/_vendor/html5lib/treewalkers/base.py -src/pip/_vendor/html5lib/treewalkers/dom.py -src/pip/_vendor/html5lib/treewalkers/etree.py -src/pip/_vendor/html5lib/treewalkers/etree_lxml.py -src/pip/_vendor/html5lib/treewalkers/genshi.py -src/pip/_vendor/idna/LICENSE.rst -src/pip/_vendor/idna/__init__.py -src/pip/_vendor/idna/codec.py -src/pip/_vendor/idna/compat.py -src/pip/_vendor/idna/core.py -src/pip/_vendor/idna/idnadata.py -src/pip/_vendor/idna/intranges.py -src/pip/_vendor/idna/package_data.py -src/pip/_vendor/idna/uts46data.py -src/pip/_vendor/lockfile/LICENSE -src/pip/_vendor/lockfile/__init__.py -src/pip/_vendor/lockfile/linklockfile.py -src/pip/_vendor/lockfile/mkdirlockfile.py -src/pip/_vendor/lockfile/pidlockfile.py -src/pip/_vendor/lockfile/sqlitelockfile.py -src/pip/_vendor/lockfile/symlinklockfile.py -src/pip/_vendor/msgpack/COPYING -src/pip/_vendor/msgpack/__init__.py -src/pip/_vendor/msgpack/_version.py -src/pip/_vendor/msgpack/exceptions.py -src/pip/_vendor/msgpack/fallback.py -src/pip/_vendor/packaging/LICENSE -src/pip/_vendor/packaging/LICENSE.APACHE -src/pip/_vendor/packaging/LICENSE.BSD -src/pip/_vendor/packaging/__about__.py -src/pip/_vendor/packaging/__init__.py -src/pip/_vendor/packaging/_compat.py -src/pip/_vendor/packaging/_structures.py -src/pip/_vendor/packaging/markers.py -src/pip/_vendor/packaging/requirements.py -src/pip/_vendor/packaging/specifiers.py -src/pip/_vendor/packaging/utils.py -src/pip/_vendor/packaging/version.py -src/pip/_vendor/pep517/LICENSE -src/pip/_vendor/pep517/__init__.py -src/pip/_vendor/pep517/_in_process.py -src/pip/_vendor/pep517/build.py -src/pip/_vendor/pep517/check.py -src/pip/_vendor/pep517/colorlog.py -src/pip/_vendor/pep517/compat.py -src/pip/_vendor/pep517/envbuild.py -src/pip/_vendor/pep517/wrappers.py -src/pip/_vendor/pkg_resources/LICENSE -src/pip/_vendor/pkg_resources/__init__.py -src/pip/_vendor/pkg_resources/py31compat.py -src/pip/_vendor/progress/LICENSE -src/pip/_vendor/progress/__init__.py -src/pip/_vendor/progress/bar.py -src/pip/_vendor/progress/counter.py -src/pip/_vendor/progress/helpers.py -src/pip/_vendor/progress/spinner.py -src/pip/_vendor/pytoml/LICENSE -src/pip/_vendor/pytoml/__init__.py -src/pip/_vendor/pytoml/core.py -src/pip/_vendor/pytoml/parser.py -src/pip/_vendor/pytoml/test.py -src/pip/_vendor/pytoml/utils.py -src/pip/_vendor/pytoml/writer.py -src/pip/_vendor/requests/LICENSE -src/pip/_vendor/requests/__init__.py -src/pip/_vendor/requests/__version__.py -src/pip/_vendor/requests/_internal_utils.py -src/pip/_vendor/requests/adapters.py -src/pip/_vendor/requests/api.py -src/pip/_vendor/requests/auth.py -src/pip/_vendor/requests/certs.py -src/pip/_vendor/requests/compat.py -src/pip/_vendor/requests/cookies.py -src/pip/_vendor/requests/exceptions.py -src/pip/_vendor/requests/help.py -src/pip/_vendor/requests/hooks.py -src/pip/_vendor/requests/models.py -src/pip/_vendor/requests/packages.py -src/pip/_vendor/requests/sessions.py -src/pip/_vendor/requests/status_codes.py -src/pip/_vendor/requests/structures.py -src/pip/_vendor/requests/utils.py -src/pip/_vendor/urllib3/LICENSE.txt -src/pip/_vendor/urllib3/__init__.py -src/pip/_vendor/urllib3/_collections.py -src/pip/_vendor/urllib3/connection.py -src/pip/_vendor/urllib3/connectionpool.py -src/pip/_vendor/urllib3/exceptions.py -src/pip/_vendor/urllib3/fields.py -src/pip/_vendor/urllib3/filepost.py -src/pip/_vendor/urllib3/poolmanager.py -src/pip/_vendor/urllib3/request.py -src/pip/_vendor/urllib3/response.py -src/pip/_vendor/urllib3/contrib/__init__.py -src/pip/_vendor/urllib3/contrib/_appengine_environ.py -src/pip/_vendor/urllib3/contrib/appengine.py -src/pip/_vendor/urllib3/contrib/ntlmpool.py -src/pip/_vendor/urllib3/contrib/pyopenssl.py -src/pip/_vendor/urllib3/contrib/securetransport.py -src/pip/_vendor/urllib3/contrib/socks.py -src/pip/_vendor/urllib3/contrib/_securetransport/__init__.py -src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py -src/pip/_vendor/urllib3/contrib/_securetransport/low_level.py -src/pip/_vendor/urllib3/packages/__init__.py -src/pip/_vendor/urllib3/packages/six.py -src/pip/_vendor/urllib3/packages/backports/__init__.py -src/pip/_vendor/urllib3/packages/backports/makefile.py -src/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py -src/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py -src/pip/_vendor/urllib3/util/__init__.py -src/pip/_vendor/urllib3/util/connection.py -src/pip/_vendor/urllib3/util/queue.py -src/pip/_vendor/urllib3/util/request.py -src/pip/_vendor/urllib3/util/response.py -src/pip/_vendor/urllib3/util/retry.py -src/pip/_vendor/urllib3/util/ssl_.py -src/pip/_vendor/urllib3/util/timeout.py -src/pip/_vendor/urllib3/util/url.py -src/pip/_vendor/urllib3/util/wait.py -src/pip/_vendor/webencodings/LICENSE -src/pip/_vendor/webencodings/__init__.py -src/pip/_vendor/webencodings/labels.py -src/pip/_vendor/webencodings/mklabels.py -src/pip/_vendor/webencodings/tests.py -src/pip/_vendor/webencodings/x_user_defined.py \ No newline at end of file diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/dependency_links.txt b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/entry_points.txt b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/entry_points.txt deleted file mode 100644 index 6d3bbc1..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/entry_points.txt +++ /dev/null @@ -1,5 +0,0 @@ -[console_scripts] -pip = pip._internal:main -pip3 = pip._internal:main -pip3.8 = pip._internal:main - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/not-zip-safe b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/not-zip-safe deleted file mode 100644 index 8b13789..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/top_level.txt b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/top_level.txt deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/EGG-INFO/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/__init__.py deleted file mode 100644 index f48c1ca..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "19.0.3" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/__main__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/__main__.py deleted file mode 100644 index 0c223f8..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/__main__.py +++ /dev/null @@ -1,19 +0,0 @@ -from __future__ import absolute_import - -import os -import sys - -# If we are running from a wheel, add the wheel to sys.path -# This allows the usage python pip-*.whl/pip install pip-*.whl -if __package__ == '': - # __file__ is pip-*.whl/pip/__main__.py - # first dirname call strips of '/__main__.py', second strips off '/pip' - # Resulting path is the name of the wheel itself - # Add that to sys.path so we can import pip - path = os.path.dirname(os.path.dirname(__file__)) - sys.path.insert(0, path) - -from pip._internal import main as _main # isort:skip # noqa - -if __name__ == '__main__': - sys.exit(_main()) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/__init__.py deleted file mode 100644 index 276124d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/__init__.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -from __future__ import absolute_import - -import locale -import logging -import os -import warnings - -import sys - -# 2016-06-17 barry@debian.org: urllib3 1.14 added optional support for socks, -# but if invoked (i.e. imported), it will issue a warning to stderr if socks -# isn't available. requests unconditionally imports urllib3's socks contrib -# module, triggering this warning. The warning breaks DEP-8 tests (because of -# the stderr output) and is just plain annoying in normal usage. I don't want -# to add socks as yet another dependency for pip, nor do I want to allow-stder -# in the DEP-8 tests, so just suppress the warning. pdb tells me this has to -# be done before the import of pip.vcs. -from pip._vendor.urllib3.exceptions import DependencyWarning -warnings.filterwarnings("ignore", category=DependencyWarning) # noqa - -# We want to inject the use of SecureTransport as early as possible so that any -# references or sessions or what have you are ensured to have it, however we -# only want to do this in the case that we're running on macOS and the linked -# OpenSSL is too old to handle TLSv1.2 -try: - import ssl -except ImportError: - pass -else: - # Checks for OpenSSL 1.0.1 on MacOS - if sys.platform == "darwin" and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f: - try: - from pip._vendor.urllib3.contrib import securetransport - except (ImportError, OSError): - pass - else: - securetransport.inject_into_urllib3() - -from pip._internal.cli.autocompletion import autocomplete -from pip._internal.cli.main_parser import parse_command -from pip._internal.commands import commands_dict -from pip._internal.exceptions import PipError -from pip._internal.utils import deprecation -from pip._internal.vcs import git, mercurial, subversion, bazaar # noqa -from pip._vendor.urllib3.exceptions import InsecureRequestWarning - -logger = logging.getLogger(__name__) - -# Hide the InsecureRequestWarning from urllib3 -warnings.filterwarnings("ignore", category=InsecureRequestWarning) - - -def main(args=None): - if args is None: - args = sys.argv[1:] - - # Configure our deprecation warnings to be sent through loggers - deprecation.install_warning_logger() - - autocomplete() - - try: - cmd_name, cmd_args = parse_command(args) - except PipError as exc: - sys.stderr.write("ERROR: %s" % exc) - sys.stderr.write(os.linesep) - sys.exit(1) - - # Needed for locale.getpreferredencoding(False) to work - # in pip._internal.utils.encoding.auto_decode - try: - locale.setlocale(locale.LC_ALL, '') - except locale.Error as e: - # setlocale can apparently crash if locale are uninitialized - logger.debug("Ignoring error %s when setting locale", e) - command = commands_dict[cmd_name](isolated=("--isolated" in cmd_args)) - return command.main(cmd_args) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/build_env.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/build_env.py deleted file mode 100644 index d744cc7..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/build_env.py +++ /dev/null @@ -1,215 +0,0 @@ -"""Build Environment used for isolation during sdist building -""" - -import logging -import os -import sys -import textwrap -from collections import OrderedDict -from distutils.sysconfig import get_python_lib -from sysconfig import get_paths - -from pip._vendor.pkg_resources import Requirement, VersionConflict, WorkingSet - -from pip import __file__ as pip_location -from pip._internal.utils.misc import call_subprocess -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import open_spinner - -if MYPY_CHECK_RUNNING: - from typing import Tuple, Set, Iterable, Optional, List # noqa: F401 - from pip._internal.index import PackageFinder # noqa: F401 - -logger = logging.getLogger(__name__) - - -class _Prefix: - - def __init__(self, path): - # type: (str) -> None - self.path = path - self.setup = False - self.bin_dir = get_paths( - 'nt' if os.name == 'nt' else 'posix_prefix', - vars={'base': path, 'platbase': path} - )['scripts'] - # Note: prefer distutils' sysconfig to get the - # library paths so PyPy is correctly supported. - purelib = get_python_lib(plat_specific=False, prefix=path) - platlib = get_python_lib(plat_specific=True, prefix=path) - if purelib == platlib: - self.lib_dirs = [purelib] - else: - self.lib_dirs = [purelib, platlib] - - -class BuildEnvironment(object): - """Creates and manages an isolated environment to install build deps - """ - - def __init__(self): - # type: () -> None - self._temp_dir = TempDirectory(kind="build-env") - self._temp_dir.create() - - self._prefixes = OrderedDict(( - (name, _Prefix(os.path.join(self._temp_dir.path, name))) - for name in ('normal', 'overlay') - )) - - self._bin_dirs = [] # type: List[str] - self._lib_dirs = [] # type: List[str] - for prefix in reversed(list(self._prefixes.values())): - self._bin_dirs.append(prefix.bin_dir) - self._lib_dirs.extend(prefix.lib_dirs) - - # Customize site to: - # - ensure .pth files are honored - # - prevent access to system site packages - system_sites = { - os.path.normcase(site) for site in ( - get_python_lib(plat_specific=False), - get_python_lib(plat_specific=True), - ) - } - self._site_dir = os.path.join(self._temp_dir.path, 'site') - if not os.path.exists(self._site_dir): - os.mkdir(self._site_dir) - with open(os.path.join(self._site_dir, 'sitecustomize.py'), 'w') as fp: - fp.write(textwrap.dedent( - ''' - import os, site, sys - - # First, drop system-sites related paths. - original_sys_path = sys.path[:] - known_paths = set() - for path in {system_sites!r}: - site.addsitedir(path, known_paths=known_paths) - system_paths = set( - os.path.normcase(path) - for path in sys.path[len(original_sys_path):] - ) - original_sys_path = [ - path for path in original_sys_path - if os.path.normcase(path) not in system_paths - ] - sys.path = original_sys_path - - # Second, add lib directories. - # ensuring .pth file are processed. - for path in {lib_dirs!r}: - assert not path in sys.path - site.addsitedir(path) - ''' - ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)) - - def __enter__(self): - self._save_env = { - name: os.environ.get(name, None) - for name in ('PATH', 'PYTHONNOUSERSITE', 'PYTHONPATH') - } - - path = self._bin_dirs[:] - old_path = self._save_env['PATH'] - if old_path: - path.extend(old_path.split(os.pathsep)) - - pythonpath = [self._site_dir] - - os.environ.update({ - 'PATH': os.pathsep.join(path), - 'PYTHONNOUSERSITE': '1', - 'PYTHONPATH': os.pathsep.join(pythonpath), - }) - - def __exit__(self, exc_type, exc_val, exc_tb): - for varname, old_value in self._save_env.items(): - if old_value is None: - os.environ.pop(varname, None) - else: - os.environ[varname] = old_value - - def cleanup(self): - # type: () -> None - self._temp_dir.cleanup() - - def check_requirements(self, reqs): - # type: (Iterable[str]) -> Tuple[Set[Tuple[str, str]], Set[str]] - """Return 2 sets: - - conflicting requirements: set of (installed, wanted) reqs tuples - - missing requirements: set of reqs - """ - missing = set() - conflicting = set() - if reqs: - ws = WorkingSet(self._lib_dirs) - for req in reqs: - try: - if ws.find(Requirement.parse(req)) is None: - missing.add(req) - except VersionConflict as e: - conflicting.add((str(e.args[0].as_requirement()), - str(e.args[1]))) - return conflicting, missing - - def install_requirements( - self, - finder, # type: PackageFinder - requirements, # type: Iterable[str] - prefix_as_string, # type: str - message # type: Optional[str] - ): - # type: (...) -> None - prefix = self._prefixes[prefix_as_string] - assert not prefix.setup - prefix.setup = True - if not requirements: - return - args = [ - sys.executable, os.path.dirname(pip_location), 'install', - '--ignore-installed', '--no-user', '--prefix', prefix.path, - '--no-warn-script-location', - ] # type: List[str] - if logger.getEffectiveLevel() <= logging.DEBUG: - args.append('-v') - for format_control in ('no_binary', 'only_binary'): - formats = getattr(finder.format_control, format_control) - args.extend(('--' + format_control.replace('_', '-'), - ','.join(sorted(formats or {':none:'})))) - if finder.index_urls: - args.extend(['-i', finder.index_urls[0]]) - for extra_index in finder.index_urls[1:]: - args.extend(['--extra-index-url', extra_index]) - else: - args.append('--no-index') - for link in finder.find_links: - args.extend(['--find-links', link]) - for _, host, _ in finder.secure_origins: - args.extend(['--trusted-host', host]) - if finder.allow_all_prereleases: - args.append('--pre') - args.append('--') - args.extend(requirements) - with open_spinner(message) as spinner: - call_subprocess(args, show_stdout=False, spinner=spinner) - - -class NoOpBuildEnvironment(BuildEnvironment): - """A no-op drop-in replacement for BuildEnvironment - """ - - def __init__(self): - pass - - def __enter__(self): - pass - - def __exit__(self, exc_type, exc_val, exc_tb): - pass - - def cleanup(self): - pass - - def install_requirements(self, finder, requirements, prefix, message): - raise NotImplementedError() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cache.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cache.py deleted file mode 100644 index eb295c4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cache.py +++ /dev/null @@ -1,224 +0,0 @@ -"""Cache Management -""" - -import errno -import hashlib -import logging -import os - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.download import path_to_url -from pip._internal.models.link import Link -from pip._internal.utils.compat import expanduser -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel import InvalidWheelFilename, Wheel - -if MYPY_CHECK_RUNNING: - from typing import Optional, Set, List, Any # noqa: F401 - from pip._internal.index import FormatControl # noqa: F401 - -logger = logging.getLogger(__name__) - - -class Cache(object): - """An abstract class - provides cache directories for data from links - - - :param cache_dir: The root of the cache. - :param format_control: An object of FormatControl class to limit - binaries being read from the cache. - :param allowed_formats: which formats of files the cache should store. - ('binary' and 'source' are the only allowed values) - """ - - def __init__(self, cache_dir, format_control, allowed_formats): - # type: (str, FormatControl, Set[str]) -> None - super(Cache, self).__init__() - self.cache_dir = expanduser(cache_dir) if cache_dir else None - self.format_control = format_control - self.allowed_formats = allowed_formats - - _valid_formats = {"source", "binary"} - assert self.allowed_formats.union(_valid_formats) == _valid_formats - - def _get_cache_path_parts(self, link): - # type: (Link) -> List[str] - """Get parts of part that must be os.path.joined with cache_dir - """ - - # We want to generate an url to use as our cache key, we don't want to - # just re-use the URL because it might have other items in the fragment - # and we don't care about those. - key_parts = [link.url_without_fragment] - if link.hash_name is not None and link.hash is not None: - key_parts.append("=".join([link.hash_name, link.hash])) - key_url = "#".join(key_parts) - - # Encode our key url with sha224, we'll use this because it has similar - # security properties to sha256, but with a shorter total output (and - # thus less secure). However the differences don't make a lot of - # difference for our use case here. - hashed = hashlib.sha224(key_url.encode()).hexdigest() - - # We want to nest the directories some to prevent having a ton of top - # level directories where we might run out of sub directories on some - # FS. - parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] - - return parts - - def _get_candidates(self, link, package_name): - # type: (Link, Optional[str]) -> List[Any] - can_not_cache = ( - not self.cache_dir or - not package_name or - not link - ) - if can_not_cache: - return [] - - canonical_name = canonicalize_name(package_name) - formats = self.format_control.get_allowed_formats( - canonical_name - ) - if not self.allowed_formats.intersection(formats): - return [] - - root = self.get_path_for_link(link) - try: - return os.listdir(root) - except OSError as err: - if err.errno in {errno.ENOENT, errno.ENOTDIR}: - return [] - raise - - def get_path_for_link(self, link): - # type: (Link) -> str - """Return a directory to store cached items in for link. - """ - raise NotImplementedError() - - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link - """Returns a link to a cached item if it exists, otherwise returns the - passed link. - """ - raise NotImplementedError() - - def _link_for_candidate(self, link, candidate): - # type: (Link, str) -> Link - root = self.get_path_for_link(link) - path = os.path.join(root, candidate) - - return Link(path_to_url(path)) - - def cleanup(self): - # type: () -> None - pass - - -class SimpleWheelCache(Cache): - """A cache of wheels for future installs. - """ - - def __init__(self, cache_dir, format_control): - # type: (str, FormatControl) -> None - super(SimpleWheelCache, self).__init__( - cache_dir, format_control, {"binary"} - ) - - def get_path_for_link(self, link): - # type: (Link) -> str - """Return a directory to store cached wheels for link - - Because there are M wheels for any one sdist, we provide a directory - to cache them in, and then consult that directory when looking up - cache hits. - - We only insert things into the cache if they have plausible version - numbers, so that we don't contaminate the cache with things that were - not unique. E.g. ./package might have dozens of installs done for it - and build a version of 0.0...and if we built and cached a wheel, we'd - end up using the same wheel even if the source has been edited. - - :param link: The link of the sdist for which this will cache wheels. - """ - parts = self._get_cache_path_parts(link) - - # Store wheels within the root cache_dir - return os.path.join(self.cache_dir, "wheels", *parts) - - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link - candidates = [] - - for wheel_name in self._get_candidates(link, package_name): - try: - wheel = Wheel(wheel_name) - except InvalidWheelFilename: - continue - if not wheel.supported(): - # Built for a different python/arch/etc - continue - candidates.append((wheel.support_index_min(), wheel_name)) - - if not candidates: - return link - - return self._link_for_candidate(link, min(candidates)[1]) - - -class EphemWheelCache(SimpleWheelCache): - """A SimpleWheelCache that creates it's own temporary cache directory - """ - - def __init__(self, format_control): - # type: (FormatControl) -> None - self._temp_dir = TempDirectory(kind="ephem-wheel-cache") - self._temp_dir.create() - - super(EphemWheelCache, self).__init__( - self._temp_dir.path, format_control - ) - - def cleanup(self): - # type: () -> None - self._temp_dir.cleanup() - - -class WheelCache(Cache): - """Wraps EphemWheelCache and SimpleWheelCache into a single Cache - - This Cache allows for gracefully degradation, using the ephem wheel cache - when a certain link is not found in the simple wheel cache first. - """ - - def __init__(self, cache_dir, format_control): - # type: (str, FormatControl) -> None - super(WheelCache, self).__init__( - cache_dir, format_control, {'binary'} - ) - self._wheel_cache = SimpleWheelCache(cache_dir, format_control) - self._ephem_cache = EphemWheelCache(format_control) - - def get_path_for_link(self, link): - # type: (Link) -> str - return self._wheel_cache.get_path_for_link(link) - - def get_ephem_path_for_link(self, link): - # type: (Link) -> str - return self._ephem_cache.get_path_for_link(link) - - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link - retval = self._wheel_cache.get(link, package_name) - if retval is link: - retval = self._ephem_cache.get(link, package_name) - return retval - - def cleanup(self): - # type: () -> None - self._wheel_cache.cleanup() - self._ephem_cache.cleanup() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/__init__.py deleted file mode 100644 index e589bb9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Subpackage containing all of pip's command line interface related code -""" - -# This file intentionally does not import submodules diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/autocompletion.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/autocompletion.py deleted file mode 100644 index 0a04199..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/autocompletion.py +++ /dev/null @@ -1,152 +0,0 @@ -"""Logic that powers autocompletion installed by ``pip completion``. -""" - -import optparse -import os -import sys - -from pip._internal.cli.main_parser import create_main_parser -from pip._internal.commands import commands_dict, get_summaries -from pip._internal.utils.misc import get_installed_distributions - - -def autocomplete(): - """Entry Point for completion of main and subcommand options. - """ - # Don't complete if user hasn't sourced bash_completion file. - if 'PIP_AUTO_COMPLETE' not in os.environ: - return - cwords = os.environ['COMP_WORDS'].split()[1:] - cword = int(os.environ['COMP_CWORD']) - try: - current = cwords[cword - 1] - except IndexError: - current = '' - - subcommands = [cmd for cmd, summary in get_summaries()] - options = [] - # subcommand - try: - subcommand_name = [w for w in cwords if w in subcommands][0] - except IndexError: - subcommand_name = None - - parser = create_main_parser() - # subcommand options - if subcommand_name: - # special case: 'help' subcommand has no options - if subcommand_name == 'help': - sys.exit(1) - # special case: list locally installed dists for show and uninstall - should_list_installed = ( - subcommand_name in ['show', 'uninstall'] and - not current.startswith('-') - ) - if should_list_installed: - installed = [] - lc = current.lower() - for dist in get_installed_distributions(local_only=True): - if dist.key.startswith(lc) and dist.key not in cwords[1:]: - installed.append(dist.key) - # if there are no dists installed, fall back to option completion - if installed: - for dist in installed: - print(dist) - sys.exit(1) - - subcommand = commands_dict[subcommand_name]() - - for opt in subcommand.parser.option_list_all: - if opt.help != optparse.SUPPRESS_HELP: - for opt_str in opt._long_opts + opt._short_opts: - options.append((opt_str, opt.nargs)) - - # filter out previously specified options from available options - prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] - options = [(x, v) for (x, v) in options if x not in prev_opts] - # filter options by current input - options = [(k, v) for k, v in options if k.startswith(current)] - # get completion type given cwords and available subcommand options - completion_type = get_path_completion_type( - cwords, cword, subcommand.parser.option_list_all, - ) - # get completion files and directories if ``completion_type`` is - # ````, ```` or ```` - if completion_type: - options = auto_complete_paths(current, completion_type) - options = ((opt, 0) for opt in options) - for option in options: - opt_label = option[0] - # append '=' to options which require args - if option[1] and option[0][:2] == "--": - opt_label += '=' - print(opt_label) - else: - # show main parser options only when necessary - - opts = [i.option_list for i in parser.option_groups] - opts.append(parser.option_list) - opts = (o for it in opts for o in it) - if current.startswith('-'): - for opt in opts: - if opt.help != optparse.SUPPRESS_HELP: - subcommands += opt._long_opts + opt._short_opts - else: - # get completion type given cwords and all available options - completion_type = get_path_completion_type(cwords, cword, opts) - if completion_type: - subcommands = auto_complete_paths(current, completion_type) - - print(' '.join([x for x in subcommands if x.startswith(current)])) - sys.exit(1) - - -def get_path_completion_type(cwords, cword, opts): - """Get the type of path completion (``file``, ``dir``, ``path`` or None) - - :param cwords: same as the environmental variable ``COMP_WORDS`` - :param cword: same as the environmental variable ``COMP_CWORD`` - :param opts: The available options to check - :return: path completion type (``file``, ``dir``, ``path`` or None) - """ - if cword < 2 or not cwords[cword - 2].startswith('-'): - return - for opt in opts: - if opt.help == optparse.SUPPRESS_HELP: - continue - for o in str(opt).split('/'): - if cwords[cword - 2].split('=')[0] == o: - if not opt.metavar or any( - x in ('path', 'file', 'dir') - for x in opt.metavar.split('/')): - return opt.metavar - - -def auto_complete_paths(current, completion_type): - """If ``completion_type`` is ``file`` or ``path``, list all regular files - and directories starting with ``current``; otherwise only list directories - starting with ``current``. - - :param current: The word to be completed - :param completion_type: path completion type(`file`, `path` or `dir`)i - :return: A generator of regular files and/or directories - """ - directory, filename = os.path.split(current) - current_path = os.path.abspath(directory) - # Don't complete paths if they can't be accessed - if not os.access(current_path, os.R_OK): - return - filename = os.path.normcase(filename) - # list all files that start with ``filename`` - file_list = (x for x in os.listdir(current_path) - if os.path.normcase(x).startswith(filename)) - for f in file_list: - opt = os.path.join(current_path, f) - comp_file = os.path.normcase(os.path.join(directory, f)) - # complete regular files when there is not ```` after option - # complete directories when there is ````, ```` or - # ````after option - if completion_type != 'dir' and os.path.isfile(opt): - yield comp_file - elif os.path.isdir(opt): - yield os.path.join(comp_file, '') diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/base_command.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/base_command.py deleted file mode 100644 index 3ceea49..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/base_command.py +++ /dev/null @@ -1,341 +0,0 @@ -"""Base Command class, and related routines""" -from __future__ import absolute_import, print_function - -import logging -import logging.config -import optparse -import os -import platform -import sys -import traceback - -from pip._internal.cli import cmdoptions -from pip._internal.cli.parser import ( - ConfigOptionParser, UpdatingDefaultsHelpFormatter, -) -from pip._internal.cli.status_codes import ( - ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, - VIRTUALENV_NOT_FOUND, -) -from pip._internal.download import PipSession -from pip._internal.exceptions import ( - BadCommand, CommandError, InstallationError, PreviousBuildDirError, - UninstallationError, -) -from pip._internal.index import PackageFinder -from pip._internal.locations import running_under_virtualenv -from pip._internal.req.constructors import ( - install_req_from_editable, install_req_from_line, -) -from pip._internal.req.req_file import parse_requirements -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging -from pip._internal.utils.misc import ( - get_prog, normalize_path, redact_password_from_url, -) -from pip._internal.utils.outdated import pip_version_check -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, List, Tuple, Any # noqa: F401 - from optparse import Values # noqa: F401 - from pip._internal.cache import WheelCache # noqa: F401 - from pip._internal.req.req_set import RequirementSet # noqa: F401 - -__all__ = ['Command'] - -logger = logging.getLogger(__name__) - - -class Command(object): - name = None # type: Optional[str] - usage = None # type: Optional[str] - hidden = False # type: bool - ignore_require_venv = False # type: bool - - def __init__(self, isolated=False): - # type: (bool) -> None - parser_kw = { - 'usage': self.usage, - 'prog': '%s %s' % (get_prog(), self.name), - 'formatter': UpdatingDefaultsHelpFormatter(), - 'add_help_option': False, - 'name': self.name, - 'description': self.__doc__, - 'isolated': isolated, - } - - self.parser = ConfigOptionParser(**parser_kw) - - # Commands should add options to this option group - optgroup_name = '%s Options' % self.name.capitalize() - self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) - - # Add the general options - gen_opts = cmdoptions.make_option_group( - cmdoptions.general_group, - self.parser, - ) - self.parser.add_option_group(gen_opts) - - def run(self, options, args): - # type: (Values, List[Any]) -> Any - raise NotImplementedError - - def _build_session(self, options, retries=None, timeout=None): - # type: (Values, Optional[int], Optional[int]) -> PipSession - session = PipSession( - cache=( - normalize_path(os.path.join(options.cache_dir, "http")) - if options.cache_dir else None - ), - retries=retries if retries is not None else options.retries, - insecure_hosts=options.trusted_hosts, - ) - - # Handle custom ca-bundles from the user - if options.cert: - session.verify = options.cert - - # Handle SSL client certificate - if options.client_cert: - session.cert = options.client_cert - - # Handle timeouts - if options.timeout or timeout: - session.timeout = ( - timeout if timeout is not None else options.timeout - ) - - # Handle configured proxies - if options.proxy: - session.proxies = { - "http": options.proxy, - "https": options.proxy, - } - - # Determine if we can prompt the user for authentication or not - session.auth.prompting = not options.no_input - - return session - - def parse_args(self, args): - # type: (List[str]) -> Tuple - # factored out for testability - return self.parser.parse_args(args) - - def main(self, args): - # type: (List[str]) -> int - options, args = self.parse_args(args) - - # Set verbosity so that it can be used elsewhere. - self.verbosity = options.verbose - options.quiet - - level_number = setup_logging( - verbosity=self.verbosity, - no_color=options.no_color, - user_log_file=options.log, - ) - - if sys.version_info[:2] == (3, 4): - deprecated( - "Python 3.4 support has been deprecated. pip 19.1 will be the " - "last one supporting it. Please upgrade your Python as Python " - "3.4 won't be maintained after March 2019 (cf PEP 429).", - replacement=None, - gone_in='19.2', - ) - elif sys.version_info[:2] == (2, 7): - message = ( - "A future version of pip will drop support for Python 2.7." - ) - if platform.python_implementation() == "CPython": - message = ( - "Python 2.7 will reach the end of its life on January " - "1st, 2020. Please upgrade your Python as Python 2.7 " - "won't be maintained after that date. " - ) + message - deprecated(message, replacement=None, gone_in=None) - - # TODO: Try to get these passing down from the command? - # without resorting to os.environ to hold these. - # This also affects isolated builds and it should. - - if options.no_input: - os.environ['PIP_NO_INPUT'] = '1' - - if options.exists_action: - os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) - - if options.require_venv and not self.ignore_require_venv: - # If a venv is required check if it can really be found - if not running_under_virtualenv(): - logger.critical( - 'Could not find an activated virtualenv (required).' - ) - sys.exit(VIRTUALENV_NOT_FOUND) - - try: - status = self.run(options, args) - # FIXME: all commands should return an exit status - # and when it is done, isinstance is not needed anymore - if isinstance(status, int): - return status - except PreviousBuildDirError as exc: - logger.critical(str(exc)) - logger.debug('Exception information:', exc_info=True) - - return PREVIOUS_BUILD_DIR_ERROR - except (InstallationError, UninstallationError, BadCommand) as exc: - logger.critical(str(exc)) - logger.debug('Exception information:', exc_info=True) - - return ERROR - except CommandError as exc: - logger.critical('ERROR: %s', exc) - logger.debug('Exception information:', exc_info=True) - - return ERROR - except BrokenStdoutLoggingError: - # Bypass our logger and write any remaining messages to stderr - # because stdout no longer works. - print('ERROR: Pipe to stdout was broken', file=sys.stderr) - if level_number <= logging.DEBUG: - traceback.print_exc(file=sys.stderr) - - return ERROR - except KeyboardInterrupt: - logger.critical('Operation cancelled by user') - logger.debug('Exception information:', exc_info=True) - - return ERROR - except BaseException: - logger.critical('Exception:', exc_info=True) - - return UNKNOWN_ERROR - finally: - allow_version_check = ( - # Does this command have the index_group options? - hasattr(options, "no_index") and - # Is this command allowed to perform this check? - not (options.disable_pip_version_check or options.no_index) - ) - # Check if we're using the latest version of pip available - if allow_version_check: - session = self._build_session( - options, - retries=0, - timeout=min(5, options.timeout) - ) - with session: - pip_version_check(session, options) - - # Shutdown the logging module - logging.shutdown() - - return SUCCESS - - -class RequirementCommand(Command): - - @staticmethod - def populate_requirement_set(requirement_set, # type: RequirementSet - args, # type: List[str] - options, # type: Values - finder, # type: PackageFinder - session, # type: PipSession - name, # type: str - wheel_cache # type: Optional[WheelCache] - ): - # type: (...) -> None - """ - Marshal cmd line args into a requirement set. - """ - # NOTE: As a side-effect, options.require_hashes and - # requirement_set.require_hashes may be updated - - for filename in options.constraints: - for req_to_add in parse_requirements( - filename, - constraint=True, finder=finder, options=options, - session=session, wheel_cache=wheel_cache): - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - for req in args: - req_to_add = install_req_from_line( - req, None, isolated=options.isolated_mode, - use_pep517=options.use_pep517, - wheel_cache=wheel_cache - ) - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - for req in options.editables: - req_to_add = install_req_from_editable( - req, - isolated=options.isolated_mode, - use_pep517=options.use_pep517, - wheel_cache=wheel_cache - ) - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - for filename in options.requirements: - for req_to_add in parse_requirements( - filename, - finder=finder, options=options, session=session, - wheel_cache=wheel_cache, - use_pep517=options.use_pep517): - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - # If --require-hashes was a line in a requirements file, tell - # RequirementSet about it: - requirement_set.require_hashes = options.require_hashes - - if not (args or options.editables or options.requirements): - opts = {'name': name} - if options.find_links: - raise CommandError( - 'You must give at least one requirement to %(name)s ' - '(maybe you meant "pip %(name)s %(links)s"?)' % - dict(opts, links=' '.join(options.find_links))) - else: - raise CommandError( - 'You must give at least one requirement to %(name)s ' - '(see "pip help %(name)s")' % opts) - - def _build_package_finder( - self, - options, # type: Values - session, # type: PipSession - platform=None, # type: Optional[str] - python_versions=None, # type: Optional[List[str]] - abi=None, # type: Optional[str] - implementation=None # type: Optional[str] - ): - # type: (...) -> PackageFinder - """ - Create a package finder appropriate to this requirement command. - """ - index_urls = [options.index_url] + options.extra_index_urls - if options.no_index: - logger.debug( - 'Ignoring indexes: %s', - ','.join(redact_password_from_url(url) for url in index_urls), - ) - index_urls = [] - - return PackageFinder( - find_links=options.find_links, - format_control=options.format_control, - index_urls=index_urls, - trusted_hosts=options.trusted_hosts, - allow_all_prereleases=options.pre, - session=session, - platform=platform, - versions=python_versions, - abi=abi, - implementation=implementation, - prefer_binary=options.prefer_binary, - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/cmdoptions.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/cmdoptions.py deleted file mode 100644 index 5cf5ee9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/cmdoptions.py +++ /dev/null @@ -1,809 +0,0 @@ -""" -shared options and groups - -The principle here is to define options once, but *not* instantiate them -globally. One reason being that options with action='append' can carry state -between parses. pip parses general options twice internally, and shouldn't -pass on state. To be consistent, all options will follow this design. - -""" -from __future__ import absolute_import - -import textwrap -import warnings -from distutils.util import strtobool -from functools import partial -from optparse import SUPPRESS_HELP, Option, OptionGroup - -from pip._internal.exceptions import CommandError -from pip._internal.locations import USER_CACHE_DIR, src_prefix -from pip._internal.models.format_control import FormatControl -from pip._internal.models.index import PyPI -from pip._internal.utils.hashes import STRONG_HASHES -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import BAR_TYPES - -if MYPY_CHECK_RUNNING: - from typing import Any, Callable, Dict, List, Optional, Union # noqa: F401 - from optparse import OptionParser, Values # noqa: F401 - from pip._internal.cli.parser import ConfigOptionParser # noqa: F401 - - -def raise_option_error(parser, option, msg): - """ - Raise an option parsing error using parser.error(). - - Args: - parser: an OptionParser instance. - option: an Option instance. - msg: the error text. - """ - msg = '{} error: {}'.format(option, msg) - msg = textwrap.fill(' '.join(msg.split())) - parser.error(msg) - - -def make_option_group(group, parser): - # type: (Dict[str, Any], ConfigOptionParser) -> OptionGroup - """ - Return an OptionGroup object - group -- assumed to be dict with 'name' and 'options' keys - parser -- an optparse Parser - """ - option_group = OptionGroup(parser, group['name']) - for option in group['options']: - option_group.add_option(option()) - return option_group - - -def check_install_build_global(options, check_options=None): - # type: (Values, Optional[Values]) -> None - """Disable wheels if per-setup.py call options are set. - - :param options: The OptionParser options to update. - :param check_options: The options to check, if not supplied defaults to - options. - """ - if check_options is None: - check_options = options - - def getname(n): - return getattr(check_options, n, None) - names = ["build_options", "global_options", "install_options"] - if any(map(getname, names)): - control = options.format_control - control.disallow_binaries() - warnings.warn( - 'Disabling all use of wheels due to the use of --build-options ' - '/ --global-options / --install-options.', stacklevel=2, - ) - - -def check_dist_restriction(options, check_target=False): - # type: (Values, bool) -> None - """Function for determining if custom platform options are allowed. - - :param options: The OptionParser options. - :param check_target: Whether or not to check if --target is being used. - """ - dist_restriction_set = any([ - options.python_version, - options.platform, - options.abi, - options.implementation, - ]) - - binary_only = FormatControl(set(), {':all:'}) - sdist_dependencies_allowed = ( - options.format_control != binary_only and - not options.ignore_dependencies - ) - - # Installations or downloads using dist restrictions must not combine - # source distributions and dist-specific wheels, as they are not - # gauranteed to be locally compatible. - if dist_restriction_set and sdist_dependencies_allowed: - raise CommandError( - "When restricting platform and interpreter constraints using " - "--python-version, --platform, --abi, or --implementation, " - "either --no-deps must be set, or --only-binary=:all: must be " - "set and --no-binary must not be set (or must be set to " - ":none:)." - ) - - if check_target: - if dist_restriction_set and not options.target_dir: - raise CommandError( - "Can not use any platform or abi specific options unless " - "installing via '--target'" - ) - - -########### -# options # -########### - -help_ = partial( - Option, - '-h', '--help', - dest='help', - action='help', - help='Show help.', -) # type: Callable[..., Option] - -isolated_mode = partial( - Option, - "--isolated", - dest="isolated_mode", - action="store_true", - default=False, - help=( - "Run pip in an isolated mode, ignoring environment variables and user " - "configuration." - ), -) # type: Callable[..., Option] - -require_virtualenv = partial( - Option, - # Run only if inside a virtualenv, bail if not. - '--require-virtualenv', '--require-venv', - dest='require_venv', - action='store_true', - default=False, - help=SUPPRESS_HELP -) # type: Callable[..., Option] - -verbose = partial( - Option, - '-v', '--verbose', - dest='verbose', - action='count', - default=0, - help='Give more output. Option is additive, and can be used up to 3 times.' -) # type: Callable[..., Option] - -no_color = partial( - Option, - '--no-color', - dest='no_color', - action='store_true', - default=False, - help="Suppress colored output", -) # type: Callable[..., Option] - -version = partial( - Option, - '-V', '--version', - dest='version', - action='store_true', - help='Show version and exit.', -) # type: Callable[..., Option] - -quiet = partial( - Option, - '-q', '--quiet', - dest='quiet', - action='count', - default=0, - help=( - 'Give less output. Option is additive, and can be used up to 3' - ' times (corresponding to WARNING, ERROR, and CRITICAL logging' - ' levels).' - ), -) # type: Callable[..., Option] - -progress_bar = partial( - Option, - '--progress-bar', - dest='progress_bar', - type='choice', - choices=list(BAR_TYPES.keys()), - default='on', - help=( - 'Specify type of progress to be displayed [' + - '|'.join(BAR_TYPES.keys()) + '] (default: %default)' - ), -) # type: Callable[..., Option] - -log = partial( - Option, - "--log", "--log-file", "--local-log", - dest="log", - metavar="path", - help="Path to a verbose appending log." -) # type: Callable[..., Option] - -no_input = partial( - Option, - # Don't ask for input - '--no-input', - dest='no_input', - action='store_true', - default=False, - help=SUPPRESS_HELP -) # type: Callable[..., Option] - -proxy = partial( - Option, - '--proxy', - dest='proxy', - type='str', - default='', - help="Specify a proxy in the form [user:passwd@]proxy.server:port." -) # type: Callable[..., Option] - -retries = partial( - Option, - '--retries', - dest='retries', - type='int', - default=5, - help="Maximum number of retries each connection should attempt " - "(default %default times).", -) # type: Callable[..., Option] - -timeout = partial( - Option, - '--timeout', '--default-timeout', - metavar='sec', - dest='timeout', - type='float', - default=15, - help='Set the socket timeout (default %default seconds).', -) # type: Callable[..., Option] - -skip_requirements_regex = partial( - Option, - # A regex to be used to skip requirements - '--skip-requirements-regex', - dest='skip_requirements_regex', - type='str', - default='', - help=SUPPRESS_HELP, -) # type: Callable[..., Option] - - -def exists_action(): - # type: () -> Option - return Option( - # Option when path already exist - '--exists-action', - dest='exists_action', - type='choice', - choices=['s', 'i', 'w', 'b', 'a'], - default=[], - action='append', - metavar='action', - help="Default action when a path already exists: " - "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort).", - ) - - -cert = partial( - Option, - '--cert', - dest='cert', - type='str', - metavar='path', - help="Path to alternate CA bundle.", -) # type: Callable[..., Option] - -client_cert = partial( - Option, - '--client-cert', - dest='client_cert', - type='str', - default=None, - metavar='path', - help="Path to SSL client certificate, a single file containing the " - "private key and the certificate in PEM format.", -) # type: Callable[..., Option] - -index_url = partial( - Option, - '-i', '--index-url', '--pypi-url', - dest='index_url', - metavar='URL', - default=PyPI.simple_url, - help="Base URL of Python Package Index (default %default). " - "This should point to a repository compliant with PEP 503 " - "(the simple repository API) or a local directory laid out " - "in the same format.", -) # type: Callable[..., Option] - - -def extra_index_url(): - return Option( - '--extra-index-url', - dest='extra_index_urls', - metavar='URL', - action='append', - default=[], - help="Extra URLs of package indexes to use in addition to " - "--index-url. Should follow the same rules as " - "--index-url.", - ) - - -no_index = partial( - Option, - '--no-index', - dest='no_index', - action='store_true', - default=False, - help='Ignore package index (only looking at --find-links URLs instead).', -) # type: Callable[..., Option] - - -def find_links(): - # type: () -> Option - return Option( - '-f', '--find-links', - dest='find_links', - action='append', - default=[], - metavar='url', - help="If a url or path to an html file, then parse for links to " - "archives. If a local path or file:// url that's a directory, " - "then look for archives in the directory listing.", - ) - - -def trusted_host(): - # type: () -> Option - return Option( - "--trusted-host", - dest="trusted_hosts", - action="append", - metavar="HOSTNAME", - default=[], - help="Mark this host as trusted, even though it does not have valid " - "or any HTTPS.", - ) - - -def constraints(): - # type: () -> Option - return Option( - '-c', '--constraint', - dest='constraints', - action='append', - default=[], - metavar='file', - help='Constrain versions using the given constraints file. ' - 'This option can be used multiple times.' - ) - - -def requirements(): - # type: () -> Option - return Option( - '-r', '--requirement', - dest='requirements', - action='append', - default=[], - metavar='file', - help='Install from the given requirements file. ' - 'This option can be used multiple times.' - ) - - -def editable(): - # type: () -> Option - return Option( - '-e', '--editable', - dest='editables', - action='append', - default=[], - metavar='path/url', - help=('Install a project in editable mode (i.e. setuptools ' - '"develop mode") from a local project path or a VCS url.'), - ) - - -src = partial( - Option, - '--src', '--source', '--source-dir', '--source-directory', - dest='src_dir', - metavar='dir', - default=src_prefix, - help='Directory to check out editable projects into. ' - 'The default in a virtualenv is "/src". ' - 'The default for global installs is "/src".' -) # type: Callable[..., Option] - - -def _get_format_control(values, option): - # type: (Values, Option) -> Any - """Get a format_control object.""" - return getattr(values, option.dest) - - -def _handle_no_binary(option, opt_str, value, parser): - # type: (Option, str, str, OptionParser) -> None - existing = _get_format_control(parser.values, option) - FormatControl.handle_mutual_excludes( - value, existing.no_binary, existing.only_binary, - ) - - -def _handle_only_binary(option, opt_str, value, parser): - # type: (Option, str, str, OptionParser) -> None - existing = _get_format_control(parser.values, option) - FormatControl.handle_mutual_excludes( - value, existing.only_binary, existing.no_binary, - ) - - -def no_binary(): - # type: () -> Option - format_control = FormatControl(set(), set()) - return Option( - "--no-binary", dest="format_control", action="callback", - callback=_handle_no_binary, type="str", - default=format_control, - help="Do not use binary packages. Can be supplied multiple times, and " - "each time adds to the existing value. Accepts either :all: to " - "disable all binary packages, :none: to empty the set, or one or " - "more package names with commas between them. Note that some " - "packages are tricky to compile and may fail to install when " - "this option is used on them.", - ) - - -def only_binary(): - # type: () -> Option - format_control = FormatControl(set(), set()) - return Option( - "--only-binary", dest="format_control", action="callback", - callback=_handle_only_binary, type="str", - default=format_control, - help="Do not use source packages. Can be supplied multiple times, and " - "each time adds to the existing value. Accepts either :all: to " - "disable all source packages, :none: to empty the set, or one or " - "more package names with commas between them. Packages without " - "binary distributions will fail to install when this option is " - "used on them.", - ) - - -platform = partial( - Option, - '--platform', - dest='platform', - metavar='platform', - default=None, - help=("Only use wheels compatible with . " - "Defaults to the platform of the running system."), -) # type: Callable[..., Option] - - -python_version = partial( - Option, - '--python-version', - dest='python_version', - metavar='python_version', - default=None, - help=("Only use wheels compatible with Python " - "interpreter version . If not specified, then the " - "current system interpreter minor version is used. A major " - "version (e.g. '2') can be specified to match all " - "minor revs of that major version. A minor version " - "(e.g. '34') can also be specified."), -) # type: Callable[..., Option] - - -implementation = partial( - Option, - '--implementation', - dest='implementation', - metavar='implementation', - default=None, - help=("Only use wheels compatible with Python " - "implementation , e.g. 'pp', 'jy', 'cp', " - " or 'ip'. If not specified, then the current " - "interpreter implementation is used. Use 'py' to force " - "implementation-agnostic wheels."), -) # type: Callable[..., Option] - - -abi = partial( - Option, - '--abi', - dest='abi', - metavar='abi', - default=None, - help=("Only use wheels compatible with Python " - "abi , e.g. 'pypy_41'. If not specified, then the " - "current interpreter abi tag is used. Generally " - "you will need to specify --implementation, " - "--platform, and --python-version when using " - "this option."), -) # type: Callable[..., Option] - - -def prefer_binary(): - # type: () -> Option - return Option( - "--prefer-binary", - dest="prefer_binary", - action="store_true", - default=False, - help="Prefer older binary packages over newer source packages." - ) - - -cache_dir = partial( - Option, - "--cache-dir", - dest="cache_dir", - default=USER_CACHE_DIR, - metavar="dir", - help="Store the cache data in ." -) # type: Callable[..., Option] - - -def no_cache_dir_callback(option, opt, value, parser): - """ - Process a value provided for the --no-cache-dir option. - - This is an optparse.Option callback for the --no-cache-dir option. - """ - # The value argument will be None if --no-cache-dir is passed via the - # command-line, since the option doesn't accept arguments. However, - # the value can be non-None if the option is triggered e.g. by an - # environment variable, like PIP_NO_CACHE_DIR=true. - if value is not None: - # Then parse the string value to get argument error-checking. - try: - strtobool(value) - except ValueError as exc: - raise_option_error(parser, option=option, msg=str(exc)) - - # Originally, setting PIP_NO_CACHE_DIR to a value that strtobool() - # converted to 0 (like "false" or "no") caused cache_dir to be disabled - # rather than enabled (logic would say the latter). Thus, we disable - # the cache directory not just on values that parse to True, but (for - # backwards compatibility reasons) also on values that parse to False. - # In other words, always set it to False if the option is provided in - # some (valid) form. - parser.values.cache_dir = False - - -no_cache = partial( - Option, - "--no-cache-dir", - dest="cache_dir", - action="callback", - callback=no_cache_dir_callback, - help="Disable the cache.", -) # type: Callable[..., Option] - -no_deps = partial( - Option, - '--no-deps', '--no-dependencies', - dest='ignore_dependencies', - action='store_true', - default=False, - help="Don't install package dependencies.", -) # type: Callable[..., Option] - -build_dir = partial( - Option, - '-b', '--build', '--build-dir', '--build-directory', - dest='build_dir', - metavar='dir', - help='Directory to unpack packages into and build in. Note that ' - 'an initial build still takes place in a temporary directory. ' - 'The location of temporary directories can be controlled by setting ' - 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' - 'When passed, build directories are not cleaned in case of failures.' -) # type: Callable[..., Option] - -ignore_requires_python = partial( - Option, - '--ignore-requires-python', - dest='ignore_requires_python', - action='store_true', - help='Ignore the Requires-Python information.' -) # type: Callable[..., Option] - -no_build_isolation = partial( - Option, - '--no-build-isolation', - dest='build_isolation', - action='store_false', - default=True, - help='Disable isolation when building a modern source distribution. ' - 'Build dependencies specified by PEP 518 must be already installed ' - 'if this option is used.' -) # type: Callable[..., Option] - - -def no_use_pep517_callback(option, opt, value, parser): - """ - Process a value provided for the --no-use-pep517 option. - - This is an optparse.Option callback for the no_use_pep517 option. - """ - # Since --no-use-pep517 doesn't accept arguments, the value argument - # will be None if --no-use-pep517 is passed via the command-line. - # However, the value can be non-None if the option is triggered e.g. - # by an environment variable, for example "PIP_NO_USE_PEP517=true". - if value is not None: - msg = """A value was passed for --no-use-pep517, - probably using either the PIP_NO_USE_PEP517 environment variable - or the "no-use-pep517" config file option. Use an appropriate value - of the PIP_USE_PEP517 environment variable or the "use-pep517" - config file option instead. - """ - raise_option_error(parser, option=option, msg=msg) - - # Otherwise, --no-use-pep517 was passed via the command-line. - parser.values.use_pep517 = False - - -use_pep517 = partial( - Option, - '--use-pep517', - dest='use_pep517', - action='store_true', - default=None, - help='Use PEP 517 for building source distributions ' - '(use --no-use-pep517 to force legacy behaviour).' -) # type: Any - -no_use_pep517 = partial( - Option, - '--no-use-pep517', - dest='use_pep517', - action='callback', - callback=no_use_pep517_callback, - default=None, - help=SUPPRESS_HELP -) # type: Any - -install_options = partial( - Option, - '--install-option', - dest='install_options', - action='append', - metavar='options', - help="Extra arguments to be supplied to the setup.py install " - "command (use like --install-option=\"--install-scripts=/usr/local/" - "bin\"). Use multiple --install-option options to pass multiple " - "options to setup.py install. If you are using an option with a " - "directory path, be sure to use absolute path.", -) # type: Callable[..., Option] - -global_options = partial( - Option, - '--global-option', - dest='global_options', - action='append', - metavar='options', - help="Extra global options to be supplied to the setup.py " - "call before the install command.", -) # type: Callable[..., Option] - -no_clean = partial( - Option, - '--no-clean', - action='store_true', - default=False, - help="Don't clean up build directories." -) # type: Callable[..., Option] - -pre = partial( - Option, - '--pre', - action='store_true', - default=False, - help="Include pre-release and development versions. By default, " - "pip only finds stable versions.", -) # type: Callable[..., Option] - -disable_pip_version_check = partial( - Option, - "--disable-pip-version-check", - dest="disable_pip_version_check", - action="store_true", - default=False, - help="Don't periodically check PyPI to determine whether a new version " - "of pip is available for download. Implied with --no-index.", -) # type: Callable[..., Option] - - -# Deprecated, Remove later -always_unzip = partial( - Option, - '-Z', '--always-unzip', - dest='always_unzip', - action='store_true', - help=SUPPRESS_HELP, -) # type: Callable[..., Option] - - -def _merge_hash(option, opt_str, value, parser): - # type: (Option, str, str, OptionParser) -> None - """Given a value spelled "algo:digest", append the digest to a list - pointed to in a dict by the algo name.""" - if not parser.values.hashes: - parser.values.hashes = {} # type: ignore - try: - algo, digest = value.split(':', 1) - except ValueError: - parser.error('Arguments to %s must be a hash name ' - 'followed by a value, like --hash=sha256:abcde...' % - opt_str) - if algo not in STRONG_HASHES: - parser.error('Allowed hash algorithms for %s are %s.' % - (opt_str, ', '.join(STRONG_HASHES))) - parser.values.hashes.setdefault(algo, []).append(digest) - - -hash = partial( - Option, - '--hash', - # Hash values eventually end up in InstallRequirement.hashes due to - # __dict__ copying in process_line(). - dest='hashes', - action='callback', - callback=_merge_hash, - type='string', - help="Verify that the package's archive matches this " - 'hash before installing. Example: --hash=sha256:abcdef...', -) # type: Callable[..., Option] - - -require_hashes = partial( - Option, - '--require-hashes', - dest='require_hashes', - action='store_true', - default=False, - help='Require a hash to check each requirement against, for ' - 'repeatable installs. This option is implied when any package in a ' - 'requirements file has a --hash option.', -) # type: Callable[..., Option] - - -########## -# groups # -########## - -general_group = { - 'name': 'General Options', - 'options': [ - help_, - isolated_mode, - require_virtualenv, - verbose, - version, - quiet, - log, - no_input, - proxy, - retries, - timeout, - skip_requirements_regex, - exists_action, - trusted_host, - cert, - client_cert, - cache_dir, - no_cache, - disable_pip_version_check, - no_color, - ] -} # type: Dict[str, Any] - -index_group = { - 'name': 'Package Index Options', - 'options': [ - index_url, - extra_index_url, - no_index, - find_links, - ] -} # type: Dict[str, Any] diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/main_parser.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/main_parser.py deleted file mode 100644 index b17c749..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/main_parser.py +++ /dev/null @@ -1,104 +0,0 @@ -"""A single place for constructing and exposing the main parser -""" - -import os -import sys - -from pip import __version__ -from pip._internal.cli import cmdoptions -from pip._internal.cli.parser import ( - ConfigOptionParser, UpdatingDefaultsHelpFormatter, -) -from pip._internal.commands import ( - commands_dict, get_similar_commands, get_summaries, -) -from pip._internal.exceptions import CommandError -from pip._internal.utils.misc import get_prog -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Tuple, List # noqa: F401 - - -__all__ = ["create_main_parser", "parse_command"] - - -def create_main_parser(): - # type: () -> ConfigOptionParser - """Creates and returns the main parser for pip's CLI - """ - - parser_kw = { - 'usage': '\n%prog [options]', - 'add_help_option': False, - 'formatter': UpdatingDefaultsHelpFormatter(), - 'name': 'global', - 'prog': get_prog(), - } - - parser = ConfigOptionParser(**parser_kw) - parser.disable_interspersed_args() - - pip_pkg_dir = os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", "..", - )) - parser.version = 'pip %s from %s (python %s)' % ( - __version__, pip_pkg_dir, sys.version[:3], - ) - - # add the general options - gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) - parser.add_option_group(gen_opts) - - # so the help formatter knows - parser.main = True # type: ignore - - # create command listing for description - command_summaries = get_summaries() - description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] - parser.description = '\n'.join(description) - - return parser - - -def parse_command(args): - # type: (List[str]) -> Tuple[str, List[str]] - parser = create_main_parser() - - # Note: parser calls disable_interspersed_args(), so the result of this - # call is to split the initial args into the general options before the - # subcommand and everything else. - # For example: - # args: ['--timeout=5', 'install', '--user', 'INITools'] - # general_options: ['--timeout==5'] - # args_else: ['install', '--user', 'INITools'] - general_options, args_else = parser.parse_args(args) - - # --version - if general_options.version: - sys.stdout.write(parser.version) # type: ignore - sys.stdout.write(os.linesep) - sys.exit() - - # pip || pip help -> print_help() - if not args_else or (args_else[0] == 'help' and len(args_else) == 1): - parser.print_help() - sys.exit() - - # the subcommand name - cmd_name = args_else[0] - - if cmd_name not in commands_dict: - guess = get_similar_commands(cmd_name) - - msg = ['unknown command "%s"' % cmd_name] - if guess: - msg.append('maybe you meant "%s"' % guess) - - raise CommandError(' - '.join(msg)) - - # all the args without the subcommand - cmd_args = args[:] - cmd_args.remove(cmd_name) - - return cmd_name, cmd_args diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/parser.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/parser.py deleted file mode 100644 index e1eaac4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/parser.py +++ /dev/null @@ -1,261 +0,0 @@ -"""Base option parser setup""" -from __future__ import absolute_import - -import logging -import optparse -import sys -import textwrap -from distutils.util import strtobool - -from pip._vendor.six import string_types - -from pip._internal.cli.status_codes import UNKNOWN_ERROR -from pip._internal.configuration import Configuration, ConfigurationError -from pip._internal.utils.compat import get_terminal_size - -logger = logging.getLogger(__name__) - - -class PrettyHelpFormatter(optparse.IndentedHelpFormatter): - """A prettier/less verbose help formatter for optparse.""" - - def __init__(self, *args, **kwargs): - # help position must be aligned with __init__.parseopts.description - kwargs['max_help_position'] = 30 - kwargs['indent_increment'] = 1 - kwargs['width'] = get_terminal_size()[0] - 2 - optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) - - def format_option_strings(self, option): - return self._format_option_strings(option, ' <%s>', ', ') - - def _format_option_strings(self, option, mvarfmt=' <%s>', optsep=', '): - """ - Return a comma-separated list of option strings and metavars. - - :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') - :param mvarfmt: metavar format string - evaluated as mvarfmt % metavar - :param optsep: separator - """ - opts = [] - - if option._short_opts: - opts.append(option._short_opts[0]) - if option._long_opts: - opts.append(option._long_opts[0]) - if len(opts) > 1: - opts.insert(1, optsep) - - if option.takes_value(): - metavar = option.metavar or option.dest.lower() - opts.append(mvarfmt % metavar.lower()) - - return ''.join(opts) - - def format_heading(self, heading): - if heading == 'Options': - return '' - return heading + ':\n' - - def format_usage(self, usage): - """ - Ensure there is only one newline between usage and the first heading - if there is no description. - """ - msg = '\nUsage: %s\n' % self.indent_lines(textwrap.dedent(usage), " ") - return msg - - def format_description(self, description): - # leave full control over description to us - if description: - if hasattr(self.parser, 'main'): - label = 'Commands' - else: - label = 'Description' - # some doc strings have initial newlines, some don't - description = description.lstrip('\n') - # some doc strings have final newlines and spaces, some don't - description = description.rstrip() - # dedent, then reindent - description = self.indent_lines(textwrap.dedent(description), " ") - description = '%s:\n%s\n' % (label, description) - return description - else: - return '' - - def format_epilog(self, epilog): - # leave full control over epilog to us - if epilog: - return epilog - else: - return '' - - def indent_lines(self, text, indent): - new_lines = [indent + line for line in text.split('\n')] - return "\n".join(new_lines) - - -class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): - """Custom help formatter for use in ConfigOptionParser. - - This is updates the defaults before expanding them, allowing - them to show up correctly in the help listing. - """ - - def expand_default(self, option): - if self.parser is not None: - self.parser._update_defaults(self.parser.defaults) - return optparse.IndentedHelpFormatter.expand_default(self, option) - - -class CustomOptionParser(optparse.OptionParser): - - def insert_option_group(self, idx, *args, **kwargs): - """Insert an OptionGroup at a given position.""" - group = self.add_option_group(*args, **kwargs) - - self.option_groups.pop() - self.option_groups.insert(idx, group) - - return group - - @property - def option_list_all(self): - """Get a list of all options, including those in option groups.""" - res = self.option_list[:] - for i in self.option_groups: - res.extend(i.option_list) - - return res - - -class ConfigOptionParser(CustomOptionParser): - """Custom option parser which updates its defaults by checking the - configuration files and environmental variables""" - - def __init__(self, *args, **kwargs): - self.name = kwargs.pop('name') - - isolated = kwargs.pop("isolated", False) - self.config = Configuration(isolated) - - assert self.name - optparse.OptionParser.__init__(self, *args, **kwargs) - - def check_default(self, option, key, val): - try: - return option.check_value(key, val) - except optparse.OptionValueError as exc: - print("An error occurred during configuration: %s" % exc) - sys.exit(3) - - def _get_ordered_configuration_items(self): - # Configuration gives keys in an unordered manner. Order them. - override_order = ["global", self.name, ":env:"] - - # Pool the options into different groups - section_items = {name: [] for name in override_order} - for section_key, val in self.config.items(): - # ignore empty values - if not val: - logger.debug( - "Ignoring configuration key '%s' as it's value is empty.", - section_key - ) - continue - - section, key = section_key.split(".", 1) - if section in override_order: - section_items[section].append((key, val)) - - # Yield each group in their override order - for section in override_order: - for key, val in section_items[section]: - yield key, val - - def _update_defaults(self, defaults): - """Updates the given defaults with values from the config files and - the environ. Does a little special handling for certain types of - options (lists).""" - - # Accumulate complex default state. - self.values = optparse.Values(self.defaults) - late_eval = set() - # Then set the options with those values - for key, val in self._get_ordered_configuration_items(): - # '--' because configuration supports only long names - option = self.get_option('--' + key) - - # Ignore options not present in this parser. E.g. non-globals put - # in [global] by users that want them to apply to all applicable - # commands. - if option is None: - continue - - if option.action in ('store_true', 'store_false', 'count'): - try: - val = strtobool(val) - except ValueError: - error_msg = invalid_config_error_message( - option.action, key, val - ) - self.error(error_msg) - - elif option.action == 'append': - val = val.split() - val = [self.check_default(option, key, v) for v in val] - elif option.action == 'callback': - late_eval.add(option.dest) - opt_str = option.get_opt_string() - val = option.convert_value(opt_str, val) - # From take_action - args = option.callback_args or () - kwargs = option.callback_kwargs or {} - option.callback(option, opt_str, val, self, *args, **kwargs) - else: - val = self.check_default(option, key, val) - - defaults[option.dest] = val - - for key in late_eval: - defaults[key] = getattr(self.values, key) - self.values = None - return defaults - - def get_default_values(self): - """Overriding to make updating the defaults after instantiation of - the option parser possible, _update_defaults() does the dirty work.""" - if not self.process_default_values: - # Old, pre-Optik 1.5 behaviour. - return optparse.Values(self.defaults) - - # Load the configuration, or error out in case of an error - try: - self.config.load() - except ConfigurationError as err: - self.exit(UNKNOWN_ERROR, str(err)) - - defaults = self._update_defaults(self.defaults.copy()) # ours - for option in self._get_all_options(): - default = defaults.get(option.dest) - if isinstance(default, string_types): - opt_str = option.get_opt_string() - defaults[option.dest] = option.check_value(opt_str, default) - return optparse.Values(defaults) - - def error(self, msg): - self.print_usage(sys.stderr) - self.exit(UNKNOWN_ERROR, "%s\n" % msg) - - -def invalid_config_error_message(action, key, val): - """Returns a better error message when invalid configuration option - is provided.""" - if action in ('store_true', 'store_false'): - return ("{0} is not a valid value for {1} option, " - "please specify a boolean value like yes/no, " - "true/false or 1/0 instead.").format(val, key) - - return ("{0} is not a valid value for {1} option, " - "please specify a numerical value like 1/0 " - "instead.").format(val, key) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/status_codes.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/status_codes.py deleted file mode 100644 index 275360a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/cli/status_codes.py +++ /dev/null @@ -1,8 +0,0 @@ -from __future__ import absolute_import - -SUCCESS = 0 -ERROR = 1 -UNKNOWN_ERROR = 2 -VIRTUALENV_NOT_FOUND = 3 -PREVIOUS_BUILD_DIR_ERROR = 4 -NO_MATCHES_FOUND = 23 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/__init__.py deleted file mode 100644 index c7d1da3..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/__init__.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Package containing all pip commands -""" -from __future__ import absolute_import - -from pip._internal.commands.completion import CompletionCommand -from pip._internal.commands.configuration import ConfigurationCommand -from pip._internal.commands.download import DownloadCommand -from pip._internal.commands.freeze import FreezeCommand -from pip._internal.commands.hash import HashCommand -from pip._internal.commands.help import HelpCommand -from pip._internal.commands.list import ListCommand -from pip._internal.commands.check import CheckCommand -from pip._internal.commands.search import SearchCommand -from pip._internal.commands.show import ShowCommand -from pip._internal.commands.install import InstallCommand -from pip._internal.commands.uninstall import UninstallCommand -from pip._internal.commands.wheel import WheelCommand - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Type # noqa: F401 - from pip._internal.cli.base_command import Command # noqa: F401 - -commands_order = [ - InstallCommand, - DownloadCommand, - UninstallCommand, - FreezeCommand, - ListCommand, - ShowCommand, - CheckCommand, - ConfigurationCommand, - SearchCommand, - WheelCommand, - HashCommand, - CompletionCommand, - HelpCommand, -] # type: List[Type[Command]] - -commands_dict = {c.name: c for c in commands_order} - - -def get_summaries(ordered=True): - """Yields sorted (command name, command summary) tuples.""" - - if ordered: - cmditems = _sort_commands(commands_dict, commands_order) - else: - cmditems = commands_dict.items() - - for name, command_class in cmditems: - yield (name, command_class.summary) - - -def get_similar_commands(name): - """Command name auto-correct.""" - from difflib import get_close_matches - - name = name.lower() - - close_commands = get_close_matches(name, commands_dict.keys()) - - if close_commands: - return close_commands[0] - else: - return False - - -def _sort_commands(cmddict, order): - def keyfn(key): - try: - return order.index(key[1]) - except ValueError: - # unordered items should come last - return 0xff - - return sorted(cmddict.items(), key=keyfn) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/check.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/check.py deleted file mode 100644 index 801cecc..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/check.py +++ /dev/null @@ -1,41 +0,0 @@ -import logging - -from pip._internal.cli.base_command import Command -from pip._internal.operations.check import ( - check_package_set, create_package_set_from_installed, -) - -logger = logging.getLogger(__name__) - - -class CheckCommand(Command): - """Verify installed packages have compatible dependencies.""" - name = 'check' - usage = """ - %prog [options]""" - summary = 'Verify installed packages have compatible dependencies.' - - def run(self, options, args): - package_set, parsing_probs = create_package_set_from_installed() - missing, conflicting = check_package_set(package_set) - - for project_name in missing: - version = package_set[project_name].version - for dependency in missing[project_name]: - logger.info( - "%s %s requires %s, which is not installed.", - project_name, version, dependency[0], - ) - - for project_name in conflicting: - version = package_set[project_name].version - for dep_name, dep_version, req in conflicting[project_name]: - logger.info( - "%s %s has requirement %s, but you have %s %s.", - project_name, version, req, dep_name, dep_version, - ) - - if missing or conflicting or parsing_probs: - return 1 - else: - logger.info("No broken requirements found.") diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/completion.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/completion.py deleted file mode 100644 index 2fcdd39..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/completion.py +++ /dev/null @@ -1,94 +0,0 @@ -from __future__ import absolute_import - -import sys -import textwrap - -from pip._internal.cli.base_command import Command -from pip._internal.utils.misc import get_prog - -BASE_COMPLETION = """ -# pip %(shell)s completion start%(script)s# pip %(shell)s completion end -""" - -COMPLETION_SCRIPTS = { - 'bash': """ - _pip_completion() - { - COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\ - COMP_CWORD=$COMP_CWORD \\ - PIP_AUTO_COMPLETE=1 $1 ) ) - } - complete -o default -F _pip_completion %(prog)s - """, - 'zsh': """ - function _pip_completion { - local words cword - read -Ac words - read -cn cword - reply=( $( COMP_WORDS="$words[*]" \\ - COMP_CWORD=$(( cword-1 )) \\ - PIP_AUTO_COMPLETE=1 $words[1] ) ) - } - compctl -K _pip_completion %(prog)s - """, - 'fish': """ - function __fish_complete_pip - set -lx COMP_WORDS (commandline -o) "" - set -lx COMP_CWORD ( \\ - math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\ - ) - set -lx PIP_AUTO_COMPLETE 1 - string split \\ -- (eval $COMP_WORDS[1]) - end - complete -fa "(__fish_complete_pip)" -c %(prog)s - """, -} - - -class CompletionCommand(Command): - """A helper command to be used for command completion.""" - name = 'completion' - summary = 'A helper command used for command completion.' - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(CompletionCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( - '--bash', '-b', - action='store_const', - const='bash', - dest='shell', - help='Emit completion code for bash') - cmd_opts.add_option( - '--zsh', '-z', - action='store_const', - const='zsh', - dest='shell', - help='Emit completion code for zsh') - cmd_opts.add_option( - '--fish', '-f', - action='store_const', - const='fish', - dest='shell', - help='Emit completion code for fish') - - self.parser.insert_option_group(0, cmd_opts) - - def run(self, options, args): - """Prints the completion code of the given shell""" - shells = COMPLETION_SCRIPTS.keys() - shell_options = ['--' + shell for shell in sorted(shells)] - if options.shell in shells: - script = textwrap.dedent( - COMPLETION_SCRIPTS.get(options.shell, '') % { - 'prog': get_prog(), - } - ) - print(BASE_COMPLETION % {'script': script, 'shell': options.shell}) - else: - sys.stderr.write( - 'ERROR: You must pass %s\n' % ' or '.join(shell_options) - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/configuration.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/configuration.py deleted file mode 100644 index 826c08d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/configuration.py +++ /dev/null @@ -1,227 +0,0 @@ -import logging -import os -import subprocess - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.configuration import Configuration, kinds -from pip._internal.exceptions import PipError -from pip._internal.locations import venv_config_file -from pip._internal.utils.misc import get_prog - -logger = logging.getLogger(__name__) - - -class ConfigurationCommand(Command): - """Manage local and global configuration. - - Subcommands: - - list: List the active configuration (or from the file specified) - edit: Edit the configuration file in an editor - get: Get the value associated with name - set: Set the name=value - unset: Unset the value associated with name - - If none of --user, --global and --venv are passed, a virtual - environment configuration file is used if one is active and the file - exists. Otherwise, all modifications happen on the to the user file by - default. - """ - - name = 'config' - usage = """ - %prog [] list - %prog [] [--editor ] edit - - %prog [] get name - %prog [] set name value - %prog [] unset name - """ - - summary = "Manage local and global configuration." - - def __init__(self, *args, **kwargs): - super(ConfigurationCommand, self).__init__(*args, **kwargs) - - self.configuration = None - - self.cmd_opts.add_option( - '--editor', - dest='editor', - action='store', - default=None, - help=( - 'Editor to use to edit the file. Uses VISUAL or EDITOR ' - 'environment variables if not provided.' - ) - ) - - self.cmd_opts.add_option( - '--global', - dest='global_file', - action='store_true', - default=False, - help='Use the system-wide configuration file only' - ) - - self.cmd_opts.add_option( - '--user', - dest='user_file', - action='store_true', - default=False, - help='Use the user configuration file only' - ) - - self.cmd_opts.add_option( - '--venv', - dest='venv_file', - action='store_true', - default=False, - help='Use the virtualenv configuration file only' - ) - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - handlers = { - "list": self.list_values, - "edit": self.open_in_editor, - "get": self.get_name, - "set": self.set_name_value, - "unset": self.unset_name - } - - # Determine action - if not args or args[0] not in handlers: - logger.error("Need an action ({}) to perform.".format( - ", ".join(sorted(handlers))) - ) - return ERROR - - action = args[0] - - # Determine which configuration files are to be loaded - # Depends on whether the command is modifying. - try: - load_only = self._determine_file( - options, need_value=(action in ["get", "set", "unset", "edit"]) - ) - except PipError as e: - logger.error(e.args[0]) - return ERROR - - # Load a new configuration - self.configuration = Configuration( - isolated=options.isolated_mode, load_only=load_only - ) - self.configuration.load() - - # Error handling happens here, not in the action-handlers. - try: - handlers[action](options, args[1:]) - except PipError as e: - logger.error(e.args[0]) - return ERROR - - return SUCCESS - - def _determine_file(self, options, need_value): - file_options = { - kinds.USER: options.user_file, - kinds.GLOBAL: options.global_file, - kinds.VENV: options.venv_file - } - - if sum(file_options.values()) == 0: - if not need_value: - return None - # Default to user, unless there's a virtualenv file. - elif os.path.exists(venv_config_file): - return kinds.VENV - else: - return kinds.USER - elif sum(file_options.values()) == 1: - # There's probably a better expression for this. - return [key for key in file_options if file_options[key]][0] - - raise PipError( - "Need exactly one file to operate upon " - "(--user, --venv, --global) to perform." - ) - - def list_values(self, options, args): - self._get_n_args(args, "list", n=0) - - for key, value in sorted(self.configuration.items()): - logger.info("%s=%r", key, value) - - def get_name(self, options, args): - key = self._get_n_args(args, "get [name]", n=1) - value = self.configuration.get_value(key) - - logger.info("%s", value) - - def set_name_value(self, options, args): - key, value = self._get_n_args(args, "set [name] [value]", n=2) - self.configuration.set_value(key, value) - - self._save_configuration() - - def unset_name(self, options, args): - key = self._get_n_args(args, "unset [name]", n=1) - self.configuration.unset_value(key) - - self._save_configuration() - - def open_in_editor(self, options, args): - editor = self._determine_editor(options) - - fname = self.configuration.get_file_to_edit() - if fname is None: - raise PipError("Could not determine appropriate file.") - - try: - subprocess.check_call([editor, fname]) - except subprocess.CalledProcessError as e: - raise PipError( - "Editor Subprocess exited with exit code {}" - .format(e.returncode) - ) - - def _get_n_args(self, args, example, n): - """Helper to make sure the command got the right number of arguments - """ - if len(args) != n: - msg = ( - 'Got unexpected number of arguments, expected {}. ' - '(example: "{} config {}")' - ).format(n, get_prog(), example) - raise PipError(msg) - - if n == 1: - return args[0] - else: - return args - - def _save_configuration(self): - # We successfully ran a modifying command. Need to save the - # configuration. - try: - self.configuration.save() - except Exception: - logger.error( - "Unable to save configuration. Please report this as a bug.", - exc_info=1 - ) - raise PipError("Internal Error.") - - def _determine_editor(self, options): - if options.editor is not None: - return options.editor - elif "VISUAL" in os.environ: - return os.environ["VISUAL"] - elif "EDITOR" in os.environ: - return os.environ["EDITOR"] - else: - raise PipError("Could not determine editor to use.") diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/download.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/download.py deleted file mode 100644 index a57e4bc..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/download.py +++ /dev/null @@ -1,176 +0,0 @@ -from __future__ import absolute_import - -import logging -import os - -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import RequirementCommand -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req import RequirementSet -from pip._internal.req.req_tracker import RequirementTracker -from pip._internal.resolve import Resolver -from pip._internal.utils.filesystem import check_path_owner -from pip._internal.utils.misc import ensure_dir, normalize_path -from pip._internal.utils.temp_dir import TempDirectory - -logger = logging.getLogger(__name__) - - -class DownloadCommand(RequirementCommand): - """ - Download packages from: - - - PyPI (and other indexes) using requirement specifiers. - - VCS project urls. - - Local project directories. - - Local or remote source archives. - - pip also supports downloading from "requirements files", which provide - an easy way to specify a whole environment to be downloaded. - """ - name = 'download' - - usage = """ - %prog [options] [package-index-options] ... - %prog [options] -r [package-index-options] ... - %prog [options] ... - %prog [options] ... - %prog [options] ...""" - - summary = 'Download packages.' - - def __init__(self, *args, **kw): - super(DownloadCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.global_options()) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option(cmdoptions.pre()) - cmd_opts.add_option(cmdoptions.no_clean()) - cmd_opts.add_option(cmdoptions.require_hashes()) - cmd_opts.add_option(cmdoptions.progress_bar()) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - - cmd_opts.add_option( - '-d', '--dest', '--destination-dir', '--destination-directory', - dest='download_dir', - metavar='dir', - default=os.curdir, - help=("Download packages into ."), - ) - - cmd_opts.add_option(cmdoptions.platform()) - cmd_opts.add_option(cmdoptions.python_version()) - cmd_opts.add_option(cmdoptions.implementation()) - cmd_opts.add_option(cmdoptions.abi()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - def run(self, options, args): - options.ignore_installed = True - # editable doesn't really make sense for `pip download`, but the bowels - # of the RequirementSet code require that property. - options.editables = [] - - if options.python_version: - python_versions = [options.python_version] - else: - python_versions = None - - cmdoptions.check_dist_restriction(options) - - options.src_dir = os.path.abspath(options.src_dir) - options.download_dir = normalize_path(options.download_dir) - - ensure_dir(options.download_dir) - - with self._build_session(options) as session: - finder = self._build_package_finder( - options=options, - session=session, - platform=options.platform, - python_versions=python_versions, - abi=options.abi, - implementation=options.implementation, - ) - build_delete = (not (options.no_clean or options.build_dir)) - if options.cache_dir and not check_path_owner(options.cache_dir): - logger.warning( - "The directory '%s' or its parent directory is not owned " - "by the current user and caching wheels has been " - "disabled. check the permissions and owner of that " - "directory. If executing pip with sudo, you may want " - "sudo's -H flag.", - options.cache_dir, - ) - options.cache_dir = None - - with RequirementTracker() as req_tracker, TempDirectory( - options.build_dir, delete=build_delete, kind="download" - ) as directory: - - requirement_set = RequirementSet( - require_hashes=options.require_hashes, - ) - self.populate_requirement_set( - requirement_set, - args, - options, - finder, - session, - self.name, - None - ) - - preparer = RequirementPreparer( - build_dir=directory.path, - src_dir=options.src_dir, - download_dir=options.download_dir, - wheel_download_dir=None, - progress_bar=options.progress_bar, - build_isolation=options.build_isolation, - req_tracker=req_tracker, - ) - - resolver = Resolver( - preparer=preparer, - finder=finder, - session=session, - wheel_cache=None, - use_user_site=False, - upgrade_strategy="to-satisfy-only", - force_reinstall=False, - ignore_dependencies=options.ignore_dependencies, - ignore_requires_python=False, - ignore_installed=True, - isolated=options.isolated_mode, - ) - resolver.resolve(requirement_set) - - downloaded = ' '.join([ - req.name for req in requirement_set.successfully_downloaded - ]) - if downloaded: - logger.info('Successfully downloaded %s', downloaded) - - # Clean up - if not options.no_clean: - requirement_set.cleanup_files() - - return requirement_set diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/freeze.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/freeze.py deleted file mode 100644 index dc9c53a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/freeze.py +++ /dev/null @@ -1,96 +0,0 @@ -from __future__ import absolute_import - -import sys - -from pip._internal.cache import WheelCache -from pip._internal.cli.base_command import Command -from pip._internal.models.format_control import FormatControl -from pip._internal.operations.freeze import freeze -from pip._internal.utils.compat import stdlib_pkgs - -DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'} - - -class FreezeCommand(Command): - """ - Output installed packages in requirements format. - - packages are listed in a case-insensitive sorted order. - """ - name = 'freeze' - usage = """ - %prog [options]""" - summary = 'Output installed packages in requirements format.' - log_streams = ("ext://sys.stderr", "ext://sys.stderr") - - def __init__(self, *args, **kw): - super(FreezeCommand, self).__init__(*args, **kw) - - self.cmd_opts.add_option( - '-r', '--requirement', - dest='requirements', - action='append', - default=[], - metavar='file', - help="Use the order in the given requirements file and its " - "comments when generating output. This option can be " - "used multiple times.") - self.cmd_opts.add_option( - '-f', '--find-links', - dest='find_links', - action='append', - default=[], - metavar='URL', - help='URL for finding packages, which will be added to the ' - 'output.') - self.cmd_opts.add_option( - '-l', '--local', - dest='local', - action='store_true', - default=False, - help='If in a virtualenv that has global access, do not output ' - 'globally-installed packages.') - self.cmd_opts.add_option( - '--user', - dest='user', - action='store_true', - default=False, - help='Only output packages installed in user-site.') - self.cmd_opts.add_option( - '--all', - dest='freeze_all', - action='store_true', - help='Do not skip these packages in the output:' - ' %s' % ', '.join(DEV_PKGS)) - self.cmd_opts.add_option( - '--exclude-editable', - dest='exclude_editable', - action='store_true', - help='Exclude editable package from output.') - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - format_control = FormatControl(set(), set()) - wheel_cache = WheelCache(options.cache_dir, format_control) - skip = set(stdlib_pkgs) - if not options.freeze_all: - skip.update(DEV_PKGS) - - freeze_kwargs = dict( - requirement=options.requirements, - find_links=options.find_links, - local_only=options.local, - user_only=options.user, - skip_regex=options.skip_requirements_regex, - isolated=options.isolated_mode, - wheel_cache=wheel_cache, - skip=skip, - exclude_editable=options.exclude_editable, - ) - - try: - for line in freeze(**freeze_kwargs): - sys.stdout.write(line + '\n') - finally: - wheel_cache.cleanup() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/hash.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/hash.py deleted file mode 100644 index 423440e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/hash.py +++ /dev/null @@ -1,57 +0,0 @@ -from __future__ import absolute_import - -import hashlib -import logging -import sys - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR -from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES -from pip._internal.utils.misc import read_chunks - -logger = logging.getLogger(__name__) - - -class HashCommand(Command): - """ - Compute a hash of a local package archive. - - These can be used with --hash in a requirements file to do repeatable - installs. - - """ - name = 'hash' - usage = '%prog [options] ...' - summary = 'Compute hashes of package archives.' - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(HashCommand, self).__init__(*args, **kw) - self.cmd_opts.add_option( - '-a', '--algorithm', - dest='algorithm', - choices=STRONG_HASHES, - action='store', - default=FAVORITE_HASH, - help='The hash algorithm to use: one of %s' % - ', '.join(STRONG_HASHES)) - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - if not args: - self.parser.print_usage(sys.stderr) - return ERROR - - algorithm = options.algorithm - for path in args: - logger.info('%s:\n--hash=%s:%s', - path, algorithm, _hash_of_file(path, algorithm)) - - -def _hash_of_file(path, algorithm): - """Return the hash digest of a file.""" - with open(path, 'rb') as archive: - hash = hashlib.new(algorithm) - for chunk in read_chunks(archive): - hash.update(chunk) - return hash.hexdigest() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/help.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/help.py deleted file mode 100644 index 49a81cb..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/help.py +++ /dev/null @@ -1,37 +0,0 @@ -from __future__ import absolute_import - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.exceptions import CommandError - - -class HelpCommand(Command): - """Show help for commands""" - name = 'help' - usage = """ - %prog """ - summary = 'Show help for commands.' - ignore_require_venv = True - - def run(self, options, args): - from pip._internal.commands import commands_dict, get_similar_commands - - try: - # 'pip help' with no args is handled by pip.__init__.parseopt() - cmd_name = args[0] # the command we need help for - except IndexError: - return SUCCESS - - if cmd_name not in commands_dict: - guess = get_similar_commands(cmd_name) - - msg = ['unknown command "%s"' % cmd_name] - if guess: - msg.append('maybe you meant "%s"' % guess) - - raise CommandError(' - '.join(msg)) - - command = commands_dict[cmd_name]() - command.parser.print_help() - - return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/install.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/install.py deleted file mode 100644 index 1c244d2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/install.py +++ /dev/null @@ -1,566 +0,0 @@ -from __future__ import absolute_import - -import errno -import logging -import operator -import os -import shutil -from optparse import SUPPRESS_HELP - -from pip._vendor import pkg_resources - -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import RequirementCommand -from pip._internal.cli.status_codes import ERROR -from pip._internal.exceptions import ( - CommandError, InstallationError, PreviousBuildDirError, -) -from pip._internal.locations import distutils_scheme, virtualenv_no_global -from pip._internal.operations.check import check_install_conflicts -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req import RequirementSet, install_given_reqs -from pip._internal.req.req_tracker import RequirementTracker -from pip._internal.resolve import Resolver -from pip._internal.utils.filesystem import check_path_owner -from pip._internal.utils.misc import ( - ensure_dir, get_installed_version, - protect_pip_from_modification_on_windows, -) -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.wheel import WheelBuilder - -logger = logging.getLogger(__name__) - - -class InstallCommand(RequirementCommand): - """ - Install packages from: - - - PyPI (and other indexes) using requirement specifiers. - - VCS project urls. - - Local project directories. - - Local or remote source archives. - - pip also supports installing from "requirements files", which provide - an easy way to specify a whole environment to be installed. - """ - name = 'install' - - usage = """ - %prog [options] [package-index-options] ... - %prog [options] -r [package-index-options] ... - %prog [options] [-e] ... - %prog [options] [-e] ... - %prog [options] ...""" - - summary = 'Install packages.' - - def __init__(self, *args, **kw): - super(InstallCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.pre()) - - cmd_opts.add_option(cmdoptions.editable()) - cmd_opts.add_option( - '-t', '--target', - dest='target_dir', - metavar='dir', - default=None, - help='Install packages into . ' - 'By default this will not replace existing files/folders in ' - '. Use --upgrade to replace existing packages in ' - 'with new versions.' - ) - cmd_opts.add_option(cmdoptions.platform()) - cmd_opts.add_option(cmdoptions.python_version()) - cmd_opts.add_option(cmdoptions.implementation()) - cmd_opts.add_option(cmdoptions.abi()) - - cmd_opts.add_option( - '--user', - dest='use_user_site', - action='store_true', - help="Install to the Python user install directory for your " - "platform. Typically ~/.local/, or %APPDATA%\\Python on " - "Windows. (See the Python documentation for site.USER_BASE " - "for full details.)") - cmd_opts.add_option( - '--no-user', - dest='use_user_site', - action='store_false', - help=SUPPRESS_HELP) - cmd_opts.add_option( - '--root', - dest='root_path', - metavar='dir', - default=None, - help="Install everything relative to this alternate root " - "directory.") - cmd_opts.add_option( - '--prefix', - dest='prefix_path', - metavar='dir', - default=None, - help="Installation prefix where lib, bin and other top-level " - "folders are placed") - - cmd_opts.add_option(cmdoptions.build_dir()) - - cmd_opts.add_option(cmdoptions.src()) - - cmd_opts.add_option( - '-U', '--upgrade', - dest='upgrade', - action='store_true', - help='Upgrade all specified packages to the newest available ' - 'version. The handling of dependencies depends on the ' - 'upgrade-strategy used.' - ) - - cmd_opts.add_option( - '--upgrade-strategy', - dest='upgrade_strategy', - default='only-if-needed', - choices=['only-if-needed', 'eager'], - help='Determines how dependency upgrading should be handled ' - '[default: %default]. ' - '"eager" - dependencies are upgraded regardless of ' - 'whether the currently installed version satisfies the ' - 'requirements of the upgraded package(s). ' - '"only-if-needed" - are upgraded only when they do not ' - 'satisfy the requirements of the upgraded package(s).' - ) - - cmd_opts.add_option( - '--force-reinstall', - dest='force_reinstall', - action='store_true', - help='Reinstall all packages even if they are already ' - 'up-to-date.') - - cmd_opts.add_option( - '-I', '--ignore-installed', - dest='ignore_installed', - action='store_true', - help='Ignore the installed packages (reinstalling instead).') - - cmd_opts.add_option(cmdoptions.ignore_requires_python()) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - - cmd_opts.add_option(cmdoptions.install_options()) - cmd_opts.add_option(cmdoptions.global_options()) - - cmd_opts.add_option( - "--compile", - action="store_true", - dest="compile", - default=True, - help="Compile Python source files to bytecode", - ) - - cmd_opts.add_option( - "--no-compile", - action="store_false", - dest="compile", - help="Do not compile Python source files to bytecode", - ) - - cmd_opts.add_option( - "--no-warn-script-location", - action="store_false", - dest="warn_script_location", - default=True, - help="Do not warn when installing scripts outside PATH", - ) - cmd_opts.add_option( - "--no-warn-conflicts", - action="store_false", - dest="warn_about_conflicts", - default=True, - help="Do not warn about broken dependencies", - ) - - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option(cmdoptions.no_clean()) - cmd_opts.add_option(cmdoptions.require_hashes()) - cmd_opts.add_option(cmdoptions.progress_bar()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - def run(self, options, args): - cmdoptions.check_install_build_global(options) - upgrade_strategy = "to-satisfy-only" - if options.upgrade: - upgrade_strategy = options.upgrade_strategy - - if options.build_dir: - options.build_dir = os.path.abspath(options.build_dir) - - cmdoptions.check_dist_restriction(options, check_target=True) - - if options.python_version: - python_versions = [options.python_version] - else: - python_versions = None - - options.src_dir = os.path.abspath(options.src_dir) - install_options = options.install_options or [] - if options.use_user_site: - if options.prefix_path: - raise CommandError( - "Can not combine '--user' and '--prefix' as they imply " - "different installation locations" - ) - if virtualenv_no_global(): - raise InstallationError( - "Can not perform a '--user' install. User site-packages " - "are not visible in this virtualenv." - ) - install_options.append('--user') - install_options.append('--prefix=') - - target_temp_dir = TempDirectory(kind="target") - if options.target_dir: - options.ignore_installed = True - options.target_dir = os.path.abspath(options.target_dir) - if (os.path.exists(options.target_dir) and not - os.path.isdir(options.target_dir)): - raise CommandError( - "Target path exists but is not a directory, will not " - "continue." - ) - - # Create a target directory for using with the target option - target_temp_dir.create() - install_options.append('--home=' + target_temp_dir.path) - - global_options = options.global_options or [] - - with self._build_session(options) as session: - finder = self._build_package_finder( - options=options, - session=session, - platform=options.platform, - python_versions=python_versions, - abi=options.abi, - implementation=options.implementation, - ) - build_delete = (not (options.no_clean or options.build_dir)) - wheel_cache = WheelCache(options.cache_dir, options.format_control) - - if options.cache_dir and not check_path_owner(options.cache_dir): - logger.warning( - "The directory '%s' or its parent directory is not owned " - "by the current user and caching wheels has been " - "disabled. check the permissions and owner of that " - "directory. If executing pip with sudo, you may want " - "sudo's -H flag.", - options.cache_dir, - ) - options.cache_dir = None - - with RequirementTracker() as req_tracker, TempDirectory( - options.build_dir, delete=build_delete, kind="install" - ) as directory: - requirement_set = RequirementSet( - require_hashes=options.require_hashes, - check_supported_wheels=not options.target_dir, - ) - - try: - self.populate_requirement_set( - requirement_set, args, options, finder, session, - self.name, wheel_cache - ) - preparer = RequirementPreparer( - build_dir=directory.path, - src_dir=options.src_dir, - download_dir=None, - wheel_download_dir=None, - progress_bar=options.progress_bar, - build_isolation=options.build_isolation, - req_tracker=req_tracker, - ) - - resolver = Resolver( - preparer=preparer, - finder=finder, - session=session, - wheel_cache=wheel_cache, - use_user_site=options.use_user_site, - upgrade_strategy=upgrade_strategy, - force_reinstall=options.force_reinstall, - ignore_dependencies=options.ignore_dependencies, - ignore_requires_python=options.ignore_requires_python, - ignore_installed=options.ignore_installed, - isolated=options.isolated_mode, - use_pep517=options.use_pep517 - ) - resolver.resolve(requirement_set) - - protect_pip_from_modification_on_windows( - modifying_pip=requirement_set.has_requirement("pip") - ) - - # Consider legacy and PEP517-using requirements separately - legacy_requirements = [] - pep517_requirements = [] - for req in requirement_set.requirements.values(): - if req.use_pep517: - pep517_requirements.append(req) - else: - legacy_requirements.append(req) - - # We don't build wheels for legacy requirements if we - # don't have wheel installed or we don't have a cache dir - try: - import wheel # noqa: F401 - build_legacy = bool(options.cache_dir) - except ImportError: - build_legacy = False - - wb = WheelBuilder( - finder, preparer, wheel_cache, - build_options=[], global_options=[], - ) - - # Always build PEP 517 requirements - build_failures = wb.build( - pep517_requirements, - session=session, autobuilding=True - ) - - if build_legacy: - # We don't care about failures building legacy - # requirements, as we'll fall through to a direct - # install for those. - wb.build( - legacy_requirements, - session=session, autobuilding=True - ) - - # If we're using PEP 517, we cannot do a direct install - # so we fail here. - if build_failures: - raise InstallationError( - "Could not build wheels for {} which use" - " PEP 517 and cannot be installed directly".format( - ", ".join(r.name for r in build_failures))) - - to_install = resolver.get_installation_order( - requirement_set - ) - - # Consistency Checking of the package set we're installing. - should_warn_about_conflicts = ( - not options.ignore_dependencies and - options.warn_about_conflicts - ) - if should_warn_about_conflicts: - self._warn_about_conflicts(to_install) - - # Don't warn about script install locations if - # --target has been specified - warn_script_location = options.warn_script_location - if options.target_dir: - warn_script_location = False - - installed = install_given_reqs( - to_install, - install_options, - global_options, - root=options.root_path, - home=target_temp_dir.path, - prefix=options.prefix_path, - pycompile=options.compile, - warn_script_location=warn_script_location, - use_user_site=options.use_user_site, - ) - - lib_locations = get_lib_location_guesses( - user=options.use_user_site, - home=target_temp_dir.path, - root=options.root_path, - prefix=options.prefix_path, - isolated=options.isolated_mode, - ) - working_set = pkg_resources.WorkingSet(lib_locations) - - reqs = sorted(installed, key=operator.attrgetter('name')) - items = [] - for req in reqs: - item = req.name - try: - installed_version = get_installed_version( - req.name, working_set=working_set - ) - if installed_version: - item += '-' + installed_version - except Exception: - pass - items.append(item) - installed = ' '.join(items) - if installed: - logger.info('Successfully installed %s', installed) - except EnvironmentError as error: - show_traceback = (self.verbosity >= 1) - - message = create_env_error_message( - error, show_traceback, options.use_user_site, - ) - logger.error(message, exc_info=show_traceback) - - return ERROR - except PreviousBuildDirError: - options.no_clean = True - raise - finally: - # Clean up - if not options.no_clean: - requirement_set.cleanup_files() - wheel_cache.cleanup() - - if options.target_dir: - self._handle_target_dir( - options.target_dir, target_temp_dir, options.upgrade - ) - return requirement_set - - def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): - ensure_dir(target_dir) - - # Checking both purelib and platlib directories for installed - # packages to be moved to target directory - lib_dir_list = [] - - with target_temp_dir: - # Checking both purelib and platlib directories for installed - # packages to be moved to target directory - scheme = distutils_scheme('', home=target_temp_dir.path) - purelib_dir = scheme['purelib'] - platlib_dir = scheme['platlib'] - data_dir = scheme['data'] - - if os.path.exists(purelib_dir): - lib_dir_list.append(purelib_dir) - if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: - lib_dir_list.append(platlib_dir) - if os.path.exists(data_dir): - lib_dir_list.append(data_dir) - - for lib_dir in lib_dir_list: - for item in os.listdir(lib_dir): - if lib_dir == data_dir: - ddir = os.path.join(data_dir, item) - if any(s.startswith(ddir) for s in lib_dir_list[:-1]): - continue - target_item_dir = os.path.join(target_dir, item) - if os.path.exists(target_item_dir): - if not upgrade: - logger.warning( - 'Target directory %s already exists. Specify ' - '--upgrade to force replacement.', - target_item_dir - ) - continue - if os.path.islink(target_item_dir): - logger.warning( - 'Target directory %s already exists and is ' - 'a link. Pip will not automatically replace ' - 'links, please remove if replacement is ' - 'desired.', - target_item_dir - ) - continue - if os.path.isdir(target_item_dir): - shutil.rmtree(target_item_dir) - else: - os.remove(target_item_dir) - - shutil.move( - os.path.join(lib_dir, item), - target_item_dir - ) - - def _warn_about_conflicts(self, to_install): - try: - package_set, _dep_info = check_install_conflicts(to_install) - except Exception: - logger.error("Error checking for conflicts.", exc_info=True) - return - missing, conflicting = _dep_info - - # NOTE: There is some duplication here from pip check - for project_name in missing: - version = package_set[project_name][0] - for dependency in missing[project_name]: - logger.critical( - "%s %s requires %s, which is not installed.", - project_name, version, dependency[1], - ) - - for project_name in conflicting: - version = package_set[project_name][0] - for dep_name, dep_version, req in conflicting[project_name]: - logger.critical( - "%s %s has requirement %s, but you'll have %s %s which is " - "incompatible.", - project_name, version, req, dep_name, dep_version, - ) - - -def get_lib_location_guesses(*args, **kwargs): - scheme = distutils_scheme('', *args, **kwargs) - return [scheme['purelib'], scheme['platlib']] - - -def create_env_error_message(error, show_traceback, using_user_site): - """Format an error message for an EnvironmentError - - It may occur anytime during the execution of the install command. - """ - parts = [] - - # Mention the error if we are not going to show a traceback - parts.append("Could not install packages due to an EnvironmentError") - if not show_traceback: - parts.append(": ") - parts.append(str(error)) - else: - parts.append(".") - - # Spilt the error indication from a helper message (if any) - parts[-1] += "\n" - - # Suggest useful actions to the user: - # (1) using user site-packages or (2) verifying the permissions - if error.errno == errno.EACCES: - user_option_part = "Consider using the `--user` option" - permissions_part = "Check the permissions" - - if not using_user_site: - parts.extend([ - user_option_part, " or ", - permissions_part.lower(), - ]) - else: - parts.append(permissions_part) - parts.append(".\n") - - return "".join(parts).strip() + "\n" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/list.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/list.py deleted file mode 100644 index a640274..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/list.py +++ /dev/null @@ -1,301 +0,0 @@ -from __future__ import absolute_import - -import json -import logging - -from pip._vendor import six -from pip._vendor.six.moves import zip_longest - -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.exceptions import CommandError -from pip._internal.index import PackageFinder -from pip._internal.utils.misc import ( - dist_is_editable, get_installed_distributions, -) -from pip._internal.utils.packaging import get_installer - -logger = logging.getLogger(__name__) - - -class ListCommand(Command): - """ - List installed packages, including editables. - - Packages are listed in a case-insensitive sorted order. - """ - name = 'list' - usage = """ - %prog [options]""" - summary = 'List installed packages.' - - def __init__(self, *args, **kw): - super(ListCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( - '-o', '--outdated', - action='store_true', - default=False, - help='List outdated packages') - cmd_opts.add_option( - '-u', '--uptodate', - action='store_true', - default=False, - help='List uptodate packages') - cmd_opts.add_option( - '-e', '--editable', - action='store_true', - default=False, - help='List editable projects.') - cmd_opts.add_option( - '-l', '--local', - action='store_true', - default=False, - help=('If in a virtualenv that has global access, do not list ' - 'globally-installed packages.'), - ) - self.cmd_opts.add_option( - '--user', - dest='user', - action='store_true', - default=False, - help='Only output packages installed in user-site.') - - cmd_opts.add_option( - '--pre', - action='store_true', - default=False, - help=("Include pre-release and development versions. By default, " - "pip only finds stable versions."), - ) - - cmd_opts.add_option( - '--format', - action='store', - dest='list_format', - default="columns", - choices=('columns', 'freeze', 'json'), - help="Select the output format among: columns (default), freeze, " - "or json", - ) - - cmd_opts.add_option( - '--not-required', - action='store_true', - dest='not_required', - help="List packages that are not dependencies of " - "installed packages.", - ) - - cmd_opts.add_option( - '--exclude-editable', - action='store_false', - dest='include_editable', - help='Exclude editable package from output.', - ) - cmd_opts.add_option( - '--include-editable', - action='store_true', - dest='include_editable', - help='Include editable package from output.', - default=True, - ) - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, self.parser - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - def _build_package_finder(self, options, index_urls, session): - """ - Create a package finder appropriate to this list command. - """ - return PackageFinder( - find_links=options.find_links, - index_urls=index_urls, - allow_all_prereleases=options.pre, - trusted_hosts=options.trusted_hosts, - session=session, - ) - - def run(self, options, args): - if options.outdated and options.uptodate: - raise CommandError( - "Options --outdated and --uptodate cannot be combined.") - - packages = get_installed_distributions( - local_only=options.local, - user_only=options.user, - editables_only=options.editable, - include_editables=options.include_editable, - ) - - # get_not_required must be called firstly in order to find and - # filter out all dependencies correctly. Otherwise a package - # can't be identified as requirement because some parent packages - # could be filtered out before. - if options.not_required: - packages = self.get_not_required(packages, options) - - if options.outdated: - packages = self.get_outdated(packages, options) - elif options.uptodate: - packages = self.get_uptodate(packages, options) - - self.output_package_listing(packages, options) - - def get_outdated(self, packages, options): - return [ - dist for dist in self.iter_packages_latest_infos(packages, options) - if dist.latest_version > dist.parsed_version - ] - - def get_uptodate(self, packages, options): - return [ - dist for dist in self.iter_packages_latest_infos(packages, options) - if dist.latest_version == dist.parsed_version - ] - - def get_not_required(self, packages, options): - dep_keys = set() - for dist in packages: - dep_keys.update(requirement.key for requirement in dist.requires()) - return {pkg for pkg in packages if pkg.key not in dep_keys} - - def iter_packages_latest_infos(self, packages, options): - index_urls = [options.index_url] + options.extra_index_urls - if options.no_index: - logger.debug('Ignoring indexes: %s', ','.join(index_urls)) - index_urls = [] - - with self._build_session(options) as session: - finder = self._build_package_finder(options, index_urls, session) - - for dist in packages: - typ = 'unknown' - all_candidates = finder.find_all_candidates(dist.key) - if not options.pre: - # Remove prereleases - all_candidates = [candidate for candidate in all_candidates - if not candidate.version.is_prerelease] - - if not all_candidates: - continue - best_candidate = max(all_candidates, - key=finder._candidate_sort_key) - remote_version = best_candidate.version - if best_candidate.location.is_wheel: - typ = 'wheel' - else: - typ = 'sdist' - # This is dirty but makes the rest of the code much cleaner - dist.latest_version = remote_version - dist.latest_filetype = typ - yield dist - - def output_package_listing(self, packages, options): - packages = sorted( - packages, - key=lambda dist: dist.project_name.lower(), - ) - if options.list_format == 'columns' and packages: - data, header = format_for_columns(packages, options) - self.output_package_listing_columns(data, header) - elif options.list_format == 'freeze': - for dist in packages: - if options.verbose >= 1: - logger.info("%s==%s (%s)", dist.project_name, - dist.version, dist.location) - else: - logger.info("%s==%s", dist.project_name, dist.version) - elif options.list_format == 'json': - logger.info(format_for_json(packages, options)) - - def output_package_listing_columns(self, data, header): - # insert the header first: we need to know the size of column names - if len(data) > 0: - data.insert(0, header) - - pkg_strings, sizes = tabulate(data) - - # Create and add a separator. - if len(data) > 0: - pkg_strings.insert(1, " ".join(map(lambda x: '-' * x, sizes))) - - for val in pkg_strings: - logger.info(val) - - -def tabulate(vals): - # From pfmoore on GitHub: - # https://github.com/pypa/pip/issues/3651#issuecomment-216932564 - assert len(vals) > 0 - - sizes = [0] * max(len(x) for x in vals) - for row in vals: - sizes = [max(s, len(str(c))) for s, c in zip_longest(sizes, row)] - - result = [] - for row in vals: - display = " ".join([str(c).ljust(s) if c is not None else '' - for s, c in zip_longest(sizes, row)]) - result.append(display) - - return result, sizes - - -def format_for_columns(pkgs, options): - """ - Convert the package data into something usable - by output_package_listing_columns. - """ - running_outdated = options.outdated - # Adjust the header for the `pip list --outdated` case. - if running_outdated: - header = ["Package", "Version", "Latest", "Type"] - else: - header = ["Package", "Version"] - - data = [] - if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs): - header.append("Location") - if options.verbose >= 1: - header.append("Installer") - - for proj in pkgs: - # if we're working on the 'outdated' list, separate out the - # latest_version and type - row = [proj.project_name, proj.version] - - if running_outdated: - row.append(proj.latest_version) - row.append(proj.latest_filetype) - - if options.verbose >= 1 or dist_is_editable(proj): - row.append(proj.location) - if options.verbose >= 1: - row.append(get_installer(proj)) - - data.append(row) - - return data, header - - -def format_for_json(packages, options): - data = [] - for dist in packages: - info = { - 'name': dist.project_name, - 'version': six.text_type(dist.version), - } - if options.verbose >= 1: - info['location'] = dist.location - info['installer'] = get_installer(dist) - if options.outdated: - info['latest_version'] = six.text_type(dist.latest_version) - info['latest_filetype'] = dist.latest_filetype - data.append(info) - return json.dumps(data) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/search.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/search.py deleted file mode 100644 index c157a31..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/search.py +++ /dev/null @@ -1,135 +0,0 @@ -from __future__ import absolute_import - -import logging -import sys -import textwrap -from collections import OrderedDict - -from pip._vendor import pkg_resources -from pip._vendor.packaging.version import parse as parse_version -# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is -# why we ignore the type on this import -from pip._vendor.six.moves import xmlrpc_client # type: ignore - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS -from pip._internal.download import PipXmlrpcTransport -from pip._internal.exceptions import CommandError -from pip._internal.models.index import PyPI -from pip._internal.utils.compat import get_terminal_size -from pip._internal.utils.logging import indent_log - -logger = logging.getLogger(__name__) - - -class SearchCommand(Command): - """Search for PyPI packages whose name or summary contains .""" - name = 'search' - usage = """ - %prog [options] """ - summary = 'Search PyPI for packages.' - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(SearchCommand, self).__init__(*args, **kw) - self.cmd_opts.add_option( - '-i', '--index', - dest='index', - metavar='URL', - default=PyPI.pypi_url, - help='Base URL of Python Package Index (default %default)') - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - if not args: - raise CommandError('Missing required argument (search query).') - query = args - pypi_hits = self.search(query, options) - hits = transform_hits(pypi_hits) - - terminal_width = None - if sys.stdout.isatty(): - terminal_width = get_terminal_size()[0] - - print_results(hits, terminal_width=terminal_width) - if pypi_hits: - return SUCCESS - return NO_MATCHES_FOUND - - def search(self, query, options): - index_url = options.index - with self._build_session(options) as session: - transport = PipXmlrpcTransport(index_url, session) - pypi = xmlrpc_client.ServerProxy(index_url, transport) - hits = pypi.search({'name': query, 'summary': query}, 'or') - return hits - - -def transform_hits(hits): - """ - The list from pypi is really a list of versions. We want a list of - packages with the list of versions stored inline. This converts the - list from pypi into one we can use. - """ - packages = OrderedDict() - for hit in hits: - name = hit['name'] - summary = hit['summary'] - version = hit['version'] - - if name not in packages.keys(): - packages[name] = { - 'name': name, - 'summary': summary, - 'versions': [version], - } - else: - packages[name]['versions'].append(version) - - # if this is the highest version, replace summary and score - if version == highest_version(packages[name]['versions']): - packages[name]['summary'] = summary - - return list(packages.values()) - - -def print_results(hits, name_column_width=None, terminal_width=None): - if not hits: - return - if name_column_width is None: - name_column_width = max([ - len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) - for hit in hits - ]) + 4 - - installed_packages = [p.project_name for p in pkg_resources.working_set] - for hit in hits: - name = hit['name'] - summary = hit['summary'] or '' - latest = highest_version(hit.get('versions', ['-'])) - if terminal_width is not None: - target_width = terminal_width - name_column_width - 5 - if target_width > 10: - # wrap and indent summary to fit terminal - summary = textwrap.wrap(summary, target_width) - summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) - - line = '%-*s - %s' % (name_column_width, - '%s (%s)' % (name, latest), summary) - try: - logger.info(line) - if name in installed_packages: - dist = pkg_resources.get_distribution(name) - with indent_log(): - if dist.version == latest: - logger.info('INSTALLED: %s (latest)', dist.version) - else: - logger.info('INSTALLED: %s', dist.version) - logger.info('LATEST: %s', latest) - except UnicodeEncodeError: - pass - - -def highest_version(versions): - return max(versions, key=parse_version) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/show.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/show.py deleted file mode 100644 index f92c9bc..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/show.py +++ /dev/null @@ -1,168 +0,0 @@ -from __future__ import absolute_import - -import logging -import os -from email.parser import FeedParser # type: ignore - -from pip._vendor import pkg_resources -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS - -logger = logging.getLogger(__name__) - - -class ShowCommand(Command): - """ - Show information about one or more installed packages. - - The output is in RFC-compliant mail header format. - """ - name = 'show' - usage = """ - %prog [options] ...""" - summary = 'Show information about installed packages.' - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(ShowCommand, self).__init__(*args, **kw) - self.cmd_opts.add_option( - '-f', '--files', - dest='files', - action='store_true', - default=False, - help='Show the full list of installed files for each package.') - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - if not args: - logger.warning('ERROR: Please provide a package name or names.') - return ERROR - query = args - - results = search_packages_info(query) - if not print_results( - results, list_files=options.files, verbose=options.verbose): - return ERROR - return SUCCESS - - -def search_packages_info(query): - """ - Gather details from installed distributions. Print distribution name, - version, location, and installed files. Installed files requires a - pip generated 'installed-files.txt' in the distributions '.egg-info' - directory. - """ - installed = {} - for p in pkg_resources.working_set: - installed[canonicalize_name(p.project_name)] = p - - query_names = [canonicalize_name(name) for name in query] - - for dist in [installed[pkg] for pkg in query_names if pkg in installed]: - package = { - 'name': dist.project_name, - 'version': dist.version, - 'location': dist.location, - 'requires': [dep.project_name for dep in dist.requires()], - } - file_list = None - metadata = None - if isinstance(dist, pkg_resources.DistInfoDistribution): - # RECORDs should be part of .dist-info metadatas - if dist.has_metadata('RECORD'): - lines = dist.get_metadata_lines('RECORD') - paths = [l.split(',')[0] for l in lines] - paths = [os.path.join(dist.location, p) for p in paths] - file_list = [os.path.relpath(p, dist.location) for p in paths] - - if dist.has_metadata('METADATA'): - metadata = dist.get_metadata('METADATA') - else: - # Otherwise use pip's log for .egg-info's - if dist.has_metadata('installed-files.txt'): - paths = dist.get_metadata_lines('installed-files.txt') - paths = [os.path.join(dist.egg_info, p) for p in paths] - file_list = [os.path.relpath(p, dist.location) for p in paths] - - if dist.has_metadata('PKG-INFO'): - metadata = dist.get_metadata('PKG-INFO') - - if dist.has_metadata('entry_points.txt'): - entry_points = dist.get_metadata_lines('entry_points.txt') - package['entry_points'] = entry_points - - if dist.has_metadata('INSTALLER'): - for line in dist.get_metadata_lines('INSTALLER'): - if line.strip(): - package['installer'] = line.strip() - break - - # @todo: Should pkg_resources.Distribution have a - # `get_pkg_info` method? - feed_parser = FeedParser() - feed_parser.feed(metadata) - pkg_info_dict = feed_parser.close() - for key in ('metadata-version', 'summary', - 'home-page', 'author', 'author-email', 'license'): - package[key] = pkg_info_dict.get(key) - - # It looks like FeedParser cannot deal with repeated headers - classifiers = [] - for line in metadata.splitlines(): - if line.startswith('Classifier: '): - classifiers.append(line[len('Classifier: '):]) - package['classifiers'] = classifiers - - if file_list: - package['files'] = sorted(file_list) - yield package - - -def print_results(distributions, list_files=False, verbose=False): - """ - Print the informations from installed distributions found. - """ - results_printed = False - for i, dist in enumerate(distributions): - results_printed = True - if i > 0: - logger.info("---") - - name = dist.get('name', '') - required_by = [ - pkg.project_name for pkg in pkg_resources.working_set - if name in [required.name for required in pkg.requires()] - ] - - logger.info("Name: %s", name) - logger.info("Version: %s", dist.get('version', '')) - logger.info("Summary: %s", dist.get('summary', '')) - logger.info("Home-page: %s", dist.get('home-page', '')) - logger.info("Author: %s", dist.get('author', '')) - logger.info("Author-email: %s", dist.get('author-email', '')) - logger.info("License: %s", dist.get('license', '')) - logger.info("Location: %s", dist.get('location', '')) - logger.info("Requires: %s", ', '.join(dist.get('requires', []))) - logger.info("Required-by: %s", ', '.join(required_by)) - - if verbose: - logger.info("Metadata-Version: %s", - dist.get('metadata-version', '')) - logger.info("Installer: %s", dist.get('installer', '')) - logger.info("Classifiers:") - for classifier in dist.get('classifiers', []): - logger.info(" %s", classifier) - logger.info("Entry-points:") - for entry in dist.get('entry_points', []): - logger.info(" %s", entry.strip()) - if list_files: - logger.info("Files:") - for line in dist.get('files', []): - logger.info(" %s", line.strip()) - if "files" not in dist: - logger.info("Cannot locate installed-files.txt") - return results_printed diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/uninstall.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/uninstall.py deleted file mode 100644 index 0cd6f54..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/uninstall.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import absolute_import - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.cli.base_command import Command -from pip._internal.exceptions import InstallationError -from pip._internal.req import parse_requirements -from pip._internal.req.constructors import install_req_from_line -from pip._internal.utils.misc import protect_pip_from_modification_on_windows - - -class UninstallCommand(Command): - """ - Uninstall packages. - - pip is able to uninstall most installed packages. Known exceptions are: - - - Pure distutils packages installed with ``python setup.py install``, which - leave behind no metadata to determine what files were installed. - - Script wrappers installed by ``python setup.py develop``. - """ - name = 'uninstall' - usage = """ - %prog [options] ... - %prog [options] -r ...""" - summary = 'Uninstall packages.' - - def __init__(self, *args, **kw): - super(UninstallCommand, self).__init__(*args, **kw) - self.cmd_opts.add_option( - '-r', '--requirement', - dest='requirements', - action='append', - default=[], - metavar='file', - help='Uninstall all the packages listed in the given requirements ' - 'file. This option can be used multiple times.', - ) - self.cmd_opts.add_option( - '-y', '--yes', - dest='yes', - action='store_true', - help="Don't ask for confirmation of uninstall deletions.") - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - with self._build_session(options) as session: - reqs_to_uninstall = {} - for name in args: - req = install_req_from_line( - name, isolated=options.isolated_mode, - ) - if req.name: - reqs_to_uninstall[canonicalize_name(req.name)] = req - for filename in options.requirements: - for req in parse_requirements( - filename, - options=options, - session=session): - if req.name: - reqs_to_uninstall[canonicalize_name(req.name)] = req - if not reqs_to_uninstall: - raise InstallationError( - 'You must give at least one requirement to %(name)s (see ' - '"pip help %(name)s")' % dict(name=self.name) - ) - - protect_pip_from_modification_on_windows( - modifying_pip="pip" in reqs_to_uninstall - ) - - for req in reqs_to_uninstall.values(): - uninstall_pathset = req.uninstall( - auto_confirm=options.yes, verbose=self.verbosity > 0, - ) - if uninstall_pathset: - uninstall_pathset.commit() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/wheel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/wheel.py deleted file mode 100644 index cd72a3d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/commands/wheel.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import - -import logging -import os - -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import RequirementCommand -from pip._internal.exceptions import CommandError, PreviousBuildDirError -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req import RequirementSet -from pip._internal.req.req_tracker import RequirementTracker -from pip._internal.resolve import Resolver -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.wheel import WheelBuilder - -logger = logging.getLogger(__name__) - - -class WheelCommand(RequirementCommand): - """ - Build Wheel archives for your requirements and dependencies. - - Wheel is a built-package format, and offers the advantage of not - recompiling your software during every install. For more details, see the - wheel docs: https://wheel.readthedocs.io/en/latest/ - - Requirements: setuptools>=0.8, and wheel. - - 'pip wheel' uses the bdist_wheel setuptools extension from the wheel - package to build individual wheels. - - """ - - name = 'wheel' - usage = """ - %prog [options] ... - %prog [options] -r ... - %prog [options] [-e] ... - %prog [options] [-e] ... - %prog [options] ...""" - - summary = 'Build wheels from your requirements.' - - def __init__(self, *args, **kw): - super(WheelCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( - '-w', '--wheel-dir', - dest='wheel_dir', - metavar='dir', - default=os.curdir, - help=("Build wheels into , where the default is the " - "current working directory."), - ) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option( - '--build-option', - dest='build_options', - metavar='options', - action='append', - help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", - ) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.editable()) - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option(cmdoptions.ignore_requires_python()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.progress_bar()) - - cmd_opts.add_option( - '--global-option', - dest='global_options', - action='append', - metavar='options', - help="Extra global options to be supplied to the setup.py " - "call before the 'bdist_wheel' command.") - - cmd_opts.add_option( - '--pre', - action='store_true', - default=False, - help=("Include pre-release and development versions. By default, " - "pip only finds stable versions."), - ) - - cmd_opts.add_option(cmdoptions.no_clean()) - cmd_opts.add_option(cmdoptions.require_hashes()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - def run(self, options, args): - cmdoptions.check_install_build_global(options) - - index_urls = [options.index_url] + options.extra_index_urls - if options.no_index: - logger.debug('Ignoring indexes: %s', ','.join(index_urls)) - index_urls = [] - - if options.build_dir: - options.build_dir = os.path.abspath(options.build_dir) - - options.src_dir = os.path.abspath(options.src_dir) - - with self._build_session(options) as session: - finder = self._build_package_finder(options, session) - build_delete = (not (options.no_clean or options.build_dir)) - wheel_cache = WheelCache(options.cache_dir, options.format_control) - - with RequirementTracker() as req_tracker, TempDirectory( - options.build_dir, delete=build_delete, kind="wheel" - ) as directory: - - requirement_set = RequirementSet( - require_hashes=options.require_hashes, - ) - - try: - self.populate_requirement_set( - requirement_set, args, options, finder, session, - self.name, wheel_cache - ) - - preparer = RequirementPreparer( - build_dir=directory.path, - src_dir=options.src_dir, - download_dir=None, - wheel_download_dir=options.wheel_dir, - progress_bar=options.progress_bar, - build_isolation=options.build_isolation, - req_tracker=req_tracker, - ) - - resolver = Resolver( - preparer=preparer, - finder=finder, - session=session, - wheel_cache=wheel_cache, - use_user_site=False, - upgrade_strategy="to-satisfy-only", - force_reinstall=False, - ignore_dependencies=options.ignore_dependencies, - ignore_requires_python=options.ignore_requires_python, - ignore_installed=True, - isolated=options.isolated_mode, - use_pep517=options.use_pep517 - ) - resolver.resolve(requirement_set) - - # build wheels - wb = WheelBuilder( - finder, preparer, wheel_cache, - build_options=options.build_options or [], - global_options=options.global_options or [], - no_clean=options.no_clean, - ) - build_failures = wb.build( - requirement_set.requirements.values(), session=session, - ) - if len(build_failures) != 0: - raise CommandError( - "Failed to build one or more wheels" - ) - except PreviousBuildDirError: - options.no_clean = True - raise - finally: - if not options.no_clean: - requirement_set.cleanup_files() - wheel_cache.cleanup() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/configuration.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/configuration.py deleted file mode 100644 index fe6df9b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/configuration.py +++ /dev/null @@ -1,387 +0,0 @@ -"""Configuration management setup - -Some terminology: -- name - As written in config files. -- value - Value associated with a name -- key - Name combined with it's section (section.name) -- variant - A single word describing where the configuration key-value pair came from -""" - -import locale -import logging -import os - -from pip._vendor import six -from pip._vendor.six.moves import configparser - -from pip._internal.exceptions import ( - ConfigurationError, ConfigurationFileCouldNotBeLoaded, -) -from pip._internal.locations import ( - legacy_config_file, new_config_file, running_under_virtualenv, - site_config_files, venv_config_file, -) -from pip._internal.utils.misc import ensure_dir, enum -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Any, Dict, Iterable, List, NewType, Optional, Tuple - ) - - RawConfigParser = configparser.RawConfigParser # Shorthand - Kind = NewType("Kind", str) - -logger = logging.getLogger(__name__) - - -# NOTE: Maybe use the optionx attribute to normalize keynames. -def _normalize_name(name): - # type: (str) -> str - """Make a name consistent regardless of source (environment or file) - """ - name = name.lower().replace('_', '-') - if name.startswith('--'): - name = name[2:] # only prefer long opts - return name - - -def _disassemble_key(name): - # type: (str) -> List[str] - return name.split(".", 1) - - -# The kinds of configurations there are. -kinds = enum( - USER="user", # User Specific - GLOBAL="global", # System Wide - VENV="venv", # Virtual Environment Specific - ENV="env", # from PIP_CONFIG_FILE - ENV_VAR="env-var", # from Environment Variables -) - - -class Configuration(object): - """Handles management of configuration. - - Provides an interface to accessing and managing configuration files. - - This class converts provides an API that takes "section.key-name" style - keys and stores the value associated with it as "key-name" under the - section "section". - - This allows for a clean interface wherein the both the section and the - key-name are preserved in an easy to manage form in the configuration files - and the data stored is also nice. - """ - - def __init__(self, isolated, load_only=None): - # type: (bool, Kind) -> None - super(Configuration, self).__init__() - - _valid_load_only = [kinds.USER, kinds.GLOBAL, kinds.VENV, None] - if load_only not in _valid_load_only: - raise ConfigurationError( - "Got invalid value for load_only - should be one of {}".format( - ", ".join(map(repr, _valid_load_only[:-1])) - ) - ) - self.isolated = isolated # type: bool - self.load_only = load_only # type: Optional[Kind] - - # The order here determines the override order. - self._override_order = [ - kinds.GLOBAL, kinds.USER, kinds.VENV, kinds.ENV, kinds.ENV_VAR - ] - - self._ignore_env_names = ["version", "help"] - - # Because we keep track of where we got the data from - self._parsers = { - variant: [] for variant in self._override_order - } # type: Dict[Kind, List[Tuple[str, RawConfigParser]]] - self._config = { - variant: {} for variant in self._override_order - } # type: Dict[Kind, Dict[str, Any]] - self._modified_parsers = [] # type: List[Tuple[str, RawConfigParser]] - - def load(self): - # type: () -> None - """Loads configuration from configuration files and environment - """ - self._load_config_files() - if not self.isolated: - self._load_environment_vars() - - def get_file_to_edit(self): - # type: () -> Optional[str] - """Returns the file with highest priority in configuration - """ - assert self.load_only is not None, \ - "Need to be specified a file to be editing" - - try: - return self._get_parser_to_modify()[0] - except IndexError: - return None - - def items(self): - # type: () -> Iterable[Tuple[str, Any]] - """Returns key-value pairs like dict.items() representing the loaded - configuration - """ - return self._dictionary.items() - - def get_value(self, key): - # type: (str) -> Any - """Get a value from the configuration. - """ - try: - return self._dictionary[key] - except KeyError: - raise ConfigurationError("No such key - {}".format(key)) - - def set_value(self, key, value): - # type: (str, Any) -> None - """Modify a value in the configuration. - """ - self._ensure_have_load_only() - - fname, parser = self._get_parser_to_modify() - - if parser is not None: - section, name = _disassemble_key(key) - - # Modify the parser and the configuration - if not parser.has_section(section): - parser.add_section(section) - parser.set(section, name, value) - - self._config[self.load_only][key] = value - self._mark_as_modified(fname, parser) - - def unset_value(self, key): - # type: (str) -> None - """Unset a value in the configuration. - """ - self._ensure_have_load_only() - - if key not in self._config[self.load_only]: - raise ConfigurationError("No such key - {}".format(key)) - - fname, parser = self._get_parser_to_modify() - - if parser is not None: - section, name = _disassemble_key(key) - - # Remove the key in the parser - modified_something = False - if parser.has_section(section): - # Returns whether the option was removed or not - modified_something = parser.remove_option(section, name) - - if modified_something: - # name removed from parser, section may now be empty - section_iter = iter(parser.items(section)) - try: - val = six.next(section_iter) - except StopIteration: - val = None - - if val is None: - parser.remove_section(section) - - self._mark_as_modified(fname, parser) - else: - raise ConfigurationError( - "Fatal Internal error [id=1]. Please report as a bug." - ) - - del self._config[self.load_only][key] - - def save(self): - # type: () -> None - """Save the currentin-memory state. - """ - self._ensure_have_load_only() - - for fname, parser in self._modified_parsers: - logger.info("Writing to %s", fname) - - # Ensure directory exists. - ensure_dir(os.path.dirname(fname)) - - with open(fname, "w") as f: - parser.write(f) # type: ignore - - # - # Private routines - # - - def _ensure_have_load_only(self): - # type: () -> None - if self.load_only is None: - raise ConfigurationError("Needed a specific file to be modifying.") - logger.debug("Will be working with %s variant only", self.load_only) - - @property - def _dictionary(self): - # type: () -> Dict[str, Any] - """A dictionary representing the loaded configuration. - """ - # NOTE: Dictionaries are not populated if not loaded. So, conditionals - # are not needed here. - retval = {} - - for variant in self._override_order: - retval.update(self._config[variant]) - - return retval - - def _load_config_files(self): - # type: () -> None - """Loads configuration from configuration files - """ - config_files = dict(self._iter_config_files()) - if config_files[kinds.ENV][0:1] == [os.devnull]: - logger.debug( - "Skipping loading configuration files due to " - "environment's PIP_CONFIG_FILE being os.devnull" - ) - return - - for variant, files in config_files.items(): - for fname in files: - # If there's specific variant set in `load_only`, load only - # that variant, not the others. - if self.load_only is not None and variant != self.load_only: - logger.debug( - "Skipping file '%s' (variant: %s)", fname, variant - ) - continue - - parser = self._load_file(variant, fname) - - # Keeping track of the parsers used - self._parsers[variant].append((fname, parser)) - - def _load_file(self, variant, fname): - # type: (Kind, str) -> RawConfigParser - logger.debug("For variant '%s', will try loading '%s'", variant, fname) - parser = self._construct_parser(fname) - - for section in parser.sections(): - items = parser.items(section) - self._config[variant].update(self._normalized_keys(section, items)) - - return parser - - def _construct_parser(self, fname): - # type: (str) -> RawConfigParser - parser = configparser.RawConfigParser() - # If there is no such file, don't bother reading it but create the - # parser anyway, to hold the data. - # Doing this is useful when modifying and saving files, where we don't - # need to construct a parser. - if os.path.exists(fname): - try: - parser.read(fname) - except UnicodeDecodeError: - # See https://github.com/pypa/pip/issues/4963 - raise ConfigurationFileCouldNotBeLoaded( - reason="contains invalid {} characters".format( - locale.getpreferredencoding(False) - ), - fname=fname, - ) - except configparser.Error as error: - # See https://github.com/pypa/pip/issues/4893 - raise ConfigurationFileCouldNotBeLoaded(error=error) - return parser - - def _load_environment_vars(self): - # type: () -> None - """Loads configuration from environment variables - """ - self._config[kinds.ENV_VAR].update( - self._normalized_keys(":env:", self._get_environ_vars()) - ) - - def _normalized_keys(self, section, items): - # type: (str, Iterable[Tuple[str, Any]]) -> Dict[str, Any] - """Normalizes items to construct a dictionary with normalized keys. - - This routine is where the names become keys and are made the same - regardless of source - configuration files or environment. - """ - normalized = {} - for name, val in items: - key = section + "." + _normalize_name(name) - normalized[key] = val - return normalized - - def _get_environ_vars(self): - # type: () -> Iterable[Tuple[str, str]] - """Returns a generator with all environmental vars with prefix PIP_""" - for key, val in os.environ.items(): - should_be_yielded = ( - key.startswith("PIP_") and - key[4:].lower() not in self._ignore_env_names - ) - if should_be_yielded: - yield key[4:].lower(), val - - # XXX: This is patched in the tests. - def _iter_config_files(self): - # type: () -> Iterable[Tuple[Kind, List[str]]] - """Yields variant and configuration files associated with it. - - This should be treated like items of a dictionary. - """ - # SMELL: Move the conditions out of this function - - # environment variables have the lowest priority - config_file = os.environ.get('PIP_CONFIG_FILE', None) - if config_file is not None: - yield kinds.ENV, [config_file] - else: - yield kinds.ENV, [] - - # at the base we have any global configuration - yield kinds.GLOBAL, list(site_config_files) - - # per-user configuration next - should_load_user_config = not self.isolated and not ( - config_file and os.path.exists(config_file) - ) - if should_load_user_config: - # The legacy config file is overridden by the new config file - yield kinds.USER, [legacy_config_file, new_config_file] - - # finally virtualenv configuration first trumping others - if running_under_virtualenv(): - yield kinds.VENV, [venv_config_file] - - def _get_parser_to_modify(self): - # type: () -> Tuple[str, RawConfigParser] - # Determine which parser to modify - parsers = self._parsers[self.load_only] - if not parsers: - # This should not happen if everything works correctly. - raise ConfigurationError( - "Fatal Internal error [id=2]. Please report as a bug." - ) - - # Use the highest priority parser. - return parsers[-1] - - # XXX: This is patched in the tests. - def _mark_as_modified(self, fname, parser): - # type: (str, RawConfigParser) -> None - file_parser_tuple = (fname, parser) - if file_parser_tuple not in self._modified_parsers: - self._modified_parsers.append(file_parser_tuple) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/download.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/download.py deleted file mode 100644 index 2bbe176..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/download.py +++ /dev/null @@ -1,971 +0,0 @@ -from __future__ import absolute_import - -import cgi -import email.utils -import getpass -import json -import logging -import mimetypes -import os -import platform -import re -import shutil -import sys - -from pip._vendor import requests, six, urllib3 -from pip._vendor.cachecontrol import CacheControlAdapter -from pip._vendor.cachecontrol.caches import FileCache -from pip._vendor.lockfile import LockError -from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter -from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth -from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response -from pip._vendor.requests.structures import CaseInsensitiveDict -from pip._vendor.requests.utils import get_netrc_auth -# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is -# why we ignore the type on this import -from pip._vendor.six.moves import xmlrpc_client # type: ignore -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request -from pip._vendor.urllib3.util import IS_PYOPENSSL - -import pip -from pip._internal.exceptions import HashMismatch, InstallationError -from pip._internal.locations import write_delete_marker_file -from pip._internal.models.index import PyPI -from pip._internal.utils.encoding import auto_decode -from pip._internal.utils.filesystem import check_path_owner -from pip._internal.utils.glibc import libc_ver -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - ARCHIVE_EXTENSIONS, ask_path_exists, backup_dir, call_subprocess, consume, - display_path, format_size, get_installed_version, rmtree, - split_auth_from_netloc, splitext, unpack_file, -) -from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import DownloadProgressProvider -from pip._internal.vcs import vcs - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Optional, Tuple, Dict, IO, Text, Union - ) - from pip._internal.models.link import Link # noqa: F401 - from pip._internal.utils.hashes import Hashes # noqa: F401 - from pip._internal.vcs import AuthInfo # noqa: F401 - -try: - import ssl # noqa -except ImportError: - ssl = None - -HAS_TLS = (ssl is not None) or IS_PYOPENSSL - -__all__ = ['get_file_content', - 'is_url', 'url_to_path', 'path_to_url', - 'is_archive_file', 'unpack_vcs_link', - 'unpack_file_url', 'is_vcs_url', 'is_file_url', - 'unpack_http_url', 'unpack_url'] - - -logger = logging.getLogger(__name__) - - -def user_agent(): - """ - Return a string representing the user agent. - """ - data = { - "installer": {"name": "pip", "version": pip.__version__}, - "python": platform.python_version(), - "implementation": { - "name": platform.python_implementation(), - }, - } - - if data["implementation"]["name"] == 'CPython': - data["implementation"]["version"] = platform.python_version() - elif data["implementation"]["name"] == 'PyPy': - if sys.pypy_version_info.releaselevel == 'final': - pypy_version_info = sys.pypy_version_info[:3] - else: - pypy_version_info = sys.pypy_version_info - data["implementation"]["version"] = ".".join( - [str(x) for x in pypy_version_info] - ) - elif data["implementation"]["name"] == 'Jython': - # Complete Guess - data["implementation"]["version"] = platform.python_version() - elif data["implementation"]["name"] == 'IronPython': - # Complete Guess - data["implementation"]["version"] = platform.python_version() - - if sys.platform.startswith("linux"): - from pip._vendor import distro - distro_infos = dict(filter( - lambda x: x[1], - zip(["name", "version", "id"], distro.linux_distribution()), - )) - libc = dict(filter( - lambda x: x[1], - zip(["lib", "version"], libc_ver()), - )) - if libc: - distro_infos["libc"] = libc - if distro_infos: - data["distro"] = distro_infos - - if sys.platform.startswith("darwin") and platform.mac_ver()[0]: - data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} - - if platform.system(): - data.setdefault("system", {})["name"] = platform.system() - - if platform.release(): - data.setdefault("system", {})["release"] = platform.release() - - if platform.machine(): - data["cpu"] = platform.machine() - - if HAS_TLS: - data["openssl_version"] = ssl.OPENSSL_VERSION - - setuptools_version = get_installed_version("setuptools") - if setuptools_version is not None: - data["setuptools_version"] = setuptools_version - - return "{data[installer][name]}/{data[installer][version]} {json}".format( - data=data, - json=json.dumps(data, separators=(",", ":"), sort_keys=True), - ) - - -class MultiDomainBasicAuth(AuthBase): - - def __init__(self, prompting=True): - # type: (bool) -> None - self.prompting = prompting - self.passwords = {} # type: Dict[str, AuthInfo] - - def __call__(self, req): - parsed = urllib_parse.urlparse(req.url) - - # Split the credentials from the netloc. - netloc, url_user_password = split_auth_from_netloc(parsed.netloc) - - # Set the url of the request to the url without any credentials - req.url = urllib_parse.urlunparse(parsed[:1] + (netloc,) + parsed[2:]) - - # Use any stored credentials that we have for this netloc - username, password = self.passwords.get(netloc, (None, None)) - - # Use the credentials embedded in the url if we have none stored - if username is None: - username, password = url_user_password - - # Get creds from netrc if we still don't have them - if username is None and password is None: - netrc_auth = get_netrc_auth(req.url) - username, password = netrc_auth if netrc_auth else (None, None) - - if username or password: - # Store the username and password - self.passwords[netloc] = (username, password) - - # Send the basic auth with this request - req = HTTPBasicAuth(username or "", password or "")(req) - - # Attach a hook to handle 401 responses - req.register_hook("response", self.handle_401) - - return req - - def handle_401(self, resp, **kwargs): - # We only care about 401 responses, anything else we want to just - # pass through the actual response - if resp.status_code != 401: - return resp - - # We are not able to prompt the user so simply return the response - if not self.prompting: - return resp - - parsed = urllib_parse.urlparse(resp.url) - - # Prompt the user for a new username and password - username = six.moves.input("User for %s: " % parsed.netloc) - password = getpass.getpass("Password: ") - - # Store the new username and password to use for future requests - if username or password: - self.passwords[parsed.netloc] = (username, password) - - # Consume content and release the original connection to allow our new - # request to reuse the same one. - resp.content - resp.raw.release_conn() - - # Add our new username and password to the request - req = HTTPBasicAuth(username or "", password or "")(resp.request) - req.register_hook("response", self.warn_on_401) - - # Send our new request - new_resp = resp.connection.send(req, **kwargs) - new_resp.history.append(resp) - - return new_resp - - def warn_on_401(self, resp, **kwargs): - # warn user that they provided incorrect credentials - if resp.status_code == 401: - logger.warning('401 Error, Credentials not correct for %s', - resp.request.url) - - -class LocalFSAdapter(BaseAdapter): - - def send(self, request, stream=None, timeout=None, verify=None, cert=None, - proxies=None): - pathname = url_to_path(request.url) - - resp = Response() - resp.status_code = 200 - resp.url = request.url - - try: - stats = os.stat(pathname) - except OSError as exc: - resp.status_code = 404 - resp.raw = exc - else: - modified = email.utils.formatdate(stats.st_mtime, usegmt=True) - content_type = mimetypes.guess_type(pathname)[0] or "text/plain" - resp.headers = CaseInsensitiveDict({ - "Content-Type": content_type, - "Content-Length": stats.st_size, - "Last-Modified": modified, - }) - - resp.raw = open(pathname, "rb") - resp.close = resp.raw.close - - return resp - - def close(self): - pass - - -class SafeFileCache(FileCache): - """ - A file based cache which is safe to use even when the target directory may - not be accessible or writable. - """ - - def __init__(self, *args, **kwargs): - super(SafeFileCache, self).__init__(*args, **kwargs) - - # Check to ensure that the directory containing our cache directory - # is owned by the user current executing pip. If it does not exist - # we will check the parent directory until we find one that does exist. - # If it is not owned by the user executing pip then we will disable - # the cache and log a warning. - if not check_path_owner(self.directory): - logger.warning( - "The directory '%s' or its parent directory is not owned by " - "the current user and the cache has been disabled. Please " - "check the permissions and owner of that directory. If " - "executing pip with sudo, you may want sudo's -H flag.", - self.directory, - ) - - # Set our directory to None to disable the Cache - self.directory = None - - def get(self, *args, **kwargs): - # If we don't have a directory, then the cache should be a no-op. - if self.directory is None: - return - - try: - return super(SafeFileCache, self).get(*args, **kwargs) - except (LockError, OSError, IOError): - # We intentionally silence this error, if we can't access the cache - # then we can just skip caching and process the request as if - # caching wasn't enabled. - pass - - def set(self, *args, **kwargs): - # If we don't have a directory, then the cache should be a no-op. - if self.directory is None: - return - - try: - return super(SafeFileCache, self).set(*args, **kwargs) - except (LockError, OSError, IOError): - # We intentionally silence this error, if we can't access the cache - # then we can just skip caching and process the request as if - # caching wasn't enabled. - pass - - def delete(self, *args, **kwargs): - # If we don't have a directory, then the cache should be a no-op. - if self.directory is None: - return - - try: - return super(SafeFileCache, self).delete(*args, **kwargs) - except (LockError, OSError, IOError): - # We intentionally silence this error, if we can't access the cache - # then we can just skip caching and process the request as if - # caching wasn't enabled. - pass - - -class InsecureHTTPAdapter(HTTPAdapter): - - def cert_verify(self, conn, url, verify, cert): - conn.cert_reqs = 'CERT_NONE' - conn.ca_certs = None - - -class PipSession(requests.Session): - - timeout = None # type: Optional[int] - - def __init__(self, *args, **kwargs): - retries = kwargs.pop("retries", 0) - cache = kwargs.pop("cache", None) - insecure_hosts = kwargs.pop("insecure_hosts", []) - - super(PipSession, self).__init__(*args, **kwargs) - - # Attach our User Agent to the request - self.headers["User-Agent"] = user_agent() - - # Attach our Authentication handler to the session - self.auth = MultiDomainBasicAuth() - - # Create our urllib3.Retry instance which will allow us to customize - # how we handle retries. - retries = urllib3.Retry( - # Set the total number of retries that a particular request can - # have. - total=retries, - - # A 503 error from PyPI typically means that the Fastly -> Origin - # connection got interrupted in some way. A 503 error in general - # is typically considered a transient error so we'll go ahead and - # retry it. - # A 500 may indicate transient error in Amazon S3 - # A 520 or 527 - may indicate transient error in CloudFlare - status_forcelist=[500, 503, 520, 527], - - # Add a small amount of back off between failed requests in - # order to prevent hammering the service. - backoff_factor=0.25, - ) - - # We want to _only_ cache responses on securely fetched origins. We do - # this because we can't validate the response of an insecurely fetched - # origin, and we don't want someone to be able to poison the cache and - # require manual eviction from the cache to fix it. - if cache: - secure_adapter = CacheControlAdapter( - cache=SafeFileCache(cache, use_dir_lock=True), - max_retries=retries, - ) - else: - secure_adapter = HTTPAdapter(max_retries=retries) - - # Our Insecure HTTPAdapter disables HTTPS validation. It does not - # support caching (see above) so we'll use it for all http:// URLs as - # well as any https:// host that we've marked as ignoring TLS errors - # for. - insecure_adapter = InsecureHTTPAdapter(max_retries=retries) - - self.mount("https://", secure_adapter) - self.mount("http://", insecure_adapter) - - # Enable file:// urls - self.mount("file://", LocalFSAdapter()) - - # We want to use a non-validating adapter for any requests which are - # deemed insecure. - for host in insecure_hosts: - self.mount("https://{}/".format(host), insecure_adapter) - - def request(self, method, url, *args, **kwargs): - # Allow setting a default timeout on a session - kwargs.setdefault("timeout", self.timeout) - - # Dispatch the actual request - return super(PipSession, self).request(method, url, *args, **kwargs) - - -def get_file_content(url, comes_from=None, session=None): - # type: (str, Optional[str], Optional[PipSession]) -> Tuple[str, Text] - """Gets the content of a file; it may be a filename, file: URL, or - http: URL. Returns (location, content). Content is unicode. - - :param url: File path or url. - :param comes_from: Origin description of requirements. - :param session: Instance of pip.download.PipSession. - """ - if session is None: - raise TypeError( - "get_file_content() missing 1 required keyword argument: 'session'" - ) - - match = _scheme_re.search(url) - if match: - scheme = match.group(1).lower() - if (scheme == 'file' and comes_from and - comes_from.startswith('http')): - raise InstallationError( - 'Requirements file %s references URL %s, which is local' - % (comes_from, url)) - if scheme == 'file': - path = url.split(':', 1)[1] - path = path.replace('\\', '/') - match = _url_slash_drive_re.match(path) - if match: - path = match.group(1) + ':' + path.split('|', 1)[1] - path = urllib_parse.unquote(path) - if path.startswith('/'): - path = '/' + path.lstrip('/') - url = path - else: - # FIXME: catch some errors - resp = session.get(url) - resp.raise_for_status() - return resp.url, resp.text - try: - with open(url, 'rb') as f: - content = auto_decode(f.read()) - except IOError as exc: - raise InstallationError( - 'Could not open requirements file: %s' % str(exc) - ) - return url, content - - -_scheme_re = re.compile(r'^(http|https|file):', re.I) -_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) - - -def is_url(name): - # type: (Union[str, Text]) -> bool - """Returns true if the name looks like a URL""" - if ':' not in name: - return False - scheme = name.split(':', 1)[0].lower() - return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes - - -def url_to_path(url): - # type: (str) -> str - """ - Convert a file: URL to a path. - """ - assert url.startswith('file:'), ( - "You can only turn file: urls into filenames (not %r)" % url) - - _, netloc, path, _, _ = urllib_parse.urlsplit(url) - - # if we have a UNC path, prepend UNC share notation - if netloc: - netloc = '\\\\' + netloc - - path = urllib_request.url2pathname(netloc + path) - return path - - -def path_to_url(path): - # type: (Union[str, Text]) -> str - """ - Convert a path to a file: URL. The path will be made absolute and have - quoted path parts. - """ - path = os.path.normpath(os.path.abspath(path)) - url = urllib_parse.urljoin('file:', urllib_request.pathname2url(path)) - return url - - -def is_archive_file(name): - # type: (str) -> bool - """Return True if `name` is a considered as an archive file.""" - ext = splitext(name)[1].lower() - if ext in ARCHIVE_EXTENSIONS: - return True - return False - - -def unpack_vcs_link(link, location): - vcs_backend = _get_used_vcs_backend(link) - vcs_backend.unpack(location) - - -def _get_used_vcs_backend(link): - for backend in vcs.backends: - if link.scheme in backend.schemes: - vcs_backend = backend(link.url) - return vcs_backend - - -def is_vcs_url(link): - # type: (Link) -> bool - return bool(_get_used_vcs_backend(link)) - - -def is_file_url(link): - # type: (Link) -> bool - return link.url.lower().startswith('file:') - - -def is_dir_url(link): - # type: (Link) -> bool - """Return whether a file:// Link points to a directory. - - ``link`` must not have any other scheme but file://. Call is_file_url() - first. - - """ - link_path = url_to_path(link.url_without_fragment) - return os.path.isdir(link_path) - - -def _progress_indicator(iterable, *args, **kwargs): - return iterable - - -def _download_url( - resp, # type: Response - link, # type: Link - content_file, # type: IO - hashes, # type: Hashes - progress_bar # type: str -): - # type: (...) -> None - try: - total_length = int(resp.headers['content-length']) - except (ValueError, KeyError, TypeError): - total_length = 0 - - cached_resp = getattr(resp, "from_cache", False) - if logger.getEffectiveLevel() > logging.INFO: - show_progress = False - elif cached_resp: - show_progress = False - elif total_length > (40 * 1000): - show_progress = True - elif not total_length: - show_progress = True - else: - show_progress = False - - show_url = link.show_url - - def resp_read(chunk_size): - try: - # Special case for urllib3. - for chunk in resp.raw.stream( - chunk_size, - # We use decode_content=False here because we don't - # want urllib3 to mess with the raw bytes we get - # from the server. If we decompress inside of - # urllib3 then we cannot verify the checksum - # because the checksum will be of the compressed - # file. This breakage will only occur if the - # server adds a Content-Encoding header, which - # depends on how the server was configured: - # - Some servers will notice that the file isn't a - # compressible file and will leave the file alone - # and with an empty Content-Encoding - # - Some servers will notice that the file is - # already compressed and will leave the file - # alone and will add a Content-Encoding: gzip - # header - # - Some servers won't notice anything at all and - # will take a file that's already been compressed - # and compress it again and set the - # Content-Encoding: gzip header - # - # By setting this not to decode automatically we - # hope to eliminate problems with the second case. - decode_content=False): - yield chunk - except AttributeError: - # Standard file-like object. - while True: - chunk = resp.raw.read(chunk_size) - if not chunk: - break - yield chunk - - def written_chunks(chunks): - for chunk in chunks: - content_file.write(chunk) - yield chunk - - progress_indicator = _progress_indicator - - if link.netloc == PyPI.netloc: - url = show_url - else: - url = link.url_without_fragment - - if show_progress: # We don't show progress on cached responses - progress_indicator = DownloadProgressProvider(progress_bar, - max=total_length) - if total_length: - logger.info("Downloading %s (%s)", url, format_size(total_length)) - else: - logger.info("Downloading %s", url) - elif cached_resp: - logger.info("Using cached %s", url) - else: - logger.info("Downloading %s", url) - - logger.debug('Downloading from URL %s', link) - - downloaded_chunks = written_chunks( - progress_indicator( - resp_read(CONTENT_CHUNK_SIZE), - CONTENT_CHUNK_SIZE - ) - ) - if hashes: - hashes.check_against_chunks(downloaded_chunks) - else: - consume(downloaded_chunks) - - -def _copy_file(filename, location, link): - copy = True - download_location = os.path.join(location, link.filename) - if os.path.exists(download_location): - response = ask_path_exists( - 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' % - display_path(download_location), ('i', 'w', 'b', 'a')) - if response == 'i': - copy = False - elif response == 'w': - logger.warning('Deleting %s', display_path(download_location)) - os.remove(download_location) - elif response == 'b': - dest_file = backup_dir(download_location) - logger.warning( - 'Backing up %s to %s', - display_path(download_location), - display_path(dest_file), - ) - shutil.move(download_location, dest_file) - elif response == 'a': - sys.exit(-1) - if copy: - shutil.copy(filename, download_location) - logger.info('Saved %s', display_path(download_location)) - - -def unpack_http_url( - link, # type: Link - location, # type: str - download_dir=None, # type: Optional[str] - session=None, # type: Optional[PipSession] - hashes=None, # type: Optional[Hashes] - progress_bar="on" # type: str -): - # type: (...) -> None - if session is None: - raise TypeError( - "unpack_http_url() missing 1 required keyword argument: 'session'" - ) - - with TempDirectory(kind="unpack") as temp_dir: - # If a download dir is specified, is the file already downloaded there? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir(link, - download_dir, - hashes) - - if already_downloaded_path: - from_path = already_downloaded_path - content_type = mimetypes.guess_type(from_path)[0] - else: - # let's download to a tmp dir - from_path, content_type = _download_http_url(link, - session, - temp_dir.path, - hashes, - progress_bar) - - # unpack the archive to the build dir location. even when only - # downloading archives, they have to be unpacked to parse dependencies - unpack_file(from_path, location, content_type, link) - - # a download dir is specified; let's copy the archive there - if download_dir and not already_downloaded_path: - _copy_file(from_path, download_dir, link) - - if not already_downloaded_path: - os.unlink(from_path) - - -def unpack_file_url( - link, # type: Link - location, # type: str - download_dir=None, # type: Optional[str] - hashes=None # type: Optional[Hashes] -): - # type: (...) -> None - """Unpack link into location. - - If download_dir is provided and link points to a file, make a copy - of the link file inside download_dir. - """ - link_path = url_to_path(link.url_without_fragment) - - # If it's a url to a local directory - if is_dir_url(link): - if os.path.isdir(location): - rmtree(location) - shutil.copytree(link_path, location, symlinks=True) - if download_dir: - logger.info('Link is a directory, ignoring download_dir') - return - - # If --require-hashes is off, `hashes` is either empty, the - # link's embedded hash, or MissingHashes; it is required to - # match. If --require-hashes is on, we are satisfied by any - # hash in `hashes` matching: a URL-based or an option-based - # one; no internet-sourced hash will be in `hashes`. - if hashes: - hashes.check_against_path(link_path) - - # If a download dir is specified, is the file already there and valid? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir(link, - download_dir, - hashes) - - if already_downloaded_path: - from_path = already_downloaded_path - else: - from_path = link_path - - content_type = mimetypes.guess_type(from_path)[0] - - # unpack the archive to the build dir location. even when only downloading - # archives, they have to be unpacked to parse dependencies - unpack_file(from_path, location, content_type, link) - - # a download dir is specified and not already downloaded - if download_dir and not already_downloaded_path: - _copy_file(from_path, download_dir, link) - - -def _copy_dist_from_dir(link_path, location): - """Copy distribution files in `link_path` to `location`. - - Invoked when user requests to install a local directory. E.g.: - - pip install . - pip install ~/dev/git-repos/python-prompt-toolkit - - """ - - # Note: This is currently VERY SLOW if you have a lot of data in the - # directory, because it copies everything with `shutil.copytree`. - # What it should really do is build an sdist and install that. - # See https://github.com/pypa/pip/issues/2195 - - if os.path.isdir(location): - rmtree(location) - - # build an sdist - setup_py = 'setup.py' - sdist_args = [sys.executable] - sdist_args.append('-c') - sdist_args.append(SETUPTOOLS_SHIM % setup_py) - sdist_args.append('sdist') - sdist_args += ['--dist-dir', location] - logger.info('Running setup.py sdist for %s', link_path) - - with indent_log(): - call_subprocess(sdist_args, cwd=link_path, show_stdout=False) - - # unpack sdist into `location` - sdist = os.path.join(location, os.listdir(location)[0]) - logger.info('Unpacking sdist %s into %s', sdist, location) - unpack_file(sdist, location, content_type=None, link=None) - - -class PipXmlrpcTransport(xmlrpc_client.Transport): - """Provide a `xmlrpclib.Transport` implementation via a `PipSession` - object. - """ - - def __init__(self, index_url, session, use_datetime=False): - xmlrpc_client.Transport.__init__(self, use_datetime) - index_parts = urllib_parse.urlparse(index_url) - self._scheme = index_parts.scheme - self._session = session - - def request(self, host, handler, request_body, verbose=False): - parts = (self._scheme, host, handler, None, None, None) - url = urllib_parse.urlunparse(parts) - try: - headers = {'Content-Type': 'text/xml'} - response = self._session.post(url, data=request_body, - headers=headers, stream=True) - response.raise_for_status() - self.verbose = verbose - return self.parse_response(response.raw) - except requests.HTTPError as exc: - logger.critical( - "HTTP error %s while getting %s", - exc.response.status_code, url, - ) - raise - - -def unpack_url( - link, # type: Optional[Link] - location, # type: Optional[str] - download_dir=None, # type: Optional[str] - only_download=False, # type: bool - session=None, # type: Optional[PipSession] - hashes=None, # type: Optional[Hashes] - progress_bar="on" # type: str -): - # type: (...) -> None - """Unpack link. - If link is a VCS link: - if only_download, export into download_dir and ignore location - else unpack into location - for other types of link: - - unpack into location - - if download_dir, copy the file into download_dir - - if only_download, mark location for deletion - - :param hashes: A Hashes object, one of whose embedded hashes must match, - or HashMismatch will be raised. If the Hashes is empty, no matches are - required, and unhashable types of requirements (like VCS ones, which - would ordinarily raise HashUnsupported) are allowed. - """ - # non-editable vcs urls - if is_vcs_url(link): - unpack_vcs_link(link, location) - - # file urls - elif is_file_url(link): - unpack_file_url(link, location, download_dir, hashes=hashes) - - # http urls - else: - if session is None: - session = PipSession() - - unpack_http_url( - link, - location, - download_dir, - session, - hashes=hashes, - progress_bar=progress_bar - ) - if only_download: - write_delete_marker_file(location) - - -def _download_http_url( - link, # type: Link - session, # type: PipSession - temp_dir, # type: str - hashes, # type: Hashes - progress_bar # type: str -): - # type: (...) -> Tuple[str, str] - """Download link url into temp_dir using provided session""" - target_url = link.url.split('#', 1)[0] - try: - resp = session.get( - target_url, - # We use Accept-Encoding: identity here because requests - # defaults to accepting compressed responses. This breaks in - # a variety of ways depending on how the server is configured. - # - Some servers will notice that the file isn't a compressible - # file and will leave the file alone and with an empty - # Content-Encoding - # - Some servers will notice that the file is already - # compressed and will leave the file alone and will add a - # Content-Encoding: gzip header - # - Some servers won't notice anything at all and will take - # a file that's already been compressed and compress it again - # and set the Content-Encoding: gzip header - # By setting this to request only the identity encoding We're - # hoping to eliminate the third case. Hopefully there does not - # exist a server which when given a file will notice it is - # already compressed and that you're not asking for a - # compressed file and will then decompress it before sending - # because if that's the case I don't think it'll ever be - # possible to make this work. - headers={"Accept-Encoding": "identity"}, - stream=True, - ) - resp.raise_for_status() - except requests.HTTPError as exc: - logger.critical( - "HTTP error %s while getting %s", exc.response.status_code, link, - ) - raise - - content_type = resp.headers.get('content-type', '') - filename = link.filename # fallback - # Have a look at the Content-Disposition header for a better guess - content_disposition = resp.headers.get('content-disposition') - if content_disposition: - type, params = cgi.parse_header(content_disposition) - # We use ``or`` here because we don't want to use an "empty" value - # from the filename param. - filename = params.get('filename') or filename - ext = splitext(filename)[1] - if not ext: - ext = mimetypes.guess_extension(content_type) - if ext: - filename += ext - if not ext and link.url != resp.url: - ext = os.path.splitext(resp.url)[1] - if ext: - filename += ext - file_path = os.path.join(temp_dir, filename) - with open(file_path, 'wb') as content_file: - _download_url(resp, link, content_file, hashes, progress_bar) - return file_path, content_type - - -def _check_download_dir(link, download_dir, hashes): - # type: (Link, str, Hashes) -> Optional[str] - """ Check download_dir for previously downloaded file with correct hash - If a correct file is found return its path else None - """ - download_path = os.path.join(download_dir, link.filename) - if os.path.exists(download_path): - # If already downloaded, does its hash match? - logger.info('File was already downloaded %s', download_path) - if hashes: - try: - hashes.check_against_path(download_path) - except HashMismatch: - logger.warning( - 'Previously-downloaded file %s has bad hash. ' - 'Re-downloading.', - download_path - ) - os.unlink(download_path) - return None - return download_path - return None diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/exceptions.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/exceptions.py deleted file mode 100644 index 38ceeea..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/exceptions.py +++ /dev/null @@ -1,274 +0,0 @@ -"""Exceptions used throughout package""" -from __future__ import absolute_import - -from itertools import chain, groupby, repeat - -from pip._vendor.six import iteritems - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional # noqa: F401 - from pip._internal.req.req_install import InstallRequirement # noqa: F401 - - -class PipError(Exception): - """Base pip exception""" - - -class ConfigurationError(PipError): - """General exception in configuration""" - - -class InstallationError(PipError): - """General exception during installation""" - - -class UninstallationError(PipError): - """General exception during uninstallation""" - - -class DistributionNotFound(InstallationError): - """Raised when a distribution cannot be found to satisfy a requirement""" - - -class RequirementsFileParseError(InstallationError): - """Raised when a general error occurs parsing a requirements file line.""" - - -class BestVersionAlreadyInstalled(PipError): - """Raised when the most up-to-date version of a package is already - installed.""" - - -class BadCommand(PipError): - """Raised when virtualenv or a command is not found""" - - -class CommandError(PipError): - """Raised when there is an error in command-line arguments""" - - -class PreviousBuildDirError(PipError): - """Raised when there's a previous conflicting build directory""" - - -class InvalidWheelFilename(InstallationError): - """Invalid wheel filename.""" - - -class UnsupportedWheel(InstallationError): - """Unsupported wheel.""" - - -class HashErrors(InstallationError): - """Multiple HashError instances rolled into one for reporting""" - - def __init__(self): - self.errors = [] - - def append(self, error): - self.errors.append(error) - - def __str__(self): - lines = [] - self.errors.sort(key=lambda e: e.order) - for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): - lines.append(cls.head) - lines.extend(e.body() for e in errors_of_cls) - if lines: - return '\n'.join(lines) - - def __nonzero__(self): - return bool(self.errors) - - def __bool__(self): - return self.__nonzero__() - - -class HashError(InstallationError): - """ - A failure to verify a package against known-good hashes - - :cvar order: An int sorting hash exception classes by difficulty of - recovery (lower being harder), so the user doesn't bother fretting - about unpinned packages when he has deeper issues, like VCS - dependencies, to deal with. Also keeps error reports in a - deterministic order. - :cvar head: A section heading for display above potentially many - exceptions of this kind - :ivar req: The InstallRequirement that triggered this error. This is - pasted on after the exception is instantiated, because it's not - typically available earlier. - - """ - req = None # type: Optional[InstallRequirement] - head = '' - - def body(self): - """Return a summary of me for display under the heading. - - This default implementation simply prints a description of the - triggering requirement. - - :param req: The InstallRequirement that provoked this error, with - populate_link() having already been called - - """ - return ' %s' % self._requirement_name() - - def __str__(self): - return '%s\n%s' % (self.head, self.body()) - - def _requirement_name(self): - """Return a description of the requirement that triggered me. - - This default implementation returns long description of the req, with - line numbers - - """ - return str(self.req) if self.req else 'unknown package' - - -class VcsHashUnsupported(HashError): - """A hash was provided for a version-control-system-based requirement, but - we don't have a method for hashing those.""" - - order = 0 - head = ("Can't verify hashes for these requirements because we don't " - "have a way to hash version control repositories:") - - -class DirectoryUrlHashUnsupported(HashError): - """A hash was provided for a version-control-system-based requirement, but - we don't have a method for hashing those.""" - - order = 1 - head = ("Can't verify hashes for these file:// requirements because they " - "point to directories:") - - -class HashMissing(HashError): - """A hash was needed for a requirement but is absent.""" - - order = 2 - head = ('Hashes are required in --require-hashes mode, but they are ' - 'missing from some requirements. Here is a list of those ' - 'requirements along with the hashes their downloaded archives ' - 'actually had. Add lines like these to your requirements files to ' - 'prevent tampering. (If you did not enable --require-hashes ' - 'manually, note that it turns on automatically when any package ' - 'has a hash.)') - - def __init__(self, gotten_hash): - """ - :param gotten_hash: The hash of the (possibly malicious) archive we - just downloaded - """ - self.gotten_hash = gotten_hash - - def body(self): - # Dodge circular import. - from pip._internal.utils.hashes import FAVORITE_HASH - - package = None - if self.req: - # In the case of URL-based requirements, display the original URL - # seen in the requirements file rather than the package name, - # so the output can be directly copied into the requirements file. - package = (self.req.original_link if self.req.original_link - # In case someone feeds something downright stupid - # to InstallRequirement's constructor. - else getattr(self.req, 'req', None)) - return ' %s --hash=%s:%s' % (package or 'unknown package', - FAVORITE_HASH, - self.gotten_hash) - - -class HashUnpinned(HashError): - """A requirement had a hash specified but was not pinned to a specific - version.""" - - order = 3 - head = ('In --require-hashes mode, all requirements must have their ' - 'versions pinned with ==. These do not:') - - -class HashMismatch(HashError): - """ - Distribution file hash values don't match. - - :ivar package_name: The name of the package that triggered the hash - mismatch. Feel free to write to this after the exception is raise to - improve its error message. - - """ - order = 4 - head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' - 'FILE. If you have updated the package versions, please update ' - 'the hashes. Otherwise, examine the package contents carefully; ' - 'someone may have tampered with them.') - - def __init__(self, allowed, gots): - """ - :param allowed: A dict of algorithm names pointing to lists of allowed - hex digests - :param gots: A dict of algorithm names pointing to hashes we - actually got from the files under suspicion - """ - self.allowed = allowed - self.gots = gots - - def body(self): - return ' %s:\n%s' % (self._requirement_name(), - self._hash_comparison()) - - def _hash_comparison(self): - """ - Return a comparison of actual and expected hash values. - - Example:: - - Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde - or 123451234512345123451234512345123451234512345 - Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef - - """ - def hash_then_or(hash_name): - # For now, all the decent hashes have 6-char names, so we can get - # away with hard-coding space literals. - return chain([hash_name], repeat(' or')) - - lines = [] - for hash_name, expecteds in iteritems(self.allowed): - prefix = hash_then_or(hash_name) - lines.extend((' Expected %s %s' % (next(prefix), e)) - for e in expecteds) - lines.append(' Got %s\n' % - self.gots[hash_name].hexdigest()) - prefix = ' or' - return '\n'.join(lines) - - -class UnsupportedPythonVersion(InstallationError): - """Unsupported python version according to Requires-Python package - metadata.""" - - -class ConfigurationFileCouldNotBeLoaded(ConfigurationError): - """When there are errors while loading a configuration file - """ - - def __init__(self, reason="could not be loaded", fname=None, error=None): - super(ConfigurationFileCouldNotBeLoaded, self).__init__(error) - self.reason = reason - self.fname = fname - self.error = error - - def __str__(self): - if self.fname is not None: - message_part = " in {}.".format(self.fname) - else: - assert self.error is not None - message_part = ".\n{}\n".format(self.error.message) - return "Configuration file {}{}".format(self.reason, message_part) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/index.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/index.py deleted file mode 100644 index 9eda3a3..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/index.py +++ /dev/null @@ -1,990 +0,0 @@ -"""Routines related to PyPI, indexes""" -from __future__ import absolute_import - -import cgi -import itertools -import logging -import mimetypes -import os -import posixpath -import re -import sys -from collections import namedtuple - -from pip._vendor import html5lib, requests, six -from pip._vendor.distlib.compat import unescape -from pip._vendor.packaging import specifiers -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.packaging.version import parse as parse_version -from pip._vendor.requests.exceptions import RetryError, SSLError -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request - -from pip._internal.download import HAS_TLS, is_url, path_to_url, url_to_path -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename, - UnsupportedWheel, -) -from pip._internal.models.candidate import InstallationCandidate -from pip._internal.models.format_control import FormatControl -from pip._internal.models.index import PyPI -from pip._internal.models.link import Link -from pip._internal.pep425tags import get_supported -from pip._internal.utils.compat import ipaddress -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, WHEEL_EXTENSION, normalize_path, - redact_password_from_url, -) -from pip._internal.utils.packaging import check_requires_python -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel import Wheel - -if MYPY_CHECK_RUNNING: - from logging import Logger # noqa: F401 - from typing import ( # noqa: F401 - Tuple, Optional, Any, List, Union, Callable, Set, Sequence, - Iterable, MutableMapping - ) - from pip._vendor.packaging.version import _BaseVersion # noqa: F401 - from pip._vendor.requests import Response # noqa: F401 - from pip._internal.req import InstallRequirement # noqa: F401 - from pip._internal.download import PipSession # noqa: F401 - - SecureOrigin = Tuple[str, str, Optional[str]] - BuildTag = Tuple[Any, ...] # either emply tuple or Tuple[int, str] - CandidateSortingKey = Tuple[int, _BaseVersion, BuildTag, Optional[int]] - -__all__ = ['FormatControl', 'PackageFinder'] - - -SECURE_ORIGINS = [ - # protocol, hostname, port - # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) - ("https", "*", "*"), - ("*", "localhost", "*"), - ("*", "127.0.0.0/8", "*"), - ("*", "::1/128", "*"), - ("file", "*", None), - # ssh is always secure. - ("ssh", "*", "*"), -] # type: List[SecureOrigin] - - -logger = logging.getLogger(__name__) - - -def _match_vcs_scheme(url): - # type: (str) -> Optional[str] - """Look for VCS schemes in the URL. - - Returns the matched VCS scheme, or None if there's no match. - """ - from pip._internal.vcs import VcsSupport - for scheme in VcsSupport.schemes: - if url.lower().startswith(scheme) and url[len(scheme)] in '+:': - return scheme - return None - - -def _is_url_like_archive(url): - # type: (str) -> bool - """Return whether the URL looks like an archive. - """ - filename = Link(url).filename - for bad_ext in ARCHIVE_EXTENSIONS: - if filename.endswith(bad_ext): - return True - return False - - -class _NotHTML(Exception): - def __init__(self, content_type, request_desc): - # type: (str, str) -> None - super(_NotHTML, self).__init__(content_type, request_desc) - self.content_type = content_type - self.request_desc = request_desc - - -def _ensure_html_header(response): - # type: (Response) -> None - """Check the Content-Type header to ensure the response contains HTML. - - Raises `_NotHTML` if the content type is not text/html. - """ - content_type = response.headers.get("Content-Type", "") - if not content_type.lower().startswith("text/html"): - raise _NotHTML(content_type, response.request.method) - - -class _NotHTTP(Exception): - pass - - -def _ensure_html_response(url, session): - # type: (str, PipSession) -> None - """Send a HEAD request to the URL, and ensure the response contains HTML. - - Raises `_NotHTTP` if the URL is not available for a HEAD request, or - `_NotHTML` if the content type is not text/html. - """ - scheme, netloc, path, query, fragment = urllib_parse.urlsplit(url) - if scheme not in {'http', 'https'}: - raise _NotHTTP() - - resp = session.head(url, allow_redirects=True) - resp.raise_for_status() - - _ensure_html_header(resp) - - -def _get_html_response(url, session): - # type: (str, PipSession) -> Response - """Access an HTML page with GET, and return the response. - - This consists of three parts: - - 1. If the URL looks suspiciously like an archive, send a HEAD first to - check the Content-Type is HTML, to avoid downloading a large file. - Raise `_NotHTTP` if the content type cannot be determined, or - `_NotHTML` if it is not HTML. - 2. Actually perform the request. Raise HTTP exceptions on network failures. - 3. Check the Content-Type header to make sure we got HTML, and raise - `_NotHTML` otherwise. - """ - if _is_url_like_archive(url): - _ensure_html_response(url, session=session) - - logger.debug('Getting page %s', url) - - resp = session.get( - url, - headers={ - "Accept": "text/html", - # We don't want to blindly returned cached data for - # /simple/, because authors generally expecting that - # twine upload && pip install will function, but if - # they've done a pip install in the last ~10 minutes - # it won't. Thus by setting this to zero we will not - # blindly use any cached data, however the benefit of - # using max-age=0 instead of no-cache, is that we will - # still support conditional requests, so we will still - # minimize traffic sent in cases where the page hasn't - # changed at all, we will just always incur the round - # trip for the conditional GET now instead of only - # once per 10 minutes. - # For more information, please see pypa/pip#5670. - "Cache-Control": "max-age=0", - }, - ) - resp.raise_for_status() - - # The check for archives above only works if the url ends with - # something that looks like an archive. However that is not a - # requirement of an url. Unless we issue a HEAD request on every - # url we cannot know ahead of time for sure if something is HTML - # or not. However we can check after we've downloaded it. - _ensure_html_header(resp) - - return resp - - -def _handle_get_page_fail( - link, # type: Link - reason, # type: Union[str, Exception] - meth=None # type: Optional[Callable[..., None]] -): - # type: (...) -> None - if meth is None: - meth = logger.debug - meth("Could not fetch URL %s: %s - skipping", link, reason) - - -def _get_html_page(link, session=None): - # type: (Link, Optional[PipSession]) -> Optional[HTMLPage] - if session is None: - raise TypeError( - "_get_html_page() missing 1 required keyword argument: 'session'" - ) - - url = link.url.split('#', 1)[0] - - # Check for VCS schemes that do not support lookup as web pages. - vcs_scheme = _match_vcs_scheme(url) - if vcs_scheme: - logger.debug('Cannot look at %s URL %s', vcs_scheme, link) - return None - - # Tack index.html onto file:// URLs that point to directories - scheme, _, path, _, _, _ = urllib_parse.urlparse(url) - if (scheme == 'file' and os.path.isdir(urllib_request.url2pathname(path))): - # add trailing slash if not present so urljoin doesn't trim - # final segment - if not url.endswith('/'): - url += '/' - url = urllib_parse.urljoin(url, 'index.html') - logger.debug(' file: URL is directory, getting %s', url) - - try: - resp = _get_html_response(url, session=session) - except _NotHTTP as exc: - logger.debug( - 'Skipping page %s because it looks like an archive, and cannot ' - 'be checked by HEAD.', link, - ) - except _NotHTML as exc: - logger.debug( - 'Skipping page %s because the %s request got Content-Type: %s', - link, exc.request_desc, exc.content_type, - ) - except requests.HTTPError as exc: - _handle_get_page_fail(link, exc) - except RetryError as exc: - _handle_get_page_fail(link, exc) - except SSLError as exc: - reason = "There was a problem confirming the ssl certificate: " - reason += str(exc) - _handle_get_page_fail(link, reason, meth=logger.info) - except requests.ConnectionError as exc: - _handle_get_page_fail(link, "connection error: %s" % exc) - except requests.Timeout: - _handle_get_page_fail(link, "timed out") - else: - return HTMLPage(resp.content, resp.url, resp.headers) - return None - - -class PackageFinder(object): - """This finds packages. - - This is meant to match easy_install's technique for looking for - packages, by reading pages and looking for appropriate links. - """ - - def __init__( - self, - find_links, # type: List[str] - index_urls, # type: List[str] - allow_all_prereleases=False, # type: bool - trusted_hosts=None, # type: Optional[Iterable[str]] - session=None, # type: Optional[PipSession] - format_control=None, # type: Optional[FormatControl] - platform=None, # type: Optional[str] - versions=None, # type: Optional[List[str]] - abi=None, # type: Optional[str] - implementation=None, # type: Optional[str] - prefer_binary=False # type: bool - ): - # type: (...) -> None - """Create a PackageFinder. - - :param format_control: A FormatControl object or None. Used to control - the selection of source packages / binary packages when consulting - the index and links. - :param platform: A string or None. If None, searches for packages - that are supported by the current system. Otherwise, will find - packages that can be built on the platform passed in. These - packages will only be downloaded for distribution: they will - not be built locally. - :param versions: A list of strings or None. This is passed directly - to pep425tags.py in the get_supported() method. - :param abi: A string or None. This is passed directly - to pep425tags.py in the get_supported() method. - :param implementation: A string or None. This is passed directly - to pep425tags.py in the get_supported() method. - """ - if session is None: - raise TypeError( - "PackageFinder() missing 1 required keyword argument: " - "'session'" - ) - - # Build find_links. If an argument starts with ~, it may be - # a local file relative to a home directory. So try normalizing - # it and if it exists, use the normalized version. - # This is deliberately conservative - it might be fine just to - # blindly normalize anything starting with a ~... - self.find_links = [] # type: List[str] - for link in find_links: - if link.startswith('~'): - new_link = normalize_path(link) - if os.path.exists(new_link): - link = new_link - self.find_links.append(link) - - self.index_urls = index_urls - - # These are boring links that have already been logged somehow: - self.logged_links = set() # type: Set[Link] - - self.format_control = format_control or FormatControl(set(), set()) - - # Domains that we won't emit warnings for when not using HTTPS - self.secure_origins = [ - ("*", host, "*") - for host in (trusted_hosts if trusted_hosts else []) - ] # type: List[SecureOrigin] - - # Do we want to allow _all_ pre-releases? - self.allow_all_prereleases = allow_all_prereleases - - # The Session we'll use to make requests - self.session = session - - # The valid tags to check potential found wheel candidates against - self.valid_tags = get_supported( - versions=versions, - platform=platform, - abi=abi, - impl=implementation, - ) - - # Do we prefer old, but valid, binary dist over new source dist - self.prefer_binary = prefer_binary - - # If we don't have TLS enabled, then WARN if anyplace we're looking - # relies on TLS. - if not HAS_TLS: - for link in itertools.chain(self.index_urls, self.find_links): - parsed = urllib_parse.urlparse(link) - if parsed.scheme == "https": - logger.warning( - "pip is configured with locations that require " - "TLS/SSL, however the ssl module in Python is not " - "available." - ) - break - - def get_formatted_locations(self): - # type: () -> str - lines = [] - if self.index_urls and self.index_urls != [PyPI.simple_url]: - lines.append( - "Looking in indexes: {}".format(", ".join( - redact_password_from_url(url) for url in self.index_urls)) - ) - if self.find_links: - lines.append( - "Looking in links: {}".format(", ".join(self.find_links)) - ) - return "\n".join(lines) - - @staticmethod - def _sort_locations(locations, expand_dir=False): - # type: (Sequence[str], bool) -> Tuple[List[str], List[str]] - """ - Sort locations into "files" (archives) and "urls", and return - a pair of lists (files,urls) - """ - files = [] - urls = [] - - # puts the url for the given file path into the appropriate list - def sort_path(path): - url = path_to_url(path) - if mimetypes.guess_type(url, strict=False)[0] == 'text/html': - urls.append(url) - else: - files.append(url) - - for url in locations: - - is_local_path = os.path.exists(url) - is_file_url = url.startswith('file:') - - if is_local_path or is_file_url: - if is_local_path: - path = url - else: - path = url_to_path(url) - if os.path.isdir(path): - if expand_dir: - path = os.path.realpath(path) - for item in os.listdir(path): - sort_path(os.path.join(path, item)) - elif is_file_url: - urls.append(url) - else: - logger.warning( - "Path '{0}' is ignored: " - "it is a directory.".format(path), - ) - elif os.path.isfile(path): - sort_path(path) - else: - logger.warning( - "Url '%s' is ignored: it is neither a file " - "nor a directory.", url, - ) - elif is_url(url): - # Only add url with clear scheme - urls.append(url) - else: - logger.warning( - "Url '%s' is ignored. It is either a non-existing " - "path or lacks a specific scheme.", url, - ) - - return files, urls - - def _candidate_sort_key(self, candidate): - # type: (InstallationCandidate) -> CandidateSortingKey - """ - Function used to generate link sort key for link tuples. - The greater the return value, the more preferred it is. - If not finding wheels, then sorted by version only. - If finding wheels, then the sort order is by version, then: - 1. existing installs - 2. wheels ordered via Wheel.support_index_min(self.valid_tags) - 3. source archives - If prefer_binary was set, then all wheels are sorted above sources. - Note: it was considered to embed this logic into the Link - comparison operators, but then different sdist links - with the same version, would have to be considered equal - """ - support_num = len(self.valid_tags) - build_tag = tuple() # type: BuildTag - binary_preference = 0 - if candidate.location.is_wheel: - # can raise InvalidWheelFilename - wheel = Wheel(candidate.location.filename) - if not wheel.supported(self.valid_tags): - raise UnsupportedWheel( - "%s is not a supported wheel for this platform. It " - "can't be sorted." % wheel.filename - ) - if self.prefer_binary: - binary_preference = 1 - pri = -(wheel.support_index_min(self.valid_tags)) - if wheel.build_tag is not None: - match = re.match(r'^(\d+)(.*)$', wheel.build_tag) - build_tag_groups = match.groups() - build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) - else: # sdist - pri = -(support_num) - return (binary_preference, candidate.version, build_tag, pri) - - def _validate_secure_origin(self, logger, location): - # type: (Logger, Link) -> bool - # Determine if this url used a secure transport mechanism - parsed = urllib_parse.urlparse(str(location)) - origin = (parsed.scheme, parsed.hostname, parsed.port) - - # The protocol to use to see if the protocol matches. - # Don't count the repository type as part of the protocol: in - # cases such as "git+ssh", only use "ssh". (I.e., Only verify against - # the last scheme.) - protocol = origin[0].rsplit('+', 1)[-1] - - # Determine if our origin is a secure origin by looking through our - # hardcoded list of secure origins, as well as any additional ones - # configured on this PackageFinder instance. - for secure_origin in (SECURE_ORIGINS + self.secure_origins): - if protocol != secure_origin[0] and secure_origin[0] != "*": - continue - - try: - # We need to do this decode dance to ensure that we have a - # unicode object, even on Python 2.x. - addr = ipaddress.ip_address( - origin[1] - if ( - isinstance(origin[1], six.text_type) or - origin[1] is None - ) - else origin[1].decode("utf8") - ) - network = ipaddress.ip_network( - secure_origin[1] - if isinstance(secure_origin[1], six.text_type) - # setting secure_origin[1] to proper Union[bytes, str] - # creates problems in other places - else secure_origin[1].decode("utf8") # type: ignore - ) - except ValueError: - # We don't have both a valid address or a valid network, so - # we'll check this origin against hostnames. - if (origin[1] and - origin[1].lower() != secure_origin[1].lower() and - secure_origin[1] != "*"): - continue - else: - # We have a valid address and network, so see if the address - # is contained within the network. - if addr not in network: - continue - - # Check to see if the port patches - if (origin[2] != secure_origin[2] and - secure_origin[2] != "*" and - secure_origin[2] is not None): - continue - - # If we've gotten here, then this origin matches the current - # secure origin and we should return True - return True - - # If we've gotten to this point, then the origin isn't secure and we - # will not accept it as a valid location to search. We will however - # log a warning that we are ignoring it. - logger.warning( - "The repository located at %s is not a trusted or secure host and " - "is being ignored. If this repository is available via HTTPS we " - "recommend you use HTTPS instead, otherwise you may silence " - "this warning and allow it anyway with '--trusted-host %s'.", - parsed.hostname, - parsed.hostname, - ) - - return False - - def _get_index_urls_locations(self, project_name): - # type: (str) -> List[str] - """Returns the locations found via self.index_urls - - Checks the url_name on the main (first in the list) index and - use this url_name to produce all locations - """ - - def mkurl_pypi_url(url): - loc = posixpath.join( - url, - urllib_parse.quote(canonicalize_name(project_name))) - # For maximum compatibility with easy_install, ensure the path - # ends in a trailing slash. Although this isn't in the spec - # (and PyPI can handle it without the slash) some other index - # implementations might break if they relied on easy_install's - # behavior. - if not loc.endswith('/'): - loc = loc + '/' - return loc - - return [mkurl_pypi_url(url) for url in self.index_urls] - - def find_all_candidates(self, project_name): - # type: (str) -> List[Optional[InstallationCandidate]] - """Find all available InstallationCandidate for project_name - - This checks index_urls and find_links. - All versions found are returned as an InstallationCandidate list. - - See _link_package_versions for details on which files are accepted - """ - index_locations = self._get_index_urls_locations(project_name) - index_file_loc, index_url_loc = self._sort_locations(index_locations) - fl_file_loc, fl_url_loc = self._sort_locations( - self.find_links, expand_dir=True, - ) - - file_locations = (Link(url) for url in itertools.chain( - index_file_loc, fl_file_loc, - )) - - # We trust every url that the user has given us whether it was given - # via --index-url or --find-links. - # We want to filter out any thing which does not have a secure origin. - url_locations = [ - link for link in itertools.chain( - (Link(url) for url in index_url_loc), - (Link(url) for url in fl_url_loc), - ) - if self._validate_secure_origin(logger, link) - ] - - logger.debug('%d location(s) to search for versions of %s:', - len(url_locations), project_name) - - for location in url_locations: - logger.debug('* %s', location) - - canonical_name = canonicalize_name(project_name) - formats = self.format_control.get_allowed_formats(canonical_name) - search = Search(project_name, canonical_name, formats) - find_links_versions = self._package_versions( - # We trust every directly linked archive in find_links - (Link(url, '-f') for url in self.find_links), - search - ) - - page_versions = [] - for page in self._get_pages(url_locations, project_name): - logger.debug('Analyzing links from page %s', page.url) - with indent_log(): - page_versions.extend( - self._package_versions(page.iter_links(), search) - ) - - file_versions = self._package_versions(file_locations, search) - if file_versions: - file_versions.sort(reverse=True) - logger.debug( - 'Local files found: %s', - ', '.join([ - url_to_path(candidate.location.url) - for candidate in file_versions - ]) - ) - - # This is an intentional priority ordering - return file_versions + find_links_versions + page_versions - - def find_requirement(self, req, upgrade): - # type: (InstallRequirement, bool) -> Optional[Link] - """Try to find a Link matching req - - Expects req, an InstallRequirement and upgrade, a boolean - Returns a Link if found, - Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise - """ - all_candidates = self.find_all_candidates(req.name) - - # Filter out anything which doesn't match our specifier - compatible_versions = set( - req.specifier.filter( - # We turn the version object into a str here because otherwise - # when we're debundled but setuptools isn't, Python will see - # packaging.version.Version and - # pkg_resources._vendor.packaging.version.Version as different - # types. This way we'll use a str as a common data interchange - # format. If we stop using the pkg_resources provided specifier - # and start using our own, we can drop the cast to str(). - [str(c.version) for c in all_candidates], - prereleases=( - self.allow_all_prereleases - if self.allow_all_prereleases else None - ), - ) - ) - applicable_candidates = [ - # Again, converting to str to deal with debundling. - c for c in all_candidates if str(c.version) in compatible_versions - ] - - if applicable_candidates: - best_candidate = max(applicable_candidates, - key=self._candidate_sort_key) - else: - best_candidate = None - - if req.satisfied_by is not None: - installed_version = parse_version(req.satisfied_by.version) - else: - installed_version = None - - if installed_version is None and best_candidate is None: - logger.critical( - 'Could not find a version that satisfies the requirement %s ' - '(from versions: %s)', - req, - ', '.join( - sorted( - {str(c.version) for c in all_candidates}, - key=parse_version, - ) - ) - ) - - raise DistributionNotFound( - 'No matching distribution found for %s' % req - ) - - best_installed = False - if installed_version and ( - best_candidate is None or - best_candidate.version <= installed_version): - best_installed = True - - if not upgrade and installed_version is not None: - if best_installed: - logger.debug( - 'Existing installed version (%s) is most up-to-date and ' - 'satisfies requirement', - installed_version, - ) - else: - logger.debug( - 'Existing installed version (%s) satisfies requirement ' - '(most up-to-date version is %s)', - installed_version, - best_candidate.version, - ) - return None - - if best_installed: - # We have an existing version, and its the best version - logger.debug( - 'Installed version (%s) is most up-to-date (past versions: ' - '%s)', - installed_version, - ', '.join(sorted(compatible_versions, key=parse_version)) or - "none", - ) - raise BestVersionAlreadyInstalled - - logger.debug( - 'Using version %s (newest of versions: %s)', - best_candidate.version, - ', '.join(sorted(compatible_versions, key=parse_version)) - ) - return best_candidate.location - - def _get_pages(self, locations, project_name): - # type: (Iterable[Link], str) -> Iterable[HTMLPage] - """ - Yields (page, page_url) from the given locations, skipping - locations that have errors. - """ - seen = set() # type: Set[Link] - for location in locations: - if location in seen: - continue - seen.add(location) - - page = _get_html_page(location, session=self.session) - if page is None: - continue - - yield page - - _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') - - def _sort_links(self, links): - # type: (Iterable[Link]) -> List[Link] - """ - Returns elements of links in order, non-egg links first, egg links - second, while eliminating duplicates - """ - eggs, no_eggs = [], [] - seen = set() # type: Set[Link] - for link in links: - if link not in seen: - seen.add(link) - if link.egg_fragment: - eggs.append(link) - else: - no_eggs.append(link) - return no_eggs + eggs - - def _package_versions( - self, - links, # type: Iterable[Link] - search # type: Search - ): - # type: (...) -> List[Optional[InstallationCandidate]] - result = [] - for link in self._sort_links(links): - v = self._link_package_versions(link, search) - if v is not None: - result.append(v) - return result - - def _log_skipped_link(self, link, reason): - # type: (Link, str) -> None - if link not in self.logged_links: - logger.debug('Skipping link %s; %s', link, reason) - self.logged_links.add(link) - - def _link_package_versions(self, link, search): - # type: (Link, Search) -> Optional[InstallationCandidate] - """Return an InstallationCandidate or None""" - version = None - if link.egg_fragment: - egg_info = link.egg_fragment - ext = link.ext - else: - egg_info, ext = link.splitext() - if not ext: - self._log_skipped_link(link, 'not a file') - return None - if ext not in SUPPORTED_EXTENSIONS: - self._log_skipped_link( - link, 'unsupported archive format: %s' % ext, - ) - return None - if "binary" not in search.formats and ext == WHEEL_EXTENSION: - self._log_skipped_link( - link, 'No binaries permitted for %s' % search.supplied, - ) - return None - if "macosx10" in link.path and ext == '.zip': - self._log_skipped_link(link, 'macosx10 one') - return None - if ext == WHEEL_EXTENSION: - try: - wheel = Wheel(link.filename) - except InvalidWheelFilename: - self._log_skipped_link(link, 'invalid wheel filename') - return None - if canonicalize_name(wheel.name) != search.canonical: - self._log_skipped_link( - link, 'wrong project name (not %s)' % search.supplied) - return None - - if not wheel.supported(self.valid_tags): - self._log_skipped_link( - link, 'it is not compatible with this Python') - return None - - version = wheel.version - - # This should be up by the search.ok_binary check, but see issue 2700. - if "source" not in search.formats and ext != WHEEL_EXTENSION: - self._log_skipped_link( - link, 'No sources permitted for %s' % search.supplied, - ) - return None - - if not version: - version = _egg_info_matches(egg_info, search.canonical) - if not version: - self._log_skipped_link( - link, 'Missing project version for %s' % search.supplied) - return None - - match = self._py_version_re.search(version) - if match: - version = version[:match.start()] - py_version = match.group(1) - if py_version != sys.version[:3]: - self._log_skipped_link( - link, 'Python version is incorrect') - return None - try: - support_this_python = check_requires_python(link.requires_python) - except specifiers.InvalidSpecifier: - logger.debug("Package %s has an invalid Requires-Python entry: %s", - link.filename, link.requires_python) - support_this_python = True - - if not support_this_python: - logger.debug("The package %s is incompatible with the python " - "version in use. Acceptable python versions are: %s", - link, link.requires_python) - return None - logger.debug('Found link %s, version: %s', link, version) - - return InstallationCandidate(search.supplied, version, link) - - -def _find_name_version_sep(egg_info, canonical_name): - # type: (str, str) -> int - """Find the separator's index based on the package's canonical name. - - `egg_info` must be an egg info string for the given package, and - `canonical_name` must be the package's canonical name. - - This function is needed since the canonicalized name does not necessarily - have the same length as the egg info's name part. An example:: - - >>> egg_info = 'foo__bar-1.0' - >>> canonical_name = 'foo-bar' - >>> _find_name_version_sep(egg_info, canonical_name) - 8 - """ - # Project name and version must be separated by one single dash. Find all - # occurrences of dashes; if the string in front of it matches the canonical - # name, this is the one separating the name and version parts. - for i, c in enumerate(egg_info): - if c != "-": - continue - if canonicalize_name(egg_info[:i]) == canonical_name: - return i - raise ValueError("{} does not match {}".format(egg_info, canonical_name)) - - -def _egg_info_matches(egg_info, canonical_name): - # type: (str, str) -> Optional[str] - """Pull the version part out of a string. - - :param egg_info: The string to parse. E.g. foo-2.1 - :param canonical_name: The canonicalized name of the package this - belongs to. - """ - try: - version_start = _find_name_version_sep(egg_info, canonical_name) + 1 - except ValueError: - return None - version = egg_info[version_start:] - if not version: - return None - return version - - -def _determine_base_url(document, page_url): - """Determine the HTML document's base URL. - - This looks for a ```` tag in the HTML document. If present, its href - attribute denotes the base URL of anchor tags in the document. If there is - no such tag (or if it does not have a valid href attribute), the HTML - file's URL is used as the base URL. - - :param document: An HTML document representation. The current - implementation expects the result of ``html5lib.parse()``. - :param page_url: The URL of the HTML document. - """ - for base in document.findall(".//base"): - href = base.get("href") - if href is not None: - return href - return page_url - - -def _get_encoding_from_headers(headers): - """Determine if we have any encoding information in our headers. - """ - if headers and "Content-Type" in headers: - content_type, params = cgi.parse_header(headers["Content-Type"]) - if "charset" in params: - return params['charset'] - return None - - -_CLEAN_LINK_RE = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) - - -def _clean_link(url): - # type: (str) -> str - """Makes sure a link is fully encoded. That is, if a ' ' shows up in - the link, it will be rewritten to %20 (while not over-quoting - % or other characters).""" - return _CLEAN_LINK_RE.sub(lambda match: '%%%2x' % ord(match.group(0)), url) - - -class HTMLPage(object): - """Represents one page, along with its URL""" - - def __init__(self, content, url, headers=None): - # type: (bytes, str, MutableMapping[str, str]) -> None - self.content = content - self.url = url - self.headers = headers - - def __str__(self): - return redact_password_from_url(self.url) - - def iter_links(self): - # type: () -> Iterable[Link] - """Yields all links in the page""" - document = html5lib.parse( - self.content, - transport_encoding=_get_encoding_from_headers(self.headers), - namespaceHTMLElements=False, - ) - base_url = _determine_base_url(document, self.url) - for anchor in document.findall(".//a"): - if anchor.get("href"): - href = anchor.get("href") - url = _clean_link(urllib_parse.urljoin(base_url, href)) - pyrequire = anchor.get('data-requires-python') - pyrequire = unescape(pyrequire) if pyrequire else None - yield Link(url, self.url, requires_python=pyrequire) - - -Search = namedtuple('Search', 'supplied canonical formats') -"""Capture key aspects of a search. - -:attribute supplied: The user supplied package. -:attribute canonical: The canonical package name. -:attribute formats: The formats allowed for this package. Should be a set - with 'binary' or 'source' or both in it. -""" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/locations.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/locations.py deleted file mode 100644 index c6e2a3e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/locations.py +++ /dev/null @@ -1,211 +0,0 @@ -"""Locations where we look for configs, install stuff, etc""" -from __future__ import absolute_import - -import os -import os.path -import platform -import site -import sys -import sysconfig -from distutils import sysconfig as distutils_sysconfig -from distutils.command.install import SCHEME_KEYS # type: ignore - -from pip._internal.utils import appdirs -from pip._internal.utils.compat import WINDOWS, expanduser -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Union, Dict, List, Optional # noqa: F401 - - -# Application Directories -USER_CACHE_DIR = appdirs.user_cache_dir("pip") - - -DELETE_MARKER_MESSAGE = '''\ -This file is placed here by pip to indicate the source was put -here by pip. - -Once this package is successfully installed this source code will be -deleted (unless you remove this file). -''' -PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt' - - -def write_delete_marker_file(directory): - # type: (str) -> None - """ - Write the pip delete marker file into this directory. - """ - filepath = os.path.join(directory, PIP_DELETE_MARKER_FILENAME) - with open(filepath, 'w') as marker_fp: - marker_fp.write(DELETE_MARKER_MESSAGE) - - -def running_under_virtualenv(): - # type: () -> bool - """ - Return True if we're running inside a virtualenv, False otherwise. - - """ - if hasattr(sys, 'real_prefix'): - return True - elif sys.prefix != getattr(sys, "base_prefix", sys.prefix): - return True - - return False - - -def virtualenv_no_global(): - # type: () -> bool - """ - Return True if in a venv and no system site packages. - """ - # this mirrors the logic in virtualenv.py for locating the - # no-global-site-packages.txt file - site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) - no_global_file = os.path.join(site_mod_dir, 'no-global-site-packages.txt') - if running_under_virtualenv() and os.path.isfile(no_global_file): - return True - else: - return False - - -if running_under_virtualenv(): - src_prefix = os.path.join(sys.prefix, 'src') -else: - # FIXME: keep src in cwd for now (it is not a temporary folder) - try: - src_prefix = os.path.join(os.getcwd(), 'src') - except OSError: - # In case the current working directory has been renamed or deleted - sys.exit( - "The folder you are executing pip from can no longer be found." - ) - -# under macOS + virtualenv sys.prefix is not properly resolved -# it is something like /path/to/python/bin/.. -# Note: using realpath due to tmp dirs on OSX being symlinks -src_prefix = os.path.abspath(src_prefix) - -# FIXME doesn't account for venv linked to global site-packages - -site_packages = sysconfig.get_path("purelib") # type: Optional[str] - -# This is because of a bug in PyPy's sysconfig module, see -# https://bitbucket.org/pypy/pypy/issues/2506/sysconfig-returns-incorrect-paths -# for more information. -if platform.python_implementation().lower() == "pypy": - site_packages = distutils_sysconfig.get_python_lib() -try: - # Use getusersitepackages if this is present, as it ensures that the - # value is initialised properly. - user_site = site.getusersitepackages() -except AttributeError: - user_site = site.USER_SITE -user_dir = expanduser('~') -if WINDOWS: - bin_py = os.path.join(sys.prefix, 'Scripts') - bin_user = os.path.join(user_site, 'Scripts') - # buildout uses 'bin' on Windows too? - if not os.path.exists(bin_py): - bin_py = os.path.join(sys.prefix, 'bin') - bin_user = os.path.join(user_site, 'bin') - - config_basename = 'pip.ini' - - legacy_storage_dir = os.path.join(user_dir, 'pip') - legacy_config_file = os.path.join( - legacy_storage_dir, - config_basename, - ) -else: - bin_py = os.path.join(sys.prefix, 'bin') - bin_user = os.path.join(user_site, 'bin') - - config_basename = 'pip.conf' - - legacy_storage_dir = os.path.join(user_dir, '.pip') - legacy_config_file = os.path.join( - legacy_storage_dir, - config_basename, - ) - # Forcing to use /usr/local/bin for standard macOS framework installs - # Also log to ~/Library/Logs/ for use with the Console.app log viewer - if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': - bin_py = '/usr/local/bin' - -site_config_files = [ - os.path.join(path, config_basename) - for path in appdirs.site_config_dirs('pip') -] - -venv_config_file = os.path.join(sys.prefix, config_basename) -new_config_file = os.path.join(appdirs.user_config_dir("pip"), config_basename) - - -def distutils_scheme(dist_name, user=False, home=None, root=None, - isolated=False, prefix=None): - # type:(str, bool, str, str, bool, str) -> dict - """ - Return a distutils install scheme - """ - from distutils.dist import Distribution - - scheme = {} - - if isolated: - extra_dist_args = {"script_args": ["--no-user-cfg"]} - else: - extra_dist_args = {} - dist_args = {'name': dist_name} # type: Dict[str, Union[str, List[str]]] - dist_args.update(extra_dist_args) - - d = Distribution(dist_args) - # Ignoring, typeshed issue reported python/typeshed/issues/2567 - d.parse_config_files() - # NOTE: Ignoring type since mypy can't find attributes on 'Command' - i = d.get_command_obj('install', create=True) # type: Any - assert i is not None - # NOTE: setting user or home has the side-effect of creating the home dir - # or user base for installations during finalize_options() - # ideally, we'd prefer a scheme class that has no side-effects. - assert not (user and prefix), "user={} prefix={}".format(user, prefix) - i.user = user or i.user - if user: - i.prefix = "" - i.prefix = prefix or i.prefix - i.home = home or i.home - i.root = root or i.root - i.finalize_options() - for key in SCHEME_KEYS: - scheme[key] = getattr(i, 'install_' + key) - - # install_lib specified in setup.cfg should install *everything* - # into there (i.e. it takes precedence over both purelib and - # platlib). Note, i.install_lib is *always* set after - # finalize_options(); we only want to override here if the user - # has explicitly requested it hence going back to the config - - # Ignoring, typeshed issue reported python/typeshed/issues/2567 - if 'install_lib' in d.get_option_dict('install'): # type: ignore - scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) - - if running_under_virtualenv(): - scheme['headers'] = os.path.join( - sys.prefix, - 'include', - 'site', - 'python' + sys.version[:3], - dist_name, - ) - - if root is not None: - path_no_drive = os.path.splitdrive( - os.path.abspath(scheme["headers"]))[1] - scheme["headers"] = os.path.join( - root, - path_no_drive[1:], - ) - - return scheme diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/__init__.py deleted file mode 100644 index 7855226..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""A package that contains models that represent entities. -""" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/candidate.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/candidate.py deleted file mode 100644 index 4475458..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/candidate.py +++ /dev/null @@ -1,31 +0,0 @@ -from pip._vendor.packaging.version import parse as parse_version - -from pip._internal.utils.models import KeyBasedCompareMixin -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from pip._vendor.packaging.version import _BaseVersion # noqa: F401 - from pip._internal.models.link import Link # noqa: F401 - from typing import Any, Union # noqa: F401 - - -class InstallationCandidate(KeyBasedCompareMixin): - """Represents a potential "candidate" for installation. - """ - - def __init__(self, project, version, location): - # type: (Any, str, Link) -> None - self.project = project - self.version = parse_version(version) # type: _BaseVersion - self.location = location - - super(InstallationCandidate, self).__init__( - key=(self.project, self.version, self.location), - defining_class=InstallationCandidate - ) - - def __repr__(self): - # type: () -> str - return "".format( - self.project, self.version, self.location, - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/format_control.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/format_control.py deleted file mode 100644 index 971a391..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/format_control.py +++ /dev/null @@ -1,73 +0,0 @@ -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Set, FrozenSet # noqa: F401 - - -class FormatControl(object): - """Helper for managing formats from which a package can be installed. - """ - - def __init__(self, no_binary=None, only_binary=None): - # type: (Optional[Set], Optional[Set]) -> None - if no_binary is None: - no_binary = set() - if only_binary is None: - only_binary = set() - - self.no_binary = no_binary - self.only_binary = only_binary - - def __eq__(self, other): - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "{}({}, {})".format( - self.__class__.__name__, - self.no_binary, - self.only_binary - ) - - @staticmethod - def handle_mutual_excludes(value, target, other): - # type: (str, Optional[Set], Optional[Set]) -> None - new = value.split(',') - while ':all:' in new: - other.clear() - target.clear() - target.add(':all:') - del new[:new.index(':all:') + 1] - # Without a none, we want to discard everything as :all: covers it - if ':none:' not in new: - return - for name in new: - if name == ':none:': - target.clear() - continue - name = canonicalize_name(name) - other.discard(name) - target.add(name) - - def get_allowed_formats(self, canonical_name): - # type: (str) -> FrozenSet - result = {"binary", "source"} - if canonical_name in self.only_binary: - result.discard('source') - elif canonical_name in self.no_binary: - result.discard('binary') - elif ':all:' in self.only_binary: - result.discard('source') - elif ':all:' in self.no_binary: - result.discard('binary') - return frozenset(result) - - def disallow_binaries(self): - # type: () -> None - self.handle_mutual_excludes( - ':all:', self.no_binary, self.only_binary, - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/index.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/index.py deleted file mode 100644 index ead1efb..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/index.py +++ /dev/null @@ -1,31 +0,0 @@ -from pip._vendor.six.moves.urllib import parse as urllib_parse - - -class PackageIndex(object): - """Represents a Package Index and provides easier access to endpoints - """ - - def __init__(self, url, file_storage_domain): - # type: (str, str) -> None - super(PackageIndex, self).__init__() - self.url = url - self.netloc = urllib_parse.urlsplit(url).netloc - self.simple_url = self._url_for_path('simple') - self.pypi_url = self._url_for_path('pypi') - - # This is part of a temporary hack used to block installs of PyPI - # packages which depend on external urls only necessary until PyPI can - # block such packages themselves - self.file_storage_domain = file_storage_domain - - def _url_for_path(self, path): - # type: (str) -> str - return urllib_parse.urljoin(self.url, path) - - -PyPI = PackageIndex( - 'https://pypi.org/', file_storage_domain='files.pythonhosted.org' -) -TestPyPI = PackageIndex( - 'https://test.pypi.org/', file_storage_domain='test-files.pythonhosted.org' -) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/link.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/link.py deleted file mode 100644 index ad2f93e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/models/link.py +++ /dev/null @@ -1,163 +0,0 @@ -import posixpath -import re - -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.download import path_to_url -from pip._internal.utils.misc import ( - WHEEL_EXTENSION, redact_password_from_url, splitext, -) -from pip._internal.utils.models import KeyBasedCompareMixin -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Tuple, Union, Text # noqa: F401 - from pip._internal.index import HTMLPage # noqa: F401 - - -class Link(KeyBasedCompareMixin): - """Represents a parsed link from a Package Index's simple URL - """ - - def __init__(self, url, comes_from=None, requires_python=None): - # type: (str, Optional[Union[str, HTMLPage]], Optional[str]) -> None - """ - url: - url of the resource pointed to (href of the link) - comes_from: - instance of HTMLPage where the link was found, or string. - requires_python: - String containing the `Requires-Python` metadata field, specified - in PEP 345. This may be specified by a data-requires-python - attribute in the HTML link tag, as described in PEP 503. - """ - - # url can be a UNC windows share - if url.startswith('\\\\'): - url = path_to_url(url) - - self.url = url - self.comes_from = comes_from - self.requires_python = requires_python if requires_python else None - - super(Link, self).__init__( - key=(self.url), - defining_class=Link - ) - - def __str__(self): - if self.requires_python: - rp = ' (requires-python:%s)' % self.requires_python - else: - rp = '' - if self.comes_from: - return '%s (from %s)%s' % (redact_password_from_url(self.url), - self.comes_from, rp) - else: - return redact_password_from_url(str(self.url)) - - def __repr__(self): - return '' % self - - @property - def filename(self): - # type: () -> str - _, netloc, path, _, _ = urllib_parse.urlsplit(self.url) - name = posixpath.basename(path.rstrip('/')) or netloc - name = urllib_parse.unquote(name) - assert name, ('URL %r produced no filename' % self.url) - return name - - @property - def scheme(self): - # type: () -> str - return urllib_parse.urlsplit(self.url)[0] - - @property - def netloc(self): - # type: () -> str - return urllib_parse.urlsplit(self.url)[1] - - @property - def path(self): - # type: () -> str - return urllib_parse.unquote(urllib_parse.urlsplit(self.url)[2]) - - def splitext(self): - # type: () -> Tuple[str, str] - return splitext(posixpath.basename(self.path.rstrip('/'))) - - @property - def ext(self): - # type: () -> str - return self.splitext()[1] - - @property - def url_without_fragment(self): - # type: () -> str - scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url) - return urllib_parse.urlunsplit((scheme, netloc, path, query, None)) - - _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') - - @property - def egg_fragment(self): - # type: () -> Optional[str] - match = self._egg_fragment_re.search(self.url) - if not match: - return None - return match.group(1) - - _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') - - @property - def subdirectory_fragment(self): - # type: () -> Optional[str] - match = self._subdirectory_fragment_re.search(self.url) - if not match: - return None - return match.group(1) - - _hash_re = re.compile( - r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' - ) - - @property - def hash(self): - # type: () -> Optional[str] - match = self._hash_re.search(self.url) - if match: - return match.group(2) - return None - - @property - def hash_name(self): - # type: () -> Optional[str] - match = self._hash_re.search(self.url) - if match: - return match.group(1) - return None - - @property - def show_url(self): - # type: () -> Optional[str] - return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0]) - - @property - def is_wheel(self): - # type: () -> bool - return self.ext == WHEEL_EXTENSION - - @property - def is_artifact(self): - # type: () -> bool - """ - Determines if this points to an actual artifact (e.g. a tarball) or if - it points to an "abstract" thing like a path or a VCS location. - """ - from pip._internal.vcs import vcs - - if self.scheme in vcs.all_schemes: - return False - - return True diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/check.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/check.py deleted file mode 100644 index 0b56eda..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/check.py +++ /dev/null @@ -1,155 +0,0 @@ -"""Validation of dependencies of packages -""" - -import logging -from collections import namedtuple - -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.pkg_resources import RequirementParseError - -from pip._internal.operations.prepare import make_abstract_dist -from pip._internal.utils.misc import get_installed_distributions -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -logger = logging.getLogger(__name__) - -if MYPY_CHECK_RUNNING: - from pip._internal.req.req_install import InstallRequirement # noqa: F401 - from typing import ( # noqa: F401 - Any, Callable, Dict, Optional, Set, Tuple, List - ) - - # Shorthands - PackageSet = Dict[str, 'PackageDetails'] - Missing = Tuple[str, Any] - Conflicting = Tuple[str, str, Any] - - MissingDict = Dict[str, List[Missing]] - ConflictingDict = Dict[str, List[Conflicting]] - CheckResult = Tuple[MissingDict, ConflictingDict] - -PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) - - -def create_package_set_from_installed(**kwargs): - # type: (**Any) -> Tuple[PackageSet, bool] - """Converts a list of distributions into a PackageSet. - """ - # Default to using all packages installed on the system - if kwargs == {}: - kwargs = {"local_only": False, "skip": ()} - - package_set = {} - problems = False - for dist in get_installed_distributions(**kwargs): - name = canonicalize_name(dist.project_name) - try: - package_set[name] = PackageDetails(dist.version, dist.requires()) - except RequirementParseError as e: - # Don't crash on broken metadata - logging.warning("Error parsing requirements for %s: %s", name, e) - problems = True - return package_set, problems - - -def check_package_set(package_set, should_ignore=None): - # type: (PackageSet, Optional[Callable[[str], bool]]) -> CheckResult - """Check if a package set is consistent - - If should_ignore is passed, it should be a callable that takes a - package name and returns a boolean. - """ - if should_ignore is None: - def should_ignore(name): - return False - - missing = dict() - conflicting = dict() - - for package_name in package_set: - # Info about dependencies of package_name - missing_deps = set() # type: Set[Missing] - conflicting_deps = set() # type: Set[Conflicting] - - if should_ignore(package_name): - continue - - for req in package_set[package_name].requires: - name = canonicalize_name(req.project_name) # type: str - - # Check if it's missing - if name not in package_set: - missed = True - if req.marker is not None: - missed = req.marker.evaluate() - if missed: - missing_deps.add((name, req)) - continue - - # Check if there's a conflict - version = package_set[name].version # type: str - if not req.specifier.contains(version, prereleases=True): - conflicting_deps.add((name, version, req)) - - if missing_deps: - missing[package_name] = sorted(missing_deps, key=str) - if conflicting_deps: - conflicting[package_name] = sorted(conflicting_deps, key=str) - - return missing, conflicting - - -def check_install_conflicts(to_install): - # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] - """For checking if the dependency graph would be consistent after \ - installing given requirements - """ - # Start from the current state - package_set, _ = create_package_set_from_installed() - # Install packages - would_be_installed = _simulate_installation_of(to_install, package_set) - - # Only warn about directly-dependent packages; create a whitelist of them - whitelist = _create_whitelist(would_be_installed, package_set) - - return ( - package_set, - check_package_set( - package_set, should_ignore=lambda name: name not in whitelist - ) - ) - - -def _simulate_installation_of(to_install, package_set): - # type: (List[InstallRequirement], PackageSet) -> Set[str] - """Computes the version of packages after installing to_install. - """ - - # Keep track of packages that were installed - installed = set() - - # Modify it as installing requirement_set would (assuming no errors) - for inst_req in to_install: - dist = make_abstract_dist(inst_req).dist() - name = canonicalize_name(dist.key) - package_set[name] = PackageDetails(dist.version, dist.requires()) - - installed.add(name) - - return installed - - -def _create_whitelist(would_be_installed, package_set): - # type: (Set[str], PackageSet) -> Set[str] - packages_affected = set(would_be_installed) - - for package_name in package_set: - if package_name in packages_affected: - continue - - for req in package_set[package_name].requires: - if canonicalize_name(req.name) in packages_affected: - packages_affected.add(package_name) - break - - return packages_affected diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/freeze.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/freeze.py deleted file mode 100644 index 388bb73..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/freeze.py +++ /dev/null @@ -1,247 +0,0 @@ -from __future__ import absolute_import - -import collections -import logging -import os -import re - -from pip._vendor import six -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.pkg_resources import RequirementParseError - -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.req.constructors import ( - install_req_from_editable, install_req_from_line, -) -from pip._internal.req.req_file import COMMENT_RE -from pip._internal.utils.misc import ( - dist_is_editable, get_installed_distributions, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Iterator, Optional, List, Container, Set, Dict, Tuple, Iterable, Union - ) - from pip._internal.cache import WheelCache # noqa: F401 - from pip._vendor.pkg_resources import ( # noqa: F401 - Distribution, Requirement - ) - - RequirementInfo = Tuple[Optional[Union[str, Requirement]], bool, List[str]] - - -logger = logging.getLogger(__name__) - - -def freeze( - requirement=None, # type: Optional[List[str]] - find_links=None, # type: Optional[List[str]] - local_only=None, # type: Optional[bool] - user_only=None, # type: Optional[bool] - skip_regex=None, # type: Optional[str] - isolated=False, # type: bool - wheel_cache=None, # type: Optional[WheelCache] - exclude_editable=False, # type: bool - skip=() # type: Container[str] -): - # type: (...) -> Iterator[str] - find_links = find_links or [] - skip_match = None - - if skip_regex: - skip_match = re.compile(skip_regex).search - - for link in find_links: - yield '-f %s' % link - installations = {} # type: Dict[str, FrozenRequirement] - for dist in get_installed_distributions(local_only=local_only, - skip=(), - user_only=user_only): - try: - req = FrozenRequirement.from_dist(dist) - except RequirementParseError: - logger.warning( - "Could not parse requirement: %s", - dist.project_name - ) - continue - if exclude_editable and req.editable: - continue - installations[req.name] = req - - if requirement: - # the options that don't get turned into an InstallRequirement - # should only be emitted once, even if the same option is in multiple - # requirements files, so we need to keep track of what has been emitted - # so that we don't emit it again if it's seen again - emitted_options = set() # type: Set[str] - # keep track of which files a requirement is in so that we can - # give an accurate warning if a requirement appears multiple times. - req_files = collections.defaultdict(list) # type: Dict[str, List[str]] - for req_file_path in requirement: - with open(req_file_path) as req_file: - for line in req_file: - if (not line.strip() or - line.strip().startswith('#') or - (skip_match and skip_match(line)) or - line.startswith(( - '-r', '--requirement', - '-Z', '--always-unzip', - '-f', '--find-links', - '-i', '--index-url', - '--pre', - '--trusted-host', - '--process-dependency-links', - '--extra-index-url'))): - line = line.rstrip() - if line not in emitted_options: - emitted_options.add(line) - yield line - continue - - if line.startswith('-e') or line.startswith('--editable'): - if line.startswith('-e'): - line = line[2:].strip() - else: - line = line[len('--editable'):].strip().lstrip('=') - line_req = install_req_from_editable( - line, - isolated=isolated, - wheel_cache=wheel_cache, - ) - else: - line_req = install_req_from_line( - COMMENT_RE.sub('', line).strip(), - isolated=isolated, - wheel_cache=wheel_cache, - ) - - if not line_req.name: - logger.info( - "Skipping line in requirement file [%s] because " - "it's not clear what it would install: %s", - req_file_path, line.strip(), - ) - logger.info( - " (add #egg=PackageName to the URL to avoid" - " this warning)" - ) - elif line_req.name not in installations: - # either it's not installed, or it is installed - # but has been processed already - if not req_files[line_req.name]: - logger.warning( - "Requirement file [%s] contains %s, but " - "package %r is not installed", - req_file_path, - COMMENT_RE.sub('', line).strip(), line_req.name - ) - else: - req_files[line_req.name].append(req_file_path) - else: - yield str(installations[line_req.name]).rstrip() - del installations[line_req.name] - req_files[line_req.name].append(req_file_path) - - # Warn about requirements that were included multiple times (in a - # single requirements file or in different requirements files). - for name, files in six.iteritems(req_files): - if len(files) > 1: - logger.warning("Requirement %s included multiple times [%s]", - name, ', '.join(sorted(set(files)))) - - yield( - '## The following requirements were added by ' - 'pip freeze:' - ) - for installation in sorted( - installations.values(), key=lambda x: x.name.lower()): - if canonicalize_name(installation.name) not in skip: - yield str(installation).rstrip() - - -def get_requirement_info(dist): - # type: (Distribution) -> RequirementInfo - """ - Compute and return values (req, editable, comments) for use in - FrozenRequirement.from_dist(). - """ - if not dist_is_editable(dist): - return (None, False, []) - - location = os.path.normcase(os.path.abspath(dist.location)) - - from pip._internal.vcs import vcs, RemoteNotFoundError - vc_type = vcs.get_backend_type(location) - - if not vc_type: - req = dist.as_requirement() - logger.debug( - 'No VCS found for editable requirement {!r} in: {!r}', req, - location, - ) - comments = [ - '# Editable install with no version control ({})'.format(req) - ] - return (location, True, comments) - - try: - req = vc_type.get_src_requirement(location, dist.project_name) - except RemoteNotFoundError: - req = dist.as_requirement() - comments = [ - '# Editable {} install with no remote ({})'.format( - vc_type.__name__, req, - ) - ] - return (location, True, comments) - - except BadCommand: - logger.warning( - 'cannot determine version of editable source in %s ' - '(%s command not found in path)', - location, - vc_type.name, - ) - return (None, True, []) - - except InstallationError as exc: - logger.warning( - "Error when trying to get requirement for VCS system %s, " - "falling back to uneditable format", exc - ) - else: - if req is not None: - return (req, True, []) - - logger.warning( - 'Could not determine repository location of %s', location - ) - comments = ['## !! Could not determine repository location'] - - return (None, False, comments) - - -class FrozenRequirement(object): - def __init__(self, name, req, editable, comments=()): - # type: (str, Union[str, Requirement], bool, Iterable[str]) -> None - self.name = name - self.req = req - self.editable = editable - self.comments = comments - - @classmethod - def from_dist(cls, dist): - # type: (Distribution) -> FrozenRequirement - req, editable, comments = get_requirement_info(dist) - if req is None: - req = dist.as_requirement() - - return cls(dist.project_name, req, editable, comments=comments) - - def __str__(self): - req = self.req - if self.editable: - req = '-e %s' % req - return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/prepare.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/prepare.py deleted file mode 100644 index 4f31dd5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/operations/prepare.py +++ /dev/null @@ -1,413 +0,0 @@ -"""Prepares a distribution for installation -""" - -import logging -import os - -from pip._vendor import pkg_resources, requests - -from pip._internal.build_env import BuildEnvironment -from pip._internal.download import ( - is_dir_url, is_file_url, is_vcs_url, unpack_url, url_to_path, -) -from pip._internal.exceptions import ( - DirectoryUrlHashUnsupported, HashUnpinned, InstallationError, - PreviousBuildDirError, VcsHashUnsupported, -) -from pip._internal.utils.compat import expanduser -from pip._internal.utils.hashes import MissingHashes -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import display_path, normalize_path -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.vcs import vcs - -if MYPY_CHECK_RUNNING: - from typing import Any, Optional # noqa: F401 - from pip._internal.req.req_install import InstallRequirement # noqa: F401 - from pip._internal.index import PackageFinder # noqa: F401 - from pip._internal.download import PipSession # noqa: F401 - from pip._internal.req.req_tracker import RequirementTracker # noqa: F401 - -logger = logging.getLogger(__name__) - - -def make_abstract_dist(req): - # type: (InstallRequirement) -> DistAbstraction - """Factory to make an abstract dist object. - - Preconditions: Either an editable req with a source_dir, or satisfied_by or - a wheel link, or a non-editable req with a source_dir. - - :return: A concrete DistAbstraction. - """ - if req.editable: - return IsSDist(req) - elif req.link and req.link.is_wheel: - return IsWheel(req) - else: - return IsSDist(req) - - -class DistAbstraction(object): - """Abstracts out the wheel vs non-wheel Resolver.resolve() logic. - - The requirements for anything installable are as follows: - - we must be able to determine the requirement name - (or we can't correctly handle the non-upgrade case). - - we must be able to generate a list of run-time dependencies - without installing any additional packages (or we would - have to either burn time by doing temporary isolated installs - or alternatively violate pips 'don't start installing unless - all requirements are available' rule - neither of which are - desirable). - - for packages with setup requirements, we must also be able - to determine their requirements without installing additional - packages (for the same reason as run-time dependencies) - - we must be able to create a Distribution object exposing the - above metadata. - """ - - def __init__(self, req): - # type: (InstallRequirement) -> None - self.req = req # type: InstallRequirement - - def dist(self): - # type: () -> Any - """Return a setuptools Dist object.""" - raise NotImplementedError - - def prep_for_dist(self, finder, build_isolation): - # type: (PackageFinder, bool) -> Any - """Ensure that we can get a Dist for this requirement.""" - raise NotImplementedError - - -class IsWheel(DistAbstraction): - - def dist(self): - # type: () -> pkg_resources.Distribution - return list(pkg_resources.find_distributions( - self.req.source_dir))[0] - - def prep_for_dist(self, finder, build_isolation): - # type: (PackageFinder, bool) -> Any - # FIXME:https://github.com/pypa/pip/issues/1112 - pass - - -class IsSDist(DistAbstraction): - - def dist(self): - return self.req.get_dist() - - def prep_for_dist(self, finder, build_isolation): - # type: (PackageFinder, bool) -> None - # Prepare for building. We need to: - # 1. Load pyproject.toml (if it exists) - # 2. Set up the build environment - - self.req.load_pyproject_toml() - should_isolate = self.req.use_pep517 and build_isolation - - def _raise_conflicts(conflicting_with, conflicting_reqs): - raise InstallationError( - "Some build dependencies for %s conflict with %s: %s." % ( - self.req, conflicting_with, ', '.join( - '%s is incompatible with %s' % (installed, wanted) - for installed, wanted in sorted(conflicting)))) - - if should_isolate: - # Isolate in a BuildEnvironment and install the build-time - # requirements. - self.req.build_env = BuildEnvironment() - self.req.build_env.install_requirements( - finder, self.req.pyproject_requires, 'overlay', - "Installing build dependencies" - ) - conflicting, missing = self.req.build_env.check_requirements( - self.req.requirements_to_check - ) - if conflicting: - _raise_conflicts("PEP 517/518 supported requirements", - conflicting) - if missing: - logger.warning( - "Missing build requirements in pyproject.toml for %s.", - self.req, - ) - logger.warning( - "The project does not specify a build backend, and " - "pip cannot fall back to setuptools without %s.", - " and ".join(map(repr, sorted(missing))) - ) - # Install any extra build dependencies that the backend requests. - # This must be done in a second pass, as the pyproject.toml - # dependencies must be installed before we can call the backend. - with self.req.build_env: - # We need to have the env active when calling the hook. - self.req.spin_message = "Getting requirements to build wheel" - reqs = self.req.pep517_backend.get_requires_for_build_wheel() - conflicting, missing = self.req.build_env.check_requirements(reqs) - if conflicting: - _raise_conflicts("the backend dependencies", conflicting) - self.req.build_env.install_requirements( - finder, missing, 'normal', - "Installing backend dependencies" - ) - - self.req.prepare_metadata() - self.req.assert_source_matches_version() - - -class Installed(DistAbstraction): - - def dist(self): - # type: () -> pkg_resources.Distribution - return self.req.satisfied_by - - def prep_for_dist(self, finder, build_isolation): - # type: (PackageFinder, bool) -> Any - pass - - -class RequirementPreparer(object): - """Prepares a Requirement - """ - - def __init__( - self, - build_dir, # type: str - download_dir, # type: Optional[str] - src_dir, # type: str - wheel_download_dir, # type: Optional[str] - progress_bar, # type: str - build_isolation, # type: bool - req_tracker # type: RequirementTracker - ): - # type: (...) -> None - super(RequirementPreparer, self).__init__() - - self.src_dir = src_dir - self.build_dir = build_dir - self.req_tracker = req_tracker - - # Where still packed archives should be written to. If None, they are - # not saved, and are deleted immediately after unpacking. - self.download_dir = download_dir - - # Where still-packed .whl files should be written to. If None, they are - # written to the download_dir parameter. Separate to download_dir to - # permit only keeping wheel archives for pip wheel. - if wheel_download_dir: - wheel_download_dir = normalize_path(wheel_download_dir) - self.wheel_download_dir = wheel_download_dir - - # NOTE - # download_dir and wheel_download_dir overlap semantically and may - # be combined if we're willing to have non-wheel archives present in - # the wheelhouse output by 'pip wheel'. - - self.progress_bar = progress_bar - - # Is build isolation allowed? - self.build_isolation = build_isolation - - @property - def _download_should_save(self): - # type: () -> bool - # TODO: Modify to reduce indentation needed - if self.download_dir: - self.download_dir = expanduser(self.download_dir) - if os.path.exists(self.download_dir): - return True - else: - logger.critical('Could not find download directory') - raise InstallationError( - "Could not find or access download directory '%s'" - % display_path(self.download_dir)) - return False - - def prepare_linked_requirement( - self, - req, # type: InstallRequirement - session, # type: PipSession - finder, # type: PackageFinder - upgrade_allowed, # type: bool - require_hashes # type: bool - ): - # type: (...) -> DistAbstraction - """Prepare a requirement that would be obtained from req.link - """ - # TODO: Breakup into smaller functions - if req.link and req.link.scheme == 'file': - path = url_to_path(req.link.url) - logger.info('Processing %s', display_path(path)) - else: - logger.info('Collecting %s', req) - - with indent_log(): - # @@ if filesystem packages are not marked - # editable in a req, a non deterministic error - # occurs when the script attempts to unpack the - # build directory - req.ensure_has_source_dir(self.build_dir) - # If a checkout exists, it's unwise to keep going. version - # inconsistencies are logged later, but do not fail the - # installation. - # FIXME: this won't upgrade when there's an existing - # package unpacked in `req.source_dir` - # package unpacked in `req.source_dir` - if os.path.exists(os.path.join(req.source_dir, 'setup.py')): - raise PreviousBuildDirError( - "pip can't proceed with requirements '%s' due to a" - " pre-existing build directory (%s). This is " - "likely due to a previous installation that failed" - ". pip is being responsible and not assuming it " - "can delete this. Please delete it and try again." - % (req, req.source_dir) - ) - req.populate_link(finder, upgrade_allowed, require_hashes) - - # We can't hit this spot and have populate_link return None. - # req.satisfied_by is None here (because we're - # guarded) and upgrade has no impact except when satisfied_by - # is not None. - # Then inside find_requirement existing_applicable -> False - # If no new versions are found, DistributionNotFound is raised, - # otherwise a result is guaranteed. - assert req.link - link = req.link - - # Now that we have the real link, we can tell what kind of - # requirements we have and raise some more informative errors - # than otherwise. (For example, we can raise VcsHashUnsupported - # for a VCS URL rather than HashMissing.) - if require_hashes: - # We could check these first 2 conditions inside - # unpack_url and save repetition of conditions, but then - # we would report less-useful error messages for - # unhashable requirements, complaining that there's no - # hash provided. - if is_vcs_url(link): - raise VcsHashUnsupported() - elif is_file_url(link) and is_dir_url(link): - raise DirectoryUrlHashUnsupported() - if not req.original_link and not req.is_pinned: - # Unpinned packages are asking for trouble when a new - # version is uploaded. This isn't a security check, but - # it saves users a surprising hash mismatch in the - # future. - # - # file:/// URLs aren't pinnable, so don't complain - # about them not being pinned. - raise HashUnpinned() - - hashes = req.hashes(trust_internet=not require_hashes) - if require_hashes and not hashes: - # Known-good hashes are missing for this requirement, so - # shim it with a facade object that will provoke hash - # computation and then raise a HashMissing exception - # showing the user what the hash should be. - hashes = MissingHashes() - - try: - download_dir = self.download_dir - # We always delete unpacked sdists after pip ran. - autodelete_unpacked = True - if req.link.is_wheel and self.wheel_download_dir: - # when doing 'pip wheel` we download wheels to a - # dedicated dir. - download_dir = self.wheel_download_dir - if req.link.is_wheel: - if download_dir: - # When downloading, we only unpack wheels to get - # metadata. - autodelete_unpacked = True - else: - # When installing a wheel, we use the unpacked - # wheel. - autodelete_unpacked = False - unpack_url( - req.link, req.source_dir, - download_dir, autodelete_unpacked, - session=session, hashes=hashes, - progress_bar=self.progress_bar - ) - except requests.HTTPError as exc: - logger.critical( - 'Could not install requirement %s because of error %s', - req, - exc, - ) - raise InstallationError( - 'Could not install requirement %s because of HTTP ' - 'error %s for URL %s' % - (req, exc, req.link) - ) - abstract_dist = make_abstract_dist(req) - with self.req_tracker.track(req): - abstract_dist.prep_for_dist(finder, self.build_isolation) - if self._download_should_save: - # Make a .zip of the source_dir we already created. - if req.link.scheme in vcs.all_schemes: - req.archive(self.download_dir) - return abstract_dist - - def prepare_editable_requirement( - self, - req, # type: InstallRequirement - require_hashes, # type: bool - use_user_site, # type: bool - finder # type: PackageFinder - ): - # type: (...) -> DistAbstraction - """Prepare an editable requirement - """ - assert req.editable, "cannot prepare a non-editable req as editable" - - logger.info('Obtaining %s', req) - - with indent_log(): - if require_hashes: - raise InstallationError( - 'The editable requirement %s cannot be installed when ' - 'requiring hashes, because there is no single file to ' - 'hash.' % req - ) - req.ensure_has_source_dir(self.src_dir) - req.update_editable(not self._download_should_save) - - abstract_dist = make_abstract_dist(req) - with self.req_tracker.track(req): - abstract_dist.prep_for_dist(finder, self.build_isolation) - - if self._download_should_save: - req.archive(self.download_dir) - req.check_if_exists(use_user_site) - - return abstract_dist - - def prepare_installed_requirement(self, req, require_hashes, skip_reason): - # type: (InstallRequirement, bool, Optional[str]) -> DistAbstraction - """Prepare an already-installed requirement - """ - assert req.satisfied_by, "req should have been satisfied but isn't" - assert skip_reason is not None, ( - "did not get skip reason skipped but req.satisfied_by " - "is set to %r" % (req.satisfied_by,) - ) - logger.info( - 'Requirement %s: %s (%s)', - skip_reason, req, req.satisfied_by.version - ) - with indent_log(): - if require_hashes: - logger.debug( - 'Since it is already installed, we are trusting this ' - 'package without checking its hash. To ensure a ' - 'completely repeatable environment, install into an ' - 'empty virtualenv.' - ) - abstract_dist = Installed(req) - - return abstract_dist diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/pep425tags.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/pep425tags.py deleted file mode 100644 index 1e782d1..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/pep425tags.py +++ /dev/null @@ -1,381 +0,0 @@ -"""Generate and work with PEP 425 Compatibility Tags.""" -from __future__ import absolute_import - -import distutils.util -import logging -import platform -import re -import sys -import sysconfig -import warnings -from collections import OrderedDict - -import pip._internal.utils.glibc -from pip._internal.utils.compat import get_extension_suffixes -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Tuple, Callable, List, Optional, Union, Dict - ) - - Pep425Tag = Tuple[str, str, str] - -logger = logging.getLogger(__name__) - -_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') - - -def get_config_var(var): - # type: (str) -> Optional[str] - try: - return sysconfig.get_config_var(var) - except IOError as e: # Issue #1074 - warnings.warn("{}".format(e), RuntimeWarning) - return None - - -def get_abbr_impl(): - # type: () -> str - """Return abbreviated implementation name.""" - if hasattr(sys, 'pypy_version_info'): - pyimpl = 'pp' - elif sys.platform.startswith('java'): - pyimpl = 'jy' - elif sys.platform == 'cli': - pyimpl = 'ip' - else: - pyimpl = 'cp' - return pyimpl - - -def get_impl_ver(): - # type: () -> str - """Return implementation version.""" - impl_ver = get_config_var("py_version_nodot") - if not impl_ver or get_abbr_impl() == 'pp': - impl_ver = ''.join(map(str, get_impl_version_info())) - return impl_ver - - -def get_impl_version_info(): - # type: () -> Tuple[int, ...] - """Return sys.version_info-like tuple for use in decrementing the minor - version.""" - if get_abbr_impl() == 'pp': - # as per https://github.com/pypa/pip/issues/2882 - # attrs exist only on pypy - return (sys.version_info[0], - sys.pypy_version_info.major, # type: ignore - sys.pypy_version_info.minor) # type: ignore - else: - return sys.version_info[0], sys.version_info[1] - - -def get_impl_tag(): - # type: () -> str - """ - Returns the Tag for this specific implementation. - """ - return "{}{}".format(get_abbr_impl(), get_impl_ver()) - - -def get_flag(var, fallback, expected=True, warn=True): - # type: (str, Callable[..., bool], Union[bool, int], bool) -> bool - """Use a fallback method for determining SOABI flags if the needed config - var is unset or unavailable.""" - val = get_config_var(var) - if val is None: - if warn: - logger.debug("Config variable '%s' is unset, Python ABI tag may " - "be incorrect", var) - return fallback() - return val == expected - - -def get_abi_tag(): - # type: () -> Optional[str] - """Return the ABI tag based on SOABI (if available) or emulate SOABI - (CPython 2, PyPy).""" - soabi = get_config_var('SOABI') - impl = get_abbr_impl() - if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): - d = '' - m = '' - u = '' - if get_flag('Py_DEBUG', - lambda: hasattr(sys, 'gettotalrefcount'), - warn=(impl == 'cp')): - d = 'd' - if get_flag('WITH_PYMALLOC', - lambda: impl == 'cp', - warn=(impl == 'cp')): - m = 'm' - if get_flag('Py_UNICODE_SIZE', - lambda: sys.maxunicode == 0x10ffff, - expected=4, - warn=(impl == 'cp' and - sys.version_info < (3, 3))) \ - and sys.version_info < (3, 3): - u = 'u' - abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) - elif soabi and soabi.startswith('cpython-'): - abi = 'cp' + soabi.split('-')[1] - elif soabi: - abi = soabi.replace('.', '_').replace('-', '_') - else: - abi = None - return abi - - -def _is_running_32bit(): - # type: () -> bool - return sys.maxsize == 2147483647 - - -def get_platform(): - # type: () -> str - """Return our platform name 'win32', 'linux_x86_64'""" - if sys.platform == 'darwin': - # distutils.util.get_platform() returns the release based on the value - # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may - # be significantly older than the user's current machine. - release, _, machine = platform.mac_ver() - split_ver = release.split('.') - - if machine == "x86_64" and _is_running_32bit(): - machine = "i386" - elif machine == "ppc64" and _is_running_32bit(): - machine = "ppc" - - return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) - - # XXX remove distutils dependency - result = distutils.util.get_platform().replace('.', '_').replace('-', '_') - if result == "linux_x86_64" and _is_running_32bit(): - # 32 bit Python program (running on a 64 bit Linux): pip should only - # install and run 32 bit compiled extensions in that case. - result = "linux_i686" - - return result - - -def is_manylinux1_compatible(): - # type: () -> bool - # Only Linux, and only x86-64 / i686 - if get_platform() not in {"linux_x86_64", "linux_i686"}: - return False - - # Check for presence of _manylinux module - try: - import _manylinux - return bool(_manylinux.manylinux1_compatible) - except (ImportError, AttributeError): - # Fall through to heuristic check below - pass - - # Check glibc version. CentOS 5 uses glibc 2.5. - return pip._internal.utils.glibc.have_compatible_glibc(2, 5) - - -def is_manylinux2010_compatible(): - # type: () -> bool - # Only Linux, and only x86-64 / i686 - if get_platform() not in {"linux_x86_64", "linux_i686"}: - return False - - # Check for presence of _manylinux module - try: - import _manylinux - return bool(_manylinux.manylinux2010_compatible) - except (ImportError, AttributeError): - # Fall through to heuristic check below - pass - - # Check glibc version. CentOS 6 uses glibc 2.12. - return pip._internal.utils.glibc.have_compatible_glibc(2, 12) - - -def get_darwin_arches(major, minor, machine): - # type: (int, int, str) -> List[str] - """Return a list of supported arches (including group arches) for - the given major, minor and machine architecture of an macOS machine. - """ - arches = [] - - def _supports_arch(major, minor, arch): - # type: (int, int, str) -> bool - # Looking at the application support for macOS versions in the chart - # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears - # our timeline looks roughly like: - # - # 10.0 - Introduces ppc support. - # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 - # and x86_64 support is CLI only, and cannot be used for GUI - # applications. - # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. - # 10.6 - Drops support for ppc64 - # 10.7 - Drops support for ppc - # - # Given that we do not know if we're installing a CLI or a GUI - # application, we must be conservative and assume it might be a GUI - # application and behave as if ppc64 and x86_64 support did not occur - # until 10.5. - # - # Note: The above information is taken from the "Application support" - # column in the chart not the "Processor support" since I believe - # that we care about what instruction sets an application can use - # not which processors the OS supports. - if arch == 'ppc': - return (major, minor) <= (10, 5) - if arch == 'ppc64': - return (major, minor) == (10, 5) - if arch == 'i386': - return (major, minor) >= (10, 4) - if arch == 'x86_64': - return (major, minor) >= (10, 5) - if arch in groups: - for garch in groups[arch]: - if _supports_arch(major, minor, garch): - return True - return False - - groups = OrderedDict([ - ("fat", ("i386", "ppc")), - ("intel", ("x86_64", "i386")), - ("fat64", ("x86_64", "ppc64")), - ("fat32", ("x86_64", "i386", "ppc")), - ]) # type: Dict[str, Tuple[str, ...]] - - if _supports_arch(major, minor, machine): - arches.append(machine) - - for garch in groups: - if machine in groups[garch] and _supports_arch(major, minor, garch): - arches.append(garch) - - arches.append('universal') - - return arches - - -def get_all_minor_versions_as_strings(version_info): - # type: (Tuple[int, ...]) -> List[str] - versions = [] - major = version_info[:-1] - # Support all previous minor Python versions. - for minor in range(version_info[-1], -1, -1): - versions.append(''.join(map(str, major + (minor,)))) - return versions - - -def get_supported( - versions=None, # type: Optional[List[str]] - noarch=False, # type: bool - platform=None, # type: Optional[str] - impl=None, # type: Optional[str] - abi=None # type: Optional[str] -): - # type: (...) -> List[Pep425Tag] - """Return a list of supported tags for each version specified in - `versions`. - - :param versions: a list of string versions, of the form ["33", "32"], - or None. The first version will be assumed to support our ABI. - :param platform: specify the exact platform you want valid - tags for, or None. If None, use the local system platform. - :param impl: specify the exact implementation you want valid - tags for, or None. If None, use the local interpreter impl. - :param abi: specify the exact abi you want valid - tags for, or None. If None, use the local interpreter abi. - """ - supported = [] - - # Versions must be given with respect to the preference - if versions is None: - version_info = get_impl_version_info() - versions = get_all_minor_versions_as_strings(version_info) - - impl = impl or get_abbr_impl() - - abis = [] # type: List[str] - - abi = abi or get_abi_tag() - if abi: - abis[0:0] = [abi] - - abi3s = set() - for suffix in get_extension_suffixes(): - if suffix.startswith('.abi'): - abi3s.add(suffix.split('.', 2)[1]) - - abis.extend(sorted(list(abi3s))) - - abis.append('none') - - if not noarch: - arch = platform or get_platform() - arch_prefix, arch_sep, arch_suffix = arch.partition('_') - if arch.startswith('macosx'): - # support macosx-10.6-intel on macosx-10.9-x86_64 - match = _osx_arch_pat.match(arch) - if match: - name, major, minor, actual_arch = match.groups() - tpl = '{}_{}_%i_%s'.format(name, major) - arches = [] - for m in reversed(range(int(minor) + 1)): - for a in get_darwin_arches(int(major), m, actual_arch): - arches.append(tpl % (m, a)) - else: - # arch pattern didn't match (?!) - arches = [arch] - elif arch_prefix == 'manylinux2010': - # manylinux1 wheels run on most manylinux2010 systems with the - # exception of wheels depending on ncurses. PEP 571 states - # manylinux1 wheels should be considered manylinux2010 wheels: - # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels - arches = [arch, 'manylinux1' + arch_sep + arch_suffix] - elif platform is None: - arches = [] - if is_manylinux2010_compatible(): - arches.append('manylinux2010' + arch_sep + arch_suffix) - if is_manylinux1_compatible(): - arches.append('manylinux1' + arch_sep + arch_suffix) - arches.append(arch) - else: - arches = [arch] - - # Current version, current API (built specifically for our Python): - for abi in abis: - for arch in arches: - supported.append(('%s%s' % (impl, versions[0]), abi, arch)) - - # abi3 modules compatible with older version of Python - for version in versions[1:]: - # abi3 was introduced in Python 3.2 - if version in {'31', '30'}: - break - for abi in abi3s: # empty set if not Python 3 - for arch in arches: - supported.append(("%s%s" % (impl, version), abi, arch)) - - # Has binaries, does not use the Python API: - for arch in arches: - supported.append(('py%s' % (versions[0][0]), 'none', arch)) - - # No abi / arch, but requires our implementation: - supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) - # Tagged specifically as being cross-version compatible - # (with just the major version specified) - supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) - - # No abi / arch, generic Python - for i, version in enumerate(versions): - supported.append(('py%s' % (version,), 'none', 'any')) - if i == 0: - supported.append(('py%s' % (version[0]), 'none', 'any')) - - return supported - - -implementation_tag = get_impl_tag() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/pyproject.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/pyproject.py deleted file mode 100644 index 8d739a6..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/pyproject.py +++ /dev/null @@ -1,171 +0,0 @@ -from __future__ import absolute_import - -import io -import os -import sys - -from pip._vendor import pytoml, six - -from pip._internal.exceptions import InstallationError -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Tuple, Optional, List # noqa: F401 - - -def _is_list_of_str(obj): - # type: (Any) -> bool - return ( - isinstance(obj, list) and - all(isinstance(item, six.string_types) for item in obj) - ) - - -def make_pyproject_path(setup_py_dir): - # type: (str) -> str - path = os.path.join(setup_py_dir, 'pyproject.toml') - - # Python2 __file__ should not be unicode - if six.PY2 and isinstance(path, six.text_type): - path = path.encode(sys.getfilesystemencoding()) - - return path - - -def load_pyproject_toml( - use_pep517, # type: Optional[bool] - pyproject_toml, # type: str - setup_py, # type: str - req_name # type: str -): - # type: (...) -> Optional[Tuple[List[str], str, List[str]]] - """Load the pyproject.toml file. - - Parameters: - use_pep517 - Has the user requested PEP 517 processing? None - means the user hasn't explicitly specified. - pyproject_toml - Location of the project's pyproject.toml file - setup_py - Location of the project's setup.py file - req_name - The name of the requirement we're processing (for - error reporting) - - Returns: - None if we should use the legacy code path, otherwise a tuple - ( - requirements from pyproject.toml, - name of PEP 517 backend, - requirements we should check are installed after setting - up the build environment - ) - """ - has_pyproject = os.path.isfile(pyproject_toml) - has_setup = os.path.isfile(setup_py) - - if has_pyproject: - with io.open(pyproject_toml, encoding="utf-8") as f: - pp_toml = pytoml.load(f) - build_system = pp_toml.get("build-system") - else: - build_system = None - - # The following cases must use PEP 517 - # We check for use_pep517 being non-None and falsey because that means - # the user explicitly requested --no-use-pep517. The value 0 as - # opposed to False can occur when the value is provided via an - # environment variable or config file option (due to the quirk of - # strtobool() returning an integer in pip's configuration code). - if has_pyproject and not has_setup: - if use_pep517 is not None and not use_pep517: - raise InstallationError( - "Disabling PEP 517 processing is invalid: " - "project does not have a setup.py" - ) - use_pep517 = True - elif build_system and "build-backend" in build_system: - if use_pep517 is not None and not use_pep517: - raise InstallationError( - "Disabling PEP 517 processing is invalid: " - "project specifies a build backend of {} " - "in pyproject.toml".format( - build_system["build-backend"] - ) - ) - use_pep517 = True - - # If we haven't worked out whether to use PEP 517 yet, - # and the user hasn't explicitly stated a preference, - # we do so if the project has a pyproject.toml file. - elif use_pep517 is None: - use_pep517 = has_pyproject - - # At this point, we know whether we're going to use PEP 517. - assert use_pep517 is not None - - # If we're using the legacy code path, there is nothing further - # for us to do here. - if not use_pep517: - return None - - if build_system is None: - # Either the user has a pyproject.toml with no build-system - # section, or the user has no pyproject.toml, but has opted in - # explicitly via --use-pep517. - # In the absence of any explicit backend specification, we - # assume the setuptools backend that most closely emulates the - # traditional direct setup.py execution, and require wheel and - # a version of setuptools that supports that backend. - - build_system = { - "requires": ["setuptools>=40.8.0", "wheel"], - "build-backend": "setuptools.build_meta:__legacy__", - } - - # If we're using PEP 517, we have build system information (either - # from pyproject.toml, or defaulted by the code above). - # Note that at this point, we do not know if the user has actually - # specified a backend, though. - assert build_system is not None - - # Ensure that the build-system section in pyproject.toml conforms - # to PEP 518. - error_template = ( - "{package} has a pyproject.toml file that does not comply " - "with PEP 518: {reason}" - ) - - # Specifying the build-system table but not the requires key is invalid - if "requires" not in build_system: - raise InstallationError( - error_template.format(package=req_name, reason=( - "it has a 'build-system' table but not " - "'build-system.requires' which is mandatory in the table" - )) - ) - - # Error out if requires is not a list of strings - requires = build_system["requires"] - if not _is_list_of_str(requires): - raise InstallationError(error_template.format( - package=req_name, - reason="'build-system.requires' is not a list of strings.", - )) - - backend = build_system.get("build-backend") - check = [] # type: List[str] - if backend is None: - # If the user didn't specify a backend, we assume they want to use - # the setuptools backend. But we can't be sure they have included - # a version of setuptools which supplies the backend, or wheel - # (which is needed by the backend) in their requirements. So we - # make a note to check that those requirements are present once - # we have set up the environment. - # This is quite a lot of work to check for a very specific case. But - # the problem is, that case is potentially quite common - projects that - # adopted PEP 518 early for the ability to specify requirements to - # execute setup.py, but never considered needing to mention the build - # tools themselves. The original PEP 518 code had a similar check (but - # implemented in a different way). - backend = "setuptools.build_meta:__legacy__" - check = ["setuptools>=40.8.0", "wheel"] - - return (requires, backend, check) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/__init__.py deleted file mode 100644 index 5e4eb92..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/__init__.py +++ /dev/null @@ -1,77 +0,0 @@ -from __future__ import absolute_import - -import logging - -from .req_install import InstallRequirement -from .req_set import RequirementSet -from .req_file import parse_requirements -from pip._internal.utils.logging import indent_log -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Sequence # noqa: F401 - -__all__ = [ - "RequirementSet", "InstallRequirement", - "parse_requirements", "install_given_reqs", -] - -logger = logging.getLogger(__name__) - - -def install_given_reqs( - to_install, # type: List[InstallRequirement] - install_options, # type: List[str] - global_options=(), # type: Sequence[str] - *args, **kwargs -): - # type: (...) -> List[InstallRequirement] - """ - Install everything in the given list. - - (to be called after having downloaded and unpacked the packages) - """ - - if to_install: - logger.info( - 'Installing collected packages: %s', - ', '.join([req.name for req in to_install]), - ) - - with indent_log(): - for requirement in to_install: - if requirement.conflicts_with: - logger.info( - 'Found existing installation: %s', - requirement.conflicts_with, - ) - with indent_log(): - uninstalled_pathset = requirement.uninstall( - auto_confirm=True - ) - try: - requirement.install( - install_options, - global_options, - *args, - **kwargs - ) - except Exception: - should_rollback = ( - requirement.conflicts_with and - not requirement.install_succeeded - ) - # if install did not succeed, rollback previous uninstall - if should_rollback: - uninstalled_pathset.rollback() - raise - else: - should_commit = ( - requirement.conflicts_with and - requirement.install_succeeded - ) - if should_commit: - uninstalled_pathset.commit() - requirement.remove_temporary_source() - - return to_install diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/constructors.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/constructors.py deleted file mode 100644 index 1eed1dd..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/constructors.py +++ /dev/null @@ -1,339 +0,0 @@ -"""Backing implementation for InstallRequirement's various constructors - -The idea here is that these formed a major chunk of InstallRequirement's size -so, moving them and support code dedicated to them outside of that class -helps creates for better understandability for the rest of the code. - -These are meant to be used elsewhere within pip to create instances of -InstallRequirement. -""" - -import logging -import os -import re - -from pip._vendor.packaging.markers import Marker -from pip._vendor.packaging.requirements import InvalidRequirement, Requirement -from pip._vendor.packaging.specifiers import Specifier -from pip._vendor.pkg_resources import RequirementParseError, parse_requirements - -from pip._internal.download import ( - is_archive_file, is_url, path_to_url, url_to_path, -) -from pip._internal.exceptions import InstallationError -from pip._internal.models.index import PyPI, TestPyPI -from pip._internal.models.link import Link -from pip._internal.pyproject import make_pyproject_path -from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.misc import is_installable_dir -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.vcs import vcs -from pip._internal.wheel import Wheel - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Optional, Tuple, Set, Any, Union, Text, Dict, - ) - from pip._internal.cache import WheelCache # noqa: F401 - - -__all__ = [ - "install_req_from_editable", "install_req_from_line", - "parse_editable" -] - -logger = logging.getLogger(__name__) -operators = Specifier._operators.keys() - - -def _strip_extras(path): - # type: (str) -> Tuple[str, Optional[str]] - m = re.match(r'^(.+)(\[[^\]]+\])$', path) - extras = None - if m: - path_no_extras = m.group(1) - extras = m.group(2) - else: - path_no_extras = path - - return path_no_extras, extras - - -def parse_editable(editable_req): - # type: (str) -> Tuple[Optional[str], str, Optional[Set[str]]] - """Parses an editable requirement into: - - a requirement name - - an URL - - extras - - editable options - Accepted requirements: - svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir - .[some_extra] - """ - - url = editable_req - - # If a file path is specified with extras, strip off the extras. - url_no_extras, extras = _strip_extras(url) - - if os.path.isdir(url_no_extras): - if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): - msg = ( - 'File "setup.py" not found. Directory cannot be installed ' - 'in editable mode: {}'.format(os.path.abspath(url_no_extras)) - ) - pyproject_path = make_pyproject_path(url_no_extras) - if os.path.isfile(pyproject_path): - msg += ( - '\n(A "pyproject.toml" file was found, but editable ' - 'mode currently requires a setup.py based build.)' - ) - raise InstallationError(msg) - - # Treating it as code that has already been checked out - url_no_extras = path_to_url(url_no_extras) - - if url_no_extras.lower().startswith('file:'): - package_name = Link(url_no_extras).egg_fragment - if extras: - return ( - package_name, - url_no_extras, - Requirement("placeholder" + extras.lower()).extras, - ) - else: - return package_name, url_no_extras, None - - for version_control in vcs: - if url.lower().startswith('%s:' % version_control): - url = '%s+%s' % (version_control, url) - break - - if '+' not in url: - raise InstallationError( - '%s should either be a path to a local project or a VCS url ' - 'beginning with svn+, git+, hg+, or bzr+' % - editable_req - ) - - vc_type = url.split('+', 1)[0].lower() - - if not vcs.get_backend(vc_type): - error_message = 'For --editable=%s only ' % editable_req + \ - ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \ - ' is currently supported' - raise InstallationError(error_message) - - package_name = Link(url).egg_fragment - if not package_name: - raise InstallationError( - "Could not detect requirement name for '%s', please specify one " - "with #egg=your_package_name" % editable_req - ) - return package_name, url, None - - -def deduce_helpful_msg(req): - # type: (str) -> str - """Returns helpful msg in case requirements file does not exist, - or cannot be parsed. - - :params req: Requirements file path - """ - msg = "" - if os.path.exists(req): - msg = " It does exist." - # Try to parse and check if it is a requirements file. - try: - with open(req, 'r') as fp: - # parse first line only - next(parse_requirements(fp.read())) - msg += " The argument you provided " + \ - "(%s) appears to be a" % (req) + \ - " requirements file. If that is the" + \ - " case, use the '-r' flag to install" + \ - " the packages specified within it." - except RequirementParseError: - logger.debug("Cannot parse '%s' as requirements \ - file" % (req), exc_info=True) - else: - msg += " File '%s' does not exist." % (req) - return msg - - -# ---- The actual constructors follow ---- - - -def install_req_from_editable( - editable_req, # type: str - comes_from=None, # type: Optional[str] - use_pep517=None, # type: Optional[bool] - isolated=False, # type: bool - options=None, # type: Optional[Dict[str, Any]] - wheel_cache=None, # type: Optional[WheelCache] - constraint=False # type: bool -): - # type: (...) -> InstallRequirement - name, url, extras_override = parse_editable(editable_req) - if url.startswith('file:'): - source_dir = url_to_path(url) - else: - source_dir = None - - if name is not None: - try: - req = Requirement(name) - except InvalidRequirement: - raise InstallationError("Invalid requirement: '%s'" % name) - else: - req = None - return InstallRequirement( - req, comes_from, source_dir=source_dir, - editable=True, - link=Link(url), - constraint=constraint, - use_pep517=use_pep517, - isolated=isolated, - options=options if options else {}, - wheel_cache=wheel_cache, - extras=extras_override or (), - ) - - -def install_req_from_line( - name, # type: str - comes_from=None, # type: Optional[Union[str, InstallRequirement]] - use_pep517=None, # type: Optional[bool] - isolated=False, # type: bool - options=None, # type: Optional[Dict[str, Any]] - wheel_cache=None, # type: Optional[WheelCache] - constraint=False # type: bool -): - # type: (...) -> InstallRequirement - """Creates an InstallRequirement from a name, which might be a - requirement, directory containing 'setup.py', filename, or URL. - """ - if is_url(name): - marker_sep = '; ' - else: - marker_sep = ';' - if marker_sep in name: - name, markers_as_string = name.split(marker_sep, 1) - markers_as_string = markers_as_string.strip() - if not markers_as_string: - markers = None - else: - markers = Marker(markers_as_string) - else: - markers = None - name = name.strip() - req_as_string = None - path = os.path.normpath(os.path.abspath(name)) - link = None - extras_as_string = None - - if is_url(name): - link = Link(name) - else: - p, extras_as_string = _strip_extras(path) - looks_like_dir = os.path.isdir(p) and ( - os.path.sep in name or - (os.path.altsep is not None and os.path.altsep in name) or - name.startswith('.') - ) - if looks_like_dir: - if not is_installable_dir(p): - raise InstallationError( - "Directory %r is not installable. Neither 'setup.py' " - "nor 'pyproject.toml' found." % name - ) - link = Link(path_to_url(p)) - elif is_archive_file(p): - if not os.path.isfile(p): - logger.warning( - 'Requirement %r looks like a filename, but the ' - 'file does not exist', - name - ) - link = Link(path_to_url(p)) - - # it's a local file, dir, or url - if link: - # Handle relative file URLs - if link.scheme == 'file' and re.search(r'\.\./', link.url): - link = Link( - path_to_url(os.path.normpath(os.path.abspath(link.path)))) - # wheel file - if link.is_wheel: - wheel = Wheel(link.filename) # can raise InvalidWheelFilename - req_as_string = "%s==%s" % (wheel.name, wheel.version) - else: - # set the req to the egg fragment. when it's not there, this - # will become an 'unnamed' requirement - req_as_string = link.egg_fragment - - # a requirement specifier - else: - req_as_string = name - - if extras_as_string: - extras = Requirement("placeholder" + extras_as_string.lower()).extras - else: - extras = () - if req_as_string is not None: - try: - req = Requirement(req_as_string) - except InvalidRequirement: - if os.path.sep in req_as_string: - add_msg = "It looks like a path." - add_msg += deduce_helpful_msg(req_as_string) - elif ('=' in req_as_string and - not any(op in req_as_string for op in operators)): - add_msg = "= is not a valid operator. Did you mean == ?" - else: - add_msg = "" - raise InstallationError( - "Invalid requirement: '%s'\n%s" % (req_as_string, add_msg) - ) - else: - req = None - - return InstallRequirement( - req, comes_from, link=link, markers=markers, - use_pep517=use_pep517, isolated=isolated, - options=options if options else {}, - wheel_cache=wheel_cache, - constraint=constraint, - extras=extras, - ) - - -def install_req_from_req_string( - req_string, # type: str - comes_from=None, # type: Optional[InstallRequirement] - isolated=False, # type: bool - wheel_cache=None, # type: Optional[WheelCache] - use_pep517=None # type: Optional[bool] -): - # type: (...) -> InstallRequirement - try: - req = Requirement(req_string) - except InvalidRequirement: - raise InstallationError("Invalid requirement: '%s'" % req) - - domains_not_allowed = [ - PyPI.file_storage_domain, - TestPyPI.file_storage_domain, - ] - if req.url and comes_from.link.netloc in domains_not_allowed: - # Explicitly disallow pypi packages that depend on external urls - raise InstallationError( - "Packages installed from PyPI cannot depend on packages " - "which are not also hosted on PyPI.\n" - "%s depends on %s " % (comes_from.name, req) - ) - - return InstallRequirement( - req, comes_from, isolated=isolated, wheel_cache=wheel_cache, - use_pep517=use_pep517 - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_file.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_file.py deleted file mode 100644 index 726f2f6..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_file.py +++ /dev/null @@ -1,382 +0,0 @@ -""" -Requirements file parsing -""" - -from __future__ import absolute_import - -import optparse -import os -import re -import shlex -import sys - -from pip._vendor.six.moves import filterfalse -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.cli import cmdoptions -from pip._internal.download import get_file_content -from pip._internal.exceptions import RequirementsFileParseError -from pip._internal.req.constructors import ( - install_req_from_editable, install_req_from_line, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Iterator, Tuple, Optional, List, Callable, Text - ) - from pip._internal.req import InstallRequirement # noqa: F401 - from pip._internal.cache import WheelCache # noqa: F401 - from pip._internal.index import PackageFinder # noqa: F401 - from pip._internal.download import PipSession # noqa: F401 - - ReqFileLines = Iterator[Tuple[int, Text]] - -__all__ = ['parse_requirements'] - -SCHEME_RE = re.compile(r'^(http|https|file):', re.I) -COMMENT_RE = re.compile(r'(^|\s)+#.*$') - -# Matches environment variable-style values in '${MY_VARIABLE_1}' with the -# variable name consisting of only uppercase letters, digits or the '_' -# (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, -# 2013 Edition. -ENV_VAR_RE = re.compile(r'(?P\$\{(?P[A-Z0-9_]+)\})') - -SUPPORTED_OPTIONS = [ - cmdoptions.constraints, - cmdoptions.editable, - cmdoptions.requirements, - cmdoptions.no_index, - cmdoptions.index_url, - cmdoptions.find_links, - cmdoptions.extra_index_url, - cmdoptions.always_unzip, - cmdoptions.no_binary, - cmdoptions.only_binary, - cmdoptions.pre, - cmdoptions.trusted_host, - cmdoptions.require_hashes, -] # type: List[Callable[..., optparse.Option]] - -# options to be passed to requirements -SUPPORTED_OPTIONS_REQ = [ - cmdoptions.install_options, - cmdoptions.global_options, - cmdoptions.hash, -] # type: List[Callable[..., optparse.Option]] - -# the 'dest' string values -SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ] - - -def parse_requirements( - filename, # type: str - finder=None, # type: Optional[PackageFinder] - comes_from=None, # type: Optional[str] - options=None, # type: Optional[optparse.Values] - session=None, # type: Optional[PipSession] - constraint=False, # type: bool - wheel_cache=None, # type: Optional[WheelCache] - use_pep517=None # type: Optional[bool] -): - # type: (...) -> Iterator[InstallRequirement] - """Parse a requirements file and yield InstallRequirement instances. - - :param filename: Path or url of requirements file. - :param finder: Instance of pip.index.PackageFinder. - :param comes_from: Origin description of requirements. - :param options: cli options. - :param session: Instance of pip.download.PipSession. - :param constraint: If true, parsing a constraint file rather than - requirements file. - :param wheel_cache: Instance of pip.wheel.WheelCache - :param use_pep517: Value of the --use-pep517 option. - """ - if session is None: - raise TypeError( - "parse_requirements() missing 1 required keyword argument: " - "'session'" - ) - - _, content = get_file_content( - filename, comes_from=comes_from, session=session - ) - - lines_enum = preprocess(content, options) - - for line_number, line in lines_enum: - req_iter = process_line(line, filename, line_number, finder, - comes_from, options, session, wheel_cache, - use_pep517=use_pep517, constraint=constraint) - for req in req_iter: - yield req - - -def preprocess(content, options): - # type: (Text, Optional[optparse.Values]) -> ReqFileLines - """Split, filter, and join lines, and return a line iterator - - :param content: the content of the requirements file - :param options: cli options - """ - lines_enum = enumerate(content.splitlines(), start=1) # type: ReqFileLines - lines_enum = join_lines(lines_enum) - lines_enum = ignore_comments(lines_enum) - lines_enum = skip_regex(lines_enum, options) - lines_enum = expand_env_variables(lines_enum) - return lines_enum - - -def process_line( - line, # type: Text - filename, # type: str - line_number, # type: int - finder=None, # type: Optional[PackageFinder] - comes_from=None, # type: Optional[str] - options=None, # type: Optional[optparse.Values] - session=None, # type: Optional[PipSession] - wheel_cache=None, # type: Optional[WheelCache] - use_pep517=None, # type: Optional[bool] - constraint=False # type: bool -): - # type: (...) -> Iterator[InstallRequirement] - """Process a single requirements line; This can result in creating/yielding - requirements, or updating the finder. - - For lines that contain requirements, the only options that have an effect - are from SUPPORTED_OPTIONS_REQ, and they are scoped to the - requirement. Other options from SUPPORTED_OPTIONS may be present, but are - ignored. - - For lines that do not contain requirements, the only options that have an - effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may - be present, but are ignored. These lines may contain multiple options - (although our docs imply only one is supported), and all our parsed and - affect the finder. - - :param constraint: If True, parsing a constraints file. - :param options: OptionParser options that we may update - """ - parser = build_parser(line) - defaults = parser.get_default_values() - defaults.index_url = None - if finder: - defaults.format_control = finder.format_control - args_str, options_str = break_args_options(line) - # Prior to 2.7.3, shlex cannot deal with unicode entries - if sys.version_info < (2, 7, 3): - # https://github.com/python/mypy/issues/1174 - options_str = options_str.encode('utf8') # type: ignore - # https://github.com/python/mypy/issues/1174 - opts, _ = parser.parse_args( - shlex.split(options_str), defaults) # type: ignore - - # preserve for the nested code path - line_comes_from = '%s %s (line %s)' % ( - '-c' if constraint else '-r', filename, line_number, - ) - - # yield a line requirement - if args_str: - isolated = options.isolated_mode if options else False - if options: - cmdoptions.check_install_build_global(options, opts) - # get the options that apply to requirements - req_options = {} - for dest in SUPPORTED_OPTIONS_REQ_DEST: - if dest in opts.__dict__ and opts.__dict__[dest]: - req_options[dest] = opts.__dict__[dest] - yield install_req_from_line( - args_str, line_comes_from, constraint=constraint, - use_pep517=use_pep517, - isolated=isolated, options=req_options, wheel_cache=wheel_cache - ) - - # yield an editable requirement - elif opts.editables: - isolated = options.isolated_mode if options else False - yield install_req_from_editable( - opts.editables[0], comes_from=line_comes_from, - use_pep517=use_pep517, - constraint=constraint, isolated=isolated, wheel_cache=wheel_cache - ) - - # parse a nested requirements file - elif opts.requirements or opts.constraints: - if opts.requirements: - req_path = opts.requirements[0] - nested_constraint = False - else: - req_path = opts.constraints[0] - nested_constraint = True - # original file is over http - if SCHEME_RE.search(filename): - # do a url join so relative paths work - req_path = urllib_parse.urljoin(filename, req_path) - # original file and nested file are paths - elif not SCHEME_RE.search(req_path): - # do a join so relative paths work - req_path = os.path.join(os.path.dirname(filename), req_path) - # TODO: Why not use `comes_from='-r {} (line {})'` here as well? - parsed_reqs = parse_requirements( - req_path, finder, comes_from, options, session, - constraint=nested_constraint, wheel_cache=wheel_cache - ) - for req in parsed_reqs: - yield req - - # percolate hash-checking option upward - elif opts.require_hashes: - options.require_hashes = opts.require_hashes - - # set finder options - elif finder: - if opts.index_url: - finder.index_urls = [opts.index_url] - if opts.no_index is True: - finder.index_urls = [] - if opts.extra_index_urls: - finder.index_urls.extend(opts.extra_index_urls) - if opts.find_links: - # FIXME: it would be nice to keep track of the source - # of the find_links: support a find-links local path - # relative to a requirements file. - value = opts.find_links[0] - req_dir = os.path.dirname(os.path.abspath(filename)) - relative_to_reqs_file = os.path.join(req_dir, value) - if os.path.exists(relative_to_reqs_file): - value = relative_to_reqs_file - finder.find_links.append(value) - if opts.pre: - finder.allow_all_prereleases = True - if opts.trusted_hosts: - finder.secure_origins.extend( - ("*", host, "*") for host in opts.trusted_hosts) - - -def break_args_options(line): - # type: (Text) -> Tuple[str, Text] - """Break up the line into an args and options string. We only want to shlex - (and then optparse) the options, not the args. args can contain markers - which are corrupted by shlex. - """ - tokens = line.split(' ') - args = [] - options = tokens[:] - for token in tokens: - if token.startswith('-') or token.startswith('--'): - break - else: - args.append(token) - options.pop(0) - return ' '.join(args), ' '.join(options) # type: ignore - - -def build_parser(line): - # type: (Text) -> optparse.OptionParser - """ - Return a parser for parsing requirement lines - """ - parser = optparse.OptionParser(add_help_option=False) - - option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ - for option_factory in option_factories: - option = option_factory() - parser.add_option(option) - - # By default optparse sys.exits on parsing errors. We want to wrap - # that in our own exception. - def parser_exit(self, msg): - # add offending line - msg = 'Invalid requirement: %s\n%s' % (line, msg) - raise RequirementsFileParseError(msg) - # NOTE: mypy disallows assigning to a method - # https://github.com/python/mypy/issues/2427 - parser.exit = parser_exit # type: ignore - - return parser - - -def join_lines(lines_enum): - # type: (ReqFileLines) -> ReqFileLines - """Joins a line ending in '\' with the previous line (except when following - comments). The joined line takes on the index of the first line. - """ - primary_line_number = None - new_line = [] # type: List[Text] - for line_number, line in lines_enum: - if not line.endswith('\\') or COMMENT_RE.match(line): - if COMMENT_RE.match(line): - # this ensures comments are always matched later - line = ' ' + line - if new_line: - new_line.append(line) - yield primary_line_number, ''.join(new_line) - new_line = [] - else: - yield line_number, line - else: - if not new_line: - primary_line_number = line_number - new_line.append(line.strip('\\')) - - # last line contains \ - if new_line: - yield primary_line_number, ''.join(new_line) - - # TODO: handle space after '\'. - - -def ignore_comments(lines_enum): - # type: (ReqFileLines) -> ReqFileLines - """ - Strips comments and filter empty lines. - """ - for line_number, line in lines_enum: - line = COMMENT_RE.sub('', line) - line = line.strip() - if line: - yield line_number, line - - -def skip_regex(lines_enum, options): - # type: (ReqFileLines, Optional[optparse.Values]) -> ReqFileLines - """ - Skip lines that match '--skip-requirements-regex' pattern - - Note: the regex pattern is only built once - """ - skip_regex = options.skip_requirements_regex if options else None - if skip_regex: - pattern = re.compile(skip_regex) - lines_enum = filterfalse(lambda e: pattern.search(e[1]), lines_enum) - return lines_enum - - -def expand_env_variables(lines_enum): - # type: (ReqFileLines) -> ReqFileLines - """Replace all environment variables that can be retrieved via `os.getenv`. - - The only allowed format for environment variables defined in the - requirement file is `${MY_VARIABLE_1}` to ensure two things: - - 1. Strings that contain a `$` aren't accidentally (partially) expanded. - 2. Ensure consistency across platforms for requirement files. - - These points are the result of a discusssion on the `github pull - request #3514 `_. - - Valid characters in variable names follow the `POSIX standard - `_ and are limited - to uppercase letter, digits and the `_` (underscore). - """ - for line_number, line in lines_enum: - for env_var, var_name in ENV_VAR_RE.findall(line): - value = os.getenv(var_name) - if not value: - continue - - line = line.replace(env_var, value) - - yield line_number, line diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_install.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_install.py deleted file mode 100644 index a4834b0..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_install.py +++ /dev/null @@ -1,1021 +0,0 @@ -from __future__ import absolute_import - -import logging -import os -import shutil -import sys -import sysconfig -import zipfile -from distutils.util import change_root - -from pip._vendor import pkg_resources, six -from pip._vendor.packaging.requirements import Requirement -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.packaging.version import Version -from pip._vendor.packaging.version import parse as parse_version -from pip._vendor.pep517.wrappers import Pep517HookCaller - -from pip._internal import wheel -from pip._internal.build_env import NoOpBuildEnvironment -from pip._internal.exceptions import InstallationError -from pip._internal.locations import ( - PIP_DELETE_MARKER_FILENAME, running_under_virtualenv, -) -from pip._internal.models.link import Link -from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path -from pip._internal.req.req_uninstall import UninstallPathSet -from pip._internal.utils.compat import native_str -from pip._internal.utils.hashes import Hashes -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - _make_build_dir, ask_path_exists, backup_dir, call_subprocess, - display_path, dist_in_site_packages, dist_in_usersite, ensure_dir, - get_installed_version, redact_password_from_url, rmtree, -) -from pip._internal.utils.packaging import get_metadata -from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import open_spinner -from pip._internal.vcs import vcs -from pip._internal.wheel import move_wheel_files - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Optional, Iterable, List, Union, Any, Text, Sequence, Dict - ) - from pip._internal.build_env import BuildEnvironment # noqa: F401 - from pip._internal.cache import WheelCache # noqa: F401 - from pip._internal.index import PackageFinder # noqa: F401 - from pip._vendor.pkg_resources import Distribution # noqa: F401 - from pip._vendor.packaging.specifiers import SpecifierSet # noqa: F401 - from pip._vendor.packaging.markers import Marker # noqa: F401 - - -logger = logging.getLogger(__name__) - - -class InstallRequirement(object): - """ - Represents something that may be installed later on, may have information - about where to fetch the relavant requirement and also contains logic for - installing the said requirement. - """ - - def __init__( - self, - req, # type: Optional[Requirement] - comes_from, # type: Optional[Union[str, InstallRequirement]] - source_dir=None, # type: Optional[str] - editable=False, # type: bool - link=None, # type: Optional[Link] - update=True, # type: bool - markers=None, # type: Optional[Marker] - use_pep517=None, # type: Optional[bool] - isolated=False, # type: bool - options=None, # type: Optional[Dict[str, Any]] - wheel_cache=None, # type: Optional[WheelCache] - constraint=False, # type: bool - extras=() # type: Iterable[str] - ): - # type: (...) -> None - assert req is None or isinstance(req, Requirement), req - self.req = req - self.comes_from = comes_from - self.constraint = constraint - if source_dir is not None: - self.source_dir = os.path.normpath(os.path.abspath(source_dir)) - else: - self.source_dir = None - self.editable = editable - - self._wheel_cache = wheel_cache - if link is None and req and req.url: - # PEP 508 URL requirement - link = Link(req.url) - self.link = self.original_link = link - - if extras: - self.extras = extras - elif req: - self.extras = { - pkg_resources.safe_extra(extra) for extra in req.extras - } - else: - self.extras = set() - if markers is None and req: - markers = req.marker - self.markers = markers - - self._egg_info_path = None # type: Optional[str] - # This holds the pkg_resources.Distribution object if this requirement - # is already available: - self.satisfied_by = None - # This hold the pkg_resources.Distribution object if this requirement - # conflicts with another installed distribution: - self.conflicts_with = None - # Temporary build location - self._temp_build_dir = TempDirectory(kind="req-build") - # Used to store the global directory where the _temp_build_dir should - # have been created. Cf _correct_build_location method. - self._ideal_build_dir = None # type: Optional[str] - # True if the editable should be updated: - self.update = update - # Set to True after successful installation - self.install_succeeded = None # type: Optional[bool] - # UninstallPathSet of uninstalled distribution (for possible rollback) - self.uninstalled_pathset = None - self.options = options if options else {} - # Set to True after successful preparation of this requirement - self.prepared = False - self.is_direct = False - - self.isolated = isolated - self.build_env = NoOpBuildEnvironment() # type: BuildEnvironment - - # For PEP 517, the directory where we request the project metadata - # gets stored. We need this to pass to build_wheel, so the backend - # can ensure that the wheel matches the metadata (see the PEP for - # details). - self.metadata_directory = None # type: Optional[str] - - # The static build requirements (from pyproject.toml) - self.pyproject_requires = None # type: Optional[List[str]] - - # Build requirements that we will check are available - self.requirements_to_check = [] # type: List[str] - - # The PEP 517 backend we should use to build the project - self.pep517_backend = None # type: Optional[Pep517HookCaller] - - # Are we using PEP 517 for this requirement? - # After pyproject.toml has been loaded, the only valid values are True - # and False. Before loading, None is valid (meaning "use the default"). - # Setting an explicit value before loading pyproject.toml is supported, - # but after loading this flag should be treated as read only. - self.use_pep517 = use_pep517 - - def __str__(self): - if self.req: - s = str(self.req) - if self.link: - s += ' from %s' % redact_password_from_url(self.link.url) - elif self.link: - s = redact_password_from_url(self.link.url) - else: - s = '' - if self.satisfied_by is not None: - s += ' in %s' % display_path(self.satisfied_by.location) - if self.comes_from: - if isinstance(self.comes_from, six.string_types): - comes_from = self.comes_from - else: - comes_from = self.comes_from.from_path() - if comes_from: - s += ' (from %s)' % comes_from - return s - - def __repr__(self): - return '<%s object: %s editable=%r>' % ( - self.__class__.__name__, str(self), self.editable) - - def populate_link(self, finder, upgrade, require_hashes): - # type: (PackageFinder, bool, bool) -> None - """Ensure that if a link can be found for this, that it is found. - - Note that self.link may still be None - if Upgrade is False and the - requirement is already installed. - - If require_hashes is True, don't use the wheel cache, because cached - wheels, always built locally, have different hashes than the files - downloaded from the index server and thus throw false hash mismatches. - Furthermore, cached wheels at present have undeterministic contents due - to file modification times. - """ - if self.link is None: - self.link = finder.find_requirement(self, upgrade) - if self._wheel_cache is not None and not require_hashes: - old_link = self.link - self.link = self._wheel_cache.get(self.link, self.name) - if old_link != self.link: - logger.debug('Using cached wheel link: %s', self.link) - - # Things that are valid for all kinds of requirements? - @property - def name(self): - # type: () -> Optional[str] - if self.req is None: - return None - return native_str(pkg_resources.safe_name(self.req.name)) - - @property - def specifier(self): - # type: () -> SpecifierSet - return self.req.specifier - - @property - def is_pinned(self): - # type: () -> bool - """Return whether I am pinned to an exact version. - - For example, some-package==1.2 is pinned; some-package>1.2 is not. - """ - specifiers = self.specifier - return (len(specifiers) == 1 and - next(iter(specifiers)).operator in {'==', '==='}) - - @property - def installed_version(self): - return get_installed_version(self.name) - - def match_markers(self, extras_requested=None): - # type: (Optional[Iterable[str]]) -> bool - if not extras_requested: - # Provide an extra to safely evaluate the markers - # without matching any extra - extras_requested = ('',) - if self.markers is not None: - return any( - self.markers.evaluate({'extra': extra}) - for extra in extras_requested) - else: - return True - - @property - def has_hash_options(self): - # type: () -> bool - """Return whether any known-good hashes are specified as options. - - These activate --require-hashes mode; hashes specified as part of a - URL do not. - - """ - return bool(self.options.get('hashes', {})) - - def hashes(self, trust_internet=True): - # type: (bool) -> Hashes - """Return a hash-comparer that considers my option- and URL-based - hashes to be known-good. - - Hashes in URLs--ones embedded in the requirements file, not ones - downloaded from an index server--are almost peers with ones from - flags. They satisfy --require-hashes (whether it was implicitly or - explicitly activated) but do not activate it. md5 and sha224 are not - allowed in flags, which should nudge people toward good algos. We - always OR all hashes together, even ones from URLs. - - :param trust_internet: Whether to trust URL-based (#md5=...) hashes - downloaded from the internet, as by populate_link() - - """ - good_hashes = self.options.get('hashes', {}).copy() - link = self.link if trust_internet else self.original_link - if link and link.hash: - good_hashes.setdefault(link.hash_name, []).append(link.hash) - return Hashes(good_hashes) - - def from_path(self): - # type: () -> Optional[str] - """Format a nice indicator to show where this "comes from" - """ - if self.req is None: - return None - s = str(self.req) - if self.comes_from: - if isinstance(self.comes_from, six.string_types): - comes_from = self.comes_from - else: - comes_from = self.comes_from.from_path() - if comes_from: - s += '->' + comes_from - return s - - def build_location(self, build_dir): - # type: (str) -> Optional[str] - assert build_dir is not None - if self._temp_build_dir.path is not None: - return self._temp_build_dir.path - if self.req is None: - # for requirement via a path to a directory: the name of the - # package is not available yet so we create a temp directory - # Once run_egg_info will have run, we'll be able - # to fix it via _correct_build_location - # Some systems have /tmp as a symlink which confuses custom - # builds (such as numpy). Thus, we ensure that the real path - # is returned. - self._temp_build_dir.create() - self._ideal_build_dir = build_dir - - return self._temp_build_dir.path - if self.editable: - name = self.name.lower() - else: - name = self.name - # FIXME: Is there a better place to create the build_dir? (hg and bzr - # need this) - if not os.path.exists(build_dir): - logger.debug('Creating directory %s', build_dir) - _make_build_dir(build_dir) - return os.path.join(build_dir, name) - - def _correct_build_location(self): - # type: () -> None - """Move self._temp_build_dir to self._ideal_build_dir/self.req.name - - For some requirements (e.g. a path to a directory), the name of the - package is not available until we run egg_info, so the build_location - will return a temporary directory and store the _ideal_build_dir. - - This is only called by self.run_egg_info to fix the temporary build - directory. - """ - if self.source_dir is not None: - return - assert self.req is not None - assert self._temp_build_dir.path - assert (self._ideal_build_dir is not None and - self._ideal_build_dir.path) # type: ignore - old_location = self._temp_build_dir.path - self._temp_build_dir.path = None - - new_location = self.build_location(self._ideal_build_dir) - if os.path.exists(new_location): - raise InstallationError( - 'A package already exists in %s; please remove it to continue' - % display_path(new_location)) - logger.debug( - 'Moving package %s from %s to new location %s', - self, display_path(old_location), display_path(new_location), - ) - shutil.move(old_location, new_location) - self._temp_build_dir.path = new_location - self._ideal_build_dir = None - self.source_dir = os.path.normpath(os.path.abspath(new_location)) - self._egg_info_path = None - - # Correct the metadata directory, if it exists - if self.metadata_directory: - old_meta = self.metadata_directory - rel = os.path.relpath(old_meta, start=old_location) - new_meta = os.path.join(new_location, rel) - new_meta = os.path.normpath(os.path.abspath(new_meta)) - self.metadata_directory = new_meta - - def remove_temporary_source(self): - # type: () -> None - """Remove the source files from this requirement, if they are marked - for deletion""" - if self.source_dir and os.path.exists( - os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME)): - logger.debug('Removing source in %s', self.source_dir) - rmtree(self.source_dir) - self.source_dir = None - self._temp_build_dir.cleanup() - self.build_env.cleanup() - - def check_if_exists(self, use_user_site): - # type: (bool) -> bool - """Find an installed distribution that satisfies or conflicts - with this requirement, and set self.satisfied_by or - self.conflicts_with appropriately. - """ - if self.req is None: - return False - try: - # get_distribution() will resolve the entire list of requirements - # anyway, and we've already determined that we need the requirement - # in question, so strip the marker so that we don't try to - # evaluate it. - no_marker = Requirement(str(self.req)) - no_marker.marker = None - self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) - if self.editable and self.satisfied_by: - self.conflicts_with = self.satisfied_by - # when installing editables, nothing pre-existing should ever - # satisfy - self.satisfied_by = None - return True - except pkg_resources.DistributionNotFound: - return False - except pkg_resources.VersionConflict: - existing_dist = pkg_resources.get_distribution( - self.req.name - ) - if use_user_site: - if dist_in_usersite(existing_dist): - self.conflicts_with = existing_dist - elif (running_under_virtualenv() and - dist_in_site_packages(existing_dist)): - raise InstallationError( - "Will not install to the user site because it will " - "lack sys.path precedence to %s in %s" % - (existing_dist.project_name, existing_dist.location) - ) - else: - self.conflicts_with = existing_dist - return True - - # Things valid for wheels - @property - def is_wheel(self): - # type: () -> bool - if not self.link: - return False - return self.link.is_wheel - - def move_wheel_files( - self, - wheeldir, # type: str - root=None, # type: Optional[str] - home=None, # type: Optional[str] - prefix=None, # type: Optional[str] - warn_script_location=True, # type: bool - use_user_site=False, # type: bool - pycompile=True # type: bool - ): - # type: (...) -> None - move_wheel_files( - self.name, self.req, wheeldir, - user=use_user_site, - home=home, - root=root, - prefix=prefix, - pycompile=pycompile, - isolated=self.isolated, - warn_script_location=warn_script_location, - ) - - # Things valid for sdists - @property - def setup_py_dir(self): - # type: () -> str - return os.path.join( - self.source_dir, - self.link and self.link.subdirectory_fragment or '') - - @property - def setup_py(self): - # type: () -> str - assert self.source_dir, "No source dir for %s" % self - - setup_py = os.path.join(self.setup_py_dir, 'setup.py') - - # Python2 __file__ should not be unicode - if six.PY2 and isinstance(setup_py, six.text_type): - setup_py = setup_py.encode(sys.getfilesystemencoding()) - - return setup_py - - @property - def pyproject_toml(self): - # type: () -> str - assert self.source_dir, "No source dir for %s" % self - - return make_pyproject_path(self.setup_py_dir) - - def load_pyproject_toml(self): - # type: () -> None - """Load the pyproject.toml file. - - After calling this routine, all of the attributes related to PEP 517 - processing for this requirement have been set. In particular, the - use_pep517 attribute can be used to determine whether we should - follow the PEP 517 or legacy (setup.py) code path. - """ - pep517_data = load_pyproject_toml( - self.use_pep517, - self.pyproject_toml, - self.setup_py, - str(self) - ) - - if pep517_data is None: - self.use_pep517 = False - else: - self.use_pep517 = True - requires, backend, check = pep517_data - self.requirements_to_check = check - self.pyproject_requires = requires - self.pep517_backend = Pep517HookCaller(self.setup_py_dir, backend) - - # Use a custom function to call subprocesses - self.spin_message = "" - - def runner(cmd, cwd=None, extra_environ=None): - with open_spinner(self.spin_message) as spinner: - call_subprocess( - cmd, - cwd=cwd, - extra_environ=extra_environ, - show_stdout=False, - spinner=spinner - ) - self.spin_message = "" - - self.pep517_backend._subprocess_runner = runner - - def prepare_metadata(self): - # type: () -> None - """Ensure that project metadata is available. - - Under PEP 517, call the backend hook to prepare the metadata. - Under legacy processing, call setup.py egg-info. - """ - assert self.source_dir - - with indent_log(): - if self.use_pep517: - self.prepare_pep517_metadata() - else: - self.run_egg_info() - - if not self.req: - if isinstance(parse_version(self.metadata["Version"]), Version): - op = "==" - else: - op = "===" - self.req = Requirement( - "".join([ - self.metadata["Name"], - op, - self.metadata["Version"], - ]) - ) - self._correct_build_location() - else: - metadata_name = canonicalize_name(self.metadata["Name"]) - if canonicalize_name(self.req.name) != metadata_name: - logger.warning( - 'Generating metadata for package %s ' - 'produced metadata for project name %s. Fix your ' - '#egg=%s fragments.', - self.name, metadata_name, self.name - ) - self.req = Requirement(metadata_name) - - def prepare_pep517_metadata(self): - # type: () -> None - assert self.pep517_backend is not None - - metadata_dir = os.path.join( - self.setup_py_dir, - 'pip-wheel-metadata' - ) - ensure_dir(metadata_dir) - - with self.build_env: - # Note that Pep517HookCaller implements a fallback for - # prepare_metadata_for_build_wheel, so we don't have to - # consider the possibility that this hook doesn't exist. - backend = self.pep517_backend - self.spin_message = "Preparing wheel metadata" - distinfo_dir = backend.prepare_metadata_for_build_wheel( - metadata_dir - ) - - self.metadata_directory = os.path.join(metadata_dir, distinfo_dir) - - def run_egg_info(self): - # type: () -> None - if self.name: - logger.debug( - 'Running setup.py (path:%s) egg_info for package %s', - self.setup_py, self.name, - ) - else: - logger.debug( - 'Running setup.py (path:%s) egg_info for package from %s', - self.setup_py, self.link, - ) - script = SETUPTOOLS_SHIM % self.setup_py - base_cmd = [sys.executable, '-c', script] - if self.isolated: - base_cmd += ["--no-user-cfg"] - egg_info_cmd = base_cmd + ['egg_info'] - # We can't put the .egg-info files at the root, because then the - # source code will be mistaken for an installed egg, causing - # problems - if self.editable: - egg_base_option = [] # type: List[str] - else: - egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info') - ensure_dir(egg_info_dir) - egg_base_option = ['--egg-base', 'pip-egg-info'] - with self.build_env: - call_subprocess( - egg_info_cmd + egg_base_option, - cwd=self.setup_py_dir, - show_stdout=False, - command_desc='python setup.py egg_info') - - @property - def egg_info_path(self): - # type: () -> str - if self._egg_info_path is None: - if self.editable: - base = self.source_dir - else: - base = os.path.join(self.setup_py_dir, 'pip-egg-info') - filenames = os.listdir(base) - if self.editable: - filenames = [] - for root, dirs, files in os.walk(base): - for dir in vcs.dirnames: - if dir in dirs: - dirs.remove(dir) - # Iterate over a copy of ``dirs``, since mutating - # a list while iterating over it can cause trouble. - # (See https://github.com/pypa/pip/pull/462.) - for dir in list(dirs): - # Don't search in anything that looks like a virtualenv - # environment - if ( - os.path.lexists( - os.path.join(root, dir, 'bin', 'python') - ) or - os.path.exists( - os.path.join( - root, dir, 'Scripts', 'Python.exe' - ) - )): - dirs.remove(dir) - # Also don't search through tests - elif dir == 'test' or dir == 'tests': - dirs.remove(dir) - filenames.extend([os.path.join(root, dir) - for dir in dirs]) - filenames = [f for f in filenames if f.endswith('.egg-info')] - - if not filenames: - raise InstallationError( - "Files/directories not found in %s" % base - ) - # if we have more than one match, we pick the toplevel one. This - # can easily be the case if there is a dist folder which contains - # an extracted tarball for testing purposes. - if len(filenames) > 1: - filenames.sort( - key=lambda x: x.count(os.path.sep) + - (os.path.altsep and x.count(os.path.altsep) or 0) - ) - self._egg_info_path = os.path.join(base, filenames[0]) - return self._egg_info_path - - @property - def metadata(self): - if not hasattr(self, '_metadata'): - self._metadata = get_metadata(self.get_dist()) - - return self._metadata - - def get_dist(self): - # type: () -> Distribution - """Return a pkg_resources.Distribution for this requirement""" - if self.metadata_directory: - base_dir, distinfo = os.path.split(self.metadata_directory) - metadata = pkg_resources.PathMetadata( - base_dir, self.metadata_directory - ) - dist_name = os.path.splitext(distinfo)[0] - typ = pkg_resources.DistInfoDistribution - else: - egg_info = self.egg_info_path.rstrip(os.path.sep) - base_dir = os.path.dirname(egg_info) - metadata = pkg_resources.PathMetadata(base_dir, egg_info) - dist_name = os.path.splitext(os.path.basename(egg_info))[0] - # https://github.com/python/mypy/issues/1174 - typ = pkg_resources.Distribution # type: ignore - - return typ( - base_dir, - project_name=dist_name, - metadata=metadata, - ) - - def assert_source_matches_version(self): - # type: () -> None - assert self.source_dir - version = self.metadata['version'] - if self.req.specifier and version not in self.req.specifier: - logger.warning( - 'Requested %s, but installing version %s', - self, - version, - ) - else: - logger.debug( - 'Source in %s has version %s, which satisfies requirement %s', - display_path(self.source_dir), - version, - self, - ) - - # For both source distributions and editables - def ensure_has_source_dir(self, parent_dir): - # type: (str) -> str - """Ensure that a source_dir is set. - - This will create a temporary build dir if the name of the requirement - isn't known yet. - - :param parent_dir: The ideal pip parent_dir for the source_dir. - Generally src_dir for editables and build_dir for sdists. - :return: self.source_dir - """ - if self.source_dir is None: - self.source_dir = self.build_location(parent_dir) - return self.source_dir - - # For editable installations - def install_editable( - self, - install_options, # type: List[str] - global_options=(), # type: Sequence[str] - prefix=None # type: Optional[str] - ): - # type: (...) -> None - logger.info('Running setup.py develop for %s', self.name) - - if self.isolated: - global_options = list(global_options) + ["--no-user-cfg"] - - if prefix: - prefix_param = ['--prefix={}'.format(prefix)] - install_options = list(install_options) + prefix_param - - with indent_log(): - # FIXME: should we do --install-headers here too? - with self.build_env: - call_subprocess( - [ - sys.executable, - '-c', - SETUPTOOLS_SHIM % self.setup_py - ] + - list(global_options) + - ['develop', '--no-deps'] + - list(install_options), - - cwd=self.setup_py_dir, - show_stdout=False, - ) - - self.install_succeeded = True - - def update_editable(self, obtain=True): - # type: (bool) -> None - if not self.link: - logger.debug( - "Cannot update repository at %s; repository location is " - "unknown", - self.source_dir, - ) - return - assert self.editable - assert self.source_dir - if self.link.scheme == 'file': - # Static paths don't get updated - return - assert '+' in self.link.url, "bad url: %r" % self.link.url - if not self.update: - return - vc_type, url = self.link.url.split('+', 1) - backend = vcs.get_backend(vc_type) - if backend: - vcs_backend = backend(self.link.url) - if obtain: - vcs_backend.obtain(self.source_dir) - else: - vcs_backend.export(self.source_dir) - else: - assert 0, ( - 'Unexpected version control type (in %s): %s' - % (self.link, vc_type)) - - # Top-level Actions - def uninstall(self, auto_confirm=False, verbose=False, - use_user_site=False): - # type: (bool, bool, bool) -> Optional[UninstallPathSet] - """ - Uninstall the distribution currently satisfying this requirement. - - Prompts before removing or modifying files unless - ``auto_confirm`` is True. - - Refuses to delete or modify files outside of ``sys.prefix`` - - thus uninstallation within a virtual environment can only - modify that virtual environment, even if the virtualenv is - linked to global site-packages. - - """ - if not self.check_if_exists(use_user_site): - logger.warning("Skipping %s as it is not installed.", self.name) - return None - dist = self.satisfied_by or self.conflicts_with - - uninstalled_pathset = UninstallPathSet.from_dist(dist) - uninstalled_pathset.remove(auto_confirm, verbose) - return uninstalled_pathset - - def _clean_zip_name(self, name, prefix): # only used by archive. - assert name.startswith(prefix + os.path.sep), ( - "name %r doesn't start with prefix %r" % (name, prefix) - ) - name = name[len(prefix) + 1:] - name = name.replace(os.path.sep, '/') - return name - - def _get_archive_name(self, path, parentdir, rootdir): - # type: (str, str, str) -> str - path = os.path.join(parentdir, path) - name = self._clean_zip_name(path, rootdir) - return self.name + '/' + name - - # TODO: Investigate if this should be kept in InstallRequirement - # Seems to be used only when VCS + downloads - def archive(self, build_dir): - # type: (str) -> None - assert self.source_dir - create_archive = True - archive_name = '%s-%s.zip' % (self.name, self.metadata["version"]) - archive_path = os.path.join(build_dir, archive_name) - if os.path.exists(archive_path): - response = ask_path_exists( - 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' % - display_path(archive_path), ('i', 'w', 'b', 'a')) - if response == 'i': - create_archive = False - elif response == 'w': - logger.warning('Deleting %s', display_path(archive_path)) - os.remove(archive_path) - elif response == 'b': - dest_file = backup_dir(archive_path) - logger.warning( - 'Backing up %s to %s', - display_path(archive_path), - display_path(dest_file), - ) - shutil.move(archive_path, dest_file) - elif response == 'a': - sys.exit(-1) - if create_archive: - zip = zipfile.ZipFile( - archive_path, 'w', zipfile.ZIP_DEFLATED, - allowZip64=True - ) - dir = os.path.normcase(os.path.abspath(self.setup_py_dir)) - for dirpath, dirnames, filenames in os.walk(dir): - if 'pip-egg-info' in dirnames: - dirnames.remove('pip-egg-info') - for dirname in dirnames: - dir_arcname = self._get_archive_name(dirname, - parentdir=dirpath, - rootdir=dir) - zipdir = zipfile.ZipInfo(dir_arcname + '/') - zipdir.external_attr = 0x1ED << 16 # 0o755 - zip.writestr(zipdir, '') - for filename in filenames: - if filename == PIP_DELETE_MARKER_FILENAME: - continue - file_arcname = self._get_archive_name(filename, - parentdir=dirpath, - rootdir=dir) - filename = os.path.join(dirpath, filename) - zip.write(filename, file_arcname) - zip.close() - logger.info('Saved %s', display_path(archive_path)) - - def install( - self, - install_options, # type: List[str] - global_options=None, # type: Optional[Sequence[str]] - root=None, # type: Optional[str] - home=None, # type: Optional[str] - prefix=None, # type: Optional[str] - warn_script_location=True, # type: bool - use_user_site=False, # type: bool - pycompile=True # type: bool - ): - # type: (...) -> None - global_options = global_options if global_options is not None else [] - if self.editable: - self.install_editable( - install_options, global_options, prefix=prefix, - ) - return - if self.is_wheel: - version = wheel.wheel_version(self.source_dir) - wheel.check_compatibility(version, self.name) - - self.move_wheel_files( - self.source_dir, root=root, prefix=prefix, home=home, - warn_script_location=warn_script_location, - use_user_site=use_user_site, pycompile=pycompile, - ) - self.install_succeeded = True - return - - # Extend the list of global and install options passed on to - # the setup.py call with the ones from the requirements file. - # Options specified in requirements file override those - # specified on the command line, since the last option given - # to setup.py is the one that is used. - global_options = list(global_options) + \ - self.options.get('global_options', []) - install_options = list(install_options) + \ - self.options.get('install_options', []) - - if self.isolated: - # https://github.com/python/mypy/issues/1174 - global_options = global_options + ["--no-user-cfg"] # type: ignore - - with TempDirectory(kind="record") as temp_dir: - record_filename = os.path.join(temp_dir.path, 'install-record.txt') - install_args = self.get_install_args( - global_options, record_filename, root, prefix, pycompile, - ) - msg = 'Running setup.py install for %s' % (self.name,) - with open_spinner(msg) as spinner: - with indent_log(): - with self.build_env: - call_subprocess( - install_args + install_options, - cwd=self.setup_py_dir, - show_stdout=False, - spinner=spinner, - ) - - if not os.path.exists(record_filename): - logger.debug('Record file %s not found', record_filename) - return - self.install_succeeded = True - - def prepend_root(path): - if root is None or not os.path.isabs(path): - return path - else: - return change_root(root, path) - - with open(record_filename) as f: - for line in f: - directory = os.path.dirname(line) - if directory.endswith('.egg-info'): - egg_info_dir = prepend_root(directory) - break - else: - logger.warning( - 'Could not find .egg-info directory in install record' - ' for %s', - self, - ) - # FIXME: put the record somewhere - # FIXME: should this be an error? - return - new_lines = [] - with open(record_filename) as f: - for line in f: - filename = line.strip() - if os.path.isdir(filename): - filename += os.path.sep - new_lines.append( - os.path.relpath(prepend_root(filename), egg_info_dir) - ) - new_lines.sort() - ensure_dir(egg_info_dir) - inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') - with open(inst_files_path, 'w') as f: - f.write('\n'.join(new_lines) + '\n') - - def get_install_args( - self, - global_options, # type: Sequence[str] - record_filename, # type: str - root, # type: Optional[str] - prefix, # type: Optional[str] - pycompile # type: bool - ): - # type: (...) -> List[str] - install_args = [sys.executable, "-u"] - install_args.append('-c') - install_args.append(SETUPTOOLS_SHIM % self.setup_py) - install_args += list(global_options) + \ - ['install', '--record', record_filename] - install_args += ['--single-version-externally-managed'] - - if root is not None: - install_args += ['--root', root] - if prefix is not None: - install_args += ['--prefix', prefix] - - if pycompile: - install_args += ["--compile"] - else: - install_args += ["--no-compile"] - - if running_under_virtualenv(): - py_ver_str = 'python' + sysconfig.get_python_version() - install_args += ['--install-headers', - os.path.join(sys.prefix, 'include', 'site', - py_ver_str, self.name)] - - return install_args diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_set.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_set.py deleted file mode 100644 index d1410e9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_set.py +++ /dev/null @@ -1,197 +0,0 @@ -from __future__ import absolute_import - -import logging -from collections import OrderedDict - -from pip._internal.exceptions import InstallationError -from pip._internal.utils.logging import indent_log -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel import Wheel - -if MYPY_CHECK_RUNNING: - from typing import Optional, List, Tuple, Dict, Iterable # noqa: F401 - from pip._internal.req.req_install import InstallRequirement # noqa: F401 - - -logger = logging.getLogger(__name__) - - -class RequirementSet(object): - - def __init__(self, require_hashes=False, check_supported_wheels=True): - # type: (bool, bool) -> None - """Create a RequirementSet. - """ - - self.requirements = OrderedDict() # type: Dict[str, InstallRequirement] # noqa: E501 - self.require_hashes = require_hashes - self.check_supported_wheels = check_supported_wheels - - # Mapping of alias: real_name - self.requirement_aliases = {} # type: Dict[str, str] - self.unnamed_requirements = [] # type: List[InstallRequirement] - self.successfully_downloaded = [] # type: List[InstallRequirement] - self.reqs_to_cleanup = [] # type: List[InstallRequirement] - - def __str__(self): - reqs = [req for req in self.requirements.values() - if not req.comes_from] - reqs.sort(key=lambda req: req.name.lower()) - return ' '.join([str(req.req) for req in reqs]) - - def __repr__(self): - reqs = [req for req in self.requirements.values()] - reqs.sort(key=lambda req: req.name.lower()) - reqs_str = ', '.join([str(req.req) for req in reqs]) - return ('<%s object; %d requirement(s): %s>' - % (self.__class__.__name__, len(reqs), reqs_str)) - - def add_requirement( - self, - install_req, # type: InstallRequirement - parent_req_name=None, # type: Optional[str] - extras_requested=None # type: Optional[Iterable[str]] - ): - # type: (...) -> Tuple[List[InstallRequirement], Optional[InstallRequirement]] # noqa: E501 - """Add install_req as a requirement to install. - - :param parent_req_name: The name of the requirement that needed this - added. The name is used because when multiple unnamed requirements - resolve to the same name, we could otherwise end up with dependency - links that point outside the Requirements set. parent_req must - already be added. Note that None implies that this is a user - supplied requirement, vs an inferred one. - :param extras_requested: an iterable of extras used to evaluate the - environment markers. - :return: Additional requirements to scan. That is either [] if - the requirement is not applicable, or [install_req] if the - requirement is applicable and has just been added. - """ - name = install_req.name - - # If the markers do not match, ignore this requirement. - if not install_req.match_markers(extras_requested): - logger.info( - "Ignoring %s: markers '%s' don't match your environment", - name, install_req.markers, - ) - return [], None - - # If the wheel is not supported, raise an error. - # Should check this after filtering out based on environment markers to - # allow specifying different wheels based on the environment/OS, in a - # single requirements file. - if install_req.link and install_req.link.is_wheel: - wheel = Wheel(install_req.link.filename) - if self.check_supported_wheels and not wheel.supported(): - raise InstallationError( - "%s is not a supported wheel on this platform." % - wheel.filename - ) - - # This next bit is really a sanity check. - assert install_req.is_direct == (parent_req_name is None), ( - "a direct req shouldn't have a parent and also, " - "a non direct req should have a parent" - ) - - # Unnamed requirements are scanned again and the requirement won't be - # added as a dependency until after scanning. - if not name: - # url or path requirement w/o an egg fragment - self.unnamed_requirements.append(install_req) - return [install_req], None - - try: - existing_req = self.get_requirement(name) - except KeyError: - existing_req = None - - has_conflicting_requirement = ( - parent_req_name is None and - existing_req and - not existing_req.constraint and - existing_req.extras == install_req.extras and - existing_req.req.specifier != install_req.req.specifier - ) - if has_conflicting_requirement: - raise InstallationError( - "Double requirement given: %s (already in %s, name=%r)" - % (install_req, existing_req, name) - ) - - # When no existing requirement exists, add the requirement as a - # dependency and it will be scanned again after. - if not existing_req: - self.requirements[name] = install_req - # FIXME: what about other normalizations? E.g., _ vs. -? - if name.lower() != name: - self.requirement_aliases[name.lower()] = name - # We'd want to rescan this requirements later - return [install_req], install_req - - # Assume there's no need to scan, and that we've already - # encountered this for scanning. - if install_req.constraint or not existing_req.constraint: - return [], existing_req - - does_not_satisfy_constraint = ( - install_req.link and - not ( - existing_req.link and - install_req.link.path == existing_req.link.path - ) - ) - if does_not_satisfy_constraint: - self.reqs_to_cleanup.append(install_req) - raise InstallationError( - "Could not satisfy constraints for '%s': " - "installation from path or url cannot be " - "constrained to a version" % name, - ) - # If we're now installing a constraint, mark the existing - # object for real installation. - existing_req.constraint = False - existing_req.extras = tuple(sorted( - set(existing_req.extras) | set(install_req.extras) - )) - logger.debug( - "Setting %s extras to: %s", - existing_req, existing_req.extras, - ) - # Return the existing requirement for addition to the parent and - # scanning again. - return [existing_req], existing_req - - def has_requirement(self, project_name): - # type: (str) -> bool - name = project_name.lower() - if (name in self.requirements and - not self.requirements[name].constraint or - name in self.requirement_aliases and - not self.requirements[self.requirement_aliases[name]].constraint): - return True - return False - - @property - def has_requirements(self): - # type: () -> List[InstallRequirement] - return list(req for req in self.requirements.values() if not - req.constraint) or self.unnamed_requirements - - def get_requirement(self, project_name): - # type: (str) -> InstallRequirement - for name in project_name, project_name.lower(): - if name in self.requirements: - return self.requirements[name] - if name in self.requirement_aliases: - return self.requirements[self.requirement_aliases[name]] - raise KeyError("No project with the name %r" % project_name) - - def cleanup_files(self): - # type: () -> None - """Clean up files, remove builds.""" - logger.debug('Cleaning up...') - with indent_log(): - for req in self.reqs_to_cleanup: - req.remove_temporary_source() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_tracker.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_tracker.py deleted file mode 100644 index 82e084a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_tracker.py +++ /dev/null @@ -1,88 +0,0 @@ -from __future__ import absolute_import - -import contextlib -import errno -import hashlib -import logging -import os - -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Set, Iterator # noqa: F401 - from pip._internal.req.req_install import InstallRequirement # noqa: F401 - from pip._internal.models.link import Link # noqa: F401 - -logger = logging.getLogger(__name__) - - -class RequirementTracker(object): - - def __init__(self): - # type: () -> None - self._root = os.environ.get('PIP_REQ_TRACKER') - if self._root is None: - self._temp_dir = TempDirectory(delete=False, kind='req-tracker') - self._temp_dir.create() - self._root = os.environ['PIP_REQ_TRACKER'] = self._temp_dir.path - logger.debug('Created requirements tracker %r', self._root) - else: - self._temp_dir = None - logger.debug('Re-using requirements tracker %r', self._root) - self._entries = set() # type: Set[InstallRequirement] - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.cleanup() - - def _entry_path(self, link): - # type: (Link) -> str - hashed = hashlib.sha224(link.url_without_fragment.encode()).hexdigest() - return os.path.join(self._root, hashed) - - def add(self, req): - # type: (InstallRequirement) -> None - link = req.link - info = str(req) - entry_path = self._entry_path(link) - try: - with open(entry_path) as fp: - # Error, these's already a build in progress. - raise LookupError('%s is already being built: %s' - % (link, fp.read())) - except IOError as e: - if e.errno != errno.ENOENT: - raise - assert req not in self._entries - with open(entry_path, 'w') as fp: - fp.write(info) - self._entries.add(req) - logger.debug('Added %s to build tracker %r', req, self._root) - - def remove(self, req): - # type: (InstallRequirement) -> None - link = req.link - self._entries.remove(req) - os.unlink(self._entry_path(link)) - logger.debug('Removed %s from build tracker %r', req, self._root) - - def cleanup(self): - # type: () -> None - for req in set(self._entries): - self.remove(req) - remove = self._temp_dir is not None - if remove: - self._temp_dir.cleanup() - logger.debug('%s build tracker %r', - 'Removed' if remove else 'Cleaned', - self._root) - - @contextlib.contextmanager - def track(self, req): - # type: (InstallRequirement) -> Iterator[None] - self.add(req) - yield - self.remove(req) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_uninstall.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_uninstall.py deleted file mode 100644 index c80959e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/req/req_uninstall.py +++ /dev/null @@ -1,596 +0,0 @@ -from __future__ import absolute_import - -import csv -import functools -import logging -import os -import sys -import sysconfig - -from pip._vendor import pkg_resources - -from pip._internal.exceptions import UninstallationError -from pip._internal.locations import bin_py, bin_user -from pip._internal.utils.compat import WINDOWS, cache_from_source, uses_pycache -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - FakeFile, ask, dist_in_usersite, dist_is_local, egg_link_path, is_local, - normalize_path, renames, rmtree, -) -from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory - -logger = logging.getLogger(__name__) - - -def _script_names(dist, script_name, is_gui): - """Create the fully qualified name of the files created by - {console,gui}_scripts for the given ``dist``. - Returns the list of file names - """ - if dist_in_usersite(dist): - bin_dir = bin_user - else: - bin_dir = bin_py - exe_name = os.path.join(bin_dir, script_name) - paths_to_remove = [exe_name] - if WINDOWS: - paths_to_remove.append(exe_name + '.exe') - paths_to_remove.append(exe_name + '.exe.manifest') - if is_gui: - paths_to_remove.append(exe_name + '-script.pyw') - else: - paths_to_remove.append(exe_name + '-script.py') - return paths_to_remove - - -def _unique(fn): - @functools.wraps(fn) - def unique(*args, **kw): - seen = set() - for item in fn(*args, **kw): - if item not in seen: - seen.add(item) - yield item - return unique - - -@_unique -def uninstallation_paths(dist): - """ - Yield all the uninstallation paths for dist based on RECORD-without-.py[co] - - Yield paths to all the files in RECORD. For each .py file in RECORD, add - the .pyc and .pyo in the same directory. - - UninstallPathSet.add() takes care of the __pycache__ .py[co]. - """ - r = csv.reader(FakeFile(dist.get_metadata_lines('RECORD'))) - for row in r: - path = os.path.join(dist.location, row[0]) - yield path - if path.endswith('.py'): - dn, fn = os.path.split(path) - base = fn[:-3] - path = os.path.join(dn, base + '.pyc') - yield path - path = os.path.join(dn, base + '.pyo') - yield path - - -def compact(paths): - """Compact a path set to contain the minimal number of paths - necessary to contain all paths in the set. If /a/path/ and - /a/path/to/a/file.txt are both in the set, leave only the - shorter path.""" - - sep = os.path.sep - short_paths = set() - for path in sorted(paths, key=len): - should_skip = any( - path.startswith(shortpath.rstrip("*")) and - path[len(shortpath.rstrip("*").rstrip(sep))] == sep - for shortpath in short_paths - ) - if not should_skip: - short_paths.add(path) - return short_paths - - -def compress_for_rename(paths): - """Returns a set containing the paths that need to be renamed. - - This set may include directories when the original sequence of paths - included every file on disk. - """ - case_map = dict((os.path.normcase(p), p) for p in paths) - remaining = set(case_map) - unchecked = sorted(set(os.path.split(p)[0] - for p in case_map.values()), key=len) - wildcards = set() - - def norm_join(*a): - return os.path.normcase(os.path.join(*a)) - - for root in unchecked: - if any(os.path.normcase(root).startswith(w) - for w in wildcards): - # This directory has already been handled. - continue - - all_files = set() - all_subdirs = set() - for dirname, subdirs, files in os.walk(root): - all_subdirs.update(norm_join(root, dirname, d) - for d in subdirs) - all_files.update(norm_join(root, dirname, f) - for f in files) - # If all the files we found are in our remaining set of files to - # remove, then remove them from the latter set and add a wildcard - # for the directory. - if not (all_files - remaining): - remaining.difference_update(all_files) - wildcards.add(root + os.sep) - - return set(map(case_map.__getitem__, remaining)) | wildcards - - -def compress_for_output_listing(paths): - """Returns a tuple of 2 sets of which paths to display to user - - The first set contains paths that would be deleted. Files of a package - are not added and the top-level directory of the package has a '*' added - at the end - to signify that all it's contents are removed. - - The second set contains files that would have been skipped in the above - folders. - """ - - will_remove = list(paths) - will_skip = set() - - # Determine folders and files - folders = set() - files = set() - for path in will_remove: - if path.endswith(".pyc"): - continue - if path.endswith("__init__.py") or ".dist-info" in path: - folders.add(os.path.dirname(path)) - files.add(path) - - _normcased_files = set(map(os.path.normcase, files)) - - folders = compact(folders) - - # This walks the tree using os.walk to not miss extra folders - # that might get added. - for folder in folders: - for dirpath, _, dirfiles in os.walk(folder): - for fname in dirfiles: - if fname.endswith(".pyc"): - continue - - file_ = os.path.join(dirpath, fname) - if (os.path.isfile(file_) and - os.path.normcase(file_) not in _normcased_files): - # We are skipping this file. Add it to the set. - will_skip.add(file_) - - will_remove = files | { - os.path.join(folder, "*") for folder in folders - } - - return will_remove, will_skip - - -class StashedUninstallPathSet(object): - """A set of file rename operations to stash files while - tentatively uninstalling them.""" - def __init__(self): - # Mapping from source file root to [Adjacent]TempDirectory - # for files under that directory. - self._save_dirs = {} - # (old path, new path) tuples for each move that may need - # to be undone. - self._moves = [] - - def _get_directory_stash(self, path): - """Stashes a directory. - - Directories are stashed adjacent to their original location if - possible, or else moved/copied into the user's temp dir.""" - - try: - save_dir = AdjacentTempDirectory(path) - save_dir.create() - except OSError: - save_dir = TempDirectory(kind="uninstall") - save_dir.create() - self._save_dirs[os.path.normcase(path)] = save_dir - - return save_dir.path - - def _get_file_stash(self, path): - """Stashes a file. - - If no root has been provided, one will be created for the directory - in the user's temp directory.""" - path = os.path.normcase(path) - head, old_head = os.path.dirname(path), None - save_dir = None - - while head != old_head: - try: - save_dir = self._save_dirs[head] - break - except KeyError: - pass - head, old_head = os.path.dirname(head), head - else: - # Did not find any suitable root - head = os.path.dirname(path) - save_dir = TempDirectory(kind='uninstall') - save_dir.create() - self._save_dirs[head] = save_dir - - relpath = os.path.relpath(path, head) - if relpath and relpath != os.path.curdir: - return os.path.join(save_dir.path, relpath) - return save_dir.path - - def stash(self, path): - """Stashes the directory or file and returns its new location. - """ - if os.path.isdir(path): - new_path = self._get_directory_stash(path) - else: - new_path = self._get_file_stash(path) - - self._moves.append((path, new_path)) - if os.path.isdir(path) and os.path.isdir(new_path): - # If we're moving a directory, we need to - # remove the destination first or else it will be - # moved to inside the existing directory. - # We just created new_path ourselves, so it will - # be removable. - os.rmdir(new_path) - renames(path, new_path) - return new_path - - def commit(self): - """Commits the uninstall by removing stashed files.""" - for _, save_dir in self._save_dirs.items(): - save_dir.cleanup() - self._moves = [] - self._save_dirs = {} - - def rollback(self): - """Undoes the uninstall by moving stashed files back.""" - for p in self._moves: - logging.info("Moving to %s\n from %s", *p) - - for new_path, path in self._moves: - try: - logger.debug('Replacing %s from %s', new_path, path) - if os.path.isfile(new_path): - os.unlink(new_path) - elif os.path.isdir(new_path): - rmtree(new_path) - renames(path, new_path) - except OSError as ex: - logger.error("Failed to restore %s", new_path) - logger.debug("Exception: %s", ex) - - self.commit() - - @property - def can_rollback(self): - return bool(self._moves) - - -class UninstallPathSet(object): - """A set of file paths to be removed in the uninstallation of a - requirement.""" - def __init__(self, dist): - self.paths = set() - self._refuse = set() - self.pth = {} - self.dist = dist - self._moved_paths = StashedUninstallPathSet() - - def _permitted(self, path): - """ - Return True if the given path is one we are permitted to - remove/modify, False otherwise. - - """ - return is_local(path) - - def add(self, path): - head, tail = os.path.split(path) - - # we normalize the head to resolve parent directory symlinks, but not - # the tail, since we only want to uninstall symlinks, not their targets - path = os.path.join(normalize_path(head), os.path.normcase(tail)) - - if not os.path.exists(path): - return - if self._permitted(path): - self.paths.add(path) - else: - self._refuse.add(path) - - # __pycache__ files can show up after 'installed-files.txt' is created, - # due to imports - if os.path.splitext(path)[1] == '.py' and uses_pycache: - self.add(cache_from_source(path)) - - def add_pth(self, pth_file, entry): - pth_file = normalize_path(pth_file) - if self._permitted(pth_file): - if pth_file not in self.pth: - self.pth[pth_file] = UninstallPthEntries(pth_file) - self.pth[pth_file].add(entry) - else: - self._refuse.add(pth_file) - - def remove(self, auto_confirm=False, verbose=False): - """Remove paths in ``self.paths`` with confirmation (unless - ``auto_confirm`` is True).""" - - if not self.paths: - logger.info( - "Can't uninstall '%s'. No files were found to uninstall.", - self.dist.project_name, - ) - return - - dist_name_version = ( - self.dist.project_name + "-" + self.dist.version - ) - logger.info('Uninstalling %s:', dist_name_version) - - with indent_log(): - if auto_confirm or self._allowed_to_proceed(verbose): - moved = self._moved_paths - - for_rename = compress_for_rename(self.paths) - - for path in sorted(compact(for_rename)): - moved.stash(path) - logger.debug('Removing file or directory %s', path) - - for pth in self.pth.values(): - pth.remove() - - logger.info('Successfully uninstalled %s', dist_name_version) - - def _allowed_to_proceed(self, verbose): - """Display which files would be deleted and prompt for confirmation - """ - - def _display(msg, paths): - if not paths: - return - - logger.info(msg) - with indent_log(): - for path in sorted(compact(paths)): - logger.info(path) - - if not verbose: - will_remove, will_skip = compress_for_output_listing(self.paths) - else: - # In verbose mode, display all the files that are going to be - # deleted. - will_remove = list(self.paths) - will_skip = set() - - _display('Would remove:', will_remove) - _display('Would not remove (might be manually added):', will_skip) - _display('Would not remove (outside of prefix):', self._refuse) - if verbose: - _display('Will actually move:', compress_for_rename(self.paths)) - - return ask('Proceed (y/n)? ', ('y', 'n')) == 'y' - - def rollback(self): - """Rollback the changes previously made by remove().""" - if not self._moved_paths.can_rollback: - logger.error( - "Can't roll back %s; was not uninstalled", - self.dist.project_name, - ) - return False - logger.info('Rolling back uninstall of %s', self.dist.project_name) - self._moved_paths.rollback() - for pth in self.pth.values(): - pth.rollback() - - def commit(self): - """Remove temporary save dir: rollback will no longer be possible.""" - self._moved_paths.commit() - - @classmethod - def from_dist(cls, dist): - dist_path = normalize_path(dist.location) - if not dist_is_local(dist): - logger.info( - "Not uninstalling %s at %s, outside environment %s", - dist.key, - dist_path, - sys.prefix, - ) - return cls(dist) - - if dist_path in {p for p in {sysconfig.get_path("stdlib"), - sysconfig.get_path("platstdlib")} - if p}: - logger.info( - "Not uninstalling %s at %s, as it is in the standard library.", - dist.key, - dist_path, - ) - return cls(dist) - - paths_to_remove = cls(dist) - develop_egg_link = egg_link_path(dist) - develop_egg_link_egg_info = '{}.egg-info'.format( - pkg_resources.to_filename(dist.project_name)) - egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) - # Special case for distutils installed package - distutils_egg_info = getattr(dist._provider, 'path', None) - - # Uninstall cases order do matter as in the case of 2 installs of the - # same package, pip needs to uninstall the currently detected version - if (egg_info_exists and dist.egg_info.endswith('.egg-info') and - not dist.egg_info.endswith(develop_egg_link_egg_info)): - # if dist.egg_info.endswith(develop_egg_link_egg_info), we - # are in fact in the develop_egg_link case - paths_to_remove.add(dist.egg_info) - if dist.has_metadata('installed-files.txt'): - for installed_file in dist.get_metadata( - 'installed-files.txt').splitlines(): - path = os.path.normpath( - os.path.join(dist.egg_info, installed_file) - ) - paths_to_remove.add(path) - # FIXME: need a test for this elif block - # occurs with --single-version-externally-managed/--record outside - # of pip - elif dist.has_metadata('top_level.txt'): - if dist.has_metadata('namespace_packages.txt'): - namespaces = dist.get_metadata('namespace_packages.txt') - else: - namespaces = [] - for top_level_pkg in [ - p for p - in dist.get_metadata('top_level.txt').splitlines() - if p and p not in namespaces]: - path = os.path.join(dist.location, top_level_pkg) - paths_to_remove.add(path) - paths_to_remove.add(path + '.py') - paths_to_remove.add(path + '.pyc') - paths_to_remove.add(path + '.pyo') - - elif distutils_egg_info: - raise UninstallationError( - "Cannot uninstall {!r}. It is a distutils installed project " - "and thus we cannot accurately determine which files belong " - "to it which would lead to only a partial uninstall.".format( - dist.project_name, - ) - ) - - elif dist.location.endswith('.egg'): - # package installed by easy_install - # We cannot match on dist.egg_name because it can slightly vary - # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg - paths_to_remove.add(dist.location) - easy_install_egg = os.path.split(dist.location)[1] - easy_install_pth = os.path.join(os.path.dirname(dist.location), - 'easy-install.pth') - paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) - - elif egg_info_exists and dist.egg_info.endswith('.dist-info'): - for path in uninstallation_paths(dist): - paths_to_remove.add(path) - - elif develop_egg_link: - # develop egg - with open(develop_egg_link, 'r') as fh: - link_pointer = os.path.normcase(fh.readline().strip()) - assert (link_pointer == dist.location), ( - 'Egg-link %s does not match installed location of %s ' - '(at %s)' % (link_pointer, dist.project_name, dist.location) - ) - paths_to_remove.add(develop_egg_link) - easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), - 'easy-install.pth') - paths_to_remove.add_pth(easy_install_pth, dist.location) - - else: - logger.debug( - 'Not sure how to uninstall: %s - Check: %s', - dist, dist.location, - ) - - # find distutils scripts= scripts - if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): - for script in dist.metadata_listdir('scripts'): - if dist_in_usersite(dist): - bin_dir = bin_user - else: - bin_dir = bin_py - paths_to_remove.add(os.path.join(bin_dir, script)) - if WINDOWS: - paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') - - # find console_scripts - _scripts_to_remove = [] - console_scripts = dist.get_entry_map(group='console_scripts') - for name in console_scripts.keys(): - _scripts_to_remove.extend(_script_names(dist, name, False)) - # find gui_scripts - gui_scripts = dist.get_entry_map(group='gui_scripts') - for name in gui_scripts.keys(): - _scripts_to_remove.extend(_script_names(dist, name, True)) - - for s in _scripts_to_remove: - paths_to_remove.add(s) - - return paths_to_remove - - -class UninstallPthEntries(object): - def __init__(self, pth_file): - if not os.path.isfile(pth_file): - raise UninstallationError( - "Cannot remove entries from nonexistent file %s" % pth_file - ) - self.file = pth_file - self.entries = set() - self._saved_lines = None - - def add(self, entry): - entry = os.path.normcase(entry) - # On Windows, os.path.normcase converts the entry to use - # backslashes. This is correct for entries that describe absolute - # paths outside of site-packages, but all the others use forward - # slashes. - if WINDOWS and not os.path.splitdrive(entry)[0]: - entry = entry.replace('\\', '/') - self.entries.add(entry) - - def remove(self): - logger.debug('Removing pth entries from %s:', self.file) - with open(self.file, 'rb') as fh: - # windows uses '\r\n' with py3k, but uses '\n' with py2.x - lines = fh.readlines() - self._saved_lines = lines - if any(b'\r\n' in line for line in lines): - endline = '\r\n' - else: - endline = '\n' - # handle missing trailing newline - if lines and not lines[-1].endswith(endline.encode("utf-8")): - lines[-1] = lines[-1] + endline.encode("utf-8") - for entry in self.entries: - try: - logger.debug('Removing entry: %s', entry) - lines.remove((entry + endline).encode("utf-8")) - except ValueError: - pass - with open(self.file, 'wb') as fh: - fh.writelines(lines) - - def rollback(self): - if self._saved_lines is None: - logger.error( - 'Cannot roll back changes to %s, none were made', self.file - ) - return False - logger.debug('Rolling %s back to previous state', self.file) - with open(self.file, 'wb') as fh: - fh.writelines(self._saved_lines) - return True diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/resolve.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/resolve.py deleted file mode 100644 index 33f572f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/resolve.py +++ /dev/null @@ -1,393 +0,0 @@ -"""Dependency Resolution - -The dependency resolution in pip is performed as follows: - -for top-level requirements: - a. only one spec allowed per project, regardless of conflicts or not. - otherwise a "double requirement" exception is raised - b. they override sub-dependency requirements. -for sub-dependencies - a. "first found, wins" (where the order is breadth first) -""" - -import logging -from collections import defaultdict -from itertools import chain - -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, - UnsupportedPythonVersion, -) -from pip._internal.req.constructors import install_req_from_req_string -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import dist_in_usersite, ensure_dir -from pip._internal.utils.packaging import check_dist_requires_python -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, DefaultDict, List, Set # noqa: F401 - from pip._internal.download import PipSession # noqa: F401 - from pip._internal.req.req_install import InstallRequirement # noqa: F401 - from pip._internal.index import PackageFinder # noqa: F401 - from pip._internal.req.req_set import RequirementSet # noqa: F401 - from pip._internal.operations.prepare import ( # noqa: F401 - DistAbstraction, RequirementPreparer - ) - from pip._internal.cache import WheelCache # noqa: F401 - -logger = logging.getLogger(__name__) - - -class Resolver(object): - """Resolves which packages need to be installed/uninstalled to perform \ - the requested operation without breaking the requirements of any package. - """ - - _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} - - def __init__( - self, - preparer, # type: RequirementPreparer - session, # type: PipSession - finder, # type: PackageFinder - wheel_cache, # type: Optional[WheelCache] - use_user_site, # type: bool - ignore_dependencies, # type: bool - ignore_installed, # type: bool - ignore_requires_python, # type: bool - force_reinstall, # type: bool - isolated, # type: bool - upgrade_strategy, # type: str - use_pep517=None # type: Optional[bool] - ): - # type: (...) -> None - super(Resolver, self).__init__() - assert upgrade_strategy in self._allowed_strategies - - self.preparer = preparer - self.finder = finder - self.session = session - - # NOTE: This would eventually be replaced with a cache that can give - # information about both sdist and wheels transparently. - self.wheel_cache = wheel_cache - - # This is set in resolve - self.require_hashes = None # type: Optional[bool] - - self.upgrade_strategy = upgrade_strategy - self.force_reinstall = force_reinstall - self.isolated = isolated - self.ignore_dependencies = ignore_dependencies - self.ignore_installed = ignore_installed - self.ignore_requires_python = ignore_requires_python - self.use_user_site = use_user_site - self.use_pep517 = use_pep517 - - self._discovered_dependencies = \ - defaultdict(list) # type: DefaultDict[str, List] - - def resolve(self, requirement_set): - # type: (RequirementSet) -> None - """Resolve what operations need to be done - - As a side-effect of this method, the packages (and their dependencies) - are downloaded, unpacked and prepared for installation. This - preparation is done by ``pip.operations.prepare``. - - Once PyPI has static dependency metadata available, it would be - possible to move the preparation to become a step separated from - dependency resolution. - """ - # make the wheelhouse - if self.preparer.wheel_download_dir: - ensure_dir(self.preparer.wheel_download_dir) - - # If any top-level requirement has a hash specified, enter - # hash-checking mode, which requires hashes from all. - root_reqs = ( - requirement_set.unnamed_requirements + - list(requirement_set.requirements.values()) - ) - self.require_hashes = ( - requirement_set.require_hashes or - any(req.has_hash_options for req in root_reqs) - ) - - # Display where finder is looking for packages - locations = self.finder.get_formatted_locations() - if locations: - logger.info(locations) - - # Actually prepare the files, and collect any exceptions. Most hash - # exceptions cannot be checked ahead of time, because - # req.populate_link() needs to be called before we can make decisions - # based on link type. - discovered_reqs = [] # type: List[InstallRequirement] - hash_errors = HashErrors() - for req in chain(root_reqs, discovered_reqs): - try: - discovered_reqs.extend( - self._resolve_one(requirement_set, req) - ) - except HashError as exc: - exc.req = req - hash_errors.append(exc) - - if hash_errors: - raise hash_errors - - def _is_upgrade_allowed(self, req): - # type: (InstallRequirement) -> bool - if self.upgrade_strategy == "to-satisfy-only": - return False - elif self.upgrade_strategy == "eager": - return True - else: - assert self.upgrade_strategy == "only-if-needed" - return req.is_direct - - def _set_req_to_reinstall(self, req): - # type: (InstallRequirement) -> None - """ - Set a requirement to be installed. - """ - # Don't uninstall the conflict if doing a user install and the - # conflict is not a user install. - if not self.use_user_site or dist_in_usersite(req.satisfied_by): - req.conflicts_with = req.satisfied_by - req.satisfied_by = None - - # XXX: Stop passing requirement_set for options - def _check_skip_installed(self, req_to_install): - # type: (InstallRequirement) -> Optional[str] - """Check if req_to_install should be skipped. - - This will check if the req is installed, and whether we should upgrade - or reinstall it, taking into account all the relevant user options. - - After calling this req_to_install will only have satisfied_by set to - None if the req_to_install is to be upgraded/reinstalled etc. Any - other value will be a dist recording the current thing installed that - satisfies the requirement. - - Note that for vcs urls and the like we can't assess skipping in this - routine - we simply identify that we need to pull the thing down, - then later on it is pulled down and introspected to assess upgrade/ - reinstalls etc. - - :return: A text reason for why it was skipped, or None. - """ - if self.ignore_installed: - return None - - req_to_install.check_if_exists(self.use_user_site) - if not req_to_install.satisfied_by: - return None - - if self.force_reinstall: - self._set_req_to_reinstall(req_to_install) - return None - - if not self._is_upgrade_allowed(req_to_install): - if self.upgrade_strategy == "only-if-needed": - return 'already satisfied, skipping upgrade' - return 'already satisfied' - - # Check for the possibility of an upgrade. For link-based - # requirements we have to pull the tree down and inspect to assess - # the version #, so it's handled way down. - if not req_to_install.link: - try: - self.finder.find_requirement(req_to_install, upgrade=True) - except BestVersionAlreadyInstalled: - # Then the best version is installed. - return 'already up-to-date' - except DistributionNotFound: - # No distribution found, so we squash the error. It will - # be raised later when we re-try later to do the install. - # Why don't we just raise here? - pass - - self._set_req_to_reinstall(req_to_install) - return None - - def _get_abstract_dist_for(self, req): - # type: (InstallRequirement) -> DistAbstraction - """Takes a InstallRequirement and returns a single AbstractDist \ - representing a prepared variant of the same. - """ - assert self.require_hashes is not None, ( - "require_hashes should have been set in Resolver.resolve()" - ) - - if req.editable: - return self.preparer.prepare_editable_requirement( - req, self.require_hashes, self.use_user_site, self.finder, - ) - - # satisfied_by is only evaluated by calling _check_skip_installed, - # so it must be None here. - assert req.satisfied_by is None - skip_reason = self._check_skip_installed(req) - - if req.satisfied_by: - return self.preparer.prepare_installed_requirement( - req, self.require_hashes, skip_reason - ) - - upgrade_allowed = self._is_upgrade_allowed(req) - abstract_dist = self.preparer.prepare_linked_requirement( - req, self.session, self.finder, upgrade_allowed, - self.require_hashes - ) - - # NOTE - # The following portion is for determining if a certain package is - # going to be re-installed/upgraded or not and reporting to the user. - # This should probably get cleaned up in a future refactor. - - # req.req is only avail after unpack for URL - # pkgs repeat check_if_exists to uninstall-on-upgrade - # (#14) - if not self.ignore_installed: - req.check_if_exists(self.use_user_site) - - if req.satisfied_by: - should_modify = ( - self.upgrade_strategy != "to-satisfy-only" or - self.force_reinstall or - self.ignore_installed or - req.link.scheme == 'file' - ) - if should_modify: - self._set_req_to_reinstall(req) - else: - logger.info( - 'Requirement already satisfied (use --upgrade to upgrade):' - ' %s', req, - ) - - return abstract_dist - - def _resolve_one( - self, - requirement_set, # type: RequirementSet - req_to_install # type: InstallRequirement - ): - # type: (...) -> List[InstallRequirement] - """Prepare a single requirements file. - - :return: A list of additional InstallRequirements to also install. - """ - # Tell user what we are doing for this requirement: - # obtain (editable), skipping, processing (local url), collecting - # (remote url or package name) - if req_to_install.constraint or req_to_install.prepared: - return [] - - req_to_install.prepared = True - - # register tmp src for cleanup in case something goes wrong - requirement_set.reqs_to_cleanup.append(req_to_install) - - abstract_dist = self._get_abstract_dist_for(req_to_install) - - # Parse and return dependencies - dist = abstract_dist.dist() - try: - check_dist_requires_python(dist) - except UnsupportedPythonVersion as err: - if self.ignore_requires_python: - logger.warning(err.args[0]) - else: - raise - - more_reqs = [] # type: List[InstallRequirement] - - def add_req(subreq, extras_requested): - sub_install_req = install_req_from_req_string( - str(subreq), - req_to_install, - isolated=self.isolated, - wheel_cache=self.wheel_cache, - use_pep517=self.use_pep517 - ) - parent_req_name = req_to_install.name - to_scan_again, add_to_parent = requirement_set.add_requirement( - sub_install_req, - parent_req_name=parent_req_name, - extras_requested=extras_requested, - ) - if parent_req_name and add_to_parent: - self._discovered_dependencies[parent_req_name].append( - add_to_parent - ) - more_reqs.extend(to_scan_again) - - with indent_log(): - # We add req_to_install before its dependencies, so that we - # can refer to it when adding dependencies. - if not requirement_set.has_requirement(req_to_install.name): - # 'unnamed' requirements will get added here - req_to_install.is_direct = True - requirement_set.add_requirement( - req_to_install, parent_req_name=None, - ) - - if not self.ignore_dependencies: - if req_to_install.extras: - logger.debug( - "Installing extra requirements: %r", - ','.join(req_to_install.extras), - ) - missing_requested = sorted( - set(req_to_install.extras) - set(dist.extras) - ) - for missing in missing_requested: - logger.warning( - '%s does not provide the extra \'%s\'', - dist, missing - ) - - available_requested = sorted( - set(dist.extras) & set(req_to_install.extras) - ) - for subreq in dist.requires(available_requested): - add_req(subreq, extras_requested=available_requested) - - if not req_to_install.editable and not req_to_install.satisfied_by: - # XXX: --no-install leads this to report 'Successfully - # downloaded' for only non-editable reqs, even though we took - # action on them. - requirement_set.successfully_downloaded.append(req_to_install) - - return more_reqs - - def get_installation_order(self, req_set): - # type: (RequirementSet) -> List[InstallRequirement] - """Create the installation order. - - The installation order is topological - requirements are installed - before the requiring thing. We break cycles at an arbitrary point, - and make no other guarantees. - """ - # The current implementation, which we may change at any point - # installs the user specified things in the order given, except when - # dependencies must come earlier to achieve topological order. - order = [] - ordered_reqs = set() # type: Set[InstallRequirement] - - def schedule(req): - if req.satisfied_by or req in ordered_reqs: - return - if req.constraint: - return - ordered_reqs.add(req) - for dep in self._discovered_dependencies[req.name]: - schedule(dep) - order.append(req) - - for install_req in req_set.requirements.values(): - schedule(install_req) - return order diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/appdirs.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/appdirs.py deleted file mode 100644 index 9af9fa7..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/appdirs.py +++ /dev/null @@ -1,270 +0,0 @@ -""" -This code was taken from https://github.com/ActiveState/appdirs and modified -to suit our purposes. -""" -from __future__ import absolute_import - -import os -import sys - -from pip._vendor.six import PY2, text_type - -from pip._internal.utils.compat import WINDOWS, expanduser -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - List, Union - ) - - -def user_cache_dir(appname): - # type: (str) -> str - r""" - Return full path to the user-specific cache dir for this application. - - "appname" is the name of application. - - Typical user cache directories are: - macOS: ~/Library/Caches/ - Unix: ~/.cache/ (XDG default) - Windows: C:\Users\\AppData\Local\\Cache - - On Windows the only suggestion in the MSDN docs is that local settings go - in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the - non-roaming app data dir (the default returned by `user_data_dir`). Apps - typically put cache data somewhere *under* the given dir here. Some - examples: - ...\Mozilla\Firefox\Profiles\\Cache - ...\Acme\SuperApp\Cache\1.0 - - OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. - """ - if WINDOWS: - # Get the base path - path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) - - # When using Python 2, return paths as bytes on Windows like we do on - # other operating systems. See helper function docs for more details. - if PY2 and isinstance(path, text_type): - path = _win_path_to_bytes(path) - - # Add our app name and Cache directory to it - path = os.path.join(path, appname, "Cache") - elif sys.platform == "darwin": - # Get the base path - path = expanduser("~/Library/Caches") - - # Add our app name to it - path = os.path.join(path, appname) - else: - # Get the base path - path = os.getenv("XDG_CACHE_HOME", expanduser("~/.cache")) - - # Add our app name to it - path = os.path.join(path, appname) - - return path - - -def user_data_dir(appname, roaming=False): - # type: (str, bool) -> str - r""" - Return full path to the user-specific data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - - for a discussion of issues. - - Typical user data directories are: - macOS: ~/Library/Application Support/ - if it exists, else ~/.config/ - Unix: ~/.local/share/ # or in - $XDG_DATA_HOME, if defined - Win XP (not roaming): C:\Documents and Settings\\ ... - ...Application Data\ - Win XP (roaming): C:\Documents and Settings\\Local ... - ...Settings\Application Data\ - Win 7 (not roaming): C:\\Users\\AppData\Local\ - Win 7 (roaming): C:\\Users\\AppData\Roaming\ - - For Unix, we follow the XDG spec and support $XDG_DATA_HOME. - That means, by default "~/.local/share/". - """ - if WINDOWS: - const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" - path = os.path.join(os.path.normpath(_get_win_folder(const)), appname) - elif sys.platform == "darwin": - path = os.path.join( - expanduser('~/Library/Application Support/'), - appname, - ) if os.path.isdir(os.path.join( - expanduser('~/Library/Application Support/'), - appname, - ) - ) else os.path.join( - expanduser('~/.config/'), - appname, - ) - else: - path = os.path.join( - os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), - appname, - ) - - return path - - -def user_config_dir(appname, roaming=True): - # type: (str, bool) -> str - """Return full path to the user-specific config dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "roaming" (boolean, default True) can be set False to not use the - Windows roaming appdata directory. That means that for users on a - Windows network setup for roaming profiles, this user data will be - sync'd on login. See - - for a discussion of issues. - - Typical user data directories are: - macOS: same as user_data_dir - Unix: ~/.config/ - Win *: same as user_data_dir - - For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. - That means, by default "~/.config/". - """ - if WINDOWS: - path = user_data_dir(appname, roaming=roaming) - elif sys.platform == "darwin": - path = user_data_dir(appname) - else: - path = os.getenv('XDG_CONFIG_HOME', expanduser("~/.config")) - path = os.path.join(path, appname) - - return path - - -# for the discussion regarding site_config_dirs locations -# see -def site_config_dirs(appname): - # type: (str) -> List[str] - r"""Return a list of potential user-shared config dirs for this application. - - "appname" is the name of application. - - Typical user config directories are: - macOS: /Library/Application Support// - Unix: /etc or $XDG_CONFIG_DIRS[i]// for each value in - $XDG_CONFIG_DIRS - Win XP: C:\Documents and Settings\All Users\Application ... - ...Data\\ - Vista: (Fail! "C:\ProgramData" is a hidden *system* directory - on Vista.) - Win 7: Hidden, but writeable on Win 7: - C:\ProgramData\\ - """ - if WINDOWS: - path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) - pathlist = [os.path.join(path, appname)] - elif sys.platform == 'darwin': - pathlist = [os.path.join('/Library/Application Support', appname)] - else: - # try looking in $XDG_CONFIG_DIRS - xdg_config_dirs = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') - if xdg_config_dirs: - pathlist = [ - os.path.join(expanduser(x), appname) - for x in xdg_config_dirs.split(os.pathsep) - ] - else: - pathlist = [] - - # always look in /etc directly as well - pathlist.append('/etc') - - return pathlist - - -# -- Windows support functions -- - -def _get_win_folder_from_registry(csidl_name): - # type: (str) -> str - """ - This is a fallback technique at best. I'm not sure if using the - registry for this guarantees us the correct answer for all CSIDL_* - names. - """ - import _winreg - - shell_folder_name = { - "CSIDL_APPDATA": "AppData", - "CSIDL_COMMON_APPDATA": "Common AppData", - "CSIDL_LOCAL_APPDATA": "Local AppData", - }[csidl_name] - - key = _winreg.OpenKey( - _winreg.HKEY_CURRENT_USER, - r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" - ) - directory, _type = _winreg.QueryValueEx(key, shell_folder_name) - return directory - - -def _get_win_folder_with_ctypes(csidl_name): - # type: (str) -> str - csidl_const = { - "CSIDL_APPDATA": 26, - "CSIDL_COMMON_APPDATA": 35, - "CSIDL_LOCAL_APPDATA": 28, - }[csidl_name] - - buf = ctypes.create_unicode_buffer(1024) - ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) - - # Downgrade to short path name if have highbit chars. See - # . - has_high_char = False - for c in buf: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - buf2 = ctypes.create_unicode_buffer(1024) - if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): - buf = buf2 - - return buf.value - - -if WINDOWS: - try: - import ctypes - _get_win_folder = _get_win_folder_with_ctypes - except ImportError: - _get_win_folder = _get_win_folder_from_registry - - -def _win_path_to_bytes(path): - """Encode Windows paths to bytes. Only used on Python 2. - - Motivation is to be consistent with other operating systems where paths - are also returned as bytes. This avoids problems mixing bytes and Unicode - elsewhere in the codebase. For more details and discussion see - . - - If encoding using ASCII and MBCS fails, return the original Unicode path. - """ - for encoding in ('ASCII', 'MBCS'): - try: - return path.encode(encoding) - except (UnicodeEncodeError, LookupError): - pass - return path diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/compat.py deleted file mode 100644 index 2d8b3bf..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/compat.py +++ /dev/null @@ -1,264 +0,0 @@ -"""Stuff that differs in different Python versions and platform -distributions.""" -from __future__ import absolute_import, division - -import codecs -import locale -import logging -import os -import shutil -import sys - -from pip._vendor.six import text_type - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Tuple, Text # noqa: F401 - -try: - import ipaddress -except ImportError: - try: - from pip._vendor import ipaddress # type: ignore - except ImportError: - import ipaddr as ipaddress # type: ignore - ipaddress.ip_address = ipaddress.IPAddress # type: ignore - ipaddress.ip_network = ipaddress.IPNetwork # type: ignore - - -__all__ = [ - "ipaddress", "uses_pycache", "console_to_str", "native_str", - "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", - "get_extension_suffixes", -] - - -logger = logging.getLogger(__name__) - -if sys.version_info >= (3, 4): - uses_pycache = True - from importlib.util import cache_from_source -else: - import imp - - try: - cache_from_source = imp.cache_from_source # type: ignore - except AttributeError: - # does not use __pycache__ - cache_from_source = None - - uses_pycache = cache_from_source is not None - - -if sys.version_info >= (3, 5): - backslashreplace_decode = "backslashreplace" -else: - # In version 3.4 and older, backslashreplace exists - # but does not support use for decoding. - # We implement our own replace handler for this - # situation, so that we can consistently use - # backslash replacement for all versions. - def backslashreplace_decode_fn(err): - raw_bytes = (err.object[i] for i in range(err.start, err.end)) - if sys.version_info[0] == 2: - # Python 2 gave us characters - convert to numeric bytes - raw_bytes = (ord(b) for b in raw_bytes) - return u"".join(u"\\x%x" % c for c in raw_bytes), err.end - codecs.register_error( - "backslashreplace_decode", - backslashreplace_decode_fn, - ) - backslashreplace_decode = "backslashreplace_decode" - - -def console_to_str(data): - # type: (bytes) -> Text - """Return a string, safe for output, of subprocess output. - - We assume the data is in the locale preferred encoding. - If it won't decode properly, we warn the user but decode as - best we can. - - We also ensure that the output can be safely written to - standard output without encoding errors. - """ - - # First, get the encoding we assume. This is the preferred - # encoding for the locale, unless that is not found, or - # it is ASCII, in which case assume UTF-8 - encoding = locale.getpreferredencoding() - if (not encoding) or codecs.lookup(encoding).name == "ascii": - encoding = "utf-8" - - # Now try to decode the data - if we fail, warn the user and - # decode with replacement. - try: - decoded_data = data.decode(encoding) - except UnicodeDecodeError: - logger.warning( - "Subprocess output does not appear to be encoded as %s", - encoding, - ) - decoded_data = data.decode(encoding, errors=backslashreplace_decode) - - # Make sure we can print the output, by encoding it to the output - # encoding with replacement of unencodable characters, and then - # decoding again. - # We use stderr's encoding because it's less likely to be - # redirected and if we don't find an encoding we skip this - # step (on the assumption that output is wrapped by something - # that won't fail). - # The double getattr is to deal with the possibility that we're - # being called in a situation where sys.__stderr__ doesn't exist, - # or doesn't have an encoding attribute. Neither of these cases - # should occur in normal pip use, but there's no harm in checking - # in case people use pip in (unsupported) unusual situations. - output_encoding = getattr(getattr(sys, "__stderr__", None), - "encoding", None) - - if output_encoding: - output_encoded = decoded_data.encode( - output_encoding, - errors="backslashreplace" - ) - decoded_data = output_encoded.decode(output_encoding) - - return decoded_data - - -if sys.version_info >= (3,): - def native_str(s, replace=False): - # type: (str, bool) -> str - if isinstance(s, bytes): - return s.decode('utf-8', 'replace' if replace else 'strict') - return s - -else: - def native_str(s, replace=False): - # type: (str, bool) -> str - # Replace is ignored -- unicode to UTF-8 can't fail - if isinstance(s, text_type): - return s.encode('utf-8') - return s - - -def get_path_uid(path): - # type: (str) -> int - """ - Return path's uid. - - Does not follow symlinks: - https://github.com/pypa/pip/pull/935#discussion_r5307003 - - Placed this function in compat due to differences on AIX and - Jython, that should eventually go away. - - :raises OSError: When path is a symlink or can't be read. - """ - if hasattr(os, 'O_NOFOLLOW'): - fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) - file_uid = os.fstat(fd).st_uid - os.close(fd) - else: # AIX and Jython - # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW - if not os.path.islink(path): - # older versions of Jython don't have `os.fstat` - file_uid = os.stat(path).st_uid - else: - # raise OSError for parity with os.O_NOFOLLOW above - raise OSError( - "%s is a symlink; Will not return uid for symlinks" % path - ) - return file_uid - - -if sys.version_info >= (3, 4): - from importlib.machinery import EXTENSION_SUFFIXES - - def get_extension_suffixes(): - return EXTENSION_SUFFIXES -else: - from imp import get_suffixes - - def get_extension_suffixes(): - return [suffix[0] for suffix in get_suffixes()] - - -def expanduser(path): - # type: (str) -> str - """ - Expand ~ and ~user constructions. - - Includes a workaround for https://bugs.python.org/issue14768 - """ - expanded = os.path.expanduser(path) - if path.startswith('~/') and expanded.startswith('//'): - expanded = expanded[1:] - return expanded - - -# packages in the stdlib that may have installation metadata, but should not be -# considered 'installed'. this theoretically could be determined based on -# dist.location (py27:`sysconfig.get_paths()['stdlib']`, -# py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may -# make this ineffective, so hard-coding -stdlib_pkgs = {"python", "wsgiref", "argparse"} - - -# windows detection, covers cpython and ironpython -WINDOWS = (sys.platform.startswith("win") or - (sys.platform == 'cli' and os.name == 'nt')) - - -def samefile(file1, file2): - # type: (str, str) -> bool - """Provide an alternative for os.path.samefile on Windows/Python2""" - if hasattr(os.path, 'samefile'): - return os.path.samefile(file1, file2) - else: - path1 = os.path.normcase(os.path.abspath(file1)) - path2 = os.path.normcase(os.path.abspath(file2)) - return path1 == path2 - - -if hasattr(shutil, 'get_terminal_size'): - def get_terminal_size(): - # type: () -> Tuple[int, int] - """ - Returns a tuple (x, y) representing the width(x) and the height(y) - in characters of the terminal window. - """ - return tuple(shutil.get_terminal_size()) # type: ignore -else: - def get_terminal_size(): - # type: () -> Tuple[int, int] - """ - Returns a tuple (x, y) representing the width(x) and the height(y) - in characters of the terminal window. - """ - def ioctl_GWINSZ(fd): - try: - import fcntl - import termios - import struct - cr = struct.unpack_from( - 'hh', - fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') - ) - except Exception: - return None - if cr == (0, 0): - return None - return cr - cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) - if not cr: - try: - fd = os.open(os.ctermid(), os.O_RDONLY) - cr = ioctl_GWINSZ(fd) - os.close(fd) - except Exception: - pass - if not cr: - cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) - return int(cr[1]), int(cr[0]) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/deprecation.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/deprecation.py deleted file mode 100644 index 0beaf74..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/deprecation.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -A module that implements tooling to enable easy warnings about deprecations. -""" -from __future__ import absolute_import - -import logging -import warnings - -from pip._vendor.packaging.version import parse - -from pip import __version__ as current_version -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Optional # noqa: F401 - - -class PipDeprecationWarning(Warning): - pass - - -_original_showwarning = None # type: Any - - -# Warnings <-> Logging Integration -def _showwarning(message, category, filename, lineno, file=None, line=None): - if file is not None: - if _original_showwarning is not None: - _original_showwarning( - message, category, filename, lineno, file, line, - ) - elif issubclass(category, PipDeprecationWarning): - # We use a specially named logger which will handle all of the - # deprecation messages for pip. - logger = logging.getLogger("pip._internal.deprecations") - logger.warning(message) - else: - _original_showwarning( - message, category, filename, lineno, file, line, - ) - - -def install_warning_logger(): - # type: () -> None - # Enable our Deprecation Warnings - warnings.simplefilter("default", PipDeprecationWarning, append=True) - - global _original_showwarning - - if _original_showwarning is None: - _original_showwarning = warnings.showwarning - warnings.showwarning = _showwarning - - -def deprecated(reason, replacement, gone_in, issue=None): - # type: (str, Optional[str], Optional[str], Optional[int]) -> None - """Helper to deprecate existing functionality. - - reason: - Textual reason shown to the user about why this functionality has - been deprecated. - replacement: - Textual suggestion shown to the user about what alternative - functionality they can use. - gone_in: - The version of pip does this functionality should get removed in. - Raises errors if pip's current version is greater than or equal to - this. - issue: - Issue number on the tracker that would serve as a useful place for - users to find related discussion and provide feedback. - - Always pass replacement, gone_in and issue as keyword arguments for clarity - at the call site. - """ - - # Construct a nice message. - # This is purposely eagerly formatted as we want it to appear as if someone - # typed this entire message out. - message = "DEPRECATION: " + reason - if replacement is not None: - message += " A possible replacement is {}.".format(replacement) - if issue is not None: - url = "https://github.com/pypa/pip/issues/" + str(issue) - message += " You can find discussion regarding this at {}.".format(url) - - # Raise as an error if it has to be removed. - if gone_in is not None and parse(current_version) >= parse(gone_in): - raise PipDeprecationWarning(message) - warnings.warn(message, category=PipDeprecationWarning, stacklevel=2) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/encoding.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/encoding.py deleted file mode 100644 index d36defa..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/encoding.py +++ /dev/null @@ -1,39 +0,0 @@ -import codecs -import locale -import re -import sys - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Tuple, Text # noqa: F401 - -BOMS = [ - (codecs.BOM_UTF8, 'utf8'), - (codecs.BOM_UTF16, 'utf16'), - (codecs.BOM_UTF16_BE, 'utf16-be'), - (codecs.BOM_UTF16_LE, 'utf16-le'), - (codecs.BOM_UTF32, 'utf32'), - (codecs.BOM_UTF32_BE, 'utf32-be'), - (codecs.BOM_UTF32_LE, 'utf32-le'), -] # type: List[Tuple[bytes, Text]] - -ENCODING_RE = re.compile(br'coding[:=]\s*([-\w.]+)') - - -def auto_decode(data): - # type: (bytes) -> Text - """Check a bytes string for a BOM to correctly detect the encoding - - Fallback to locale.getpreferredencoding(False) like open() on Python3""" - for bom, encoding in BOMS: - if data.startswith(bom): - return data[len(bom):].decode(encoding) - # Lets check the first two lines as in PEP263 - for line in data.split(b'\n')[:2]: - if line[0:1] == b'#' and ENCODING_RE.search(line): - encoding = ENCODING_RE.search(line).groups()[0].decode('ascii') - return data.decode(encoding) - return data.decode( - locale.getpreferredencoding(False) or sys.getdefaultencoding(), - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/filesystem.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/filesystem.py deleted file mode 100644 index 1e6b033..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/filesystem.py +++ /dev/null @@ -1,30 +0,0 @@ -import os -import os.path - -from pip._internal.utils.compat import get_path_uid - - -def check_path_owner(path): - # type: (str) -> bool - # If we don't have a way to check the effective uid of this process, then - # we'll just assume that we own the directory. - if not hasattr(os, "geteuid"): - return True - - previous = None - while path != previous: - if os.path.lexists(path): - # Check if path is writable by current user. - if os.geteuid() == 0: - # Special handling for root user in order to handle properly - # cases where users use sudo without -H flag. - try: - path_uid = get_path_uid(path) - except OSError: - return False - return path_uid == 0 - else: - return os.access(path, os.W_OK) - else: - previous, path = path, os.path.dirname(path) - return False # assume we don't own the path diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/glibc.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/glibc.py deleted file mode 100644 index 8a51f69..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/glibc.py +++ /dev/null @@ -1,93 +0,0 @@ -from __future__ import absolute_import - -import ctypes -import re -import warnings - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Tuple # noqa: F401 - - -def glibc_version_string(): - # type: () -> Optional[str] - "Returns glibc version string, or None if not using glibc." - - # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen - # manpage says, "If filename is NULL, then the returned handle is for the - # main program". This way we can let the linker do the work to figure out - # which libc our process is actually using. - process_namespace = ctypes.CDLL(None) - try: - gnu_get_libc_version = process_namespace.gnu_get_libc_version - except AttributeError: - # Symbol doesn't exist -> therefore, we are not linked to - # glibc. - return None - - # Call gnu_get_libc_version, which returns a string like "2.5" - gnu_get_libc_version.restype = ctypes.c_char_p - version_str = gnu_get_libc_version() - # py2 / py3 compatibility: - if not isinstance(version_str, str): - version_str = version_str.decode("ascii") - - return version_str - - -# Separated out from have_compatible_glibc for easier unit testing -def check_glibc_version(version_str, required_major, minimum_minor): - # type: (str, int, int) -> bool - # Parse string and check against requested version. - # - # We use a regexp instead of str.split because we want to discard any - # random junk that might come after the minor version -- this might happen - # in patched/forked versions of glibc (e.g. Linaro's version of glibc - # uses version strings like "2.20-2014.11"). See gh-3588. - m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) - if not m: - warnings.warn("Expected glibc version with 2 components major.minor," - " got: %s" % version_str, RuntimeWarning) - return False - return (int(m.group("major")) == required_major and - int(m.group("minor")) >= minimum_minor) - - -def have_compatible_glibc(required_major, minimum_minor): - # type: (int, int) -> bool - version_str = glibc_version_string() # type: Optional[str] - if version_str is None: - return False - return check_glibc_version(version_str, required_major, minimum_minor) - - -# platform.libc_ver regularly returns completely nonsensical glibc -# versions. E.g. on my computer, platform says: -# -# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' -# ('glibc', '2.7') -# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' -# ('glibc', '2.9') -# -# But the truth is: -# -# ~$ ldd --version -# ldd (Debian GLIBC 2.22-11) 2.22 -# -# This is unfortunate, because it means that the linehaul data on libc -# versions that was generated by pip 8.1.2 and earlier is useless and -# misleading. Solution: instead of using platform, use our code that actually -# works. -def libc_ver(): - # type: () -> Tuple[str, str] - """Try to determine the glibc version - - Returns a tuple of strings (lib, version) which default to empty strings - in case the lookup fails. - """ - glibc_version = glibc_version_string() - if glibc_version is None: - return ("", "") - else: - return ("glibc", glibc_version) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/hashes.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/hashes.py deleted file mode 100644 index c6df7a1..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/hashes.py +++ /dev/null @@ -1,115 +0,0 @@ -from __future__ import absolute_import - -import hashlib - -from pip._vendor.six import iteritems, iterkeys, itervalues - -from pip._internal.exceptions import ( - HashMismatch, HashMissing, InstallationError, -) -from pip._internal.utils.misc import read_chunks -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Dict, List, BinaryIO, NoReturn, Iterator - ) - from pip._vendor.six import PY3 - if PY3: - from hashlib import _Hash # noqa: F401 - else: - from hashlib import _hash as _Hash # noqa: F401 - - -# The recommended hash algo of the moment. Change this whenever the state of -# the art changes; it won't hurt backward compatibility. -FAVORITE_HASH = 'sha256' - - -# Names of hashlib algorithms allowed by the --hash option and ``pip hash`` -# Currently, those are the ones at least as collision-resistant as sha256. -STRONG_HASHES = ['sha256', 'sha384', 'sha512'] - - -class Hashes(object): - """A wrapper that builds multiple hashes at once and checks them against - known-good values - - """ - def __init__(self, hashes=None): - # type: (Dict[str, List[str]]) -> None - """ - :param hashes: A dict of algorithm names pointing to lists of allowed - hex digests - """ - self._allowed = {} if hashes is None else hashes - - def check_against_chunks(self, chunks): - # type: (Iterator[bytes]) -> None - """Check good hashes against ones built from iterable of chunks of - data. - - Raise HashMismatch if none match. - - """ - gots = {} - for hash_name in iterkeys(self._allowed): - try: - gots[hash_name] = hashlib.new(hash_name) - except (ValueError, TypeError): - raise InstallationError('Unknown hash name: %s' % hash_name) - - for chunk in chunks: - for hash in itervalues(gots): - hash.update(chunk) - - for hash_name, got in iteritems(gots): - if got.hexdigest() in self._allowed[hash_name]: - return - self._raise(gots) - - def _raise(self, gots): - # type: (Dict[str, _Hash]) -> NoReturn - raise HashMismatch(self._allowed, gots) - - def check_against_file(self, file): - # type: (BinaryIO) -> None - """Check good hashes against a file-like object - - Raise HashMismatch if none match. - - """ - return self.check_against_chunks(read_chunks(file)) - - def check_against_path(self, path): - # type: (str) -> None - with open(path, 'rb') as file: - return self.check_against_file(file) - - def __nonzero__(self): - # type: () -> bool - """Return whether I know any known-good hashes.""" - return bool(self._allowed) - - def __bool__(self): - # type: () -> bool - return self.__nonzero__() - - -class MissingHashes(Hashes): - """A workalike for Hashes used when we're missing a hash for a requirement - - It computes the actual hash of the requirement and raises a HashMissing - exception showing it to the user. - - """ - def __init__(self): - # type: () -> None - """Don't offer the ``hashes`` kwarg.""" - # Pass our favorite hash in to generate a "gotten hash". With the - # empty list, it will never match, so an error will always raise. - super(MissingHashes, self).__init__(hashes={FAVORITE_HASH: []}) - - def _raise(self, gots): - # type: (Dict[str, _Hash]) -> NoReturn - raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/logging.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/logging.py deleted file mode 100644 index 579d696..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/logging.py +++ /dev/null @@ -1,318 +0,0 @@ -from __future__ import absolute_import - -import contextlib -import errno -import logging -import logging.handlers -import os -import sys - -from pip._vendor.six import PY2 - -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.misc import ensure_dir - -try: - import threading -except ImportError: - import dummy_threading as threading # type: ignore - - -try: - from pip._vendor import colorama -# Lots of different errors can come from this, including SystemError and -# ImportError. -except Exception: - colorama = None - - -_log_state = threading.local() -_log_state.indentation = 0 - - -class BrokenStdoutLoggingError(Exception): - """ - Raised if BrokenPipeError occurs for the stdout stream while logging. - """ - pass - - -# BrokenPipeError does not exist in Python 2 and, in addition, manifests -# differently in Windows and non-Windows. -if WINDOWS: - # In Windows, a broken pipe can show up as EINVAL rather than EPIPE: - # https://bugs.python.org/issue19612 - # https://bugs.python.org/issue30418 - if PY2: - def _is_broken_pipe_error(exc_class, exc): - """See the docstring for non-Windows Python 3 below.""" - return (exc_class is IOError and - exc.errno in (errno.EINVAL, errno.EPIPE)) - else: - # In Windows, a broken pipe IOError became OSError in Python 3. - def _is_broken_pipe_error(exc_class, exc): - """See the docstring for non-Windows Python 3 below.""" - return ((exc_class is BrokenPipeError) or # noqa: F821 - (exc_class is OSError and - exc.errno in (errno.EINVAL, errno.EPIPE))) -elif PY2: - def _is_broken_pipe_error(exc_class, exc): - """See the docstring for non-Windows Python 3 below.""" - return (exc_class is IOError and exc.errno == errno.EPIPE) -else: - # Then we are in the non-Windows Python 3 case. - def _is_broken_pipe_error(exc_class, exc): - """ - Return whether an exception is a broken pipe error. - - Args: - exc_class: an exception class. - exc: an exception instance. - """ - return (exc_class is BrokenPipeError) # noqa: F821 - - -@contextlib.contextmanager -def indent_log(num=2): - """ - A context manager which will cause the log output to be indented for any - log messages emitted inside it. - """ - _log_state.indentation += num - try: - yield - finally: - _log_state.indentation -= num - - -def get_indentation(): - return getattr(_log_state, 'indentation', 0) - - -class IndentingFormatter(logging.Formatter): - def __init__(self, *args, **kwargs): - """ - A logging.Formatter obeying containing indent_log contexts. - - :param add_timestamp: A bool indicating output lines should be prefixed - with their record's timestamp. - """ - self.add_timestamp = kwargs.pop("add_timestamp", False) - super(IndentingFormatter, self).__init__(*args, **kwargs) - - def format(self, record): - """ - Calls the standard formatter, but will indent all of the log messages - by our current indentation level. - """ - formatted = super(IndentingFormatter, self).format(record) - prefix = '' - if self.add_timestamp: - prefix = self.formatTime(record, "%Y-%m-%dT%H:%M:%S ") - prefix += " " * get_indentation() - formatted = "".join([ - prefix + line - for line in formatted.splitlines(True) - ]) - return formatted - - -def _color_wrap(*colors): - def wrapped(inp): - return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) - return wrapped - - -class ColorizedStreamHandler(logging.StreamHandler): - - # Don't build up a list of colors if we don't have colorama - if colorama: - COLORS = [ - # This needs to be in order from highest logging level to lowest. - (logging.ERROR, _color_wrap(colorama.Fore.RED)), - (logging.WARNING, _color_wrap(colorama.Fore.YELLOW)), - ] - else: - COLORS = [] - - def __init__(self, stream=None, no_color=None): - logging.StreamHandler.__init__(self, stream) - self._no_color = no_color - - if WINDOWS and colorama: - self.stream = colorama.AnsiToWin32(self.stream) - - def _using_stdout(self): - """ - Return whether the handler is using sys.stdout. - """ - if WINDOWS and colorama: - # Then self.stream is an AnsiToWin32 object. - return self.stream.wrapped is sys.stdout - - return self.stream is sys.stdout - - def should_color(self): - # Don't colorize things if we do not have colorama or if told not to - if not colorama or self._no_color: - return False - - real_stream = ( - self.stream if not isinstance(self.stream, colorama.AnsiToWin32) - else self.stream.wrapped - ) - - # If the stream is a tty we should color it - if hasattr(real_stream, "isatty") and real_stream.isatty(): - return True - - # If we have an ANSI term we should color it - if os.environ.get("TERM") == "ANSI": - return True - - # If anything else we should not color it - return False - - def format(self, record): - msg = logging.StreamHandler.format(self, record) - - if self.should_color(): - for level, color in self.COLORS: - if record.levelno >= level: - msg = color(msg) - break - - return msg - - # The logging module says handleError() can be customized. - def handleError(self, record): - exc_class, exc = sys.exc_info()[:2] - # If a broken pipe occurred while calling write() or flush() on the - # stdout stream in logging's Handler.emit(), then raise our special - # exception so we can handle it in main() instead of logging the - # broken pipe error and continuing. - if (exc_class and self._using_stdout() and - _is_broken_pipe_error(exc_class, exc)): - raise BrokenStdoutLoggingError() - - return super(ColorizedStreamHandler, self).handleError(record) - - -class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): - - def _open(self): - ensure_dir(os.path.dirname(self.baseFilename)) - return logging.handlers.RotatingFileHandler._open(self) - - -class MaxLevelFilter(logging.Filter): - - def __init__(self, level): - self.level = level - - def filter(self, record): - return record.levelno < self.level - - -def setup_logging(verbosity, no_color, user_log_file): - """Configures and sets up all of the logging - - Returns the requested logging level, as its integer value. - """ - - # Determine the level to be logging at. - if verbosity >= 1: - level = "DEBUG" - elif verbosity == -1: - level = "WARNING" - elif verbosity == -2: - level = "ERROR" - elif verbosity <= -3: - level = "CRITICAL" - else: - level = "INFO" - - level_number = getattr(logging, level) - - # The "root" logger should match the "console" level *unless* we also need - # to log to a user log file. - include_user_log = user_log_file is not None - if include_user_log: - additional_log_file = user_log_file - root_level = "DEBUG" - else: - additional_log_file = "/dev/null" - root_level = level - - # Disable any logging besides WARNING unless we have DEBUG level logging - # enabled for vendored libraries. - vendored_log_level = "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" - - # Shorthands for clarity - log_streams = { - "stdout": "ext://sys.stdout", - "stderr": "ext://sys.stderr", - } - handler_classes = { - "stream": "pip._internal.utils.logging.ColorizedStreamHandler", - "file": "pip._internal.utils.logging.BetterRotatingFileHandler", - } - - logging.config.dictConfig({ - "version": 1, - "disable_existing_loggers": False, - "filters": { - "exclude_warnings": { - "()": "pip._internal.utils.logging.MaxLevelFilter", - "level": logging.WARNING, - }, - }, - "formatters": { - "indent": { - "()": IndentingFormatter, - "format": "%(message)s", - }, - "indent_with_timestamp": { - "()": IndentingFormatter, - "format": "%(message)s", - "add_timestamp": True, - }, - }, - "handlers": { - "console": { - "level": level, - "class": handler_classes["stream"], - "no_color": no_color, - "stream": log_streams["stdout"], - "filters": ["exclude_warnings"], - "formatter": "indent", - }, - "console_errors": { - "level": "WARNING", - "class": handler_classes["stream"], - "no_color": no_color, - "stream": log_streams["stderr"], - "formatter": "indent", - }, - "user_log": { - "level": "DEBUG", - "class": handler_classes["file"], - "filename": additional_log_file, - "delay": True, - "formatter": "indent_with_timestamp", - }, - }, - "root": { - "level": root_level, - "handlers": ["console", "console_errors"] + ( - ["user_log"] if include_user_log else [] - ), - }, - "loggers": { - "pip._vendor": { - "level": vendored_log_level - } - }, - }) - - return level_number diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/misc.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/misc.py deleted file mode 100644 index 84605ee..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/misc.py +++ /dev/null @@ -1,1040 +0,0 @@ -from __future__ import absolute_import - -import contextlib -import errno -import io -import locale -# we have a submodule named 'logging' which would shadow this if we used the -# regular name: -import logging as std_logging -import os -import posixpath -import re -import shutil -import stat -import subprocess -import sys -import tarfile -import zipfile -from collections import deque - -from pip._vendor import pkg_resources -# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is -# why we ignore the type on this import. -from pip._vendor.retrying import retry # type: ignore -from pip._vendor.six import PY2 -from pip._vendor.six.moves import input -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote - -from pip._internal.exceptions import CommandError, InstallationError -from pip._internal.locations import ( - running_under_virtualenv, site_packages, user_site, virtualenv_no_global, - write_delete_marker_file, -) -from pip._internal.utils.compat import ( - WINDOWS, console_to_str, expanduser, stdlib_pkgs, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if PY2: - from io import BytesIO as StringIO -else: - from io import StringIO - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Optional, Tuple, Iterable, List, Match, Union, Any, Mapping, Text, - AnyStr, Container - ) - from pip._vendor.pkg_resources import Distribution # noqa: F401 - from pip._internal.models.link import Link # noqa: F401 - from pip._internal.utils.ui import SpinnerInterface # noqa: F401 - - -__all__ = ['rmtree', 'display_path', 'backup_dir', - 'ask', 'splitext', - 'format_size', 'is_installable_dir', - 'is_svn_page', 'file_contents', - 'split_leading_dir', 'has_leading_dir', - 'normalize_path', - 'renames', 'get_prog', - 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', - 'captured_stdout', 'ensure_dir', - 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', 'WHEEL_EXTENSION', - 'get_installed_version', 'remove_auth_from_url'] - - -logger = std_logging.getLogger(__name__) - -WHEEL_EXTENSION = '.whl' -BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') -XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') -ZIP_EXTENSIONS = ('.zip', WHEEL_EXTENSION) -TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') -ARCHIVE_EXTENSIONS = ( - ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) -SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS - -try: - import bz2 # noqa - SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS -except ImportError: - logger.debug('bz2 module is not available') - -try: - # Only for Python 3.3+ - import lzma # noqa - SUPPORTED_EXTENSIONS += XZ_EXTENSIONS -except ImportError: - logger.debug('lzma module is not available') - - -def ensure_dir(path): - # type: (AnyStr) -> None - """os.path.makedirs without EEXIST.""" - try: - os.makedirs(path) - except OSError as e: - if e.errno != errno.EEXIST: - raise - - -def get_prog(): - # type: () -> str - try: - prog = os.path.basename(sys.argv[0]) - if prog in ('__main__.py', '-c'): - return "%s -m pip" % sys.executable - else: - return prog - except (AttributeError, TypeError, IndexError): - pass - return 'pip' - - -# Retry every half second for up to 3 seconds -@retry(stop_max_delay=3000, wait_fixed=500) -def rmtree(dir, ignore_errors=False): - # type: (str, bool) -> None - shutil.rmtree(dir, ignore_errors=ignore_errors, - onerror=rmtree_errorhandler) - - -def rmtree_errorhandler(func, path, exc_info): - """On Windows, the files in .svn are read-only, so when rmtree() tries to - remove them, an exception is thrown. We catch that here, remove the - read-only attribute, and hopefully continue without problems.""" - # if file type currently read only - if os.stat(path).st_mode & stat.S_IREAD: - # convert to read/write - os.chmod(path, stat.S_IWRITE) - # use the original function to repeat the operation - func(path) - return - else: - raise - - -def display_path(path): - # type: (Union[str, Text]) -> str - """Gives the display value for a given path, making it relative to cwd - if possible.""" - path = os.path.normcase(os.path.abspath(path)) - if sys.version_info[0] == 2: - path = path.decode(sys.getfilesystemencoding(), 'replace') - path = path.encode(sys.getdefaultencoding(), 'replace') - if path.startswith(os.getcwd() + os.path.sep): - path = '.' + path[len(os.getcwd()):] - return path - - -def backup_dir(dir, ext='.bak'): - # type: (str, str) -> str - """Figure out the name of a directory to back up the given dir to - (adding .bak, .bak2, etc)""" - n = 1 - extension = ext - while os.path.exists(dir + extension): - n += 1 - extension = ext + str(n) - return dir + extension - - -def ask_path_exists(message, options): - # type: (str, Iterable[str]) -> str - for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): - if action in options: - return action - return ask(message, options) - - -def ask(message, options): - # type: (str, Iterable[str]) -> str - """Ask the message interactively, with the given possible responses""" - while 1: - if os.environ.get('PIP_NO_INPUT'): - raise Exception( - 'No input was expected ($PIP_NO_INPUT set); question: %s' % - message - ) - response = input(message) - response = response.strip().lower() - if response not in options: - print( - 'Your response (%r) was not one of the expected responses: ' - '%s' % (response, ', '.join(options)) - ) - else: - return response - - -def format_size(bytes): - # type: (float) -> str - if bytes > 1000 * 1000: - return '%.1fMB' % (bytes / 1000.0 / 1000) - elif bytes > 10 * 1000: - return '%ikB' % (bytes / 1000) - elif bytes > 1000: - return '%.1fkB' % (bytes / 1000.0) - else: - return '%ibytes' % bytes - - -def is_installable_dir(path): - # type: (str) -> bool - """Is path is a directory containing setup.py or pyproject.toml? - """ - if not os.path.isdir(path): - return False - setup_py = os.path.join(path, 'setup.py') - if os.path.isfile(setup_py): - return True - pyproject_toml = os.path.join(path, 'pyproject.toml') - if os.path.isfile(pyproject_toml): - return True - return False - - -def is_svn_page(html): - # type: (Union[str, Text]) -> Optional[Match[Union[str, Text]]] - """ - Returns true if the page appears to be the index page of an svn repository - """ - return (re.search(r'[^<]*Revision \d+:', html) and - re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) - - -def file_contents(filename): - # type: (str) -> Text - with open(filename, 'rb') as fp: - return fp.read().decode('utf-8') - - -def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): - """Yield pieces of data from a file-like object until EOF.""" - while True: - chunk = file.read(size) - if not chunk: - break - yield chunk - - -def split_leading_dir(path): - # type: (Union[str, Text]) -> List[Union[str, Text]] - path = path.lstrip('/').lstrip('\\') - if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or - '\\' not in path): - return path.split('/', 1) - elif '\\' in path: - return path.split('\\', 1) - else: - return [path, ''] - - -def has_leading_dir(paths): - # type: (Iterable[Union[str, Text]]) -> bool - """Returns true if all the paths have the same leading path name - (i.e., everything is in one subdirectory in an archive)""" - common_prefix = None - for path in paths: - prefix, rest = split_leading_dir(path) - if not prefix: - return False - elif common_prefix is None: - common_prefix = prefix - elif prefix != common_prefix: - return False - return True - - -def normalize_path(path, resolve_symlinks=True): - # type: (str, bool) -> str - """ - Convert a path to its canonical, case-normalized, absolute version. - - """ - path = expanduser(path) - if resolve_symlinks: - path = os.path.realpath(path) - else: - path = os.path.abspath(path) - return os.path.normcase(path) - - -def splitext(path): - # type: (str) -> Tuple[str, str] - """Like os.path.splitext, but take off .tar too""" - base, ext = posixpath.splitext(path) - if base.lower().endswith('.tar'): - ext = base[-4:] + ext - base = base[:-4] - return base, ext - - -def renames(old, new): - # type: (str, str) -> None - """Like os.renames(), but handles renaming across devices.""" - # Implementation borrowed from os.renames(). - head, tail = os.path.split(new) - if head and tail and not os.path.exists(head): - os.makedirs(head) - - shutil.move(old, new) - - head, tail = os.path.split(old) - if head and tail: - try: - os.removedirs(head) - except OSError: - pass - - -def is_local(path): - # type: (str) -> bool - """ - Return True if path is within sys.prefix, if we're running in a virtualenv. - - If we're not in a virtualenv, all paths are considered "local." - - """ - if not running_under_virtualenv(): - return True - return normalize_path(path).startswith(normalize_path(sys.prefix)) - - -def dist_is_local(dist): - # type: (Distribution) -> bool - """ - Return True if given Distribution object is installed locally - (i.e. within current virtualenv). - - Always True if we're not in a virtualenv. - - """ - return is_local(dist_location(dist)) - - -def dist_in_usersite(dist): - # type: (Distribution) -> bool - """ - Return True if given Distribution is installed in user site. - """ - norm_path = normalize_path(dist_location(dist)) - return norm_path.startswith(normalize_path(user_site)) - - -def dist_in_site_packages(dist): - # type: (Distribution) -> bool - """ - Return True if given Distribution is installed in - sysconfig.get_python_lib(). - """ - return normalize_path( - dist_location(dist) - ).startswith(normalize_path(site_packages)) - - -def dist_is_editable(dist): - # type: (Distribution) -> bool - """ - Return True if given Distribution is an editable install. - """ - for path_item in sys.path: - egg_link = os.path.join(path_item, dist.project_name + '.egg-link') - if os.path.isfile(egg_link): - return True - return False - - -def get_installed_distributions(local_only=True, - skip=stdlib_pkgs, - include_editables=True, - editables_only=False, - user_only=False): - # type: (bool, Container[str], bool, bool, bool) -> List[Distribution] - """ - Return a list of installed Distribution objects. - - If ``local_only`` is True (default), only return installations - local to the current virtualenv, if in a virtualenv. - - ``skip`` argument is an iterable of lower-case project names to - ignore; defaults to stdlib_pkgs - - If ``include_editables`` is False, don't report editables. - - If ``editables_only`` is True , only report editables. - - If ``user_only`` is True , only report installations in the user - site directory. - - """ - if local_only: - local_test = dist_is_local - else: - def local_test(d): - return True - - if include_editables: - def editable_test(d): - return True - else: - def editable_test(d): - return not dist_is_editable(d) - - if editables_only: - def editables_only_test(d): - return dist_is_editable(d) - else: - def editables_only_test(d): - return True - - if user_only: - user_test = dist_in_usersite - else: - def user_test(d): - return True - - # because of pkg_resources vendoring, mypy cannot find stub in typeshed - return [d for d in pkg_resources.working_set # type: ignore - if local_test(d) and - d.key not in skip and - editable_test(d) and - editables_only_test(d) and - user_test(d) - ] - - -def egg_link_path(dist): - # type: (Distribution) -> Optional[str] - """ - Return the path for the .egg-link file if it exists, otherwise, None. - - There's 3 scenarios: - 1) not in a virtualenv - try to find in site.USER_SITE, then site_packages - 2) in a no-global virtualenv - try to find in site_packages - 3) in a yes-global virtualenv - try to find in site_packages, then site.USER_SITE - (don't look in global location) - - For #1 and #3, there could be odd cases, where there's an egg-link in 2 - locations. - - This method will just return the first one found. - """ - sites = [] - if running_under_virtualenv(): - if virtualenv_no_global(): - sites.append(site_packages) - else: - sites.append(site_packages) - if user_site: - sites.append(user_site) - else: - if user_site: - sites.append(user_site) - sites.append(site_packages) - - for site in sites: - egglink = os.path.join(site, dist.project_name) + '.egg-link' - if os.path.isfile(egglink): - return egglink - return None - - -def dist_location(dist): - # type: (Distribution) -> str - """ - Get the site-packages location of this distribution. Generally - this is dist.location, except in the case of develop-installed - packages, where dist.location is the source code location, and we - want to know where the egg-link file is. - - """ - egg_link = egg_link_path(dist) - if egg_link: - return egg_link - return dist.location - - -def current_umask(): - """Get the current umask which involves having to set it temporarily.""" - mask = os.umask(0) - os.umask(mask) - return mask - - -def unzip_file(filename, location, flatten=True): - # type: (str, str, bool) -> None - """ - Unzip the file (with path `filename`) to the destination `location`. All - files are written based on system defaults and umask (i.e. permissions are - not preserved), except that regular file members with any execute - permissions (user, group, or world) have "chmod +x" applied after being - written. Note that for windows, any execute changes using os.chmod are - no-ops per the python docs. - """ - ensure_dir(location) - zipfp = open(filename, 'rb') - try: - zip = zipfile.ZipFile(zipfp, allowZip64=True) - leading = has_leading_dir(zip.namelist()) and flatten - for info in zip.infolist(): - name = info.filename - fn = name - if leading: - fn = split_leading_dir(name)[1] - fn = os.path.join(location, fn) - dir = os.path.dirname(fn) - if fn.endswith('/') or fn.endswith('\\'): - # A directory - ensure_dir(fn) - else: - ensure_dir(dir) - # Don't use read() to avoid allocating an arbitrarily large - # chunk of memory for the file's content - fp = zip.open(name) - try: - with open(fn, 'wb') as destfp: - shutil.copyfileobj(fp, destfp) - finally: - fp.close() - mode = info.external_attr >> 16 - # if mode and regular file and any execute permissions for - # user/group/world? - if mode and stat.S_ISREG(mode) and mode & 0o111: - # make dest file have execute for user/group/world - # (chmod +x) no-op on windows per python docs - os.chmod(fn, (0o777 - current_umask() | 0o111)) - finally: - zipfp.close() - - -def untar_file(filename, location): - # type: (str, str) -> None - """ - Untar the file (with path `filename`) to the destination `location`. - All files are written based on system defaults and umask (i.e. permissions - are not preserved), except that regular file members with any execute - permissions (user, group, or world) have "chmod +x" applied after being - written. Note that for windows, any execute changes using os.chmod are - no-ops per the python docs. - """ - ensure_dir(location) - if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): - mode = 'r:gz' - elif filename.lower().endswith(BZ2_EXTENSIONS): - mode = 'r:bz2' - elif filename.lower().endswith(XZ_EXTENSIONS): - mode = 'r:xz' - elif filename.lower().endswith('.tar'): - mode = 'r' - else: - logger.warning( - 'Cannot determine compression type for file %s', filename, - ) - mode = 'r:*' - tar = tarfile.open(filename, mode) - try: - leading = has_leading_dir([ - member.name for member in tar.getmembers() - ]) - for member in tar.getmembers(): - fn = member.name - if leading: - # https://github.com/python/mypy/issues/1174 - fn = split_leading_dir(fn)[1] # type: ignore - path = os.path.join(location, fn) - if member.isdir(): - ensure_dir(path) - elif member.issym(): - try: - # https://github.com/python/typeshed/issues/2673 - tar._extract_member(member, path) # type: ignore - except Exception as exc: - # Some corrupt tar files seem to produce this - # (specifically bad symlinks) - logger.warning( - 'In the tar file %s the member %s is invalid: %s', - filename, member.name, exc, - ) - continue - else: - try: - fp = tar.extractfile(member) - except (KeyError, AttributeError) as exc: - # Some corrupt tar files seem to produce this - # (specifically bad symlinks) - logger.warning( - 'In the tar file %s the member %s is invalid: %s', - filename, member.name, exc, - ) - continue - ensure_dir(os.path.dirname(path)) - with open(path, 'wb') as destfp: - shutil.copyfileobj(fp, destfp) - fp.close() - # Update the timestamp (useful for cython compiled files) - # https://github.com/python/typeshed/issues/2673 - tar.utime(member, path) # type: ignore - # member have any execute permissions for user/group/world? - if member.mode & 0o111: - # make dest file have execute for user/group/world - # no-op on windows per python docs - os.chmod(path, (0o777 - current_umask() | 0o111)) - finally: - tar.close() - - -def unpack_file( - filename, # type: str - location, # type: str - content_type, # type: Optional[str] - link # type: Optional[Link] -): - # type: (...) -> None - filename = os.path.realpath(filename) - if (content_type == 'application/zip' or - filename.lower().endswith(ZIP_EXTENSIONS) or - zipfile.is_zipfile(filename)): - unzip_file( - filename, - location, - flatten=not filename.endswith('.whl') - ) - elif (content_type == 'application/x-gzip' or - tarfile.is_tarfile(filename) or - filename.lower().endswith( - TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): - untar_file(filename, location) - elif (content_type and content_type.startswith('text/html') and - is_svn_page(file_contents(filename))): - # We don't really care about this - from pip._internal.vcs.subversion import Subversion - Subversion('svn+' + link.url).unpack(location) - else: - # FIXME: handle? - # FIXME: magic signatures? - logger.critical( - 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' - 'cannot detect archive format', - filename, location, content_type, - ) - raise InstallationError( - 'Cannot determine archive format of %s' % location - ) - - -def call_subprocess( - cmd, # type: List[str] - show_stdout=True, # type: bool - cwd=None, # type: Optional[str] - on_returncode='raise', # type: str - extra_ok_returncodes=None, # type: Optional[Iterable[int]] - command_desc=None, # type: Optional[str] - extra_environ=None, # type: Optional[Mapping[str, Any]] - unset_environ=None, # type: Optional[Iterable[str]] - spinner=None # type: Optional[SpinnerInterface] -): - # type: (...) -> Optional[Text] - """ - Args: - extra_ok_returncodes: an iterable of integer return codes that are - acceptable, in addition to 0. Defaults to None, which means []. - unset_environ: an iterable of environment variable names to unset - prior to calling subprocess.Popen(). - """ - if extra_ok_returncodes is None: - extra_ok_returncodes = [] - if unset_environ is None: - unset_environ = [] - # This function's handling of subprocess output is confusing and I - # previously broke it terribly, so as penance I will write a long comment - # explaining things. - # - # The obvious thing that affects output is the show_stdout= - # kwarg. show_stdout=True means, let the subprocess write directly to our - # stdout. Even though it is nominally the default, it is almost never used - # inside pip (and should not be used in new code without a very good - # reason); as of 2016-02-22 it is only used in a few places inside the VCS - # wrapper code. Ideally we should get rid of it entirely, because it - # creates a lot of complexity here for a rarely used feature. - # - # Most places in pip set show_stdout=False. What this means is: - # - We connect the child stdout to a pipe, which we read. - # - By default, we hide the output but show a spinner -- unless the - # subprocess exits with an error, in which case we show the output. - # - If the --verbose option was passed (= loglevel is DEBUG), then we show - # the output unconditionally. (But in this case we don't want to show - # the output a second time if it turns out that there was an error.) - # - # stderr is always merged with stdout (even if show_stdout=True). - if show_stdout: - stdout = None - else: - stdout = subprocess.PIPE - if command_desc is None: - cmd_parts = [] - for part in cmd: - if ' ' in part or '\n' in part or '"' in part or "'" in part: - part = '"%s"' % part.replace('"', '\\"') - cmd_parts.append(part) - command_desc = ' '.join(cmd_parts) - logger.debug("Running command %s", command_desc) - env = os.environ.copy() - if extra_environ: - env.update(extra_environ) - for name in unset_environ: - env.pop(name, None) - try: - proc = subprocess.Popen( - cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, - stdout=stdout, cwd=cwd, env=env, - ) - proc.stdin.close() - except Exception as exc: - logger.critical( - "Error %s while executing command %s", exc, command_desc, - ) - raise - all_output = [] - if stdout is not None: - while True: - line = console_to_str(proc.stdout.readline()) - if not line: - break - line = line.rstrip() - all_output.append(line + '\n') - if logger.getEffectiveLevel() <= std_logging.DEBUG: - # Show the line immediately - logger.debug(line) - else: - # Update the spinner - if spinner is not None: - spinner.spin() - try: - proc.wait() - finally: - if proc.stdout: - proc.stdout.close() - if spinner is not None: - if proc.returncode: - spinner.finish("error") - else: - spinner.finish("done") - if proc.returncode and proc.returncode not in extra_ok_returncodes: - if on_returncode == 'raise': - if (logger.getEffectiveLevel() > std_logging.DEBUG and - not show_stdout): - logger.info( - 'Complete output from command %s:', command_desc, - ) - logger.info( - ''.join(all_output) + - '\n----------------------------------------' - ) - raise InstallationError( - 'Command "%s" failed with error code %s in %s' - % (command_desc, proc.returncode, cwd)) - elif on_returncode == 'warn': - logger.warning( - 'Command "%s" had error code %s in %s', - command_desc, proc.returncode, cwd, - ) - elif on_returncode == 'ignore': - pass - else: - raise ValueError('Invalid value: on_returncode=%s' % - repr(on_returncode)) - if not show_stdout: - return ''.join(all_output) - return None - - -def read_text_file(filename): - # type: (str) -> str - """Return the contents of *filename*. - - Try to decode the file contents with utf-8, the preferred system encoding - (e.g., cp1252 on some Windows machines), and latin1, in that order. - Decoding a byte string with latin1 will never raise an error. In the worst - case, the returned string will contain some garbage characters. - - """ - with open(filename, 'rb') as fp: - data = fp.read() - - encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1'] - for enc in encodings: - try: - # https://github.com/python/mypy/issues/1174 - data = data.decode(enc) # type: ignore - except UnicodeDecodeError: - continue - break - - assert not isinstance(data, bytes) # Latin1 should have worked. - return data - - -def _make_build_dir(build_dir): - os.makedirs(build_dir) - write_delete_marker_file(build_dir) - - -class FakeFile(object): - """Wrap a list of lines in an object with readline() to make - ConfigParser happy.""" - def __init__(self, lines): - self._gen = (l for l in lines) - - def readline(self): - try: - try: - return next(self._gen) - except NameError: - return self._gen.next() - except StopIteration: - return '' - - def __iter__(self): - return self._gen - - -class StreamWrapper(StringIO): - - @classmethod - def from_stream(cls, orig_stream): - cls.orig_stream = orig_stream - return cls() - - # compileall.compile_dir() needs stdout.encoding to print to stdout - @property - def encoding(self): - return self.orig_stream.encoding - - -@contextlib.contextmanager -def captured_output(stream_name): - """Return a context manager used by captured_stdout/stdin/stderr - that temporarily replaces the sys stream *stream_name* with a StringIO. - - Taken from Lib/support/__init__.py in the CPython repo. - """ - orig_stdout = getattr(sys, stream_name) - setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) - try: - yield getattr(sys, stream_name) - finally: - setattr(sys, stream_name, orig_stdout) - - -def captured_stdout(): - """Capture the output of sys.stdout: - - with captured_stdout() as stdout: - print('hello') - self.assertEqual(stdout.getvalue(), 'hello\n') - - Taken from Lib/support/__init__.py in the CPython repo. - """ - return captured_output('stdout') - - -def captured_stderr(): - """ - See captured_stdout(). - """ - return captured_output('stderr') - - -class cached_property(object): - """A property that is only computed once per instance and then replaces - itself with an ordinary attribute. Deleting the attribute resets the - property. - - Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 - """ - - def __init__(self, func): - self.__doc__ = getattr(func, '__doc__') - self.func = func - - def __get__(self, obj, cls): - if obj is None: - # We're being accessed from the class itself, not from an object - return self - value = obj.__dict__[self.func.__name__] = self.func(obj) - return value - - -def get_installed_version(dist_name, working_set=None): - """Get the installed version of dist_name avoiding pkg_resources cache""" - # Create a requirement that we'll look for inside of setuptools. - req = pkg_resources.Requirement.parse(dist_name) - - if working_set is None: - # We want to avoid having this cached, so we need to construct a new - # working set each time. - working_set = pkg_resources.WorkingSet() - - # Get the installed distribution from our working set - dist = working_set.find(req) - - # Check to see if we got an installed distribution or not, if we did - # we want to return it's version. - return dist.version if dist else None - - -def consume(iterator): - """Consume an iterable at C speed.""" - deque(iterator, maxlen=0) - - -# Simulates an enum -def enum(*sequential, **named): - enums = dict(zip(sequential, range(len(sequential))), **named) - reverse = {value: key for key, value in enums.items()} - enums['reverse_mapping'] = reverse - return type('Enum', (), enums) - - -def make_vcs_requirement_url(repo_url, rev, project_name, subdir=None): - """ - Return the URL for a VCS requirement. - - Args: - repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). - project_name: the (unescaped) project name. - """ - egg_project_name = pkg_resources.to_filename(project_name) - req = '{}@{}#egg={}'.format(repo_url, rev, egg_project_name) - if subdir: - req += '&subdirectory={}'.format(subdir) - - return req - - -def split_auth_from_netloc(netloc): - """ - Parse out and remove the auth information from a netloc. - - Returns: (netloc, (username, password)). - """ - if '@' not in netloc: - return netloc, (None, None) - - # Split from the right because that's how urllib.parse.urlsplit() - # behaves if more than one @ is present (which can be checked using - # the password attribute of urlsplit()'s return value). - auth, netloc = netloc.rsplit('@', 1) - if ':' in auth: - # Split from the left because that's how urllib.parse.urlsplit() - # behaves if more than one : is present (which again can be checked - # using the password attribute of the return value) - user_pass = auth.split(':', 1) - else: - user_pass = auth, None - - user_pass = tuple( - None if x is None else urllib_unquote(x) for x in user_pass - ) - - return netloc, user_pass - - -def redact_netloc(netloc): - # type: (str) -> str - """ - Replace the password in a netloc with "****", if it exists. - - For example, "user:pass@example.com" returns "user:****@example.com". - """ - netloc, (user, password) = split_auth_from_netloc(netloc) - if user is None: - return netloc - password = '' if password is None else ':****' - return '{user}{password}@{netloc}'.format(user=urllib_parse.quote(user), - password=password, - netloc=netloc) - - -def _transform_url(url, transform_netloc): - purl = urllib_parse.urlsplit(url) - netloc = transform_netloc(purl.netloc) - # stripped url - url_pieces = ( - purl.scheme, netloc, purl.path, purl.query, purl.fragment - ) - surl = urllib_parse.urlunsplit(url_pieces) - return surl - - -def _get_netloc(netloc): - return split_auth_from_netloc(netloc)[0] - - -def remove_auth_from_url(url): - # type: (str) -> str - # Return a copy of url with 'username:password@' removed. - # username/pass params are passed to subversion through flags - # and are not recognized in the url. - return _transform_url(url, _get_netloc) - - -def redact_password_from_url(url): - # type: (str) -> str - """Replace the password in a given url with ****.""" - return _transform_url(url, redact_netloc) - - -def protect_pip_from_modification_on_windows(modifying_pip): - """Protection of pip.exe from modification on Windows - - On Windows, any operation modifying pip should be run as: - python -m pip ... - """ - pip_names = [ - "pip.exe", - "pip{}.exe".format(sys.version_info[0]), - "pip{}.{}.exe".format(*sys.version_info[:2]) - ] - - # See https://github.com/pypa/pip/issues/1299 for more discussion - should_show_use_python_msg = ( - modifying_pip and - WINDOWS and - os.path.basename(sys.argv[0]) in pip_names - ) - - if should_show_use_python_msg: - new_command = [ - sys.executable, "-m", "pip" - ] + sys.argv[1:] - raise CommandError( - 'To modify pip, please run the following command:\n{}' - .format(" ".join(new_command)) - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/models.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/models.py deleted file mode 100644 index d5cb80a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/models.py +++ /dev/null @@ -1,40 +0,0 @@ -"""Utilities for defining models -""" - -import operator - - -class KeyBasedCompareMixin(object): - """Provides comparision capabilities that is based on a key - """ - - def __init__(self, key, defining_class): - self._compare_key = key - self._defining_class = defining_class - - def __hash__(self): - return hash(self._compare_key) - - def __lt__(self, other): - return self._compare(other, operator.__lt__) - - def __le__(self, other): - return self._compare(other, operator.__le__) - - def __gt__(self, other): - return self._compare(other, operator.__gt__) - - def __ge__(self, other): - return self._compare(other, operator.__ge__) - - def __eq__(self, other): - return self._compare(other, operator.__eq__) - - def __ne__(self, other): - return self._compare(other, operator.__ne__) - - def _compare(self, other, method): - if not isinstance(other, self._defining_class): - return NotImplemented - - return method(self._compare_key, other._compare_key) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/outdated.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/outdated.py deleted file mode 100644 index 37c47a4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/outdated.py +++ /dev/null @@ -1,164 +0,0 @@ -from __future__ import absolute_import - -import datetime -import json -import logging -import os.path -import sys - -from pip._vendor import lockfile, pkg_resources -from pip._vendor.packaging import version as packaging_version - -from pip._internal.index import PackageFinder -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.filesystem import check_path_owner -from pip._internal.utils.misc import ensure_dir, get_installed_version -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - import optparse # noqa: F401 - from typing import Any, Dict # noqa: F401 - from pip._internal.download import PipSession # noqa: F401 - - -SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" - - -logger = logging.getLogger(__name__) - - -class SelfCheckState(object): - def __init__(self, cache_dir): - # type: (str) -> None - self.state = {} # type: Dict[str, Any] - self.statefile_path = None - - # Try to load the existing state - if cache_dir: - self.statefile_path = os.path.join(cache_dir, "selfcheck.json") - try: - with open(self.statefile_path) as statefile: - self.state = json.load(statefile)[sys.prefix] - except (IOError, ValueError, KeyError): - # Explicitly suppressing exceptions, since we don't want to - # error out if the cache file is invalid. - pass - - def save(self, pypi_version, current_time): - # type: (str, datetime.datetime) -> None - # If we do not have a path to cache in, don't bother saving. - if not self.statefile_path: - return - - # Check to make sure that we own the directory - if not check_path_owner(os.path.dirname(self.statefile_path)): - return - - # Now that we've ensured the directory is owned by this user, we'll go - # ahead and make sure that all our directories are created. - ensure_dir(os.path.dirname(self.statefile_path)) - - # Attempt to write out our version check file - with lockfile.LockFile(self.statefile_path): - if os.path.exists(self.statefile_path): - with open(self.statefile_path) as statefile: - state = json.load(statefile) - else: - state = {} - - state[sys.prefix] = { - "last_check": current_time.strftime(SELFCHECK_DATE_FMT), - "pypi_version": pypi_version, - } - - with open(self.statefile_path, "w") as statefile: - json.dump(state, statefile, sort_keys=True, - separators=(",", ":")) - - -def was_installed_by_pip(pkg): - # type: (str) -> bool - """Checks whether pkg was installed by pip - - This is used not to display the upgrade message when pip is in fact - installed by system package manager, such as dnf on Fedora. - """ - try: - dist = pkg_resources.get_distribution(pkg) - return (dist.has_metadata('INSTALLER') and - 'pip' in dist.get_metadata_lines('INSTALLER')) - except pkg_resources.DistributionNotFound: - return False - - -def pip_version_check(session, options): - # type: (PipSession, optparse.Values) -> None - """Check for an update for pip. - - Limit the frequency of checks to once per week. State is stored either in - the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix - of the pip script path. - """ - installed_version = get_installed_version("pip") - if not installed_version: - return - - pip_version = packaging_version.parse(installed_version) - pypi_version = None - - try: - state = SelfCheckState(cache_dir=options.cache_dir) - - current_time = datetime.datetime.utcnow() - # Determine if we need to refresh the state - if "last_check" in state.state and "pypi_version" in state.state: - last_check = datetime.datetime.strptime( - state.state["last_check"], - SELFCHECK_DATE_FMT - ) - if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: - pypi_version = state.state["pypi_version"] - - # Refresh the version if we need to or just see if we need to warn - if pypi_version is None: - # Lets use PackageFinder to see what the latest pip version is - finder = PackageFinder( - find_links=options.find_links, - index_urls=[options.index_url] + options.extra_index_urls, - allow_all_prereleases=False, # Explicitly set to False - trusted_hosts=options.trusted_hosts, - session=session, - ) - all_candidates = finder.find_all_candidates("pip") - if not all_candidates: - return - pypi_version = str( - max(all_candidates, key=lambda c: c.version).version - ) - - # save that we've performed a check - state.save(pypi_version, current_time) - - remote_version = packaging_version.parse(pypi_version) - - # Determine if our pypi_version is older - if (pip_version < remote_version and - pip_version.base_version != remote_version.base_version and - was_installed_by_pip('pip')): - # Advise "python -m pip" on Windows to avoid issues - # with overwriting pip.exe. - if WINDOWS: - pip_cmd = "python -m pip" - else: - pip_cmd = "pip" - logger.warning( - "You are using pip version %s, however version %s is " - "available.\nYou should consider upgrading via the " - "'%s install --upgrade pip' command.", - pip_version, pypi_version, pip_cmd - ) - except Exception: - logger.debug( - "There was an error checking the latest version of pip", - exc_info=True, - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/packaging.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/packaging.py deleted file mode 100644 index 7aaf7b5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/packaging.py +++ /dev/null @@ -1,85 +0,0 @@ -from __future__ import absolute_import - -import logging -import sys -from email.parser import FeedParser - -from pip._vendor import pkg_resources -from pip._vendor.packaging import specifiers, version - -from pip._internal import exceptions -from pip._internal.utils.misc import display_path -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional # noqa: F401 - from email.message import Message # noqa: F401 - from pip._vendor.pkg_resources import Distribution # noqa: F401 - - -logger = logging.getLogger(__name__) - - -def check_requires_python(requires_python): - # type: (Optional[str]) -> bool - """ - Check if the python version in use match the `requires_python` specifier. - - Returns `True` if the version of python in use matches the requirement. - Returns `False` if the version of python in use does not matches the - requirement. - - Raises an InvalidSpecifier if `requires_python` have an invalid format. - """ - if requires_python is None: - # The package provides no information - return True - requires_python_specifier = specifiers.SpecifierSet(requires_python) - - # We only use major.minor.micro - python_version = version.parse('.'.join(map(str, sys.version_info[:3]))) - return python_version in requires_python_specifier - - -def get_metadata(dist): - # type: (Distribution) -> Message - if (isinstance(dist, pkg_resources.DistInfoDistribution) and - dist.has_metadata('METADATA')): - metadata = dist.get_metadata('METADATA') - elif dist.has_metadata('PKG-INFO'): - metadata = dist.get_metadata('PKG-INFO') - else: - logger.warning("No metadata found in %s", display_path(dist.location)) - metadata = '' - - feed_parser = FeedParser() - feed_parser.feed(metadata) - return feed_parser.close() - - -def check_dist_requires_python(dist): - pkg_info_dict = get_metadata(dist) - requires_python = pkg_info_dict.get('Requires-Python') - try: - if not check_requires_python(requires_python): - raise exceptions.UnsupportedPythonVersion( - "%s requires Python '%s' but the running Python is %s" % ( - dist.project_name, - requires_python, - '.'.join(map(str, sys.version_info[:3])),) - ) - except specifiers.InvalidSpecifier as e: - logger.warning( - "Package %s has an invalid Requires-Python entry %s - %s", - dist.project_name, requires_python, e, - ) - return - - -def get_installer(dist): - # type: (Distribution) -> str - if dist.has_metadata('INSTALLER'): - for line in dist.get_metadata_lines('INSTALLER'): - if line.strip(): - return line.strip() - return '' diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/setuptools_build.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/setuptools_build.py deleted file mode 100644 index 03973e9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/setuptools_build.py +++ /dev/null @@ -1,8 +0,0 @@ -# Shim to wrap setup.py invocation with setuptools -SETUPTOOLS_SHIM = ( - "import setuptools, tokenize;__file__=%r;" - "f=getattr(tokenize, 'open', open)(__file__);" - "code=f.read().replace('\\r\\n', '\\n');" - "f.close();" - "exec(compile(code, __file__, 'exec'))" -) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/temp_dir.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/temp_dir.py deleted file mode 100644 index 2c81ad5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/temp_dir.py +++ /dev/null @@ -1,155 +0,0 @@ -from __future__ import absolute_import - -import errno -import itertools -import logging -import os.path -import tempfile - -from pip._internal.utils.misc import rmtree - -logger = logging.getLogger(__name__) - - -class TempDirectory(object): - """Helper class that owns and cleans up a temporary directory. - - This class can be used as a context manager or as an OO representation of a - temporary directory. - - Attributes: - path - Location to the created temporary directory or None - delete - Whether the directory should be deleted when exiting - (when used as a contextmanager) - - Methods: - create() - Creates a temporary directory and stores its path in the path - attribute. - cleanup() - Deletes the temporary directory and sets path attribute to None - - When used as a context manager, a temporary directory is created on - entering the context and, if the delete attribute is True, on exiting the - context the created directory is deleted. - """ - - def __init__(self, path=None, delete=None, kind="temp"): - super(TempDirectory, self).__init__() - - if path is None and delete is None: - # If we were not given an explicit directory, and we were not given - # an explicit delete option, then we'll default to deleting. - delete = True - - self.path = path - self.delete = delete - self.kind = kind - - def __repr__(self): - return "<{} {!r}>".format(self.__class__.__name__, self.path) - - def __enter__(self): - self.create() - return self - - def __exit__(self, exc, value, tb): - if self.delete: - self.cleanup() - - def create(self): - """Create a temporary directory and store its path in self.path - """ - if self.path is not None: - logger.debug( - "Skipped creation of temporary directory: {}".format(self.path) - ) - return - # We realpath here because some systems have their default tmpdir - # symlinked to another directory. This tends to confuse build - # scripts, so we canonicalize the path by traversing potential - # symlinks here. - self.path = os.path.realpath( - tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) - ) - logger.debug("Created temporary directory: {}".format(self.path)) - - def cleanup(self): - """Remove the temporary directory created and reset state - """ - if self.path is not None and os.path.exists(self.path): - rmtree(self.path) - self.path = None - - -class AdjacentTempDirectory(TempDirectory): - """Helper class that creates a temporary directory adjacent to a real one. - - Attributes: - original - The original directory to create a temp directory for. - path - After calling create() or entering, contains the full - path to the temporary directory. - delete - Whether the directory should be deleted when exiting - (when used as a contextmanager) - - """ - # The characters that may be used to name the temp directory - # We always prepend a ~ and then rotate through these until - # a usable name is found. - # pkg_resources raises a different error for .dist-info folder - # with leading '-' and invalid metadata - LEADING_CHARS = "-~.=%0123456789" - - def __init__(self, original, delete=None): - super(AdjacentTempDirectory, self).__init__(delete=delete) - self.original = original.rstrip('/\\') - - @classmethod - def _generate_names(cls, name): - """Generates a series of temporary names. - - The algorithm replaces the leading characters in the name - with ones that are valid filesystem characters, but are not - valid package names (for both Python and pip definitions of - package). - """ - for i in range(1, len(name)): - for candidate in itertools.combinations_with_replacement( - cls.LEADING_CHARS, i - 1): - new_name = '~' + ''.join(candidate) + name[i:] - if new_name != name: - yield new_name - - # If we make it this far, we will have to make a longer name - for i in range(len(cls.LEADING_CHARS)): - for candidate in itertools.combinations_with_replacement( - cls.LEADING_CHARS, i): - new_name = '~' + ''.join(candidate) + name - if new_name != name: - yield new_name - - def create(self): - root, name = os.path.split(self.original) - for candidate in self._generate_names(name): - path = os.path.join(root, candidate) - try: - os.mkdir(path) - except OSError as ex: - # Continue if the name exists already - if ex.errno != errno.EEXIST: - raise - else: - self.path = os.path.realpath(path) - break - - if not self.path: - # Final fallback on the default behavior. - self.path = os.path.realpath( - tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) - ) - logger.debug("Created temporary directory: {}".format(self.path)) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/typing.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/typing.py deleted file mode 100644 index e085cdf..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/typing.py +++ /dev/null @@ -1,29 +0,0 @@ -"""For neatly implementing static typing in pip. - -`mypy` - the static type analysis tool we use - uses the `typing` module, which -provides core functionality fundamental to mypy's functioning. - -Generally, `typing` would be imported at runtime and used in that fashion - -it acts as a no-op at runtime and does not have any run-time overhead by -design. - -As it turns out, `typing` is not vendorable - it uses separate sources for -Python 2/Python 3. Thus, this codebase can not expect it to be present. -To work around this, mypy allows the typing import to be behind a False-y -optional to prevent it from running at runtime and type-comments can be used -to remove the need for the types to be accessible directly during runtime. - -This module provides the False-y guard in a nicely named fashion so that a -curious maintainer can reach here to read this. - -In pip, all static-typing related imports should be guarded as follows: - - from pip._internal.utils.typing import MYPY_CHECK_RUNNING - - if MYPY_CHECK_RUNNING: - from typing import ... # noqa: F401 - -Ref: https://github.com/python/mypy/issues/3216 -""" - -MYPY_CHECK_RUNNING = False diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/ui.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/ui.py deleted file mode 100644 index 433675d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/utils/ui.py +++ /dev/null @@ -1,441 +0,0 @@ -from __future__ import absolute_import, division - -import contextlib -import itertools -import logging -import sys -import time -from signal import SIGINT, default_int_handler, signal - -from pip._vendor import six -from pip._vendor.progress.bar import ( - Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar, - ShadyBar, -) -from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin -from pip._vendor.progress.spinner import Spinner - -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.logging import get_indentation -from pip._internal.utils.misc import format_size -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Iterator, IO # noqa: F401 - -try: - from pip._vendor import colorama -# Lots of different errors can come from this, including SystemError and -# ImportError. -except Exception: - colorama = None - -logger = logging.getLogger(__name__) - - -def _select_progress_class(preferred, fallback): - encoding = getattr(preferred.file, "encoding", None) - - # If we don't know what encoding this file is in, then we'll just assume - # that it doesn't support unicode and use the ASCII bar. - if not encoding: - return fallback - - # Collect all of the possible characters we want to use with the preferred - # bar. - characters = [ - getattr(preferred, "empty_fill", six.text_type()), - getattr(preferred, "fill", six.text_type()), - ] - characters += list(getattr(preferred, "phases", [])) - - # Try to decode the characters we're using for the bar using the encoding - # of the given file, if this works then we'll assume that we can use the - # fancier bar and if not we'll fall back to the plaintext bar. - try: - six.text_type().join(characters).encode(encoding) - except UnicodeEncodeError: - return fallback - else: - return preferred - - -_BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any - - -class InterruptibleMixin(object): - """ - Helper to ensure that self.finish() gets called on keyboard interrupt. - - This allows downloads to be interrupted without leaving temporary state - (like hidden cursors) behind. - - This class is similar to the progress library's existing SigIntMixin - helper, but as of version 1.2, that helper has the following problems: - - 1. It calls sys.exit(). - 2. It discards the existing SIGINT handler completely. - 3. It leaves its own handler in place even after an uninterrupted finish, - which will have unexpected delayed effects if the user triggers an - unrelated keyboard interrupt some time after a progress-displaying - download has already completed, for example. - """ - - def __init__(self, *args, **kwargs): - """ - Save the original SIGINT handler for later. - """ - super(InterruptibleMixin, self).__init__(*args, **kwargs) - - self.original_handler = signal(SIGINT, self.handle_sigint) - - # If signal() returns None, the previous handler was not installed from - # Python, and we cannot restore it. This probably should not happen, - # but if it does, we must restore something sensible instead, at least. - # The least bad option should be Python's default SIGINT handler, which - # just raises KeyboardInterrupt. - if self.original_handler is None: - self.original_handler = default_int_handler - - def finish(self): - """ - Restore the original SIGINT handler after finishing. - - This should happen regardless of whether the progress display finishes - normally, or gets interrupted. - """ - super(InterruptibleMixin, self).finish() - signal(SIGINT, self.original_handler) - - def handle_sigint(self, signum, frame): - """ - Call self.finish() before delegating to the original SIGINT handler. - - This handler should only be in place while the progress display is - active. - """ - self.finish() - self.original_handler(signum, frame) - - -class SilentBar(Bar): - - def update(self): - pass - - -class BlueEmojiBar(IncrementalBar): - - suffix = "%(percent)d%%" - bar_prefix = " " - bar_suffix = " " - phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535") # type: Any - - -class DownloadProgressMixin(object): - - def __init__(self, *args, **kwargs): - super(DownloadProgressMixin, self).__init__(*args, **kwargs) - self.message = (" " * (get_indentation() + 2)) + self.message - - @property - def downloaded(self): - return format_size(self.index) - - @property - def download_speed(self): - # Avoid zero division errors... - if self.avg == 0.0: - return "..." - return format_size(1 / self.avg) + "/s" - - @property - def pretty_eta(self): - if self.eta: - return "eta %s" % self.eta_td - return "" - - def iter(self, it, n=1): - for x in it: - yield x - self.next(n) - self.finish() - - -class WindowsMixin(object): - - def __init__(self, *args, **kwargs): - # The Windows terminal does not support the hide/show cursor ANSI codes - # even with colorama. So we'll ensure that hide_cursor is False on - # Windows. - # This call neds to go before the super() call, so that hide_cursor - # is set in time. The base progress bar class writes the "hide cursor" - # code to the terminal in its init, so if we don't set this soon - # enough, we get a "hide" with no corresponding "show"... - if WINDOWS and self.hide_cursor: - self.hide_cursor = False - - super(WindowsMixin, self).__init__(*args, **kwargs) - - # Check if we are running on Windows and we have the colorama module, - # if we do then wrap our file with it. - if WINDOWS and colorama: - self.file = colorama.AnsiToWin32(self.file) - # The progress code expects to be able to call self.file.isatty() - # but the colorama.AnsiToWin32() object doesn't have that, so we'll - # add it. - self.file.isatty = lambda: self.file.wrapped.isatty() - # The progress code expects to be able to call self.file.flush() - # but the colorama.AnsiToWin32() object doesn't have that, so we'll - # add it. - self.file.flush = lambda: self.file.wrapped.flush() - - -class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, - DownloadProgressMixin): - - file = sys.stdout - message = "%(percent)d%%" - suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" - -# NOTE: The "type: ignore" comments on the following classes are there to -# work around https://github.com/python/typing/issues/241 - - -class DefaultDownloadProgressBar(BaseDownloadProgressBar, - _BaseBar): - pass - - -class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore - pass - - -class DownloadIncrementalBar(BaseDownloadProgressBar, # type: ignore - IncrementalBar): - pass - - -class DownloadChargingBar(BaseDownloadProgressBar, # type: ignore - ChargingBar): - pass - - -class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar): # type: ignore - pass - - -class DownloadFillingSquaresBar(BaseDownloadProgressBar, # type: ignore - FillingSquaresBar): - pass - - -class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore - FillingCirclesBar): - pass - - -class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore - BlueEmojiBar): - pass - - -class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, - DownloadProgressMixin, WritelnMixin, Spinner): - - file = sys.stdout - suffix = "%(downloaded)s %(download_speed)s" - - def next_phase(self): - if not hasattr(self, "_phaser"): - self._phaser = itertools.cycle(self.phases) - return next(self._phaser) - - def update(self): - message = self.message % self - phase = self.next_phase() - suffix = self.suffix % self - line = ''.join([ - message, - " " if message else "", - phase, - " " if suffix else "", - suffix, - ]) - - self.writeln(line) - - -BAR_TYPES = { - "off": (DownloadSilentBar, DownloadSilentBar), - "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), - "ascii": (DownloadIncrementalBar, DownloadProgressSpinner), - "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), - "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) -} - - -def DownloadProgressProvider(progress_bar, max=None): - if max is None or max == 0: - return BAR_TYPES[progress_bar][1]().iter - else: - return BAR_TYPES[progress_bar][0](max=max).iter - - -################################################################ -# Generic "something is happening" spinners -# -# We don't even try using progress.spinner.Spinner here because it's actually -# simpler to reimplement from scratch than to coerce their code into doing -# what we need. -################################################################ - -@contextlib.contextmanager -def hidden_cursor(file): - # type: (IO) -> Iterator[None] - # The Windows terminal does not support the hide/show cursor ANSI codes, - # even via colorama. So don't even try. - if WINDOWS: - yield - # We don't want to clutter the output with control characters if we're - # writing to a file, or if the user is running with --quiet. - # See https://github.com/pypa/pip/issues/3418 - elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: - yield - else: - file.write(HIDE_CURSOR) - try: - yield - finally: - file.write(SHOW_CURSOR) - - -class RateLimiter(object): - def __init__(self, min_update_interval_seconds): - # type: (float) -> None - self._min_update_interval_seconds = min_update_interval_seconds - self._last_update = 0 # type: float - - def ready(self): - # type: () -> bool - now = time.time() - delta = now - self._last_update - return delta >= self._min_update_interval_seconds - - def reset(self): - # type: () -> None - self._last_update = time.time() - - -class SpinnerInterface(object): - def spin(self): - # type: () -> None - raise NotImplementedError() - - def finish(self, final_status): - # type: (str) -> None - raise NotImplementedError() - - -class InteractiveSpinner(SpinnerInterface): - def __init__(self, message, file=None, spin_chars="-\\|/", - # Empirically, 8 updates/second looks nice - min_update_interval_seconds=0.125): - self._message = message - if file is None: - file = sys.stdout - self._file = file - self._rate_limiter = RateLimiter(min_update_interval_seconds) - self._finished = False - - self._spin_cycle = itertools.cycle(spin_chars) - - self._file.write(" " * get_indentation() + self._message + " ... ") - self._width = 0 - - def _write(self, status): - assert not self._finished - # Erase what we wrote before by backspacing to the beginning, writing - # spaces to overwrite the old text, and then backspacing again - backup = "\b" * self._width - self._file.write(backup + " " * self._width + backup) - # Now we have a blank slate to add our status - self._file.write(status) - self._width = len(status) - self._file.flush() - self._rate_limiter.reset() - - def spin(self): - # type: () -> None - if self._finished: - return - if not self._rate_limiter.ready(): - return - self._write(next(self._spin_cycle)) - - def finish(self, final_status): - # type: (str) -> None - if self._finished: - return - self._write(final_status) - self._file.write("\n") - self._file.flush() - self._finished = True - - -# Used for dumb terminals, non-interactive installs (no tty), etc. -# We still print updates occasionally (once every 60 seconds by default) to -# act as a keep-alive for systems like Travis-CI that take lack-of-output as -# an indication that a task has frozen. -class NonInteractiveSpinner(SpinnerInterface): - def __init__(self, message, min_update_interval_seconds=60): - # type: (str, float) -> None - self._message = message - self._finished = False - self._rate_limiter = RateLimiter(min_update_interval_seconds) - self._update("started") - - def _update(self, status): - assert not self._finished - self._rate_limiter.reset() - logger.info("%s: %s", self._message, status) - - def spin(self): - # type: () -> None - if self._finished: - return - if not self._rate_limiter.ready(): - return - self._update("still running...") - - def finish(self, final_status): - # type: (str) -> None - if self._finished: - return - self._update("finished with status '%s'" % (final_status,)) - self._finished = True - - -@contextlib.contextmanager -def open_spinner(message): - # type: (str) -> Iterator[SpinnerInterface] - # Interactive spinner goes directly to sys.stdout rather than being routed - # through the logging system, but it acts like it has level INFO, - # i.e. it's only displayed if we're at level INFO or better. - # Non-interactive spinner goes through the logging system, so it is always - # in sync with logging configuration. - if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: - spinner = InteractiveSpinner(message) # type: SpinnerInterface - else: - spinner = NonInteractiveSpinner(message) - try: - with hidden_cursor(sys.stdout): - yield spinner - except KeyboardInterrupt: - spinner.finish("canceled") - raise - except Exception: - spinner.finish("error") - raise - else: - spinner.finish("done") diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/__init__.py deleted file mode 100644 index 9cba764..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/__init__.py +++ /dev/null @@ -1,534 +0,0 @@ -"""Handles all VCS (version control) support""" -from __future__ import absolute_import - -import errno -import logging -import os -import shutil -import sys - -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.exceptions import BadCommand -from pip._internal.utils.misc import ( - display_path, backup_dir, call_subprocess, rmtree, ask_path_exists, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Any, Dict, Iterable, List, Mapping, Optional, Text, Tuple, Type - ) - from pip._internal.utils.ui import SpinnerInterface # noqa: F401 - - AuthInfo = Tuple[Optional[str], Optional[str]] - -__all__ = ['vcs'] - - -logger = logging.getLogger(__name__) - - -class RemoteNotFoundError(Exception): - pass - - -class RevOptions(object): - - """ - Encapsulates a VCS-specific revision to install, along with any VCS - install options. - - Instances of this class should be treated as if immutable. - """ - - def __init__(self, vcs, rev=None, extra_args=None): - # type: (VersionControl, Optional[str], Optional[List[str]]) -> None - """ - Args: - vcs: a VersionControl object. - rev: the name of the revision to install. - extra_args: a list of extra options. - """ - if extra_args is None: - extra_args = [] - - self.extra_args = extra_args - self.rev = rev - self.vcs = vcs - - def __repr__(self): - return '<RevOptions {}: rev={!r}>'.format(self.vcs.name, self.rev) - - @property - def arg_rev(self): - # type: () -> Optional[str] - if self.rev is None: - return self.vcs.default_arg_rev - - return self.rev - - def to_args(self): - # type: () -> List[str] - """ - Return the VCS-specific command arguments. - """ - args = [] # type: List[str] - rev = self.arg_rev - if rev is not None: - args += self.vcs.get_base_rev_args(rev) - args += self.extra_args - - return args - - def to_display(self): - # type: () -> str - if not self.rev: - return '' - - return ' (to revision {})'.format(self.rev) - - def make_new(self, rev): - # type: (str) -> RevOptions - """ - Make a copy of the current instance, but with a new rev. - - Args: - rev: the name of the revision for the new object. - """ - return self.vcs.make_rev_options(rev, extra_args=self.extra_args) - - -class VcsSupport(object): - _registry = {} # type: Dict[str, Type[VersionControl]] - schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] - - def __init__(self): - # type: () -> None - # Register more schemes with urlparse for various version control - # systems - urllib_parse.uses_netloc.extend(self.schemes) - # Python >= 2.7.4, 3.3 doesn't have uses_fragment - if getattr(urllib_parse, 'uses_fragment', None): - urllib_parse.uses_fragment.extend(self.schemes) - super(VcsSupport, self).__init__() - - def __iter__(self): - return self._registry.__iter__() - - @property - def backends(self): - # type: () -> List[Type[VersionControl]] - return list(self._registry.values()) - - @property - def dirnames(self): - # type: () -> List[str] - return [backend.dirname for backend in self.backends] - - @property - def all_schemes(self): - # type: () -> List[str] - schemes = [] # type: List[str] - for backend in self.backends: - schemes.extend(backend.schemes) - return schemes - - def register(self, cls): - # type: (Type[VersionControl]) -> None - if not hasattr(cls, 'name'): - logger.warning('Cannot register VCS %s', cls.__name__) - return - if cls.name not in self._registry: - self._registry[cls.name] = cls - logger.debug('Registered VCS backend: %s', cls.name) - - def unregister(self, cls=None, name=None): - # type: (Optional[Type[VersionControl]], Optional[str]) -> None - if name in self._registry: - del self._registry[name] - elif cls in self._registry.values(): - del self._registry[cls.name] - else: - logger.warning('Cannot unregister because no class or name given') - - def get_backend_type(self, location): - # type: (str) -> Optional[Type[VersionControl]] - """ - Return the type of the version control backend if found at given - location, e.g. vcs.get_backend_type('/path/to/vcs/checkout') - """ - for vc_type in self._registry.values(): - if vc_type.controls_location(location): - logger.debug('Determine that %s uses VCS: %s', - location, vc_type.name) - return vc_type - return None - - def get_backend(self, name): - # type: (str) -> Optional[Type[VersionControl]] - name = name.lower() - if name in self._registry: - return self._registry[name] - return None - - -vcs = VcsSupport() - - -class VersionControl(object): - name = '' - dirname = '' - repo_name = '' - # List of supported schemes for this Version Control - schemes = () # type: Tuple[str, ...] - # Iterable of environment variable names to pass to call_subprocess(). - unset_environ = () # type: Tuple[str, ...] - default_arg_rev = None # type: Optional[str] - - def __init__(self, url=None, *args, **kwargs): - self.url = url - super(VersionControl, self).__init__(*args, **kwargs) - - def get_base_rev_args(self, rev): - """ - Return the base revision arguments for a vcs command. - - Args: - rev: the name of a revision to install. Cannot be None. - """ - raise NotImplementedError - - def make_rev_options(self, rev=None, extra_args=None): - # type: (Optional[str], Optional[List[str]]) -> RevOptions - """ - Return a RevOptions object. - - Args: - rev: the name of a revision to install. - extra_args: a list of extra options. - """ - return RevOptions(self, rev, extra_args=extra_args) - - @classmethod - def _is_local_repository(cls, repo): - # type: (str) -> bool - """ - posix absolute paths start with os.path.sep, - win32 ones start with drive (like c:\\folder) - """ - drive, tail = os.path.splitdrive(repo) - return repo.startswith(os.path.sep) or bool(drive) - - def export(self, location): - """ - Export the repository at the url to the destination location - i.e. only download the files, without vcs informations - """ - raise NotImplementedError - - def get_netloc_and_auth(self, netloc, scheme): - """ - Parse the repository URL's netloc, and return the new netloc to use - along with auth information. - - Args: - netloc: the original repository URL netloc. - scheme: the repository URL's scheme without the vcs prefix. - - This is mainly for the Subversion class to override, so that auth - information can be provided via the --username and --password options - instead of through the URL. For other subclasses like Git without - such an option, auth information must stay in the URL. - - Returns: (netloc, (username, password)). - """ - return netloc, (None, None) - - def get_url_rev_and_auth(self, url): - # type: (str) -> Tuple[str, Optional[str], AuthInfo] - """ - Parse the repository URL to use, and return the URL, revision, - and auth info to use. - - Returns: (url, rev, (username, password)). - """ - scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) - if '+' not in scheme: - raise ValueError( - "Sorry, {!r} is a malformed VCS url. " - "The format is <vcs>+<protocol>://<url>, " - "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp".format(url) - ) - # Remove the vcs prefix. - scheme = scheme.split('+', 1)[1] - netloc, user_pass = self.get_netloc_and_auth(netloc, scheme) - rev = None - if '@' in path: - path, rev = path.rsplit('@', 1) - url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) - return url, rev, user_pass - - def make_rev_args(self, username, password): - """ - Return the RevOptions "extra arguments" to use in obtain(). - """ - return [] - - def get_url_rev_options(self, url): - # type: (str) -> Tuple[str, RevOptions] - """ - Return the URL and RevOptions object to use in obtain() and in - some cases export(), as a tuple (url, rev_options). - """ - url, rev, user_pass = self.get_url_rev_and_auth(url) - username, password = user_pass - extra_args = self.make_rev_args(username, password) - rev_options = self.make_rev_options(rev, extra_args=extra_args) - - return url, rev_options - - def normalize_url(self, url): - # type: (str) -> str - """ - Normalize a URL for comparison by unquoting it and removing any - trailing slash. - """ - return urllib_parse.unquote(url).rstrip('/') - - def compare_urls(self, url1, url2): - # type: (str, str) -> bool - """ - Compare two repo URLs for identity, ignoring incidental differences. - """ - return (self.normalize_url(url1) == self.normalize_url(url2)) - - def fetch_new(self, dest, url, rev_options): - """ - Fetch a revision from a repository, in the case that this is the - first fetch from the repository. - - Args: - dest: the directory to fetch the repository to. - rev_options: a RevOptions object. - """ - raise NotImplementedError - - def switch(self, dest, url, rev_options): - """ - Switch the repo at ``dest`` to point to ``URL``. - - Args: - rev_options: a RevOptions object. - """ - raise NotImplementedError - - def update(self, dest, url, rev_options): - """ - Update an already-existing repo to the given ``rev_options``. - - Args: - rev_options: a RevOptions object. - """ - raise NotImplementedError - - def is_commit_id_equal(self, dest, name): - """ - Return whether the id of the current commit equals the given name. - - Args: - dest: the repository directory. - name: a string name. - """ - raise NotImplementedError - - def obtain(self, dest): - # type: (str) -> None - """ - Install or update in editable mode the package represented by this - VersionControl object. - - Args: - dest: the repository directory in which to install or update. - """ - url, rev_options = self.get_url_rev_options(self.url) - - if not os.path.exists(dest): - self.fetch_new(dest, url, rev_options) - return - - rev_display = rev_options.to_display() - if self.is_repository_directory(dest): - existing_url = self.get_remote_url(dest) - if self.compare_urls(existing_url, url): - logger.debug( - '%s in %s exists, and has correct URL (%s)', - self.repo_name.title(), - display_path(dest), - url, - ) - if not self.is_commit_id_equal(dest, rev_options.rev): - logger.info( - 'Updating %s %s%s', - display_path(dest), - self.repo_name, - rev_display, - ) - self.update(dest, url, rev_options) - else: - logger.info('Skipping because already up-to-date.') - return - - logger.warning( - '%s %s in %s exists with URL %s', - self.name, - self.repo_name, - display_path(dest), - existing_url, - ) - prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', - ('s', 'i', 'w', 'b')) - else: - logger.warning( - 'Directory %s already exists, and is not a %s %s.', - dest, - self.name, - self.repo_name, - ) - # https://github.com/python/mypy/issues/1174 - prompt = ('(i)gnore, (w)ipe, (b)ackup ', # type: ignore - ('i', 'w', 'b')) - - logger.warning( - 'The plan is to install the %s repository %s', - self.name, - url, - ) - response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) - - if response == 'a': - sys.exit(-1) - - if response == 'w': - logger.warning('Deleting %s', display_path(dest)) - rmtree(dest) - self.fetch_new(dest, url, rev_options) - return - - if response == 'b': - dest_dir = backup_dir(dest) - logger.warning( - 'Backing up %s to %s', display_path(dest), dest_dir, - ) - shutil.move(dest, dest_dir) - self.fetch_new(dest, url, rev_options) - return - - # Do nothing if the response is "i". - if response == 's': - logger.info( - 'Switching %s %s to %s%s', - self.repo_name, - display_path(dest), - url, - rev_display, - ) - self.switch(dest, url, rev_options) - - def unpack(self, location): - # type: (str) -> None - """ - Clean up current location and download the url repository - (and vcs infos) into location - """ - if os.path.exists(location): - rmtree(location) - self.obtain(location) - - @classmethod - def get_src_requirement(cls, location, project_name): - """ - Return a string representing the requirement needed to - redownload the files currently present in location, something - like: - {repository_url}@{revision}#egg={project_name}-{version_identifier} - """ - raise NotImplementedError - - @classmethod - def get_remote_url(cls, location): - """ - Return the url used at location - - Raises RemoteNotFoundError if the repository does not have a remote - url configured. - """ - raise NotImplementedError - - @classmethod - def get_revision(cls, location): - """ - Return the current commit id of the files at the given location. - """ - raise NotImplementedError - - @classmethod - def run_command( - cls, - cmd, # type: List[str] - show_stdout=True, # type: bool - cwd=None, # type: Optional[str] - on_returncode='raise', # type: str - extra_ok_returncodes=None, # type: Optional[Iterable[int]] - command_desc=None, # type: Optional[str] - extra_environ=None, # type: Optional[Mapping[str, Any]] - spinner=None # type: Optional[SpinnerInterface] - ): - # type: (...) -> Optional[Text] - """ - Run a VCS subcommand - This is simply a wrapper around call_subprocess that adds the VCS - command name, and checks that the VCS is available - """ - cmd = [cls.name] + cmd - try: - return call_subprocess(cmd, show_stdout, cwd, - on_returncode=on_returncode, - extra_ok_returncodes=extra_ok_returncodes, - command_desc=command_desc, - extra_environ=extra_environ, - unset_environ=cls.unset_environ, - spinner=spinner) - except OSError as e: - # errno.ENOENT = no such file or directory - # In other words, the VCS executable isn't available - if e.errno == errno.ENOENT: - raise BadCommand( - 'Cannot find command %r - do you have ' - '%r installed and in your ' - 'PATH?' % (cls.name, cls.name)) - else: - raise # re-raise exception if a different error occurred - - @classmethod - def is_repository_directory(cls, path): - # type: (str) -> bool - """ - Return whether a directory path is a repository directory. - """ - logger.debug('Checking in %s for %s (%s)...', - path, cls.dirname, cls.name) - return os.path.exists(os.path.join(path, cls.dirname)) - - @classmethod - def controls_location(cls, location): - # type: (str) -> bool - """ - Check if a location is controlled by the vcs. - It is meant to be overridden to implement smarter detection - mechanisms for specific vcs. - - This can do more than is_repository_directory() alone. For example, - the Git override checks that Git is actually available. - """ - return cls.is_repository_directory(location) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/bazaar.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/bazaar.py deleted file mode 100644 index 4c6ac79..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/bazaar.py +++ /dev/null @@ -1,114 +0,0 @@ -from __future__ import absolute_import - -import logging -import os - -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.download import path_to_url -from pip._internal.utils.misc import ( - display_path, make_vcs_requirement_url, rmtree, -) -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.vcs import VersionControl, vcs - -logger = logging.getLogger(__name__) - - -class Bazaar(VersionControl): - name = 'bzr' - dirname = '.bzr' - repo_name = 'branch' - schemes = ( - 'bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', - 'bzr+lp', - ) - - def __init__(self, url=None, *args, **kwargs): - super(Bazaar, self).__init__(url, *args, **kwargs) - # This is only needed for python <2.7.5 - # Register lp but do not expose as a scheme to support bzr+lp. - if getattr(urllib_parse, 'uses_fragment', None): - urllib_parse.uses_fragment.extend(['lp']) - - def get_base_rev_args(self, rev): - return ['-r', rev] - - def export(self, location): - """ - Export the Bazaar repository at the url to the destination location - """ - # Remove the location to make sure Bazaar can export it correctly - if os.path.exists(location): - rmtree(location) - - with TempDirectory(kind="export") as temp_dir: - self.unpack(temp_dir.path) - - self.run_command( - ['export', location], - cwd=temp_dir.path, show_stdout=False, - ) - - def fetch_new(self, dest, url, rev_options): - rev_display = rev_options.to_display() - logger.info( - 'Checking out %s%s to %s', - url, - rev_display, - display_path(dest), - ) - cmd_args = ['branch', '-q'] + rev_options.to_args() + [url, dest] - self.run_command(cmd_args) - - def switch(self, dest, url, rev_options): - self.run_command(['switch', url], cwd=dest) - - def update(self, dest, url, rev_options): - cmd_args = ['pull', '-q'] + rev_options.to_args() - self.run_command(cmd_args, cwd=dest) - - def get_url_rev_and_auth(self, url): - # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it - url, rev, user_pass = super(Bazaar, self).get_url_rev_and_auth(url) - if url.startswith('ssh://'): - url = 'bzr+' + url - return url, rev, user_pass - - @classmethod - def get_remote_url(cls, location): - urls = cls.run_command(['info'], show_stdout=False, cwd=location) - for line in urls.splitlines(): - line = line.strip() - for x in ('checkout of branch: ', - 'parent branch: '): - if line.startswith(x): - repo = line.split(x)[1] - if cls._is_local_repository(repo): - return path_to_url(repo) - return repo - return None - - @classmethod - def get_revision(cls, location): - revision = cls.run_command( - ['revno'], show_stdout=False, cwd=location, - ) - return revision.splitlines()[-1] - - @classmethod - def get_src_requirement(cls, location, project_name): - repo = cls.get_remote_url(location) - if not repo: - return None - if not repo.lower().startswith('bzr:'): - repo = 'bzr+' + repo - current_rev = cls.get_revision(location) - return make_vcs_requirement_url(repo, current_rev, project_name) - - def is_commit_id_equal(self, dest, name): - """Always assume the versions don't match""" - return False - - -vcs.register(Bazaar) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/git.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/git.py deleted file mode 100644 index dd2bd61..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/git.py +++ /dev/null @@ -1,369 +0,0 @@ -from __future__ import absolute_import - -import logging -import os.path -import re - -from pip._vendor.packaging.version import parse as parse_version -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request - -from pip._internal.exceptions import BadCommand -from pip._internal.utils.compat import samefile -from pip._internal.utils.misc import ( - display_path, make_vcs_requirement_url, redact_password_from_url, -) -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.vcs import RemoteNotFoundError, VersionControl, vcs - -urlsplit = urllib_parse.urlsplit -urlunsplit = urllib_parse.urlunsplit - - -logger = logging.getLogger(__name__) - - -HASH_REGEX = re.compile('[a-fA-F0-9]{40}') - - -def looks_like_hash(sha): - return bool(HASH_REGEX.match(sha)) - - -class Git(VersionControl): - name = 'git' - dirname = '.git' - repo_name = 'clone' - schemes = ( - 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', - ) - # Prevent the user's environment variables from interfering with pip: - # https://github.com/pypa/pip/issues/1130 - unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') - default_arg_rev = 'HEAD' - - def __init__(self, url=None, *args, **kwargs): - - # Works around an apparent Git bug - # (see https://article.gmane.org/gmane.comp.version-control.git/146500) - if url: - scheme, netloc, path, query, fragment = urlsplit(url) - if scheme.endswith('file'): - initial_slashes = path[:-len(path.lstrip('/'))] - newpath = ( - initial_slashes + - urllib_request.url2pathname(path) - .replace('\\', '/').lstrip('/') - ) - url = urlunsplit((scheme, netloc, newpath, query, fragment)) - after_plus = scheme.find('+') + 1 - url = scheme[:after_plus] + urlunsplit( - (scheme[after_plus:], netloc, newpath, query, fragment), - ) - - super(Git, self).__init__(url, *args, **kwargs) - - def get_base_rev_args(self, rev): - return [rev] - - def get_git_version(self): - VERSION_PFX = 'git version ' - version = self.run_command(['version'], show_stdout=False) - if version.startswith(VERSION_PFX): - version = version[len(VERSION_PFX):].split()[0] - else: - version = '' - # get first 3 positions of the git version becasue - # on windows it is x.y.z.windows.t, and this parses as - # LegacyVersion which always smaller than a Version. - version = '.'.join(version.split('.')[:3]) - return parse_version(version) - - def get_current_branch(self, location): - """ - Return the current branch, or None if HEAD isn't at a branch - (e.g. detached HEAD). - """ - # git-symbolic-ref exits with empty stdout if "HEAD" is a detached - # HEAD rather than a symbolic ref. In addition, the -q causes the - # command to exit with status code 1 instead of 128 in this case - # and to suppress the message to stderr. - args = ['symbolic-ref', '-q', 'HEAD'] - output = self.run_command( - args, extra_ok_returncodes=(1, ), show_stdout=False, cwd=location, - ) - ref = output.strip() - - if ref.startswith('refs/heads/'): - return ref[len('refs/heads/'):] - - return None - - def export(self, location): - """Export the Git repository at the url to the destination location""" - if not location.endswith('/'): - location = location + '/' - - with TempDirectory(kind="export") as temp_dir: - self.unpack(temp_dir.path) - self.run_command( - ['checkout-index', '-a', '-f', '--prefix', location], - show_stdout=False, cwd=temp_dir.path - ) - - def get_revision_sha(self, dest, rev): - """ - Return (sha_or_none, is_branch), where sha_or_none is a commit hash - if the revision names a remote branch or tag, otherwise None. - - Args: - dest: the repository directory. - rev: the revision name. - """ - # Pass rev to pre-filter the list. - output = self.run_command(['show-ref', rev], cwd=dest, - show_stdout=False, on_returncode='ignore') - refs = {} - for line in output.strip().splitlines(): - try: - sha, ref = line.split() - except ValueError: - # Include the offending line to simplify troubleshooting if - # this error ever occurs. - raise ValueError('unexpected show-ref line: {!r}'.format(line)) - - refs[ref] = sha - - branch_ref = 'refs/remotes/origin/{}'.format(rev) - tag_ref = 'refs/tags/{}'.format(rev) - - sha = refs.get(branch_ref) - if sha is not None: - return (sha, True) - - sha = refs.get(tag_ref) - - return (sha, False) - - def resolve_revision(self, dest, url, rev_options): - """ - Resolve a revision to a new RevOptions object with the SHA1 of the - branch, tag, or ref if found. - - Args: - rev_options: a RevOptions object. - """ - rev = rev_options.arg_rev - sha, is_branch = self.get_revision_sha(dest, rev) - - if sha is not None: - rev_options = rev_options.make_new(sha) - rev_options.branch_name = rev if is_branch else None - - return rev_options - - # Do not show a warning for the common case of something that has - # the form of a Git commit hash. - if not looks_like_hash(rev): - logger.warning( - "Did not find branch or tag '%s', assuming revision or ref.", - rev, - ) - - if not rev.startswith('refs/'): - return rev_options - - # If it looks like a ref, we have to fetch it explicitly. - self.run_command( - ['fetch', '-q', url] + rev_options.to_args(), - cwd=dest, - ) - # Change the revision to the SHA of the ref we fetched - sha = self.get_revision(dest, rev='FETCH_HEAD') - rev_options = rev_options.make_new(sha) - - return rev_options - - def is_commit_id_equal(self, dest, name): - """ - Return whether the current commit hash equals the given name. - - Args: - dest: the repository directory. - name: a string name. - """ - if not name: - # Then avoid an unnecessary subprocess call. - return False - - return self.get_revision(dest) == name - - def fetch_new(self, dest, url, rev_options): - rev_display = rev_options.to_display() - logger.info( - 'Cloning %s%s to %s', redact_password_from_url(url), - rev_display, display_path(dest), - ) - self.run_command(['clone', '-q', url, dest]) - - if rev_options.rev: - # Then a specific revision was requested. - rev_options = self.resolve_revision(dest, url, rev_options) - branch_name = getattr(rev_options, 'branch_name', None) - if branch_name is None: - # Only do a checkout if the current commit id doesn't match - # the requested revision. - if not self.is_commit_id_equal(dest, rev_options.rev): - cmd_args = ['checkout', '-q'] + rev_options.to_args() - self.run_command(cmd_args, cwd=dest) - elif self.get_current_branch(dest) != branch_name: - # Then a specific branch was requested, and that branch - # is not yet checked out. - track_branch = 'origin/{}'.format(branch_name) - cmd_args = [ - 'checkout', '-b', branch_name, '--track', track_branch, - ] - self.run_command(cmd_args, cwd=dest) - - #: repo may contain submodules - self.update_submodules(dest) - - def switch(self, dest, url, rev_options): - self.run_command(['config', 'remote.origin.url', url], cwd=dest) - cmd_args = ['checkout', '-q'] + rev_options.to_args() - self.run_command(cmd_args, cwd=dest) - - self.update_submodules(dest) - - def update(self, dest, url, rev_options): - # First fetch changes from the default remote - if self.get_git_version() >= parse_version('1.9.0'): - # fetch tags in addition to everything else - self.run_command(['fetch', '-q', '--tags'], cwd=dest) - else: - self.run_command(['fetch', '-q'], cwd=dest) - # Then reset to wanted revision (maybe even origin/master) - rev_options = self.resolve_revision(dest, url, rev_options) - cmd_args = ['reset', '--hard', '-q'] + rev_options.to_args() - self.run_command(cmd_args, cwd=dest) - #: update submodules - self.update_submodules(dest) - - @classmethod - def get_remote_url(cls, location): - """ - Return URL of the first remote encountered. - - Raises RemoteNotFoundError if the repository does not have a remote - url configured. - """ - # We need to pass 1 for extra_ok_returncodes since the command - # exits with return code 1 if there are no matching lines. - stdout = cls.run_command( - ['config', '--get-regexp', r'remote\..*\.url'], - extra_ok_returncodes=(1, ), show_stdout=False, cwd=location, - ) - remotes = stdout.splitlines() - try: - found_remote = remotes[0] - except IndexError: - raise RemoteNotFoundError - - for remote in remotes: - if remote.startswith('remote.origin.url '): - found_remote = remote - break - url = found_remote.split(' ')[1] - return url.strip() - - @classmethod - def get_revision(cls, location, rev=None): - if rev is None: - rev = 'HEAD' - current_rev = cls.run_command( - ['rev-parse', rev], show_stdout=False, cwd=location, - ) - return current_rev.strip() - - @classmethod - def _get_subdirectory(cls, location): - """Return the relative path of setup.py to the git repo root.""" - # find the repo root - git_dir = cls.run_command(['rev-parse', '--git-dir'], - show_stdout=False, cwd=location).strip() - if not os.path.isabs(git_dir): - git_dir = os.path.join(location, git_dir) - root_dir = os.path.join(git_dir, '..') - # find setup.py - orig_location = location - while not os.path.exists(os.path.join(location, 'setup.py')): - last_location = location - location = os.path.dirname(location) - if location == last_location: - # We've traversed up to the root of the filesystem without - # finding setup.py - logger.warning( - "Could not find setup.py for directory %s (tried all " - "parent directories)", - orig_location, - ) - return None - # relative path of setup.py to repo root - if samefile(root_dir, location): - return None - return os.path.relpath(location, root_dir) - - @classmethod - def get_src_requirement(cls, location, project_name): - repo = cls.get_remote_url(location) - if not repo.lower().startswith('git:'): - repo = 'git+' + repo - current_rev = cls.get_revision(location) - subdir = cls._get_subdirectory(location) - req = make_vcs_requirement_url(repo, current_rev, project_name, - subdir=subdir) - - return req - - def get_url_rev_and_auth(self, url): - """ - Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. - That's required because although they use SSH they sometimes don't - work with a ssh:// scheme (e.g. GitHub). But we need a scheme for - parsing. Hence we remove it again afterwards and return it as a stub. - """ - if '://' not in url: - assert 'file:' not in url - url = url.replace('git+', 'git+ssh://') - url, rev, user_pass = super(Git, self).get_url_rev_and_auth(url) - url = url.replace('ssh://', '') - else: - url, rev, user_pass = super(Git, self).get_url_rev_and_auth(url) - - return url, rev, user_pass - - def update_submodules(self, location): - if not os.path.exists(os.path.join(location, '.gitmodules')): - return - self.run_command( - ['submodule', 'update', '--init', '--recursive', '-q'], - cwd=location, - ) - - @classmethod - def controls_location(cls, location): - if super(Git, cls).controls_location(location): - return True - try: - r = cls.run_command(['rev-parse'], - cwd=location, - show_stdout=False, - on_returncode='ignore') - return not r - except BadCommand: - logger.debug("could not determine if %s is under git control " - "because git is not available", location) - return False - - -vcs.register(Git) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/mercurial.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/mercurial.py deleted file mode 100644 index 26e75de..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/mercurial.py +++ /dev/null @@ -1,103 +0,0 @@ -from __future__ import absolute_import - -import logging -import os - -from pip._vendor.six.moves import configparser - -from pip._internal.download import path_to_url -from pip._internal.utils.misc import display_path, make_vcs_requirement_url -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.vcs import VersionControl, vcs - -logger = logging.getLogger(__name__) - - -class Mercurial(VersionControl): - name = 'hg' - dirname = '.hg' - repo_name = 'clone' - schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') - - def get_base_rev_args(self, rev): - return [rev] - - def export(self, location): - """Export the Hg repository at the url to the destination location""" - with TempDirectory(kind="export") as temp_dir: - self.unpack(temp_dir.path) - - self.run_command( - ['archive', location], show_stdout=False, cwd=temp_dir.path - ) - - def fetch_new(self, dest, url, rev_options): - rev_display = rev_options.to_display() - logger.info( - 'Cloning hg %s%s to %s', - url, - rev_display, - display_path(dest), - ) - self.run_command(['clone', '--noupdate', '-q', url, dest]) - cmd_args = ['update', '-q'] + rev_options.to_args() - self.run_command(cmd_args, cwd=dest) - - def switch(self, dest, url, rev_options): - repo_config = os.path.join(dest, self.dirname, 'hgrc') - config = configparser.SafeConfigParser() - try: - config.read(repo_config) - config.set('paths', 'default', url) - with open(repo_config, 'w') as config_file: - config.write(config_file) - except (OSError, configparser.NoSectionError) as exc: - logger.warning( - 'Could not switch Mercurial repository to %s: %s', url, exc, - ) - else: - cmd_args = ['update', '-q'] + rev_options.to_args() - self.run_command(cmd_args, cwd=dest) - - def update(self, dest, url, rev_options): - self.run_command(['pull', '-q'], cwd=dest) - cmd_args = ['update', '-q'] + rev_options.to_args() - self.run_command(cmd_args, cwd=dest) - - @classmethod - def get_remote_url(cls, location): - url = cls.run_command( - ['showconfig', 'paths.default'], - show_stdout=False, cwd=location).strip() - if cls._is_local_repository(url): - url = path_to_url(url) - return url.strip() - - @classmethod - def get_revision(cls, location): - current_revision = cls.run_command( - ['parents', '--template={rev}'], - show_stdout=False, cwd=location).strip() - return current_revision - - @classmethod - def get_revision_hash(cls, location): - current_rev_hash = cls.run_command( - ['parents', '--template={node}'], - show_stdout=False, cwd=location).strip() - return current_rev_hash - - @classmethod - def get_src_requirement(cls, location, project_name): - repo = cls.get_remote_url(location) - if not repo.lower().startswith('hg:'): - repo = 'hg+' + repo - current_rev_hash = cls.get_revision_hash(location) - return make_vcs_requirement_url(repo, current_rev_hash, project_name) - - def is_commit_id_equal(self, dest, name): - """Always assume the versions don't match""" - return False - - -vcs.register(Mercurial) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/subversion.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/subversion.py deleted file mode 100644 index 42ac5ac..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/vcs/subversion.py +++ /dev/null @@ -1,200 +0,0 @@ -from __future__ import absolute_import - -import logging -import os -import re - -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - display_path, make_vcs_requirement_url, rmtree, split_auth_from_netloc, -) -from pip._internal.vcs import VersionControl, vcs - -_svn_xml_url_re = re.compile('url="([^"]+)"') -_svn_rev_re = re.compile(r'committed-rev="(\d+)"') -_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') -_svn_info_xml_url_re = re.compile(r'<url>(.*)</url>') - - -logger = logging.getLogger(__name__) - - -class Subversion(VersionControl): - name = 'svn' - dirname = '.svn' - repo_name = 'checkout' - schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn') - - def get_base_rev_args(self, rev): - return ['-r', rev] - - def export(self, location): - """Export the svn repository at the url to the destination location""" - url, rev_options = self.get_url_rev_options(self.url) - - logger.info('Exporting svn repository %s to %s', url, location) - with indent_log(): - if os.path.exists(location): - # Subversion doesn't like to check out over an existing - # directory --force fixes this, but was only added in svn 1.5 - rmtree(location) - cmd_args = ['export'] + rev_options.to_args() + [url, location] - self.run_command(cmd_args, show_stdout=False) - - def fetch_new(self, dest, url, rev_options): - rev_display = rev_options.to_display() - logger.info( - 'Checking out %s%s to %s', - url, - rev_display, - display_path(dest), - ) - cmd_args = ['checkout', '-q'] + rev_options.to_args() + [url, dest] - self.run_command(cmd_args) - - def switch(self, dest, url, rev_options): - cmd_args = ['switch'] + rev_options.to_args() + [url, dest] - self.run_command(cmd_args) - - def update(self, dest, url, rev_options): - cmd_args = ['update'] + rev_options.to_args() + [dest] - self.run_command(cmd_args) - - @classmethod - def get_revision(cls, location): - """ - Return the maximum revision for all files under a given location - """ - # Note: taken from setuptools.command.egg_info - revision = 0 - - for base, dirs, files in os.walk(location): - if cls.dirname not in dirs: - dirs[:] = [] - continue # no sense walking uncontrolled subdirs - dirs.remove(cls.dirname) - entries_fn = os.path.join(base, cls.dirname, 'entries') - if not os.path.exists(entries_fn): - # FIXME: should we warn? - continue - - dirurl, localrev = cls._get_svn_url_rev(base) - - if base == location: - base = dirurl + '/' # save the root url - elif not dirurl or not dirurl.startswith(base): - dirs[:] = [] - continue # not part of the same svn tree, skip it - revision = max(revision, localrev) - return revision - - def get_netloc_and_auth(self, netloc, scheme): - """ - This override allows the auth information to be passed to svn via the - --username and --password options instead of via the URL. - """ - if scheme == 'ssh': - # The --username and --password options can't be used for - # svn+ssh URLs, so keep the auth information in the URL. - return super(Subversion, self).get_netloc_and_auth( - netloc, scheme) - - return split_auth_from_netloc(netloc) - - def get_url_rev_and_auth(self, url): - # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it - url, rev, user_pass = super(Subversion, self).get_url_rev_and_auth(url) - if url.startswith('ssh://'): - url = 'svn+' + url - return url, rev, user_pass - - def make_rev_args(self, username, password): - extra_args = [] - if username: - extra_args += ['--username', username] - if password: - extra_args += ['--password', password] - - return extra_args - - @classmethod - def get_remote_url(cls, location): - # In cases where the source is in a subdirectory, not alongside - # setup.py we have to look up in the location until we find a real - # setup.py - orig_location = location - while not os.path.exists(os.path.join(location, 'setup.py')): - last_location = location - location = os.path.dirname(location) - if location == last_location: - # We've traversed up to the root of the filesystem without - # finding setup.py - logger.warning( - "Could not find setup.py for directory %s (tried all " - "parent directories)", - orig_location, - ) - return None - - return cls._get_svn_url_rev(location)[0] - - @classmethod - def _get_svn_url_rev(cls, location): - from pip._internal.exceptions import InstallationError - - entries_path = os.path.join(location, cls.dirname, 'entries') - if os.path.exists(entries_path): - with open(entries_path) as f: - data = f.read() - else: # subversion >= 1.7 does not have the 'entries' file - data = '' - - if (data.startswith('8') or - data.startswith('9') or - data.startswith('10')): - data = list(map(str.splitlines, data.split('\n\x0c\n'))) - del data[0][0] # get rid of the '8' - url = data[0][3] - revs = [int(d[9]) for d in data if len(d) > 9 and d[9]] + [0] - elif data.startswith('<?xml'): - match = _svn_xml_url_re.search(data) - if not match: - raise ValueError('Badly formatted data: %r' % data) - url = match.group(1) # get repository URL - revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0] - else: - try: - # subversion >= 1.7 - xml = cls.run_command( - ['info', '--xml', location], - show_stdout=False, - ) - url = _svn_info_xml_url_re.search(xml).group(1) - revs = [ - int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) - ] - except InstallationError: - url, revs = None, [] - - if revs: - rev = max(revs) - else: - rev = 0 - - return url, rev - - @classmethod - def get_src_requirement(cls, location, project_name): - repo = cls.get_remote_url(location) - if repo is None: - return None - repo = 'svn+' + repo - rev = cls.get_revision(location) - return make_vcs_requirement_url(repo, rev, project_name) - - def is_commit_id_equal(self, dest, name): - """Always assume the versions don't match""" - return False - - -vcs.register(Subversion) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/wheel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/wheel.py deleted file mode 100644 index 67bcc7f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_internal/wheel.py +++ /dev/null @@ -1,1095 +0,0 @@ -""" -Support for installing and building the "wheel" binary package format. -""" -from __future__ import absolute_import - -import collections -import compileall -import csv -import hashlib -import logging -import os.path -import re -import shutil -import stat -import sys -import warnings -from base64 import urlsafe_b64encode -from email.parser import Parser - -from pip._vendor import pkg_resources -from pip._vendor.distlib.scripts import ScriptMaker -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.six import StringIO - -from pip._internal import pep425tags -from pip._internal.download import path_to_url, unpack_url -from pip._internal.exceptions import ( - InstallationError, InvalidWheelFilename, UnsupportedWheel, -) -from pip._internal.locations import ( - PIP_DELETE_MARKER_FILENAME, distutils_scheme, -) -from pip._internal.models.link import Link -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - call_subprocess, captured_stdout, ensure_dir, read_chunks, -) -from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import open_spinner - -if MYPY_CHECK_RUNNING: - from typing import ( # noqa: F401 - Dict, List, Optional, Sequence, Mapping, Tuple, IO, Text, Any, - Union, Iterable - ) - from pip._vendor.packaging.requirements import Requirement # noqa: F401 - from pip._internal.req.req_install import InstallRequirement # noqa: F401 - from pip._internal.download import PipSession # noqa: F401 - from pip._internal.index import FormatControl, PackageFinder # noqa: F401 - from pip._internal.operations.prepare import ( # noqa: F401 - RequirementPreparer - ) - from pip._internal.cache import WheelCache # noqa: F401 - from pip._internal.pep425tags import Pep425Tag # noqa: F401 - - InstalledCSVRow = Tuple[str, ...] - - -VERSION_COMPATIBLE = (1, 0) - - -logger = logging.getLogger(__name__) - - -def normpath(src, p): - return os.path.relpath(src, p).replace(os.path.sep, '/') - - -def rehash(path, blocksize=1 << 20): - # type: (str, int) -> Tuple[str, str] - """Return (hash, length) for path using hashlib.sha256()""" - h = hashlib.sha256() - length = 0 - with open(path, 'rb') as f: - for block in read_chunks(f, size=blocksize): - length += len(block) - h.update(block) - digest = 'sha256=' + urlsafe_b64encode( - h.digest() - ).decode('latin1').rstrip('=') - # unicode/str python2 issues - return (digest, str(length)) # type: ignore - - -def open_for_csv(name, mode): - # type: (str, Text) -> IO - if sys.version_info[0] < 3: - nl = {} # type: Dict[str, Any] - bin = 'b' - else: - nl = {'newline': ''} # type: Dict[str, Any] - bin = '' - return open(name, mode + bin, **nl) - - -def replace_python_tag(wheelname, new_tag): - # type: (str, str) -> str - """Replace the Python tag in a wheel file name with a new value. - """ - parts = wheelname.split('-') - parts[-3] = new_tag - return '-'.join(parts) - - -def fix_script(path): - # type: (str) -> Optional[bool] - """Replace #!python with #!/path/to/python - Return True if file was changed.""" - # XXX RECORD hashes will need to be updated - if os.path.isfile(path): - with open(path, 'rb') as script: - firstline = script.readline() - if not firstline.startswith(b'#!python'): - return False - exename = sys.executable.encode(sys.getfilesystemencoding()) - firstline = b'#!' + exename + os.linesep.encode("ascii") - rest = script.read() - with open(path, 'wb') as script: - script.write(firstline) - script.write(rest) - return True - return None - - -dist_info_re = re.compile(r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) - \.dist-info$""", re.VERBOSE) - - -def root_is_purelib(name, wheeldir): - # type: (str, str) -> bool - """ - Return True if the extracted wheel in wheeldir should go into purelib. - """ - name_folded = name.replace("-", "_") - for item in os.listdir(wheeldir): - match = dist_info_re.match(item) - if match and match.group('name') == name_folded: - with open(os.path.join(wheeldir, item, 'WHEEL')) as wheel: - for line in wheel: - line = line.lower().rstrip() - if line == "root-is-purelib: true": - return True - return False - - -def get_entrypoints(filename): - # type: (str) -> Tuple[Dict[str, str], Dict[str, str]] - if not os.path.exists(filename): - return {}, {} - - # This is done because you can pass a string to entry_points wrappers which - # means that they may or may not be valid INI files. The attempt here is to - # strip leading and trailing whitespace in order to make them valid INI - # files. - with open(filename) as fp: - data = StringIO() - for line in fp: - data.write(line.strip()) - data.write("\n") - data.seek(0) - - # get the entry points and then the script names - entry_points = pkg_resources.EntryPoint.parse_map(data) - console = entry_points.get('console_scripts', {}) - gui = entry_points.get('gui_scripts', {}) - - def _split_ep(s): - """get the string representation of EntryPoint, remove space and split - on '='""" - return str(s).replace(" ", "").split("=") - - # convert the EntryPoint objects into strings with module:function - console = dict(_split_ep(v) for v in console.values()) - gui = dict(_split_ep(v) for v in gui.values()) - return console, gui - - -def message_about_scripts_not_on_PATH(scripts): - # type: (Sequence[str]) -> Optional[str] - """Determine if any scripts are not on PATH and format a warning. - - Returns a warning message if one or more scripts are not on PATH, - otherwise None. - """ - if not scripts: - return None - - # Group scripts by the path they were installed in - grouped_by_dir = collections.defaultdict(set) # type: Dict[str, set] - for destfile in scripts: - parent_dir = os.path.dirname(destfile) - script_name = os.path.basename(destfile) - grouped_by_dir[parent_dir].add(script_name) - - # We don't want to warn for directories that are on PATH. - not_warn_dirs = [ - os.path.normcase(i).rstrip(os.sep) for i in - os.environ.get("PATH", "").split(os.pathsep) - ] - # If an executable sits with sys.executable, we don't warn for it. - # This covers the case of venv invocations without activating the venv. - not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) - warn_for = { - parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() - if os.path.normcase(parent_dir) not in not_warn_dirs - } - if not warn_for: - return None - - # Format a message - msg_lines = [] - for parent_dir, scripts in warn_for.items(): - scripts = sorted(scripts) - if len(scripts) == 1: - start_text = "script {} is".format(scripts[0]) - else: - start_text = "scripts {} are".format( - ", ".join(scripts[:-1]) + " and " + scripts[-1] - ) - - msg_lines.append( - "The {} installed in '{}' which is not on PATH." - .format(start_text, parent_dir) - ) - - last_line_fmt = ( - "Consider adding {} to PATH or, if you prefer " - "to suppress this warning, use --no-warn-script-location." - ) - if len(msg_lines) == 1: - msg_lines.append(last_line_fmt.format("this directory")) - else: - msg_lines.append(last_line_fmt.format("these directories")) - - # Returns the formatted multiline message - return "\n".join(msg_lines) - - -def sorted_outrows(outrows): - # type: (Iterable[InstalledCSVRow]) -> List[InstalledCSVRow] - """ - Return the given rows of a RECORD file in sorted order. - - Each row is a 3-tuple (path, hash, size) and corresponds to a record of - a RECORD file (see PEP 376 and PEP 427 for details). For the rows - passed to this function, the size can be an integer as an int or string, - or the empty string. - """ - # Normally, there should only be one row per path, in which case the - # second and third elements don't come into play when sorting. - # However, in cases in the wild where a path might happen to occur twice, - # we don't want the sort operation to trigger an error (but still want - # determinism). Since the third element can be an int or string, we - # coerce each element to a string to avoid a TypeError in this case. - # For additional background, see-- - # https://github.com/pypa/pip/issues/5868 - return sorted(outrows, key=lambda row: tuple(str(x) for x in row)) - - -def get_csv_rows_for_installed( - old_csv_rows, # type: Iterable[List[str]] - installed, # type: Dict[str, str] - changed, # type: set - generated, # type: List[str] - lib_dir, # type: str -): - # type: (...) -> List[InstalledCSVRow] - """ - :param installed: A map from archive RECORD path to installation RECORD - path. - """ - installed_rows = [] # type: List[InstalledCSVRow] - for row in old_csv_rows: - if len(row) > 3: - logger.warning( - 'RECORD line has more than three elements: {}'.format(row) - ) - # Make a copy because we are mutating the row. - row = list(row) - old_path = row[0] - new_path = installed.pop(old_path, old_path) - row[0] = new_path - if new_path in changed: - digest, length = rehash(new_path) - row[1] = digest - row[2] = length - installed_rows.append(tuple(row)) - for f in generated: - digest, length = rehash(f) - installed_rows.append((normpath(f, lib_dir), digest, str(length))) - for f in installed: - installed_rows.append((installed[f], '', '')) - return installed_rows - - -def move_wheel_files( - name, # type: str - req, # type: Requirement - wheeldir, # type: str - user=False, # type: bool - home=None, # type: Optional[str] - root=None, # type: Optional[str] - pycompile=True, # type: bool - scheme=None, # type: Optional[Mapping[str, str]] - isolated=False, # type: bool - prefix=None, # type: Optional[str] - warn_script_location=True # type: bool -): - # type: (...) -> None - """Install a wheel""" - # TODO: Investigate and break this up. - # TODO: Look into moving this into a dedicated class for representing an - # installation. - - if not scheme: - scheme = distutils_scheme( - name, user=user, home=home, root=root, isolated=isolated, - prefix=prefix, - ) - - if root_is_purelib(name, wheeldir): - lib_dir = scheme['purelib'] - else: - lib_dir = scheme['platlib'] - - info_dir = [] # type: List[str] - data_dirs = [] - source = wheeldir.rstrip(os.path.sep) + os.path.sep - - # Record details of the files moved - # installed = files copied from the wheel to the destination - # changed = files changed while installing (scripts #! line typically) - # generated = files newly generated during the install (script wrappers) - installed = {} # type: Dict[str, str] - changed = set() - generated = [] # type: List[str] - - # Compile all of the pyc files that we're going to be installing - if pycompile: - with captured_stdout() as stdout: - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - compileall.compile_dir(source, force=True, quiet=True) - logger.debug(stdout.getvalue()) - - def record_installed(srcfile, destfile, modified=False): - """Map archive RECORD paths to installation RECORD paths.""" - oldpath = normpath(srcfile, wheeldir) - newpath = normpath(destfile, lib_dir) - installed[oldpath] = newpath - if modified: - changed.add(destfile) - - def clobber(source, dest, is_base, fixer=None, filter=None): - ensure_dir(dest) # common for the 'include' path - - for dir, subdirs, files in os.walk(source): - basedir = dir[len(source):].lstrip(os.path.sep) - destdir = os.path.join(dest, basedir) - if is_base and basedir.split(os.path.sep, 1)[0].endswith('.data'): - continue - for s in subdirs: - destsubdir = os.path.join(dest, basedir, s) - if is_base and basedir == '' and destsubdir.endswith('.data'): - data_dirs.append(s) - continue - elif (is_base and - s.endswith('.dist-info') and - canonicalize_name(s).startswith( - canonicalize_name(req.name))): - assert not info_dir, ('Multiple .dist-info directories: ' + - destsubdir + ', ' + - ', '.join(info_dir)) - info_dir.append(destsubdir) - for f in files: - # Skip unwanted files - if filter and filter(f): - continue - srcfile = os.path.join(dir, f) - destfile = os.path.join(dest, basedir, f) - # directory creation is lazy and after the file filtering above - # to ensure we don't install empty dirs; empty dirs can't be - # uninstalled. - ensure_dir(destdir) - - # copyfile (called below) truncates the destination if it - # exists and then writes the new contents. This is fine in most - # cases, but can cause a segfault if pip has loaded a shared - # object (e.g. from pyopenssl through its vendored urllib3) - # Since the shared object is mmap'd an attempt to call a - # symbol in it will then cause a segfault. Unlinking the file - # allows writing of new contents while allowing the process to - # continue to use the old copy. - if os.path.exists(destfile): - os.unlink(destfile) - - # We use copyfile (not move, copy, or copy2) to be extra sure - # that we are not moving directories over (copyfile fails for - # directories) as well as to ensure that we are not copying - # over any metadata because we want more control over what - # metadata we actually copy over. - shutil.copyfile(srcfile, destfile) - - # Copy over the metadata for the file, currently this only - # includes the atime and mtime. - st = os.stat(srcfile) - if hasattr(os, "utime"): - os.utime(destfile, (st.st_atime, st.st_mtime)) - - # If our file is executable, then make our destination file - # executable. - if os.access(srcfile, os.X_OK): - st = os.stat(srcfile) - permissions = ( - st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH - ) - os.chmod(destfile, permissions) - - changed = False - if fixer: - changed = fixer(destfile) - record_installed(srcfile, destfile, changed) - - clobber(source, lib_dir, True) - - assert info_dir, "%s .dist-info directory not found" % req - - # Get the defined entry points - ep_file = os.path.join(info_dir[0], 'entry_points.txt') - console, gui = get_entrypoints(ep_file) - - def is_entrypoint_wrapper(name): - # EP, EP.exe and EP-script.py are scripts generated for - # entry point EP by setuptools - if name.lower().endswith('.exe'): - matchname = name[:-4] - elif name.lower().endswith('-script.py'): - matchname = name[:-10] - elif name.lower().endswith(".pya"): - matchname = name[:-4] - else: - matchname = name - # Ignore setuptools-generated scripts - return (matchname in console or matchname in gui) - - for datadir in data_dirs: - fixer = None - filter = None - for subdir in os.listdir(os.path.join(wheeldir, datadir)): - fixer = None - if subdir == 'scripts': - fixer = fix_script - filter = is_entrypoint_wrapper - source = os.path.join(wheeldir, datadir, subdir) - dest = scheme[subdir] - clobber(source, dest, False, fixer=fixer, filter=filter) - - maker = ScriptMaker(None, scheme['scripts']) - - # Ensure old scripts are overwritten. - # See https://github.com/pypa/pip/issues/1800 - maker.clobber = True - - # Ensure we don't generate any variants for scripts because this is almost - # never what somebody wants. - # See https://bitbucket.org/pypa/distlib/issue/35/ - maker.variants = {''} - - # This is required because otherwise distlib creates scripts that are not - # executable. - # See https://bitbucket.org/pypa/distlib/issue/32/ - maker.set_mode = True - - # Simplify the script and fix the fact that the default script swallows - # every single stack trace. - # See https://bitbucket.org/pypa/distlib/issue/34/ - # See https://bitbucket.org/pypa/distlib/issue/33/ - def _get_script_text(entry): - if entry.suffix is None: - raise InstallationError( - "Invalid script entry point: %s for req: %s - A callable " - "suffix is required. Cf https://packaging.python.org/en/" - "latest/distributing.html#console-scripts for more " - "information." % (entry, req) - ) - return maker.script_template % { - "module": entry.prefix, - "import_name": entry.suffix.split(".")[0], - "func": entry.suffix, - } - # ignore type, because mypy disallows assigning to a method, - # see https://github.com/python/mypy/issues/2427 - maker._get_script_text = _get_script_text # type: ignore - maker.script_template = r"""# -*- coding: utf-8 -*- -import re -import sys - -from %(module)s import %(import_name)s - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(%(func)s()) -""" - - # Special case pip and setuptools to generate versioned wrappers - # - # The issue is that some projects (specifically, pip and setuptools) use - # code in setup.py to create "versioned" entry points - pip2.7 on Python - # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into - # the wheel metadata at build time, and so if the wheel is installed with - # a *different* version of Python the entry points will be wrong. The - # correct fix for this is to enhance the metadata to be able to describe - # such versioned entry points, but that won't happen till Metadata 2.0 is - # available. - # In the meantime, projects using versioned entry points will either have - # incorrect versioned entry points, or they will not be able to distribute - # "universal" wheels (i.e., they will need a wheel per Python version). - # - # Because setuptools and pip are bundled with _ensurepip and virtualenv, - # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we - # override the versioned entry points in the wheel and generate the - # correct ones. This code is purely a short-term measure until Metadata 2.0 - # is available. - # - # To add the level of hack in this section of code, in order to support - # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment - # variable which will control which version scripts get installed. - # - # ENSUREPIP_OPTIONS=altinstall - # - Only pipX.Y and easy_install-X.Y will be generated and installed - # ENSUREPIP_OPTIONS=install - # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note - # that this option is technically if ENSUREPIP_OPTIONS is set and is - # not altinstall - # DEFAULT - # - The default behavior is to install pip, pipX, pipX.Y, easy_install - # and easy_install-X.Y. - pip_script = console.pop('pip', None) - if pip_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - spec = 'pip = ' + pip_script - generated.extend(maker.make(spec)) - - if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": - spec = 'pip%s = %s' % (sys.version[:1], pip_script) - generated.extend(maker.make(spec)) - - spec = 'pip%s = %s' % (sys.version[:3], pip_script) - generated.extend(maker.make(spec)) - # Delete any other versioned pip entry points - pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] - for k in pip_ep: - del console[k] - easy_install_script = console.pop('easy_install', None) - if easy_install_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - spec = 'easy_install = ' + easy_install_script - generated.extend(maker.make(spec)) - - spec = 'easy_install-%s = %s' % (sys.version[:3], easy_install_script) - generated.extend(maker.make(spec)) - # Delete any other versioned easy_install entry points - easy_install_ep = [ - k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) - ] - for k in easy_install_ep: - del console[k] - - # Generate the console and GUI entry points specified in the wheel - if len(console) > 0: - generated_console_scripts = maker.make_multiple( - ['%s = %s' % kv for kv in console.items()] - ) - generated.extend(generated_console_scripts) - - if warn_script_location: - msg = message_about_scripts_not_on_PATH(generated_console_scripts) - if msg is not None: - logger.warning(msg) - - if len(gui) > 0: - generated.extend( - maker.make_multiple( - ['%s = %s' % kv for kv in gui.items()], - {'gui': True} - ) - ) - - # Record pip as the installer - installer = os.path.join(info_dir[0], 'INSTALLER') - temp_installer = os.path.join(info_dir[0], 'INSTALLER.pip') - with open(temp_installer, 'wb') as installer_file: - installer_file.write(b'pip\n') - shutil.move(temp_installer, installer) - generated.append(installer) - - # Record details of all files installed - record = os.path.join(info_dir[0], 'RECORD') - temp_record = os.path.join(info_dir[0], 'RECORD.pip') - with open_for_csv(record, 'r') as record_in: - with open_for_csv(temp_record, 'w+') as record_out: - reader = csv.reader(record_in) - outrows = get_csv_rows_for_installed( - reader, installed=installed, changed=changed, - generated=generated, lib_dir=lib_dir, - ) - writer = csv.writer(record_out) - # Sort to simplify testing. - for row in sorted_outrows(outrows): - writer.writerow(row) - shutil.move(temp_record, record) - - -def wheel_version(source_dir): - # type: (Optional[str]) -> Optional[Tuple[int, ...]] - """ - Return the Wheel-Version of an extracted wheel, if possible. - - Otherwise, return None if we couldn't parse / extract it. - """ - try: - dist = [d for d in pkg_resources.find_on_path(None, source_dir)][0] - - wheel_data = dist.get_metadata('WHEEL') - wheel_data = Parser().parsestr(wheel_data) - - version = wheel_data['Wheel-Version'].strip() - version = tuple(map(int, version.split('.'))) - return version - except Exception: - return None - - -def check_compatibility(version, name): - # type: (Optional[Tuple[int, ...]], str) -> None - """ - Raises errors or warns if called with an incompatible Wheel-Version. - - Pip should refuse to install a Wheel-Version that's a major series - ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when - installing a version only minor version ahead (e.g 1.2 > 1.1). - - version: a 2-tuple representing a Wheel-Version (Major, Minor) - name: name of wheel or package to raise exception about - - :raises UnsupportedWheel: when an incompatible Wheel-Version is given - """ - if not version: - raise UnsupportedWheel( - "%s is in an unsupported or invalid wheel" % name - ) - if version[0] > VERSION_COMPATIBLE[0]: - raise UnsupportedWheel( - "%s's Wheel-Version (%s) is not compatible with this version " - "of pip" % (name, '.'.join(map(str, version))) - ) - elif version > VERSION_COMPATIBLE: - logger.warning( - 'Installing from a newer Wheel-Version (%s)', - '.'.join(map(str, version)), - ) - - -class Wheel(object): - """A wheel file""" - - # TODO: Maybe move the class into the models sub-package - # TODO: Maybe move the install code into this class - - wheel_file_re = re.compile( - r"""^(?P<namever>(?P<name>.+?)-(?P<ver>.*?)) - ((-(?P<build>\d[^-]*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?) - \.whl|\.dist-info)$""", - re.VERBOSE - ) - - def __init__(self, filename): - # type: (str) -> None - """ - :raises InvalidWheelFilename: when the filename is invalid for a wheel - """ - wheel_info = self.wheel_file_re.match(filename) - if not wheel_info: - raise InvalidWheelFilename( - "%s is not a valid wheel filename." % filename - ) - self.filename = filename - self.name = wheel_info.group('name').replace('_', '-') - # we'll assume "_" means "-" due to wheel naming scheme - # (https://github.com/pypa/pip/issues/1150) - self.version = wheel_info.group('ver').replace('_', '-') - self.build_tag = wheel_info.group('build') - self.pyversions = wheel_info.group('pyver').split('.') - self.abis = wheel_info.group('abi').split('.') - self.plats = wheel_info.group('plat').split('.') - - # All the tag combinations from this file - self.file_tags = { - (x, y, z) for x in self.pyversions - for y in self.abis for z in self.plats - } - - def support_index_min(self, tags=None): - # type: (Optional[List[Pep425Tag]]) -> Optional[int] - """ - Return the lowest index that one of the wheel's file_tag combinations - achieves in the supported_tags list e.g. if there are 8 supported tags, - and one of the file tags is first in the list, then return 0. Returns - None is the wheel is not supported. - """ - if tags is None: # for mock - tags = pep425tags.get_supported() - indexes = [tags.index(c) for c in self.file_tags if c in tags] - return min(indexes) if indexes else None - - def supported(self, tags=None): - # type: (Optional[List[Pep425Tag]]) -> bool - """Is this wheel supported on this system?""" - if tags is None: # for mock - tags = pep425tags.get_supported() - return bool(set(tags).intersection(self.file_tags)) - - -def _contains_egg_info( - s, _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): - """Determine whether the string looks like an egg_info. - - :param s: The string to parse. E.g. foo-2.1 - """ - return bool(_egg_info_re.search(s)) - - -def should_use_ephemeral_cache( - req, # type: InstallRequirement - format_control, # type: FormatControl - autobuilding, # type: bool - cache_available # type: bool -): - # type: (...) -> Optional[bool] - """ - Return whether to build an InstallRequirement object using the - ephemeral cache. - - :param cache_available: whether a cache directory is available for the - autobuilding=True case. - - :return: True or False to build the requirement with ephem_cache=True - or False, respectively; or None not to build the requirement. - """ - if req.constraint: - return None - if req.is_wheel: - if not autobuilding: - logger.info( - 'Skipping %s, due to already being wheel.', req.name, - ) - return None - if not autobuilding: - return False - - if req.editable or not req.source_dir: - return None - - if req.link and not req.link.is_artifact: - # VCS checkout. Build wheel just for this run. - return True - - if "binary" not in format_control.get_allowed_formats( - canonicalize_name(req.name)): - logger.info( - "Skipping bdist_wheel for %s, due to binaries " - "being disabled for it.", req.name, - ) - return None - - link = req.link - base, ext = link.splitext() - if cache_available and _contains_egg_info(base): - return False - - # Otherwise, build the wheel just for this run using the ephemeral - # cache since we are either in the case of e.g. a local directory, or - # no cache directory is available to use. - return True - - -def format_command( - command_args, # type: List[str] - command_output, # type: str -): - # type: (...) -> str - """ - Format command information for logging. - """ - text = 'Command arguments: {}\n'.format(command_args) - - if not command_output: - text += 'Command output: None' - elif logger.getEffectiveLevel() > logging.DEBUG: - text += 'Command output: [use --verbose to show]' - else: - if not command_output.endswith('\n'): - command_output += '\n' - text += ( - 'Command output:\n{}' - '-----------------------------------------' - ).format(command_output) - - return text - - -def get_legacy_build_wheel_path( - names, # type: List[str] - temp_dir, # type: str - req, # type: InstallRequirement - command_args, # type: List[str] - command_output, # type: str -): - # type: (...) -> Optional[str] - """ - Return the path to the wheel in the temporary build directory. - """ - # Sort for determinism. - names = sorted(names) - if not names: - msg = ( - 'Legacy build of wheel for {!r} created no files.\n' - ).format(req.name) - msg += format_command(command_args, command_output) - logger.warning(msg) - return None - - if len(names) > 1: - msg = ( - 'Legacy build of wheel for {!r} created more than one file.\n' - 'Filenames (choosing first): {}\n' - ).format(req.name, names) - msg += format_command(command_args, command_output) - logger.warning(msg) - - return os.path.join(temp_dir, names[0]) - - -class WheelBuilder(object): - """Build wheels from a RequirementSet.""" - - def __init__( - self, - finder, # type: PackageFinder - preparer, # type: RequirementPreparer - wheel_cache, # type: WheelCache - build_options=None, # type: Optional[List[str]] - global_options=None, # type: Optional[List[str]] - no_clean=False # type: bool - ): - # type: (...) -> None - self.finder = finder - self.preparer = preparer - self.wheel_cache = wheel_cache - - self._wheel_dir = preparer.wheel_download_dir - - self.build_options = build_options or [] - self.global_options = global_options or [] - self.no_clean = no_clean - - def _build_one(self, req, output_dir, python_tag=None): - """Build one wheel. - - :return: The filename of the built wheel, or None if the build failed. - """ - # Install build deps into temporary directory (PEP 518) - with req.build_env: - return self._build_one_inside_env(req, output_dir, - python_tag=python_tag) - - def _build_one_inside_env(self, req, output_dir, python_tag=None): - with TempDirectory(kind="wheel") as temp_dir: - if req.use_pep517: - builder = self._build_one_pep517 - else: - builder = self._build_one_legacy - wheel_path = builder(req, temp_dir.path, python_tag=python_tag) - if wheel_path is not None: - wheel_name = os.path.basename(wheel_path) - dest_path = os.path.join(output_dir, wheel_name) - try: - shutil.move(wheel_path, dest_path) - logger.info('Stored in directory: %s', output_dir) - return dest_path - except Exception: - pass - # Ignore return, we can't do anything else useful. - self._clean_one(req) - return None - - def _base_setup_args(self, req): - # NOTE: Eventually, we'd want to also -S to the flags here, when we're - # isolating. Currently, it breaks Python in virtualenvs, because it - # relies on site.py to find parts of the standard library outside the - # virtualenv. - return [ - sys.executable, '-u', '-c', - SETUPTOOLS_SHIM % req.setup_py - ] + list(self.global_options) - - def _build_one_pep517(self, req, tempd, python_tag=None): - """Build one InstallRequirement using the PEP 517 build process. - - Returns path to wheel if successfully built. Otherwise, returns None. - """ - assert req.metadata_directory is not None - try: - req.spin_message = 'Building wheel for %s (PEP 517)' % (req.name,) - logger.debug('Destination directory: %s', tempd) - wheel_name = req.pep517_backend.build_wheel( - tempd, - metadata_directory=req.metadata_directory - ) - if python_tag: - # General PEP 517 backends don't necessarily support - # a "--python-tag" option, so we rename the wheel - # file directly. - new_name = replace_python_tag(wheel_name, python_tag) - os.rename( - os.path.join(tempd, wheel_name), - os.path.join(tempd, new_name) - ) - # Reassign to simplify the return at the end of function - wheel_name = new_name - except Exception: - logger.error('Failed building wheel for %s', req.name) - return None - return os.path.join(tempd, wheel_name) - - def _build_one_legacy(self, req, tempd, python_tag=None): - """Build one InstallRequirement using the "legacy" build process. - - Returns path to wheel if successfully built. Otherwise, returns None. - """ - base_args = self._base_setup_args(req) - - spin_message = 'Building wheel for %s (setup.py)' % (req.name,) - with open_spinner(spin_message) as spinner: - logger.debug('Destination directory: %s', tempd) - wheel_args = base_args + ['bdist_wheel', '-d', tempd] \ - + self.build_options - - if python_tag is not None: - wheel_args += ["--python-tag", python_tag] - - try: - output = call_subprocess(wheel_args, cwd=req.setup_py_dir, - show_stdout=False, spinner=spinner) - except Exception: - spinner.finish("error") - logger.error('Failed building wheel for %s', req.name) - return None - names = os.listdir(tempd) - wheel_path = get_legacy_build_wheel_path( - names=names, - temp_dir=tempd, - req=req, - command_args=wheel_args, - command_output=output, - ) - return wheel_path - - def _clean_one(self, req): - base_args = self._base_setup_args(req) - - logger.info('Running setup.py clean for %s', req.name) - clean_args = base_args + ['clean', '--all'] - try: - call_subprocess(clean_args, cwd=req.source_dir, show_stdout=False) - return True - except Exception: - logger.error('Failed cleaning build dir for %s', req.name) - return False - - def build( - self, - requirements, # type: Iterable[InstallRequirement] - session, # type: PipSession - autobuilding=False # type: bool - ): - # type: (...) -> List[InstallRequirement] - """Build wheels. - - :param unpack: If True, replace the sdist we built from with the - newly built wheel, in preparation for installation. - :return: True if all the wheels built correctly. - """ - buildset = [] - format_control = self.finder.format_control - # Whether a cache directory is available for autobuilding=True. - cache_available = bool(self._wheel_dir or self.wheel_cache.cache_dir) - - for req in requirements: - ephem_cache = should_use_ephemeral_cache( - req, format_control=format_control, autobuilding=autobuilding, - cache_available=cache_available, - ) - if ephem_cache is None: - continue - - buildset.append((req, ephem_cache)) - - if not buildset: - return [] - - # Is any wheel build not using the ephemeral cache? - if any(not ephem_cache for _, ephem_cache in buildset): - have_directory_for_build = self._wheel_dir or ( - autobuilding and self.wheel_cache.cache_dir - ) - assert have_directory_for_build - - # TODO by @pradyunsg - # Should break up this method into 2 separate methods. - - # Build the wheels. - logger.info( - 'Building wheels for collected packages: %s', - ', '.join([req.name for (req, _) in buildset]), - ) - _cache = self.wheel_cache # shorter name - with indent_log(): - build_success, build_failure = [], [] - for req, ephem in buildset: - python_tag = None - if autobuilding: - python_tag = pep425tags.implementation_tag - if ephem: - output_dir = _cache.get_ephem_path_for_link(req.link) - else: - output_dir = _cache.get_path_for_link(req.link) - try: - ensure_dir(output_dir) - except OSError as e: - logger.warning("Building wheel for %s failed: %s", - req.name, e) - build_failure.append(req) - continue - else: - output_dir = self._wheel_dir - wheel_file = self._build_one( - req, output_dir, - python_tag=python_tag, - ) - if wheel_file: - build_success.append(req) - if autobuilding: - # XXX: This is mildly duplicative with prepare_files, - # but not close enough to pull out to a single common - # method. - # The code below assumes temporary source dirs - - # prevent it doing bad things. - if req.source_dir and not os.path.exists(os.path.join( - req.source_dir, PIP_DELETE_MARKER_FILENAME)): - raise AssertionError( - "bad source dir - missing marker") - # Delete the source we built the wheel from - req.remove_temporary_source() - # set the build directory again - name is known from - # the work prepare_files did. - req.source_dir = req.build_location( - self.preparer.build_dir - ) - # Update the link for this. - req.link = Link(path_to_url(wheel_file)) - assert req.link.is_wheel - # extract the wheel into the dir - unpack_url( - req.link, req.source_dir, None, False, - session=session, - ) - else: - build_failure.append(req) - - # notify success/failure - if build_success: - logger.info( - 'Successfully built %s', - ' '.join([req.name for req in build_success]), - ) - if build_failure: - logger.info( - 'Failed to build %s', - ' '.join([req.name for req in build_failure]), - ) - # Return a list of requirements that failed to build - return build_failure diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/__init__.py deleted file mode 100644 index b919b54..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/__init__.py +++ /dev/null @@ -1,111 +0,0 @@ -""" -pip._vendor is for vendoring dependencies of pip to prevent needing pip to -depend on something external. - -Files inside of pip._vendor should be considered immutable and should only be -updated to versions from upstream. -""" -from __future__ import absolute_import - -import glob -import os.path -import sys - -# Downstream redistributors which have debundled our dependencies should also -# patch this value to be true. This will trigger the additional patching -# to cause things like "six" to be available as pip. -DEBUNDLED = False - -# By default, look in this directory for a bunch of .whl files which we will -# add to the beginning of sys.path before attempting to import anything. This -# is done to support downstream re-distributors like Debian and Fedora who -# wish to create their own Wheels for our dependencies to aid in debundling. -WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) - - -# Define a small helper function to alias our vendored modules to the real ones -# if the vendored ones do not exist. This idea of this was taken from -# https://github.com/kennethreitz/requests/pull/2567. -def vendored(modulename): - vendored_name = "{0}.{1}".format(__name__, modulename) - - try: - __import__(vendored_name, globals(), locals(), level=0) - except ImportError: - try: - __import__(modulename, globals(), locals(), level=0) - except ImportError: - # We can just silently allow import failures to pass here. If we - # got to this point it means that ``import pip._vendor.whatever`` - # failed and so did ``import whatever``. Since we're importing this - # upfront in an attempt to alias imports, not erroring here will - # just mean we get a regular import error whenever pip *actually* - # tries to import one of these modules to use it, which actually - # gives us a better error message than we would have otherwise - # gotten. - pass - else: - sys.modules[vendored_name] = sys.modules[modulename] - base, head = vendored_name.rsplit(".", 1) - setattr(sys.modules[base], head, sys.modules[modulename]) - - -# If we're operating in a debundled setup, then we want to go ahead and trigger -# the aliasing of our vendored libraries as well as looking for wheels to add -# to our sys.path. This will cause all of this code to be a no-op typically -# however downstream redistributors can enable it in a consistent way across -# all platforms. -if DEBUNDLED: - # Actually look inside of WHEEL_DIR to find .whl files and add them to the - # front of our sys.path. - sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path - - # Actually alias all of our vendored dependencies. - vendored("cachecontrol") - vendored("colorama") - vendored("distlib") - vendored("distro") - vendored("html5lib") - vendored("lockfile") - vendored("six") - vendored("six.moves") - vendored("six.moves.urllib") - vendored("six.moves.urllib.parse") - vendored("packaging") - vendored("packaging.version") - vendored("packaging.specifiers") - vendored("pep517") - vendored("pkg_resources") - vendored("progress") - vendored("pytoml") - vendored("retrying") - vendored("requests") - vendored("requests.packages") - vendored("requests.packages.urllib3") - vendored("requests.packages.urllib3._collections") - vendored("requests.packages.urllib3.connection") - vendored("requests.packages.urllib3.connectionpool") - vendored("requests.packages.urllib3.contrib") - vendored("requests.packages.urllib3.contrib.ntlmpool") - vendored("requests.packages.urllib3.contrib.pyopenssl") - vendored("requests.packages.urllib3.exceptions") - vendored("requests.packages.urllib3.fields") - vendored("requests.packages.urllib3.filepost") - vendored("requests.packages.urllib3.packages") - vendored("requests.packages.urllib3.packages.ordered_dict") - vendored("requests.packages.urllib3.packages.six") - vendored("requests.packages.urllib3.packages.ssl_match_hostname") - vendored("requests.packages.urllib3.packages.ssl_match_hostname." - "_implementation") - vendored("requests.packages.urllib3.poolmanager") - vendored("requests.packages.urllib3.request") - vendored("requests.packages.urllib3.response") - vendored("requests.packages.urllib3.util") - vendored("requests.packages.urllib3.util.connection") - vendored("requests.packages.urllib3.util.request") - vendored("requests.packages.urllib3.util.response") - vendored("requests.packages.urllib3.util.retry") - vendored("requests.packages.urllib3.util.ssl_") - vendored("requests.packages.urllib3.util.timeout") - vendored("requests.packages.urllib3.util.url") - vendored("urllib3") diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/appdirs.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/appdirs.py deleted file mode 100644 index 2bd3911..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/appdirs.py +++ /dev/null @@ -1,604 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (c) 2005-2010 ActiveState Software Inc. -# Copyright (c) 2013 Eddy Petrișor - -"""Utilities for determining application-specific dirs. - -See <http://github.com/ActiveState/appdirs> for details and usage. -""" -# Dev Notes: -# - MSDN on where to store app data files: -# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 -# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html -# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html - -__version_info__ = (1, 4, 3) -__version__ = '.'.join(map(str, __version_info__)) - - -import sys -import os - -PY3 = sys.version_info[0] == 3 - -if PY3: - unicode = str - -if sys.platform.startswith('java'): - import platform - os_name = platform.java_ver()[3][0] - if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. - system = 'win32' - elif os_name.startswith('Mac'): # "Mac OS X", etc. - system = 'darwin' - else: # "Linux", "SunOS", "FreeBSD", etc. - # Setting this to "linux2" is not ideal, but only Windows or Mac - # are actually checked for and the rest of the module expects - # *sys.platform* style strings. - system = 'linux2' -else: - system = sys.platform - - - -def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be "<major>.<minor>". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> - for a discussion of issues. - - Typical user data directories are: - Mac OS X: ~/Library/Application Support/<AppName> - Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined - Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName> - Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName> - Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> - Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> - - For Unix, we follow the XDG spec and support $XDG_DATA_HOME. - That means, by default "~/.local/share/<AppName>". - """ - if system == "win32": - if appauthor is None: - appauthor = appname - const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" - path = os.path.normpath(_get_win_folder(const)) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - elif system == 'darwin': - path = os.path.expanduser('~/Library/Application Support/') - if appname: - path = os.path.join(path, appname) - else: - path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): - r"""Return full path to the user-shared data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be "<major>.<minor>". - Only applied when appname is present. - "multipath" is an optional parameter only applicable to *nix - which indicates that the entire list of data dirs should be - returned. By default, the first item from XDG_DATA_DIRS is - returned, or '/usr/local/share/<AppName>', - if XDG_DATA_DIRS is not set - - Typical site data directories are: - Mac OS X: /Library/Application Support/<AppName> - Unix: /usr/local/share/<AppName> or /usr/share/<AppName> - Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> - Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) - Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. - - For Unix, this is using the $XDG_DATA_DIRS[0] default. - - WARNING: Do not use this on Windows. See the Vista-Fail note above for why. - """ - if system == "win32": - if appauthor is None: - appauthor = appname - path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - elif system == 'darwin': - path = os.path.expanduser('/Library/Application Support') - if appname: - path = os.path.join(path, appname) - else: - # XDG default for $XDG_DATA_DIRS - # only first, if multipath is False - path = os.getenv('XDG_DATA_DIRS', - os.pathsep.join(['/usr/local/share', '/usr/share'])) - pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] - if appname: - if version: - appname = os.path.join(appname, version) - pathlist = [os.sep.join([x, appname]) for x in pathlist] - - if multipath: - path = os.pathsep.join(pathlist) - else: - path = pathlist[0] - return path - - if appname and version: - path = os.path.join(path, version) - return path - - -def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific config dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be "<major>.<minor>". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> - for a discussion of issues. - - Typical user config directories are: - Mac OS X: same as user_data_dir - Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined - Win *: same as user_data_dir - - For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. - That means, by default "~/.config/<AppName>". - """ - if system in ["win32", "darwin"]: - path = user_data_dir(appname, appauthor, None, roaming) - else: - path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): - r"""Return full path to the user-shared data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be "<major>.<minor>". - Only applied when appname is present. - "multipath" is an optional parameter only applicable to *nix - which indicates that the entire list of config dirs should be - returned. By default, the first item from XDG_CONFIG_DIRS is - returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set - - Typical site config directories are: - Mac OS X: same as site_data_dir - Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in - $XDG_CONFIG_DIRS - Win *: same as site_data_dir - Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) - - For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False - - WARNING: Do not use this on Windows. See the Vista-Fail note above for why. - """ - if system in ["win32", "darwin"]: - path = site_data_dir(appname, appauthor) - if appname and version: - path = os.path.join(path, version) - else: - # XDG default for $XDG_CONFIG_DIRS - # only first, if multipath is False - path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') - pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] - if appname: - if version: - appname = os.path.join(appname, version) - pathlist = [os.sep.join([x, appname]) for x in pathlist] - - if multipath: - path = os.pathsep.join(pathlist) - else: - path = pathlist[0] - return path - - -def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): - r"""Return full path to the user-specific cache dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be "<major>.<minor>". - Only applied when appname is present. - "opinion" (boolean) can be False to disable the appending of - "Cache" to the base app data dir for Windows. See - discussion below. - - Typical user cache directories are: - Mac OS X: ~/Library/Caches/<AppName> - Unix: ~/.cache/<AppName> (XDG default) - Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache - Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache - - On Windows the only suggestion in the MSDN docs is that local settings go in - the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming - app data dir (the default returned by `user_data_dir` above). Apps typically - put cache data somewhere *under* the given dir here. Some examples: - ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache - ...\Acme\SuperApp\Cache\1.0 - OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. - This can be disabled with the `opinion=False` option. - """ - if system == "win32": - if appauthor is None: - appauthor = appname - path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - if opinion: - path = os.path.join(path, "Cache") - elif system == 'darwin': - path = os.path.expanduser('~/Library/Caches') - if appname: - path = os.path.join(path, appname) - else: - path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific state dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be "<major>.<minor>". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> - for a discussion of issues. - - Typical user state directories are: - Mac OS X: same as user_data_dir - Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined - Win *: same as user_data_dir - - For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> - to extend the XDG spec and support $XDG_STATE_HOME. - - That means, by default "~/.local/state/<AppName>". - """ - if system in ["win32", "darwin"]: - path = user_data_dir(appname, appauthor, None, roaming) - else: - path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): - r"""Return full path to the user-specific log dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be "<major>.<minor>". - Only applied when appname is present. - "opinion" (boolean) can be False to disable the appending of - "Logs" to the base app data dir for Windows, and "log" to the - base cache dir for Unix. See discussion below. - - Typical user log directories are: - Mac OS X: ~/Library/Logs/<AppName> - Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined - Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs - Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs - - On Windows the only suggestion in the MSDN docs is that local settings - go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in - examples of what some windows apps use for a logs dir.) - - OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` - value for Windows and appends "log" to the user cache dir for Unix. - This can be disabled with the `opinion=False` option. - """ - if system == "darwin": - path = os.path.join( - os.path.expanduser('~/Library/Logs'), - appname) - elif system == "win32": - path = user_data_dir(appname, appauthor, version) - version = False - if opinion: - path = os.path.join(path, "Logs") - else: - path = user_cache_dir(appname, appauthor, version) - version = False - if opinion: - path = os.path.join(path, "log") - if appname and version: - path = os.path.join(path, version) - return path - - -class AppDirs(object): - """Convenience wrapper for getting application dirs.""" - def __init__(self, appname=None, appauthor=None, version=None, - roaming=False, multipath=False): - self.appname = appname - self.appauthor = appauthor - self.version = version - self.roaming = roaming - self.multipath = multipath - - @property - def user_data_dir(self): - return user_data_dir(self.appname, self.appauthor, - version=self.version, roaming=self.roaming) - - @property - def site_data_dir(self): - return site_data_dir(self.appname, self.appauthor, - version=self.version, multipath=self.multipath) - - @property - def user_config_dir(self): - return user_config_dir(self.appname, self.appauthor, - version=self.version, roaming=self.roaming) - - @property - def site_config_dir(self): - return site_config_dir(self.appname, self.appauthor, - version=self.version, multipath=self.multipath) - - @property - def user_cache_dir(self): - return user_cache_dir(self.appname, self.appauthor, - version=self.version) - - @property - def user_state_dir(self): - return user_state_dir(self.appname, self.appauthor, - version=self.version) - - @property - def user_log_dir(self): - return user_log_dir(self.appname, self.appauthor, - version=self.version) - - -#---- internal support stuff - -def _get_win_folder_from_registry(csidl_name): - """This is a fallback technique at best. I'm not sure if using the - registry for this guarantees us the correct answer for all CSIDL_* - names. - """ - if PY3: - import winreg as _winreg - else: - import _winreg - - shell_folder_name = { - "CSIDL_APPDATA": "AppData", - "CSIDL_COMMON_APPDATA": "Common AppData", - "CSIDL_LOCAL_APPDATA": "Local AppData", - }[csidl_name] - - key = _winreg.OpenKey( - _winreg.HKEY_CURRENT_USER, - r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" - ) - dir, type = _winreg.QueryValueEx(key, shell_folder_name) - return dir - - -def _get_win_folder_with_pywin32(csidl_name): - from win32com.shell import shellcon, shell - dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) - # Try to make this a unicode path because SHGetFolderPath does - # not return unicode strings when there is unicode data in the - # path. - try: - dir = unicode(dir) - - # Downgrade to short path name if have highbit chars. See - # <http://bugs.activestate.com/show_bug.cgi?id=85099>. - has_high_char = False - for c in dir: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - try: - import win32api - dir = win32api.GetShortPathName(dir) - except ImportError: - pass - except UnicodeError: - pass - return dir - - -def _get_win_folder_with_ctypes(csidl_name): - import ctypes - - csidl_const = { - "CSIDL_APPDATA": 26, - "CSIDL_COMMON_APPDATA": 35, - "CSIDL_LOCAL_APPDATA": 28, - }[csidl_name] - - buf = ctypes.create_unicode_buffer(1024) - ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) - - # Downgrade to short path name if have highbit chars. See - # <http://bugs.activestate.com/show_bug.cgi?id=85099>. - has_high_char = False - for c in buf: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - buf2 = ctypes.create_unicode_buffer(1024) - if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): - buf = buf2 - - return buf.value - -def _get_win_folder_with_jna(csidl_name): - import array - from com.sun import jna - from com.sun.jna.platform import win32 - - buf_size = win32.WinDef.MAX_PATH * 2 - buf = array.zeros('c', buf_size) - shell = win32.Shell32.INSTANCE - shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) - dir = jna.Native.toString(buf.tostring()).rstrip("\0") - - # Downgrade to short path name if have highbit chars. See - # <http://bugs.activestate.com/show_bug.cgi?id=85099>. - has_high_char = False - for c in dir: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - buf = array.zeros('c', buf_size) - kernel = win32.Kernel32.INSTANCE - if kernel.GetShortPathName(dir, buf, buf_size): - dir = jna.Native.toString(buf.tostring()).rstrip("\0") - - return dir - -if system == "win32": - try: - from ctypes import windll - _get_win_folder = _get_win_folder_with_ctypes - except ImportError: - try: - import com.sun.jna - _get_win_folder = _get_win_folder_with_jna - except ImportError: - _get_win_folder = _get_win_folder_from_registry - - -#---- self test code - -if __name__ == "__main__": - appname = "MyApp" - appauthor = "MyCompany" - - props = ("user_data_dir", - "user_config_dir", - "user_cache_dir", - "user_state_dir", - "user_log_dir", - "site_data_dir", - "site_config_dir") - - print("-- app dirs %s --" % __version__) - - print("-- app dirs (with optional 'version')") - dirs = AppDirs(appname, appauthor, version="1.0") - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (without optional 'version')") - dirs = AppDirs(appname, appauthor) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (without optional 'appauthor')") - dirs = AppDirs(appname) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (with disabled 'appauthor')") - dirs = AppDirs(appname, appauthor=False) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/__init__.py deleted file mode 100644 index 8fdee66..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -"""CacheControl import Interface. - -Make it easy to import from cachecontrol without long namespaces. -""" -__author__ = "Eric Larson" -__email__ = "eric@ionrock.org" -__version__ = "0.12.5" - -from .wrapper import CacheControl -from .adapter import CacheControlAdapter -from .controller import CacheController diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/_cmd.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/_cmd.py deleted file mode 100644 index f1e0ad9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/_cmd.py +++ /dev/null @@ -1,57 +0,0 @@ -import logging - -from pip._vendor import requests - -from pip._vendor.cachecontrol.adapter import CacheControlAdapter -from pip._vendor.cachecontrol.cache import DictCache -from pip._vendor.cachecontrol.controller import logger - -from argparse import ArgumentParser - - -def setup_logging(): - logger.setLevel(logging.DEBUG) - handler = logging.StreamHandler() - logger.addHandler(handler) - - -def get_session(): - adapter = CacheControlAdapter( - DictCache(), cache_etags=True, serializer=None, heuristic=None - ) - sess = requests.Session() - sess.mount("http://", adapter) - sess.mount("https://", adapter) - - sess.cache_controller = adapter.controller - return sess - - -def get_args(): - parser = ArgumentParser() - parser.add_argument("url", help="The URL to try and cache") - return parser.parse_args() - - -def main(args=None): - args = get_args() - sess = get_session() - - # Make a request to get a response - resp = sess.get(args.url) - - # Turn on logging - setup_logging() - - # try setting the cache - sess.cache_controller.cache_response(resp.request, resp.raw) - - # Now try to get it - if sess.cache_controller.cached_request(resp.request): - print("Cached!") - else: - print("Not cached :(") - - -if __name__ == "__main__": - main() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/adapter.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/adapter.py deleted file mode 100644 index 780eb28..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/adapter.py +++ /dev/null @@ -1,133 +0,0 @@ -import types -import functools -import zlib - -from pip._vendor.requests.adapters import HTTPAdapter - -from .controller import CacheController -from .cache import DictCache -from .filewrapper import CallbackFileWrapper - - -class CacheControlAdapter(HTTPAdapter): - invalidating_methods = {"PUT", "DELETE"} - - def __init__( - self, - cache=None, - cache_etags=True, - controller_class=None, - serializer=None, - heuristic=None, - cacheable_methods=None, - *args, - **kw - ): - super(CacheControlAdapter, self).__init__(*args, **kw) - self.cache = cache or DictCache() - self.heuristic = heuristic - self.cacheable_methods = cacheable_methods or ("GET",) - - controller_factory = controller_class or CacheController - self.controller = controller_factory( - self.cache, cache_etags=cache_etags, serializer=serializer - ) - - def send(self, request, cacheable_methods=None, **kw): - """ - Send a request. Use the request information to see if it - exists in the cache and cache the response if we need to and can. - """ - cacheable = cacheable_methods or self.cacheable_methods - if request.method in cacheable: - try: - cached_response = self.controller.cached_request(request) - except zlib.error: - cached_response = None - if cached_response: - return self.build_response(request, cached_response, from_cache=True) - - # check for etags and add headers if appropriate - request.headers.update(self.controller.conditional_headers(request)) - - resp = super(CacheControlAdapter, self).send(request, **kw) - - return resp - - def build_response( - self, request, response, from_cache=False, cacheable_methods=None - ): - """ - Build a response by making a request or using the cache. - - This will end up calling send and returning a potentially - cached response - """ - cacheable = cacheable_methods or self.cacheable_methods - if not from_cache and request.method in cacheable: - # Check for any heuristics that might update headers - # before trying to cache. - if self.heuristic: - response = self.heuristic.apply(response) - - # apply any expiration heuristics - if response.status == 304: - # We must have sent an ETag request. This could mean - # that we've been expired already or that we simply - # have an etag. In either case, we want to try and - # update the cache if that is the case. - cached_response = self.controller.update_cached_response( - request, response - ) - - if cached_response is not response: - from_cache = True - - # We are done with the server response, read a - # possible response body (compliant servers will - # not return one, but we cannot be 100% sure) and - # release the connection back to the pool. - response.read(decode_content=False) - response.release_conn() - - response = cached_response - - # We always cache the 301 responses - elif response.status == 301: - self.controller.cache_response(request, response) - else: - # Wrap the response file with a wrapper that will cache the - # response when the stream has been consumed. - response._fp = CallbackFileWrapper( - response._fp, - functools.partial( - self.controller.cache_response, request, response - ), - ) - if response.chunked: - super_update_chunk_length = response._update_chunk_length - - def _update_chunk_length(self): - super_update_chunk_length() - if self.chunk_left == 0: - self._fp._close() - - response._update_chunk_length = types.MethodType( - _update_chunk_length, response - ) - - resp = super(CacheControlAdapter, self).build_response(request, response) - - # See if we should invalidate the cache. - if request.method in self.invalidating_methods and resp.ok: - cache_url = self.controller.cache_url(request.url) - self.cache.delete(cache_url) - - # Give the request a from_cache attr to let people use it - resp.from_cache = from_cache - - return resp - - def close(self): - self.cache.close() - super(CacheControlAdapter, self).close() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/cache.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/cache.py deleted file mode 100644 index 94e0773..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/cache.py +++ /dev/null @@ -1,39 +0,0 @@ -""" -The cache object API for implementing caches. The default is a thread -safe in-memory dictionary. -""" -from threading import Lock - - -class BaseCache(object): - - def get(self, key): - raise NotImplementedError() - - def set(self, key, value): - raise NotImplementedError() - - def delete(self, key): - raise NotImplementedError() - - def close(self): - pass - - -class DictCache(BaseCache): - - def __init__(self, init_dict=None): - self.lock = Lock() - self.data = init_dict or {} - - def get(self, key): - return self.data.get(key, None) - - def set(self, key, value): - with self.lock: - self.data.update({key: value}) - - def delete(self, key): - with self.lock: - if key in self.data: - self.data.pop(key) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/__init__.py deleted file mode 100644 index 0e1658f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .file_cache import FileCache # noqa -from .redis_cache import RedisCache # noqa diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/file_cache.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/file_cache.py deleted file mode 100644 index 1ba0080..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/file_cache.py +++ /dev/null @@ -1,146 +0,0 @@ -import hashlib -import os -from textwrap import dedent - -from ..cache import BaseCache -from ..controller import CacheController - -try: - FileNotFoundError -except NameError: - # py2.X - FileNotFoundError = (IOError, OSError) - - -def _secure_open_write(filename, fmode): - # We only want to write to this file, so open it in write only mode - flags = os.O_WRONLY - - # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only - # will open *new* files. - # We specify this because we want to ensure that the mode we pass is the - # mode of the file. - flags |= os.O_CREAT | os.O_EXCL - - # Do not follow symlinks to prevent someone from making a symlink that - # we follow and insecurely open a cache file. - if hasattr(os, "O_NOFOLLOW"): - flags |= os.O_NOFOLLOW - - # On Windows we'll mark this file as binary - if hasattr(os, "O_BINARY"): - flags |= os.O_BINARY - - # Before we open our file, we want to delete any existing file that is - # there - try: - os.remove(filename) - except (IOError, OSError): - # The file must not exist already, so we can just skip ahead to opening - pass - - # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a - # race condition happens between the os.remove and this line, that an - # error will be raised. Because we utilize a lockfile this should only - # happen if someone is attempting to attack us. - fd = os.open(filename, flags, fmode) - try: - return os.fdopen(fd, "wb") - - except: - # An error occurred wrapping our FD in a file object - os.close(fd) - raise - - -class FileCache(BaseCache): - - def __init__( - self, - directory, - forever=False, - filemode=0o0600, - dirmode=0o0700, - use_dir_lock=None, - lock_class=None, - ): - - if use_dir_lock is not None and lock_class is not None: - raise ValueError("Cannot use use_dir_lock and lock_class together") - - try: - from pip._vendor.lockfile import LockFile - from pip._vendor.lockfile.mkdirlockfile import MkdirLockFile - except ImportError: - notice = dedent( - """ - NOTE: In order to use the FileCache you must have - lockfile installed. You can install it via pip: - pip install lockfile - """ - ) - raise ImportError(notice) - - else: - if use_dir_lock: - lock_class = MkdirLockFile - - elif lock_class is None: - lock_class = LockFile - - self.directory = directory - self.forever = forever - self.filemode = filemode - self.dirmode = dirmode - self.lock_class = lock_class - - @staticmethod - def encode(x): - return hashlib.sha224(x.encode()).hexdigest() - - def _fn(self, name): - # NOTE: This method should not change as some may depend on it. - # See: https://github.com/ionrock/cachecontrol/issues/63 - hashed = self.encode(name) - parts = list(hashed[:5]) + [hashed] - return os.path.join(self.directory, *parts) - - def get(self, key): - name = self._fn(key) - try: - with open(name, "rb") as fh: - return fh.read() - - except FileNotFoundError: - return None - - def set(self, key, value): - name = self._fn(key) - - # Make sure the directory exists - try: - os.makedirs(os.path.dirname(name), self.dirmode) - except (IOError, OSError): - pass - - with self.lock_class(name) as lock: - # Write our actual file - with _secure_open_write(lock.path, self.filemode) as fh: - fh.write(value) - - def delete(self, key): - name = self._fn(key) - if not self.forever: - try: - os.remove(name) - except FileNotFoundError: - pass - - -def url_to_file_path(url, filecache): - """Return the file cache path based on the URL. - - This does not ensure the file exists! - """ - key = CacheController.cache_url(url) - return filecache._fn(key) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/redis_cache.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/redis_cache.py deleted file mode 100644 index ed705ce..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/caches/redis_cache.py +++ /dev/null @@ -1,33 +0,0 @@ -from __future__ import division - -from datetime import datetime -from pip._vendor.cachecontrol.cache import BaseCache - - -class RedisCache(BaseCache): - - def __init__(self, conn): - self.conn = conn - - def get(self, key): - return self.conn.get(key) - - def set(self, key, value, expires=None): - if not expires: - self.conn.set(key, value) - else: - expires = expires - datetime.utcnow() - self.conn.setex(key, int(expires.total_seconds()), value) - - def delete(self, key): - self.conn.delete(key) - - def clear(self): - """Helper for clearing all the keys in a database. Use with - caution!""" - for key in self.conn.keys(): - self.conn.delete(key) - - def close(self): - """Redis uses connection pooling, no need to close the connection.""" - pass diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/compat.py deleted file mode 100644 index 33b5aed..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/compat.py +++ /dev/null @@ -1,29 +0,0 @@ -try: - from urllib.parse import urljoin -except ImportError: - from urlparse import urljoin - - -try: - import cPickle as pickle -except ImportError: - import pickle - - -# Handle the case where the requests module has been patched to not have -# urllib3 bundled as part of its source. -try: - from pip._vendor.requests.packages.urllib3.response import HTTPResponse -except ImportError: - from pip._vendor.urllib3.response import HTTPResponse - -try: - from pip._vendor.requests.packages.urllib3.util import is_fp_closed -except ImportError: - from pip._vendor.urllib3.util import is_fp_closed - -# Replicate some six behaviour -try: - text_type = unicode -except NameError: - text_type = str diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/controller.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/controller.py deleted file mode 100644 index 1b2b943..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/controller.py +++ /dev/null @@ -1,367 +0,0 @@ -""" -The httplib2 algorithms ported for use with requests. -""" -import logging -import re -import calendar -import time -from email.utils import parsedate_tz - -from pip._vendor.requests.structures import CaseInsensitiveDict - -from .cache import DictCache -from .serialize import Serializer - - -logger = logging.getLogger(__name__) - -URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?") - - -def parse_uri(uri): - """Parses a URI using the regex given in Appendix B of RFC 3986. - - (scheme, authority, path, query, fragment) = parse_uri(uri) - """ - groups = URI.match(uri).groups() - return (groups[1], groups[3], groups[4], groups[6], groups[8]) - - -class CacheController(object): - """An interface to see if request should cached or not. - """ - - def __init__( - self, cache=None, cache_etags=True, serializer=None, status_codes=None - ): - self.cache = cache or DictCache() - self.cache_etags = cache_etags - self.serializer = serializer or Serializer() - self.cacheable_status_codes = status_codes or (200, 203, 300, 301) - - @classmethod - def _urlnorm(cls, uri): - """Normalize the URL to create a safe key for the cache""" - (scheme, authority, path, query, fragment) = parse_uri(uri) - if not scheme or not authority: - raise Exception("Only absolute URIs are allowed. uri = %s" % uri) - - scheme = scheme.lower() - authority = authority.lower() - - if not path: - path = "/" - - # Could do syntax based normalization of the URI before - # computing the digest. See Section 6.2.2 of Std 66. - request_uri = query and "?".join([path, query]) or path - defrag_uri = scheme + "://" + authority + request_uri - - return defrag_uri - - @classmethod - def cache_url(cls, uri): - return cls._urlnorm(uri) - - def parse_cache_control(self, headers): - known_directives = { - # https://tools.ietf.org/html/rfc7234#section-5.2 - "max-age": (int, True), - "max-stale": (int, False), - "min-fresh": (int, True), - "no-cache": (None, False), - "no-store": (None, False), - "no-transform": (None, False), - "only-if-cached": (None, False), - "must-revalidate": (None, False), - "public": (None, False), - "private": (None, False), - "proxy-revalidate": (None, False), - "s-maxage": (int, True), - } - - cc_headers = headers.get("cache-control", headers.get("Cache-Control", "")) - - retval = {} - - for cc_directive in cc_headers.split(","): - if not cc_directive.strip(): - continue - - parts = cc_directive.split("=", 1) - directive = parts[0].strip() - - try: - typ, required = known_directives[directive] - except KeyError: - logger.debug("Ignoring unknown cache-control directive: %s", directive) - continue - - if not typ or not required: - retval[directive] = None - if typ: - try: - retval[directive] = typ(parts[1].strip()) - except IndexError: - if required: - logger.debug( - "Missing value for cache-control " "directive: %s", - directive, - ) - except ValueError: - logger.debug( - "Invalid value for cache-control directive " "%s, must be %s", - directive, - typ.__name__, - ) - - return retval - - def cached_request(self, request): - """ - Return a cached response if it exists in the cache, otherwise - return False. - """ - cache_url = self.cache_url(request.url) - logger.debug('Looking up "%s" in the cache', cache_url) - cc = self.parse_cache_control(request.headers) - - # Bail out if the request insists on fresh data - if "no-cache" in cc: - logger.debug('Request header has "no-cache", cache bypassed') - return False - - if "max-age" in cc and cc["max-age"] == 0: - logger.debug('Request header has "max_age" as 0, cache bypassed') - return False - - # Request allows serving from the cache, let's see if we find something - cache_data = self.cache.get(cache_url) - if cache_data is None: - logger.debug("No cache entry available") - return False - - # Check whether it can be deserialized - resp = self.serializer.loads(request, cache_data) - if not resp: - logger.warning("Cache entry deserialization failed, entry ignored") - return False - - # If we have a cached 301, return it immediately. We don't - # need to test our response for other headers b/c it is - # intrinsically "cacheable" as it is Permanent. - # See: - # https://tools.ietf.org/html/rfc7231#section-6.4.2 - # - # Client can try to refresh the value by repeating the request - # with cache busting headers as usual (ie no-cache). - if resp.status == 301: - msg = ( - 'Returning cached "301 Moved Permanently" response ' - "(ignoring date and etag information)" - ) - logger.debug(msg) - return resp - - headers = CaseInsensitiveDict(resp.headers) - if not headers or "date" not in headers: - if "etag" not in headers: - # Without date or etag, the cached response can never be used - # and should be deleted. - logger.debug("Purging cached response: no date or etag") - self.cache.delete(cache_url) - logger.debug("Ignoring cached response: no date") - return False - - now = time.time() - date = calendar.timegm(parsedate_tz(headers["date"])) - current_age = max(0, now - date) - logger.debug("Current age based on date: %i", current_age) - - # TODO: There is an assumption that the result will be a - # urllib3 response object. This may not be best since we - # could probably avoid instantiating or constructing the - # response until we know we need it. - resp_cc = self.parse_cache_control(headers) - - # determine freshness - freshness_lifetime = 0 - - # Check the max-age pragma in the cache control header - if "max-age" in resp_cc: - freshness_lifetime = resp_cc["max-age"] - logger.debug("Freshness lifetime from max-age: %i", freshness_lifetime) - - # If there isn't a max-age, check for an expires header - elif "expires" in headers: - expires = parsedate_tz(headers["expires"]) - if expires is not None: - expire_time = calendar.timegm(expires) - date - freshness_lifetime = max(0, expire_time) - logger.debug("Freshness lifetime from expires: %i", freshness_lifetime) - - # Determine if we are setting freshness limit in the - # request. Note, this overrides what was in the response. - if "max-age" in cc: - freshness_lifetime = cc["max-age"] - logger.debug( - "Freshness lifetime from request max-age: %i", freshness_lifetime - ) - - if "min-fresh" in cc: - min_fresh = cc["min-fresh"] - # adjust our current age by our min fresh - current_age += min_fresh - logger.debug("Adjusted current age from min-fresh: %i", current_age) - - # Return entry if it is fresh enough - if freshness_lifetime > current_age: - logger.debug('The response is "fresh", returning cached response') - logger.debug("%i > %i", freshness_lifetime, current_age) - return resp - - # we're not fresh. If we don't have an Etag, clear it out - if "etag" not in headers: - logger.debug('The cached response is "stale" with no etag, purging') - self.cache.delete(cache_url) - - # return the original handler - return False - - def conditional_headers(self, request): - cache_url = self.cache_url(request.url) - resp = self.serializer.loads(request, self.cache.get(cache_url)) - new_headers = {} - - if resp: - headers = CaseInsensitiveDict(resp.headers) - - if "etag" in headers: - new_headers["If-None-Match"] = headers["ETag"] - - if "last-modified" in headers: - new_headers["If-Modified-Since"] = headers["Last-Modified"] - - return new_headers - - def cache_response(self, request, response, body=None, status_codes=None): - """ - Algorithm for caching requests. - - This assumes a requests Response object. - """ - # From httplib2: Don't cache 206's since we aren't going to - # handle byte range requests - cacheable_status_codes = status_codes or self.cacheable_status_codes - if response.status not in cacheable_status_codes: - logger.debug( - "Status code %s not in %s", response.status, cacheable_status_codes - ) - return - - response_headers = CaseInsensitiveDict(response.headers) - - # If we've been given a body, our response has a Content-Length, that - # Content-Length is valid then we can check to see if the body we've - # been given matches the expected size, and if it doesn't we'll just - # skip trying to cache it. - if ( - body is not None - and "content-length" in response_headers - and response_headers["content-length"].isdigit() - and int(response_headers["content-length"]) != len(body) - ): - return - - cc_req = self.parse_cache_control(request.headers) - cc = self.parse_cache_control(response_headers) - - cache_url = self.cache_url(request.url) - logger.debug('Updating cache with response from "%s"', cache_url) - - # Delete it from the cache if we happen to have it stored there - no_store = False - if "no-store" in cc: - no_store = True - logger.debug('Response header has "no-store"') - if "no-store" in cc_req: - no_store = True - logger.debug('Request header has "no-store"') - if no_store and self.cache.get(cache_url): - logger.debug('Purging existing cache entry to honor "no-store"') - self.cache.delete(cache_url) - if no_store: - return - - # If we've been given an etag, then keep the response - if self.cache_etags and "etag" in response_headers: - logger.debug("Caching due to etag") - self.cache.set( - cache_url, self.serializer.dumps(request, response, body=body) - ) - - # Add to the cache any 301s. We do this before looking that - # the Date headers. - elif response.status == 301: - logger.debug("Caching permanant redirect") - self.cache.set(cache_url, self.serializer.dumps(request, response)) - - # Add to the cache if the response headers demand it. If there - # is no date header then we can't do anything about expiring - # the cache. - elif "date" in response_headers: - # cache when there is a max-age > 0 - if "max-age" in cc and cc["max-age"] > 0: - logger.debug("Caching b/c date exists and max-age > 0") - self.cache.set( - cache_url, self.serializer.dumps(request, response, body=body) - ) - - # If the request can expire, it means we should cache it - # in the meantime. - elif "expires" in response_headers: - if response_headers["expires"]: - logger.debug("Caching b/c of expires header") - self.cache.set( - cache_url, self.serializer.dumps(request, response, body=body) - ) - - def update_cached_response(self, request, response): - """On a 304 we will get a new set of headers that we want to - update our cached value with, assuming we have one. - - This should only ever be called when we've sent an ETag and - gotten a 304 as the response. - """ - cache_url = self.cache_url(request.url) - - cached_response = self.serializer.loads(request, self.cache.get(cache_url)) - - if not cached_response: - # we didn't have a cached response - return response - - # Lets update our headers with the headers from the new request: - # http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-26#section-4.1 - # - # The server isn't supposed to send headers that would make - # the cached body invalid. But... just in case, we'll be sure - # to strip out ones we know that might be problmatic due to - # typical assumptions. - excluded_headers = ["content-length"] - - cached_response.headers.update( - dict( - (k, v) - for k, v in response.headers.items() - if k.lower() not in excluded_headers - ) - ) - - # we want a 200 b/c we have content via the cache - cached_response.status = 200 - - # update our cache - self.cache.set(cache_url, self.serializer.dumps(request, cached_response)) - - return cached_response diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/filewrapper.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/filewrapper.py deleted file mode 100644 index 30ed4c5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/filewrapper.py +++ /dev/null @@ -1,80 +0,0 @@ -from io import BytesIO - - -class CallbackFileWrapper(object): - """ - Small wrapper around a fp object which will tee everything read into a - buffer, and when that file is closed it will execute a callback with the - contents of that buffer. - - All attributes are proxied to the underlying file object. - - This class uses members with a double underscore (__) leading prefix so as - not to accidentally shadow an attribute. - """ - - def __init__(self, fp, callback): - self.__buf = BytesIO() - self.__fp = fp - self.__callback = callback - - def __getattr__(self, name): - # The vaguaries of garbage collection means that self.__fp is - # not always set. By using __getattribute__ and the private - # name[0] allows looking up the attribute value and raising an - # AttributeError when it doesn't exist. This stop thigns from - # infinitely recursing calls to getattr in the case where - # self.__fp hasn't been set. - # - # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers - fp = self.__getattribute__("_CallbackFileWrapper__fp") - return getattr(fp, name) - - def __is_fp_closed(self): - try: - return self.__fp.fp is None - - except AttributeError: - pass - - try: - return self.__fp.closed - - except AttributeError: - pass - - # We just don't cache it then. - # TODO: Add some logging here... - return False - - def _close(self): - if self.__callback: - self.__callback(self.__buf.getvalue()) - - # We assign this to None here, because otherwise we can get into - # really tricky problems where the CPython interpreter dead locks - # because the callback is holding a reference to something which - # has a __del__ method. Setting this to None breaks the cycle - # and allows the garbage collector to do it's thing normally. - self.__callback = None - - def read(self, amt=None): - data = self.__fp.read(amt) - self.__buf.write(data) - if self.__is_fp_closed(): - self._close() - - return data - - def _safe_read(self, amt): - data = self.__fp._safe_read(amt) - if amt == 2 and data == b"\r\n": - # urllib executes this read to toss the CRLF at the end - # of the chunk. - return data - - self.__buf.write(data) - if self.__is_fp_closed(): - self._close() - - return data diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/heuristics.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/heuristics.py deleted file mode 100644 index 6c0e979..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/heuristics.py +++ /dev/null @@ -1,135 +0,0 @@ -import calendar -import time - -from email.utils import formatdate, parsedate, parsedate_tz - -from datetime import datetime, timedelta - -TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT" - - -def expire_after(delta, date=None): - date = date or datetime.utcnow() - return date + delta - - -def datetime_to_header(dt): - return formatdate(calendar.timegm(dt.timetuple())) - - -class BaseHeuristic(object): - - def warning(self, response): - """ - Return a valid 1xx warning header value describing the cache - adjustments. - - The response is provided too allow warnings like 113 - http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need - to explicitly say response is over 24 hours old. - """ - return '110 - "Response is Stale"' - - def update_headers(self, response): - """Update the response headers with any new headers. - - NOTE: This SHOULD always include some Warning header to - signify that the response was cached by the client, not - by way of the provided headers. - """ - return {} - - def apply(self, response): - updated_headers = self.update_headers(response) - - if updated_headers: - response.headers.update(updated_headers) - warning_header_value = self.warning(response) - if warning_header_value is not None: - response.headers.update({"Warning": warning_header_value}) - - return response - - -class OneDayCache(BaseHeuristic): - """ - Cache the response by providing an expires 1 day in the - future. - """ - - def update_headers(self, response): - headers = {} - - if "expires" not in response.headers: - date = parsedate(response.headers["date"]) - expires = expire_after(timedelta(days=1), date=datetime(*date[:6])) - headers["expires"] = datetime_to_header(expires) - headers["cache-control"] = "public" - return headers - - -class ExpiresAfter(BaseHeuristic): - """ - Cache **all** requests for a defined time period. - """ - - def __init__(self, **kw): - self.delta = timedelta(**kw) - - def update_headers(self, response): - expires = expire_after(self.delta) - return {"expires": datetime_to_header(expires), "cache-control": "public"} - - def warning(self, response): - tmpl = "110 - Automatically cached for %s. Response might be stale" - return tmpl % self.delta - - -class LastModified(BaseHeuristic): - """ - If there is no Expires header already, fall back on Last-Modified - using the heuristic from - http://tools.ietf.org/html/rfc7234#section-4.2.2 - to calculate a reasonable value. - - Firefox also does something like this per - https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ - http://lxr.mozilla.org/mozilla-release/source/netwerk/protocol/http/nsHttpResponseHead.cpp#397 - Unlike mozilla we limit this to 24-hr. - """ - cacheable_by_default_statuses = { - 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501 - } - - def update_headers(self, resp): - headers = resp.headers - - if "expires" in headers: - return {} - - if "cache-control" in headers and headers["cache-control"] != "public": - return {} - - if resp.status not in self.cacheable_by_default_statuses: - return {} - - if "date" not in headers or "last-modified" not in headers: - return {} - - date = calendar.timegm(parsedate_tz(headers["date"])) - last_modified = parsedate(headers["last-modified"]) - if date is None or last_modified is None: - return {} - - now = time.time() - current_age = max(0, now - date) - delta = date - calendar.timegm(last_modified) - freshness_lifetime = max(0, min(delta / 10, 24 * 3600)) - if freshness_lifetime <= current_age: - return {} - - expires = date + freshness_lifetime - return {"expires": time.strftime(TIME_FMT, time.gmtime(expires))} - - def warning(self, resp): - return None diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/serialize.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/serialize.py deleted file mode 100644 index ec43ff2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/serialize.py +++ /dev/null @@ -1,186 +0,0 @@ -import base64 -import io -import json -import zlib - -from pip._vendor import msgpack -from pip._vendor.requests.structures import CaseInsensitiveDict - -from .compat import HTTPResponse, pickle, text_type - - -def _b64_decode_bytes(b): - return base64.b64decode(b.encode("ascii")) - - -def _b64_decode_str(s): - return _b64_decode_bytes(s).decode("utf8") - - -class Serializer(object): - - def dumps(self, request, response, body=None): - response_headers = CaseInsensitiveDict(response.headers) - - if body is None: - body = response.read(decode_content=False) - - # NOTE: 99% sure this is dead code. I'm only leaving it - # here b/c I don't have a test yet to prove - # it. Basically, before using - # `cachecontrol.filewrapper.CallbackFileWrapper`, - # this made an effort to reset the file handle. The - # `CallbackFileWrapper` short circuits this code by - # setting the body as the content is consumed, the - # result being a `body` argument is *always* passed - # into cache_response, and in turn, - # `Serializer.dump`. - response._fp = io.BytesIO(body) - - # NOTE: This is all a bit weird, but it's really important that on - # Python 2.x these objects are unicode and not str, even when - # they contain only ascii. The problem here is that msgpack - # understands the difference between unicode and bytes and we - # have it set to differentiate between them, however Python 2 - # doesn't know the difference. Forcing these to unicode will be - # enough to have msgpack know the difference. - data = { - u"response": { - u"body": body, - u"headers": dict( - (text_type(k), text_type(v)) for k, v in response.headers.items() - ), - u"status": response.status, - u"version": response.version, - u"reason": text_type(response.reason), - u"strict": response.strict, - u"decode_content": response.decode_content, - } - } - - # Construct our vary headers - data[u"vary"] = {} - if u"vary" in response_headers: - varied_headers = response_headers[u"vary"].split(",") - for header in varied_headers: - header = text_type(header).strip() - header_value = request.headers.get(header, None) - if header_value is not None: - header_value = text_type(header_value) - data[u"vary"][header] = header_value - - return b",".join([b"cc=4", msgpack.dumps(data, use_bin_type=True)]) - - def loads(self, request, data): - # Short circuit if we've been given an empty set of data - if not data: - return - - # Determine what version of the serializer the data was serialized - # with - try: - ver, data = data.split(b",", 1) - except ValueError: - ver = b"cc=0" - - # Make sure that our "ver" is actually a version and isn't a false - # positive from a , being in the data stream. - if ver[:3] != b"cc=": - data = ver + data - ver = b"cc=0" - - # Get the version number out of the cc=N - ver = ver.split(b"=", 1)[-1].decode("ascii") - - # Dispatch to the actual load method for the given version - try: - return getattr(self, "_loads_v{}".format(ver))(request, data) - - except AttributeError: - # This is a version we don't have a loads function for, so we'll - # just treat it as a miss and return None - return - - def prepare_response(self, request, cached): - """Verify our vary headers match and construct a real urllib3 - HTTPResponse object. - """ - # Special case the '*' Vary value as it means we cannot actually - # determine if the cached response is suitable for this request. - if "*" in cached.get("vary", {}): - return - - # Ensure that the Vary headers for the cached response match our - # request - for header, value in cached.get("vary", {}).items(): - if request.headers.get(header, None) != value: - return - - body_raw = cached["response"].pop("body") - - headers = CaseInsensitiveDict(data=cached["response"]["headers"]) - if headers.get("transfer-encoding", "") == "chunked": - headers.pop("transfer-encoding") - - cached["response"]["headers"] = headers - - try: - body = io.BytesIO(body_raw) - except TypeError: - # This can happen if cachecontrol serialized to v1 format (pickle) - # using Python 2. A Python 2 str(byte string) will be unpickled as - # a Python 3 str (unicode string), which will cause the above to - # fail with: - # - # TypeError: 'str' does not support the buffer interface - body = io.BytesIO(body_raw.encode("utf8")) - - return HTTPResponse(body=body, preload_content=False, **cached["response"]) - - def _loads_v0(self, request, data): - # The original legacy cache data. This doesn't contain enough - # information to construct everything we need, so we'll treat this as - # a miss. - return - - def _loads_v1(self, request, data): - try: - cached = pickle.loads(data) - except ValueError: - return - - return self.prepare_response(request, cached) - - def _loads_v2(self, request, data): - try: - cached = json.loads(zlib.decompress(data).decode("utf8")) - except (ValueError, zlib.error): - return - - # We need to decode the items that we've base64 encoded - cached["response"]["body"] = _b64_decode_bytes(cached["response"]["body"]) - cached["response"]["headers"] = dict( - (_b64_decode_str(k), _b64_decode_str(v)) - for k, v in cached["response"]["headers"].items() - ) - cached["response"]["reason"] = _b64_decode_str(cached["response"]["reason"]) - cached["vary"] = dict( - (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) - for k, v in cached["vary"].items() - ) - - return self.prepare_response(request, cached) - - def _loads_v3(self, request, data): - # Due to Python 2 encoding issues, it's impossible to know for sure - # exactly how to load v3 entries, thus we'll treat these as a miss so - # that they get rewritten out as v4 entries. - return - - def _loads_v4(self, request, data): - try: - cached = msgpack.loads(data, encoding="utf-8") - except ValueError: - return - - return self.prepare_response(request, cached) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/wrapper.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/wrapper.py deleted file mode 100644 index 265bfc8..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/cachecontrol/wrapper.py +++ /dev/null @@ -1,29 +0,0 @@ -from .adapter import CacheControlAdapter -from .cache import DictCache - - -def CacheControl( - sess, - cache=None, - cache_etags=True, - serializer=None, - heuristic=None, - controller_class=None, - adapter_class=None, - cacheable_methods=None, -): - - cache = cache or DictCache() - adapter_class = adapter_class or CacheControlAdapter - adapter = adapter_class( - cache, - cache_etags=cache_etags, - serializer=serializer, - heuristic=heuristic, - controller_class=controller_class, - cacheable_methods=cacheable_methods, - ) - sess.mount("http://", adapter) - sess.mount("https://", adapter) - - return sess diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/__init__.py deleted file mode 100644 index ef71f3a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .core import where - -__version__ = "2018.11.29" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/__main__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/__main__.py deleted file mode 100644 index ae2aff5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/__main__.py +++ /dev/null @@ -1,2 +0,0 @@ -from pip._vendor.certifi import where -print(where()) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/cacert.pem b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/cacert.pem deleted file mode 100644 index db68797..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/cacert.pem +++ /dev/null @@ -1,4512 +0,0 @@ - -# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA -# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA -# Label: "GlobalSign Root CA" -# Serial: 4835703278459707669005204 -# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a -# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c -# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw -MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT -aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ -jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp -xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp -1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG -snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ -U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 -9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B -AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz -yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE -38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP -AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad -DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME -HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 -# Label: "GlobalSign Root CA - R2" -# Serial: 4835703278459682885658125 -# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 -# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe -# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 -MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL -v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 -eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq -tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd -C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa -zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB -mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH -V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n -bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG -3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs -J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO -291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS -ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd -AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Label: "Verisign Class 3 Public Primary Certification Authority - G3" -# Serial: 206684696279472310254277870180966723415 -# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 -# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 -# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b -N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t -KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu -kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm -CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ -Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu -imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te -2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe -DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p -F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt -TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- - -# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited -# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited -# Label: "Entrust.net Premium 2048 Secure Server CA" -# Serial: 946069240 -# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 -# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 -# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 -MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub -j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo -U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b -u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ -bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er -fF6adulZkMV8gzURZVE= ------END CERTIFICATE----- - -# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust -# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust -# Label: "Baltimore CyberTrust Root" -# Serial: 33554617 -# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 -# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 -# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX -DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y -ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy -VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr -mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr -IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK -mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu -XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy -dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye -jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 -DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 -9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx -jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 -Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz -ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS -R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - -# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network -# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network -# Label: "AddTrust External Root" -# Serial: 1 -# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f -# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 -# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- - -# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. -# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. -# Label: "Entrust Root Certification Authority" -# Serial: 1164660820 -# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 -# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 -# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 -Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW -KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw -NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw -NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy -ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV -BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo -Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 -4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 -KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI -rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi -94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB -sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi -gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo -kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE -vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t -O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua -AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP -9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ -eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m -0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. -# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. -# Label: "GeoTrust Global CA" -# Serial: 144470 -# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 -# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 -# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg -R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 -9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq -fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv -iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU -1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ -bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW -MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA -ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l -uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn -Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS -tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF -PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un -hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV -5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. -# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. -# Label: "GeoTrust Universal CA" -# Serial: 1 -# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 -# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 -# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 ------BEGIN CERTIFICATE----- -MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy -c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE -BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 -IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV -VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 -cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT -QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh -F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v -c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w -mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd -VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX -teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ -f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe -Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ -nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB -/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY -MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG -9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc -aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX -IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn -ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z -uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN -Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja -QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW -koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 -ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt -DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm -bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. -# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. -# Label: "GeoTrust Universal CA 2" -# Serial: 1 -# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 -# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 -# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW -MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy -c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD -VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 -c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 -WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG -FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq -XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL -se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb -KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd -IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 -y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt -hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc -QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 -Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV -HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ -KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z -dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ -L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr -Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo -ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY -T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz -GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m -1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV -OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH -6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX -QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS ------END CERTIFICATE----- - -# Issuer: CN=AAA Certificate Services O=Comodo CA Limited -# Subject: CN=AAA Certificate Services O=Comodo CA Limited -# Label: "Comodo AAA Services root" -# Serial: 1 -# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 -# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 -# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj -YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM -GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua -BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe -3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 -YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR -rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm -ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU -oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v -QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t -b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF -AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q -GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 -G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi -l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 -smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority -# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority -# Label: "QuoVadis Root CA" -# Serial: 985026699 -# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 -# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 -# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz -MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw -IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR -dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp -li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D -rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ -WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug -F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU -xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC -Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv -dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw -ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl -IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh -c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy -ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI -KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T -KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq -y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p -dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD -VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL -MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk -fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 -7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R -cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y -mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW -xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK -SnQ2+Q== ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited -# Label: "QuoVadis Root CA 2" -# Serial: 1289 -# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b -# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 -# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa -GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg -Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J -WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB -rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp -+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 -ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i -Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz -PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og -/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH -oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI -yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud -EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 -A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL -MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f -BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn -g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl -fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K -WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha -B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc -hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR -TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD -mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z -ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y -4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza -8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 3" -# Serial: 1478 -# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf -# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 -# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM -V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB -4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr -H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd -8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv -vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT -mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe -btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc -T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt -WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ -c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A -4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD -VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG -CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 -aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu -dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw -czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G -A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg -Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 -7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem -d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd -+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B -4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN -t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x -DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 -k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s -zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j -Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT -mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK -4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- - -# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 -# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 -# Label: "Security Communication Root CA" -# Serial: 0 -# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a -# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 -# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------END CERTIFICATE----- - -# Issuer: CN=Sonera Class2 CA O=Sonera -# Subject: CN=Sonera Class2 CA O=Sonera -# Label: "Sonera Class 2 Root CA" -# Serial: 29 -# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb -# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 -# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP -MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx -MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV -BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o -Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt -5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s -3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej -vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu -8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw -DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG -MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil -zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ -3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD -FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 -Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 -ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M ------END CERTIFICATE----- - -# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com -# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com -# Label: "XRamp Global CA Root" -# Serial: 107108908803651509692980124233745014957 -# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 -# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 -# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB -gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk -MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY -UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx -NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 -dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy -dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 -38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP -KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q -DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 -qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa -JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi -PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P -BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs -jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 -eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR -vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa -IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy -i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ -O+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- - -# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority -# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority -# Label: "Go Daddy Class 2 CA" -# Serial: 0 -# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 -# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 -# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh -MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE -YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 -MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo -ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg -MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN -ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA -PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w -wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi -EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY -avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ -YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE -sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h -/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 -IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy -OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P -TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER -dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf -ReYNnyicsbkqWletNw+vHX/bvZ8= ------END CERTIFICATE----- - -# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority -# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority -# Label: "Starfield Class 2 CA" -# Serial: 0 -# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 -# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a -# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl -MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp -U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw -NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE -ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp -ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 -DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf -8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN -+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 -X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa -K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA -1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G -A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR -zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 -YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD -bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 -L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D -eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp -VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY -WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- - -# Issuer: O=Government Root Certification Authority -# Subject: O=Government Root Certification Authority -# Label: "Taiwan GRCA" -# Serial: 42023070807708724159991140556527066870 -# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e -# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9 -# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3 ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ -MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow -PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR -IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q -gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy -yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts -F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 -jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx -ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC -VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK -YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH -EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN -Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud -DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE -MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK -UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ -TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf -qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK -ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE -JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 -hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 -EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm -nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX -udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz -ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe -LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl -pYYsfPQS ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root CA" -# Serial: 17154717934120587862167794914071425081 -# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 -# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 -# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c -JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP -mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ -wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 -VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ -AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB -AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun -pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC -dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf -fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm -NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx -H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root CA" -# Serial: 10944719598952040374951832963794454346 -# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e -# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 -# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - -# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert High Assurance EV Root CA" -# Serial: 3553400076410547919724730734378100087 -# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a -# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 -# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- - -# Issuer: CN=Class 2 Primary CA O=Certplus -# Subject: CN=Class 2 Primary CA O=Certplus -# Label: "Certplus Class 2 Primary CA" -# Serial: 177770208045934040241468760488327595043 -# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b -# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb -# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw -PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz -cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 -MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz -IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ -ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR -VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL -kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd -EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas -H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 -HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud -DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 -QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu -Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ -AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 -yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR -FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA -ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB -kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- - -# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. -# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. -# Label: "DST Root CA X3" -# Serial: 91299735575339953335919266965803778155 -# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 -# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 -# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow -PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD -Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O -rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq -OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b -xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw -7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD -aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG -SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 -ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr -AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz -R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 -JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo -Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- - -# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG -# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG -# Label: "SwissSign Gold CA - G2" -# Serial: 13492815561806991280 -# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 -# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 -# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln -biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF -MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT -d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 -76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ -bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c -6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE -emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd -MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt -MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y -MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y -FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi -aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM -gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB -qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 -lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn -8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 -45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO -UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 -O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC -bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv -GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a -77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC -hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 -92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp -Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w -ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt -Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- - -# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG -# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG -# Label: "SwissSign Silver CA - G2" -# Serial: 5700383053117599563 -# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 -# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb -# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. -# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. -# Label: "GeoTrust Primary Certification Authority" -# Serial: 32798226551256963324313806436981982369 -# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf -# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 -# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY -MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo -R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx -MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 -AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA -ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 -7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W -kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI -mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ -KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 -6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl -4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K -oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj -UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU -AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA" -# Serial: 69529181992039203566298953787712940909 -# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 -# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 -# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw -NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j -LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG -A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs -W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta -3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk -6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 -Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J -NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP -r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU -DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz -YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 -/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ -LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 -jVaMaA== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" -# Serial: 33037644167568058970164719475676101450 -# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c -# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 -# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 -nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex -t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz -SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG -BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ -rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ -NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E -BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH -BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv -MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE -p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y -5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK -WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ -4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N -hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- - -# Issuer: CN=SecureTrust CA O=SecureTrust Corporation -# Subject: CN=SecureTrust CA O=SecureTrust Corporation -# Label: "SecureTrust CA" -# Serial: 17199774589125277788362757014266862032 -# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 -# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 -# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz -MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv -cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz -Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO -0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao -wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj -7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS -8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT -BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg -JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 -6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ -3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm -D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS -CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- - -# Issuer: CN=Secure Global CA O=SecureTrust Corporation -# Subject: CN=Secure Global CA O=SecureTrust Corporation -# Label: "Secure Global CA" -# Serial: 9751836167731051554232119481456978597 -# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de -# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b -# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx -MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg -Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ -iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa -/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ -jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI -HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 -sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w -gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw -KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG -AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L -URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO -H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm -I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY -iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- - -# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO Certification Authority O=COMODO CA Limited -# Label: "COMODO Certification Authority" -# Serial: 104350513648249232941998508985834464573 -# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 -# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b -# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw -MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl -YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P -RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 -UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI -2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 -Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp -+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ -DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O -nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW -/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g -PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u -QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY -SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv -IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 -zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd -BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB -ZQ== ------END CERTIFICATE----- - -# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. -# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. -# Label: "Network Solutions Certificate Authority" -# Serial: 116697915152937497490437556386812487904 -# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e -# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce -# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi -MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV -UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO -ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz -c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP -OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl -mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF -BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 -qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw -gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu -bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp -dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 -6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ -h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH -/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN -pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- - -# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited -# Label: "COMODO ECC Certification Authority" -# Serial: 41578283867086692638256921589707938090 -# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 -# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 -# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed -# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed -# Label: "OISTE WISeKey Global Root GA CA" -# Serial: 86718877871133159090080555911823548314 -# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93 -# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9 -# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5 ------BEGIN CERTIFICATE----- -MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB -ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly -aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl -ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w -NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G -A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD -VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX -SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR -VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 -w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF -mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg -4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 -4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw -EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx -SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 -ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 -vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa -hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi -Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ -/L7fCg0= ------END CERTIFICATE----- - -# Issuer: CN=Certigna O=Dhimyotis -# Subject: CN=Certigna O=Dhimyotis -# Label: "Certigna" -# Serial: 18364802974209362175 -# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff -# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 -# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV -BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X -DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ -BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 -QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny -gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw -zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q -130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 -JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw -ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT -AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj -AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG -9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h -bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc -fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu -HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w -t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- - -# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center -# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center -# Label: "Deutsche Telekom Root CA 2" -# Serial: 38 -# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08 -# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf -# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3 ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc -MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj -IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB -IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE -RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl -U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 -IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU -ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC -QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr -rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S -NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc -QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH -txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP -BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC -AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp -tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa -IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl -6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ -xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- - -# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc -# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc -# Label: "Cybertrust Global Root" -# Serial: 4835703278459682877484360 -# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 -# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 -# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG -A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh -bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE -ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS -b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 -7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS -J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y -HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP -t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz -FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY -XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ -MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw -hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js -MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA -A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj -Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx -XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o -omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc -A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- - -# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority -# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority -# Label: "ePKI Root Certification Authority" -# Serial: 28956088682735189655030529057352760477 -# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 -# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 -# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw -IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL -SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH -SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh -ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X -DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 -TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ -fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA -sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU -WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS -nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH -dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip -NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC -AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF -MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB -uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl -PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP -JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ -gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 -j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 -5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB -o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS -/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z -Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE -W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D -hNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- - -# Issuer: O=certSIGN OU=certSIGN ROOT CA -# Subject: O=certSIGN OU=certSIGN ROOT CA -# Label: "certSIGN ROOT CA" -# Serial: 35210227249154 -# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 -# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b -# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT -AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD -QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP -MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do -0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ -UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d -RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ -OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv -JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C -AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O -BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ -LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY -MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ -44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I -Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw -i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN -9u6wWk5JRFRYX0KD ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only -# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only -# Label: "GeoTrust Primary Certification Authority - G3" -# Serial: 28809105769928564313984085209975885599 -# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 -# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd -# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB -mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT -MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s -eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ -BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 -BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz -+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm -hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn -5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W -JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL -DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC -huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw -HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB -AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB -zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN -kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH -SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G -spki4cErx5z481+oghLrGREt ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA - G2" -# Serial: 71758320672825410020661621085256472406 -# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f -# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 -# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp -IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi -BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw -MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig -YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v -dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ -BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 -papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K -DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 -KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox -XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- - -# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only -# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only -# Label: "thawte Primary Root CA - G3" -# Serial: 127614157056681299805556476275995414779 -# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 -# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 -# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB -rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV -BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa -Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl -LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u -MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl -ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm -gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 -YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf -b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 -9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S -zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk -OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV -HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA -2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW -oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c -KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM -m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu -MdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- - -# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only -# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only -# Label: "GeoTrust Primary Certification Authority - G2" -# Serial: 80682863203381065782177908751794619243 -# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a -# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 -# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL -MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj -KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 -MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw -NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV -BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH -MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL -So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal -tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG -CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT -qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz -rD6ogRLQy7rQkgu2npaqBA+K ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Universal Root Certification Authority" -# Serial: 85209574734084581917763752644031726877 -# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 -# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 -# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB -vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W -ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX -MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 -IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y -IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh -bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF -9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH -H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H -LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN -/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT -rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw -WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs -exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 -sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ -seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz -4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ -BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR -lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 -7M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- - -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only -# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" -# Serial: 63143484348153506665311985501458640051 -# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 -# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a -# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp -U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg -SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln -biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm -GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve -fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ -aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj -aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW -kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC -4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga -FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- - -# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) -# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) -# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" -# Serial: 80544274841616 -# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 -# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 -# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG -EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 -MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR -dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB -pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM -b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm -aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz -IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT -lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz -AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 -VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG -ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 -BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG -AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M -U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh -bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C -+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F -uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 -XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- - -# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden -# Label: "Staat der Nederlanden Root CA - G2" -# Serial: 10000012 -# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a -# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16 -# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f ------BEGIN CERTIFICATE----- -MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX -DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 -qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp -uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU -Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE -pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp -5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M -UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN -GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy -5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv -6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK -eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 -B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ -BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov -L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG -SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS -CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen -5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 -IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK -gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL -+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL -vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm -bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk -N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC -Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z -ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== ------END CERTIFICATE----- - -# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Label: "Hongkong Post Root CA 1" -# Serial: 1000 -# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca -# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 -# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx -FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg -Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG -A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr -b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ -jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn -PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh -ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 -nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h -q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED -MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC -mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 -7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB -oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs -EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO -fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi -AmvZWg== ------END CERTIFICATE----- - -# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. -# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. -# Label: "SecureSign RootCA11" -# Serial: 1 -# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 -# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 -# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr -MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG -A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 -MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp -Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD -QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz -i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 -h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV -MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 -UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni -8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC -h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD -VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB -AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm -KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ -X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr -QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 -pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN -QSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - -# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. -# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. -# Label: "Microsec e-Szigno Root CA 2009" -# Serial: 14014712776195784473 -# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 -# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e -# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G -CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y -OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx -FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp -Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP -kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc -cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U -fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 -N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC -xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 -+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM -Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG -SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h -mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk -ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c -2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t -HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 -# Label: "GlobalSign Root CA - R3" -# Serial: 4835703278459759426209954 -# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 -# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad -# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- - -# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" -# Serial: 6047274297262753887 -# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 -# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa -# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - -# Issuer: CN=Izenpe.com O=IZENPE S.A. -# Subject: CN=Izenpe.com O=IZENPE S.A. -# Label: "Izenpe.com" -# Serial: 917563065490389241595536686991402621 -# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 -# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 -# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. -# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. -# Label: "Chambers of Commerce Root - 2008" -# Serial: 11806822484801597146 -# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 -# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c -# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz -IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz -MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj -dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw -EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp -MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 -28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq -VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q -DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR -5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL -ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a -Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl -UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s -+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 -Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx -hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV -HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 -+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN -YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t -L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy -ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt -IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV -HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w -DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW -PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF -5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 -glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH -FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 -pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD -xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG -tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq -jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De -fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ -d0jQ ------END CERTIFICATE----- - -# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. -# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. -# Label: "Global Chambersign Root - 2008" -# Serial: 14541511773111788494 -# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 -# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c -# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx -MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy -cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG -A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl -BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed -KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 -G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 -zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 -ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG -HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 -Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V -yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e -beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r -6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog -zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW -BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr -ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp -ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk -cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt -YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC -CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow -KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI -hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ -UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz -X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x -fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz -a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd -Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd -SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O -AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso -M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge -v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- - -# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. -# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. -# Label: "Go Daddy Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 -# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b -# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- - -# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Label: "Starfield Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 -# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e -# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Label: "Starfield Services Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 -# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f -# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Commercial O=AffirmTrust -# Subject: CN=AffirmTrust Commercial O=AffirmTrust -# Label: "AffirmTrust Commercial" -# Serial: 8608355977964138876 -# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 -# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 -# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP -Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr -ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL -MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 -yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr -VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ -nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG -XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj -vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt -Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g -N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC -nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Networking O=AffirmTrust -# Subject: CN=AffirmTrust Networking O=AffirmTrust -# Label: "AffirmTrust Networking" -# Serial: 8957382827206547757 -# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f -# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f -# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y -YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua -kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL -QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp -6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG -yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i -QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO -tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu -QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ -Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u -olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 -x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Premium O=AffirmTrust -# Subject: CN=AffirmTrust Premium O=AffirmTrust -# Label: "AffirmTrust Premium" -# Serial: 7893706540734352110 -# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 -# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 -# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz -dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG -A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U -cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf -qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ -JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ -+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS -s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 -HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 -70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG -V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S -qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S -5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia -C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX -OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE -FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 -KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B -8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ -MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc -0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ -u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF -u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH -YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 -GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO -RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e -KeC2uAloGRwYQw== ------END CERTIFICATE----- - -# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust -# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust -# Label: "AffirmTrust Premium ECC" -# Serial: 8401224907861490260 -# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d -# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb -# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Network CA" -# Serial: 279744 -# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 -# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e -# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM -MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D -ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU -cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 -WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg -Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw -IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH -UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM -TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU -BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM -kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x -AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y -sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL -I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 -J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY -VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- - -# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA -# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA -# Label: "TWCA Root Certification Authority" -# Serial: 1 -# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 -# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 -# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- - -# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 -# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 -# Label: "Security Communication RootCA2" -# Serial: 0 -# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 -# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 -# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX -DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy -dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj -YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV -OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr -zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM -VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ -hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO -ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw -awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs -OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 -DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF -coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc -okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 -t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy -1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ -SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- - -# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions RootCA 2011" -# Serial: 0 -# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 -# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d -# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix -RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p -YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw -NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK -EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl -cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz -dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ -fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns -bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD -75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP -FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV -HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp -5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu -b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA -A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p -6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 -dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys -Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI -l7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- - -# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 -# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 -# Label: "Actalis Authentication Root CA" -# Serial: 6271844772424770508 -# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 -# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac -# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE -BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w -MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC -SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 -ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv -UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX -4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 -KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ -gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb -rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ -51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F -be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe -KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F -v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn -fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 -jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz -ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL -e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 -jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz -WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V -SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j -pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX -X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok -fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R -K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU -ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU -LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT -LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- - -# Issuer: O=Trustis Limited OU=Trustis FPS Root CA -# Subject: O=Trustis Limited OU=Trustis FPS Root CA -# Label: "Trustis FPS Root CA" -# Serial: 36053640375399034304724988975563710553 -# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d -# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 -# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL -ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx -MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc -MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ -AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH -iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj -vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA -0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB -OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ -BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E -FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 -GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW -zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 -1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE -f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F -jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN -ZetX2fNXlrtIzYE= ------END CERTIFICATE----- - -# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 -# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 -# Label: "Buypass Class 2 Root CA" -# Serial: 2 -# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 -# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 -# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr -6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV -L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 -1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx -MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ -QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB -arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr -Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi -FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS -P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN -9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz -uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h -9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t -OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo -+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 -KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 -DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us -H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ -I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 -5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h -3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz -Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= ------END CERTIFICATE----- - -# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 -# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 -# Label: "Buypass Class 3 Root CA" -# Serial: 2 -# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec -# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 -# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y -ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E -N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 -tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX -0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c -/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X -KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY -zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS -O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D -34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP -K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv -Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj -QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS -IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 -HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa -O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv -033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u -dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE -kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 -3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD -u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq -4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= ------END CERTIFICATE----- - -# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Label: "T-TeleSec GlobalRoot Class 3" -# Serial: 1 -# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef -# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 -# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN -8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ -RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 -hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 -ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM -EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 -A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy -WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ -1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 -6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT -91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p -TpPDpFQUWw== ------END CERTIFICATE----- - -# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus -# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus -# Label: "EE Certification Centre Root CA" -# Serial: 112324828676200291871926431888494945866 -# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f -# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7 -# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76 ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 -MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 -czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG -CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy -MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl -ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS -b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy -euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO -bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw -WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d -MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE -1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ -zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB -BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF -BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV -v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG -E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u -uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW -iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v -GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH -# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH -# Label: "D-TRUST Root Class 3 CA 2 2009" -# Serial: 623603 -# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f -# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 -# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha -ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM -HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 -UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 -tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R -ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM -lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp -/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G -A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy -MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl -cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js -L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL -BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni -acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K -zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 -PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y -Johw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH -# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH -# Label: "D-TRUST Root Class 3 CA 2 EV 2009" -# Serial: 623604 -# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 -# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 -# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw -NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV -BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn -ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 -3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z -qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR -p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 -HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw -ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea -HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw -Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh -c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E -RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt -dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku -Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp -3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF -CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na -xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX -KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 ------END CERTIFICATE----- - -# Issuer: CN=CA Disig Root R2 O=Disig a.s. -# Subject: CN=CA Disig Root R2 O=Disig a.s. -# Label: "CA Disig Root R2" -# Serial: 10572350602393338211 -# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 -# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 -# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy -MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe -NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH -PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I -x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe -QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR -yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO -QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 -H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ -QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD -i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs -nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 -rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI -hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf -GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb -lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka -+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal -TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i -nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 -gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr -G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os -zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x -L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- - -# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV -# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV -# Label: "ACCVRAIZ1" -# Serial: 6828503384748696800 -# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 -# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 -# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 ------BEGIN CERTIFICATE----- -MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE -AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw -CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ -BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND -VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb -qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY -HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo -G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA -lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr -IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ -0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH -k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 -4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO -m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa -cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl -uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI -KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls -ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG -AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 -VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT -VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG -CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA -cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA -QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA -7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA -cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA -QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA -czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu -aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt -aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud -DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF -BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp -D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU -JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m -AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD -vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms -tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH -7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h -I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA -h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF -d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H -pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 ------END CERTIFICATE----- - -# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA -# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA -# Label: "TWCA Global Root CA" -# Serial: 3262 -# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 -# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 -# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- - -# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera -# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera -# Label: "TeliaSonera Root CA v1" -# Serial: 199041966741090107964904287217786801558 -# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c -# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 -# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw -NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv -b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD -VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F -VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 -7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X -Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ -/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs -81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm -dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe -Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu -sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 -pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs -slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ -arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD -VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG -9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl -dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj -TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed -Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 -Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI -OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 -vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW -t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn -HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx -SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- - -# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Label: "E-Tugra Certification Authority" -# Serial: 7667447206703254355 -# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 -# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 -# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- - -# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Label: "T-TeleSec GlobalRoot Class 2" -# Serial: 1 -# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a -# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 -# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd -AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC -FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi -1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq -jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ -wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ -WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy -NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC -uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw -IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 -g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP -BSeOE6Fuwg== ------END CERTIFICATE----- - -# Issuer: CN=Atos TrustedRoot 2011 O=Atos -# Subject: CN=Atos TrustedRoot 2011 O=Atos -# Label: "Atos TrustedRoot 2011" -# Serial: 6643877497813316402 -# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 -# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 -# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE -AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG -EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM -FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC -REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp -Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM -VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ -SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ -4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L -cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi -eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG -A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 -DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j -vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP -DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc -maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D -lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv -KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 1 G3" -# Serial: 687049649626669250736271037606554624078720034195 -# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab -# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 -# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 -MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV -wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe -rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 -68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh -4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp -UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o -abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc -3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G -KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt -hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO -Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt -zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD -ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 -cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN -qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 -YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv -b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 -8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k -NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj -ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp -q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt -nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 2 G3" -# Serial: 390156079458959257446133169266079962026824725800 -# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 -# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 -# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 -MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf -qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW -n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym -c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ -O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 -o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j -IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq -IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz -8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh -vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l -7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG -cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD -ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC -roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga -W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n -lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE -+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV -csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd -dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg -KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM -HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 -WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 3 G3" -# Serial: 268090761170461462463995952157327242137089239581 -# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 -# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d -# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 -MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR -/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu -FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR -U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c -ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR -FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k -A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw -eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl -sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp -VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q -A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ -ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD -ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI -FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv -oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg -u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP -0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf -3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl -8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ -DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN -PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ -ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root G2" -# Serial: 15385348160840213938643033620894905419 -# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d -# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f -# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root G3" -# Serial: 15459312981008553731928384953135426796 -# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb -# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 -# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root G2" -# Serial: 4293743540046975378534879503202253541 -# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 -# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 -# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root G3" -# Serial: 7089244469030293291760083333884364146 -# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca -# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e -# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Trusted Root G4" -# Serial: 7451500558977370777930084869016614236 -# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 -# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 -# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- - -# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited -# Label: "COMODO RSA Certification Authority" -# Serial: 101909084537582093308941363524873193117 -# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 -# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 -# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- - -# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network -# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network -# Label: "USERTrust RSA Certification Authority" -# Serial: 2645093764781058787591871645665788717 -# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 -# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e -# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- - -# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network -# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network -# Label: "USERTrust ECC Certification Authority" -# Serial: 123013823720199481456569720443997572134 -# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 -# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 -# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl -eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT -JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT -Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg -VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo -I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng -o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G -A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB -zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW -RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 -# Label: "GlobalSign ECC Root CA - R4" -# Serial: 14367148294922964480859022125800977897474 -# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e -# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb -# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ -FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F -uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX -kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs -ewv4n4Q= ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 -# Label: "GlobalSign ECC Root CA - R5" -# Serial: 32785792099990507226680698011560947931244 -# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 -# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa -# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc -8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke -hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI -KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg -515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO -xwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- - -# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden -# Label: "Staat der Nederlanden Root CA - G3" -# Serial: 10003001 -# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 -# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc -# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX -DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP -cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW -IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX -xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy -KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR -9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az -5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 -6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 -Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP -bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt -BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt -XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd -INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD -U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp -LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 -Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp -gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh -/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw -0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A -fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq -4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR -1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ -QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM -94B7IWcnMFk= ------END CERTIFICATE----- - -# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden -# Label: "Staat der Nederlanden EV Root CA" -# Serial: 10000013 -# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba -# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb -# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a ------BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y -MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg -TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS -b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS -M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC -UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d -Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p -rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l -pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb -j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC -KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS -/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X -cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH -1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP -px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 -MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u -2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS -v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC -wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy -CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e -vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 -Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa -Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL -eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 -FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc -7uzXLg== ------END CERTIFICATE----- - -# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust -# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust -# Label: "IdenTrust Commercial Root CA 1" -# Serial: 13298821034946342390520003877796839426 -# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 -# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 -# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu -VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw -MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw -JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT -3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU -+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp -S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 -bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi -T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL -vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK -Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK -dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT -c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv -l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N -iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD -ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt -LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 -nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 -+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK -W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT -AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq -l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG -4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ -mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A -7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H ------END CERTIFICATE----- - -# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust -# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust -# Label: "IdenTrust Public Sector Root CA 1" -# Serial: 13298821034946342390521976156843933698 -# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba -# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd -# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu -VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN -MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 -MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 -ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy -RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS -bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF -/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R -3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw -EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy -9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V -GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ -2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV -WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD -W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN -AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV -DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 -TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G -lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW -mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df -WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 -+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ -tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA -GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv -8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- - -# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only -# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only -# Label: "Entrust Root Certification Authority - G2" -# Serial: 1246989352 -# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 -# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 -# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 -cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs -IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz -dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy -NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu -dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt -dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 -aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T -RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN -cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW -wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 -U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 -jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN -BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ -jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v -1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R -nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH -VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== ------END CERTIFICATE----- - -# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only -# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only -# Label: "Entrust Root Certification Authority - EC1" -# Serial: 51543124481930649114116133369 -# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc -# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 -# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG -A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 -d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu -dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq -RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy -MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD -VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g -Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi -A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt -ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH -Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC -R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX -hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- - -# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority -# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority -# Label: "CFCA EV ROOT" -# Serial: 407555286 -# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 -# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 -# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD -TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx -MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j -aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP -T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 -sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL -TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 -/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp -7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz -EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt -hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP -a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot -aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg -TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV -PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv -cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL -tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd -BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT -ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL -jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS -ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy -P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 -xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d -Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN -5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe -/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z -AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ -5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- - -# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 -# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 -# Label: "Certinomis - Root CA" -# Serial: 1 -# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f -# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8 -# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58 ------BEGIN CERTIFICATE----- -MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET -MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb -BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz -MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx -FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g -Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 -fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl -LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV -WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF -TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb -5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc -CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri -wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ -wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG -m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 -F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng -WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 -2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF -AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ -0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw -F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS -g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj -qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN -h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ -ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V -btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj -Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ -8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW -gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= ------END CERTIFICATE----- - -# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed -# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed -# Label: "OISTE WISeKey Global Root GB CA" -# Serial: 157768595616588414422159278966750757568 -# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d -# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed -# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg -Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i -YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x -CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG -b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 -HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx -WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX -1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk -u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P -99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r -M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB -BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh -cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 -gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO -ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf -aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- - -# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. -# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. -# Label: "SZAFIR ROOT CA2" -# Serial: 357043034767186914217277344587386743377558296292 -# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 -# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de -# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL -BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 -ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw -NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L -cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg -Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN -QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT -3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw -3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 -3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 -BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN -XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF -AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw -8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG -nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP -oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy -d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg -LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Network CA 2" -# Serial: 44979900017204383099463764357512596969 -# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 -# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 -# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB -gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu -QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG -A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz -OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ -VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 -b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA -DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn -0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB -OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE -fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E -Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m -o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i -sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW -OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez -Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS -adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n -3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ -F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf -CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 -XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm -djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ -WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb -AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq -P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko -b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj -XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P -5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi -DrW5viSP ------END CERTIFICATE----- - -# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions RootCA 2015" -# Serial: 0 -# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce -# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 -# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix -DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k -IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT -N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v -dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG -A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh -ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx -QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA -4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 -AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 -4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C -ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV -9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD -gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 -Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq -NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko -LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd -ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I -XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI -M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot -9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V -Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea -j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh -X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ -l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf -bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 -pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK -e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 -vm9qp/UsQu0yrbYhnr68 ------END CERTIFICATE----- - -# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" -# Serial: 0 -# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef -# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 -# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN -BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl -bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv -b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ -BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj -YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 -MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 -dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg -QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa -jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi -C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep -lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof -TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- - -# Issuer: CN=ISRG Root X1 O=Internet Security Research Group -# Subject: CN=ISRG Root X1 O=Internet Security Research Group -# Label: "ISRG Root X1" -# Serial: 172886928669790476064670243504169061120 -# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e -# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 -# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- - -# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM -# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM -# Label: "AC RAIZ FNMT-RCM" -# Serial: 485876308206448804701554682760554759 -# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d -# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 -# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx -CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ -WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ -BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG -Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ -yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf -BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz -WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF -tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z -374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC -IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL -mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 -wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS -MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 -ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet -UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H -YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 -LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 -RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM -LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf -77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N -JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm -fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp -6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp -1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B -9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok -RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv -uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 1 O=Amazon -# Subject: CN=Amazon Root CA 1 O=Amazon -# Label: "Amazon Root CA 1" -# Serial: 143266978916655856878034712317230054538369994 -# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 -# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 -# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e ------BEGIN CERTIFICATE----- -MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj -ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM -9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw -IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 -VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L -93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm -jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA -A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI -U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs -N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv -o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU -5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy -rqXRfboQnoZsG4q5WTP468SQvvG5 ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 2 O=Amazon -# Subject: CN=Amazon Root CA 2 O=Amazon -# Label: "Amazon Root CA 2" -# Serial: 143266982885963551818349160658925006970653239 -# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 -# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a -# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK -gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ -W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg -1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K -8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r -2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me -z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR -8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj -mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz -7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 -+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI -0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm -UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 -LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY -+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS -k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl -7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm -btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl -urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ -fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 -n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE -76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H -9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT -4PsJYGw= ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 3 O=Amazon -# Subject: CN=Amazon Root CA 3 O=Amazon -# Label: "Amazon Root CA 3" -# Serial: 143266986699090766294700635381230934788665930 -# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 -# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e -# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 ------BEGIN CERTIFICATE----- -MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl -ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr -ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr -BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM -YyRIHN8wfdVoOw== ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 4 O=Amazon -# Subject: CN=Amazon Root CA 4 O=Amazon -# Label: "Amazon Root CA 4" -# Serial: 143266989758080763974105200630763877849284878 -# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd -# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be -# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 ------BEGIN CERTIFICATE----- -MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi -9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk -M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB -MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw -CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW -1KyLa2tJElMzrdfkviT8tQp21KW8EA== ------END CERTIFICATE----- - -# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A. -# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A. -# Label: "LuxTrust Global Root 2" -# Serial: 59914338225734147123941058376788110305822489521 -# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c -# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f -# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5 ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM -# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM -# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" -# Serial: 1 -# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 -# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca -# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx -GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp -bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w -KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 -BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy -dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG -EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll -IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU -QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT -TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg -LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 -a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr -LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr -N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X -YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ -iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f -AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH -V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh -AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf -IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 -lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c -8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf -lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= ------END CERTIFICATE----- - -# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. -# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. -# Label: "GDCA TrustAUTH R5 ROOT" -# Serial: 9009899650740120186 -# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 -# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 -# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE -BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ -IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 -MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV -BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w -HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj -Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj -TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u -KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj -qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm -MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 -ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP -zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk -L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC -jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA -HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC -AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg -p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm -DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 -COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry -L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf -JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg -IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io -2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV -09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ -XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq -T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe -MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== ------END CERTIFICATE----- - -# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Label: "TrustCor RootCert CA-1" -# Serial: 15752444095811006489 -# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 -# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a -# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD -VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk -MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y -IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB -pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h -IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG -A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU -cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid -RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V -seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme -9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV -EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW -hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ -DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD -ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I -/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf -ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ -yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts -L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN -zl/HHk484IkzlQsPpTLWPFp5LBk= ------END CERTIFICATE----- - -# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Label: "TrustCor RootCert CA-2" -# Serial: 2711694510199101698 -# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 -# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 -# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 ------BEGIN CERTIFICATE----- -MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV -BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw -IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy -dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig -Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk -MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg -Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD -VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy -dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ -QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq -1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp -2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK -DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape -az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF -3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 -oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM -g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 -mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh -8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd -BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U -nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw -DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX -dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ -MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL -/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX -CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa -ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW -2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 -N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 -Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB -As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp -5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu -1uwJ ------END CERTIFICATE----- - -# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority -# Label: "TrustCor ECA-1" -# Serial: 9548242946988625984 -# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c -# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd -# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD -VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk -MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y -IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV -BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw -IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy -dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig -RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb -3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA -BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 -3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou -owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ -wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF -ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf -BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv -civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 -AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F -hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 -soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI -WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi -tJ/X5g== ------END CERTIFICATE----- - -# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation -# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation -# Label: "SSL.com Root Certification Authority RSA" -# Serial: 8875640296558310041 -# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 -# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb -# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE -BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK -DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz -OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R -xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX -qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC -C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 -6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh -/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF -YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E -JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc -US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 -ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm -+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi -M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G -A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV -cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc -Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs -PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ -q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 -cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr -a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I -H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y -K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu -nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf -oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY -Ic2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- - -# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation -# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation -# Label: "SSL.com Root Certification Authority ECC" -# Serial: 8495723813297216424 -# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e -# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a -# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz -WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 -b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS -b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI -7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg -CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud -EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD -VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T -kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ -gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- - -# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation -# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation -# Label: "SSL.com EV Root Certification Authority RSA R2" -# Serial: 6248227494352943350 -# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 -# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a -# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV -BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE -CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy -MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G -A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD -DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq -M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf -OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa -4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 -HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR -aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA -b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ -Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV -PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO -pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu -UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY -MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 -9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW -s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 -Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg -cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM -79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz -/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt -ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm -Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK -QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ -w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi -S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 -mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- - -# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation -# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation -# Label: "SSL.com EV Root Certification Authority ECC" -# Serial: 3182246526754555285 -# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 -# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d -# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx -NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv -bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA -VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku -WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX -5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ -ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg -h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 -# Label: "GlobalSign Root CA - R6" -# Serial: 1417766617973444989252670301619537 -# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae -# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 -# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg -MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx -MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET -MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI -xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k -ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD -aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw -LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw -1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX -k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 -SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h -bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n -WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY -rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce -MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu -bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN -nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt -Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 -55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj -vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf -cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz -oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp -nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs -pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v -JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R -8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 -5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= ------END CERTIFICATE----- - -# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed -# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed -# Label: "OISTE WISeKey Global Root GC CA" -# Serial: 44084345621038548146064804565436152554 -# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 -# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 -# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d ------BEGIN CERTIFICATE----- -MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw -CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 -bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg -Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ -BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu -ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS -b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni -eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W -p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T -rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV -57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg -Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R1 O=Google Trust Services LLC -# Subject: CN=GTS Root R1 O=Google Trust Services LLC -# Label: "GTS Root R1" -# Serial: 146587175971765017618439757810265552097 -# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 -# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 -# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM -f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX -mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 -zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P -fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc -vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 -Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp -zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO -Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW -k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ -DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF -lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW -Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 -d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z -XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR -gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 -d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv -J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg -DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM -+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy -F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 -SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws -E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R2 O=Google Trust Services LLC -# Subject: CN=GTS Root R2 O=Google Trust Services LLC -# Label: "GTS Root R2" -# Serial: 146587176055767053814479386953112547951 -# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b -# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d -# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv -CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg -GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu -XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd -re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu -PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 -mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K -8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj -x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR -nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 -kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok -twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp -8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT -vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT -z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA -pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb -pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB -R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R -RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk -0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC -5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF -izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn -yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R3 O=Google Trust Services LLC -# Subject: CN=GTS Root R3 O=Google Trust Services LLC -# Label: "GTS Root R3" -# Serial: 146587176140553309517047991083707763997 -# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 -# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 -# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 ------BEGIN CERTIFICATE----- -MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout -736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A -DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk -fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA -njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R4 O=Google Trust Services LLC -# Subject: CN=GTS Root R4 O=Google Trust Services LLC -# Label: "GTS Root R4" -# Serial: 146587176229350439916519468929765261721 -# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 -# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb -# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd ------BEGIN CERTIFICATE----- -MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu -hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l -xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 -CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx -sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== ------END CERTIFICATE----- - -# Issuer: CN=UCA Global G2 Root O=UniTrust -# Subject: CN=UCA Global G2 Root O=UniTrust -# Label: "UCA Global G2 Root" -# Serial: 124779693093741543919145257850076631279 -# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 -# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a -# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH -bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x -CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds -b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr -b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 -kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm -VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R -VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc -C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj -tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY -D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv -j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl -NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 -iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP -O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV -ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj -L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl -1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU -b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV -PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj -y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb -EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg -DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI -+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy -YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX -UB+K+wb1whnw0A== ------END CERTIFICATE----- - -# Issuer: CN=UCA Extended Validation Root O=UniTrust -# Subject: CN=UCA Extended Validation Root O=UniTrust -# Label: "UCA Extended Validation Root" -# Serial: 106100277556486529736699587978573607008 -# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 -# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a -# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF -eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx -MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV -BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog -D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS -sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop -O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk -sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi -c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj -VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz -KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ -TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G -sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs -1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD -fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN -l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ -VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 -c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp -4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s -t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj -2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO -vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C -xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx -cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM -fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax ------END CERTIFICATE----- - -# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 -# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 -# Label: "Certigna Root CA" -# Serial: 269714418870597844693661054334862075617 -# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 -# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 -# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw -WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw -MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x -MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD -VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX -BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO -ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M -CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu -I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm -TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh -C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf -ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz -IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT -Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k -JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 -hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB -GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov -L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo -dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr -aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq -hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L -6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG -HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 -0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB -lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi -o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 -gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v -faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 -Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh -jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw -3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/core.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/core.py deleted file mode 100644 index 2d02ea4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/certifi/core.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -certifi.py -~~~~~~~~~~ - -This module returns the installation location of cacert.pem. -""" -import os - - -def where(): - f = os.path.dirname(__file__) - - return os.path.join(f, 'cacert.pem') - - -if __name__ == '__main__': - print(where()) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/__init__.py deleted file mode 100644 index 0f9f820..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/__init__.py +++ /dev/null @@ -1,39 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - - -from .compat import PY2, PY3 -from .universaldetector import UniversalDetector -from .version import __version__, VERSION - - -def detect(byte_str): - """ - Detect the encoding of the given byte string. - - :param byte_str: The byte sequence to examine. - :type byte_str: ``bytes`` or ``bytearray`` - """ - if not isinstance(byte_str, bytearray): - if not isinstance(byte_str, bytes): - raise TypeError('Expected object of type bytes or bytearray, got: ' - '{0}'.format(type(byte_str))) - else: - byte_str = bytearray(byte_str) - detector = UniversalDetector() - detector.feed(byte_str) - return detector.close() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/big5freq.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/big5freq.py deleted file mode 100644 index 38f3251..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/big5freq.py +++ /dev/null @@ -1,386 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# Big5 frequency table -# by Taiwan's Mandarin Promotion Council -# <http://www.edu.tw:81/mandr/> -# -# 128 --> 0.42261 -# 256 --> 0.57851 -# 512 --> 0.74851 -# 1024 --> 0.89384 -# 2048 --> 0.97583 -# -# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 -# Random Distribution Ration = 512/(5401-512)=0.105 -# -# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR - -BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 - -#Char to FreqOrder table -BIG5_TABLE_SIZE = 5376 - -BIG5_CHAR_TO_FREQ_ORDER = ( - 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 -3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 -1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 - 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 -3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 -4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 -5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 - 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 - 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 - 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 -2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 -1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 -3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 - 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 -1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 -3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 -2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 - 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 -3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 -1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 -5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 - 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 -5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 -1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 - 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 - 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 -3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 -3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 - 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 -2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 -2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 - 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 - 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 -3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 -1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 -1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 -1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 -2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 - 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 -4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 -1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 -5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 -2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 - 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 - 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 - 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 - 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 -5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 - 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 -1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 - 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 - 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 -5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 -1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 - 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 -3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 -4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 -3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 - 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 - 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 -1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 -4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 -3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 -3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 -2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 -5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 -3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 -5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 -1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 -2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 -1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 - 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 -1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 -4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 -3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 - 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 - 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 - 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 -2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 -5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 -1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 -2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 -1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 -1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 -5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 -5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 -5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 -3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 -4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 -4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 -2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 -5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 -3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 - 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 -5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 -5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 -1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 -2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 -3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 -4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 -5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 -3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 -4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 -1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 -1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 -4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 -1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 - 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 -1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 -1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 -3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 - 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 -5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 -2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 -1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 -1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 -5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 - 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 -4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 - 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 -2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 - 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 -1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 -1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 - 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 -4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 -4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 -1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 -3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 -5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 -5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 -1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 -2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 -1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 -3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 -2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 -3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 -2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 -4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 -4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 -3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 - 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 -3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 - 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 -3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 -4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 -3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 -1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 -5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 - 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 -5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 -1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 - 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 -4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 -4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 - 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 -2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 -2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 -3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 -1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 -4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 -2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 -1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 -1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 -2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 -3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 -1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 -5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 -1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 -4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 -1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 - 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 -1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 -4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 -4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 -2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 -1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 -4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 - 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 -5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 -2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 -3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 -4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 - 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 -5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 -5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 -1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 -4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 -4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 -2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 -3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 -3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 -2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 -1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 -4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 -3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 -3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 -2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 -4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 -5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 -3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 -2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 -3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 -1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 -2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 -3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 -4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 -2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 -2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 -5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 -1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 -2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 -1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 -3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 -4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 -2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 -3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 -3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 -2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 -4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 -2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 -3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 -4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 -5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 -3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 - 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 -1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 -4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 -1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 -4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 -5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 - 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 -5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 -5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 -2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 -3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 -2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 -2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 - 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 -1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 -4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 -3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 -3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 - 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 -2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 - 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 -2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 -4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 -1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 -4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 -1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 -3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 - 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 -3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 -5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 -5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 -3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 -3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 -1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 -2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 -5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 -1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 -1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 -3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 - 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 -1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 -4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 -5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 -2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 -3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 - 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 -1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 -2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 -2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 -5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 -5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 -5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 -2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 -2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 -1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 -4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 -3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 -3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 -4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 -4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 -2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 -2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 -5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 -4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 -5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 -4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 - 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 - 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 -1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 -3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 -4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 -1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 -5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 -2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 -2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 -3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 -5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 -1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 -3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 -5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 -1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 -5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 -2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 -3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 -2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 -3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 -3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 -3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 -4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 - 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 -2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 -4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 -3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 -5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 -1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 -5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 - 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 -1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 - 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 -4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 -1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 -4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 -1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 - 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 -3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 -4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 -5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 - 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 -3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 - 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 -2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 -) - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/big5prober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/big5prober.py deleted file mode 100644 index 98f9970..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/big5prober.py +++ /dev/null @@ -1,47 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import Big5DistributionAnalysis -from .mbcssm import BIG5_SM_MODEL - - -class Big5Prober(MultiByteCharSetProber): - def __init__(self): - super(Big5Prober, self).__init__() - self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) - self.distribution_analyzer = Big5DistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "Big5" - - @property - def language(self): - return "Chinese" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/chardistribution.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/chardistribution.py deleted file mode 100644 index c0395f4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/chardistribution.py +++ /dev/null @@ -1,233 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, - EUCTW_TYPICAL_DISTRIBUTION_RATIO) -from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, - EUCKR_TYPICAL_DISTRIBUTION_RATIO) -from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, - GB2312_TYPICAL_DISTRIBUTION_RATIO) -from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, - BIG5_TYPICAL_DISTRIBUTION_RATIO) -from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, - JIS_TYPICAL_DISTRIBUTION_RATIO) - - -class CharDistributionAnalysis(object): - ENOUGH_DATA_THRESHOLD = 1024 - SURE_YES = 0.99 - SURE_NO = 0.01 - MINIMUM_DATA_THRESHOLD = 3 - - def __init__(self): - # Mapping table to get frequency order from char order (get from - # GetOrder()) - self._char_to_freq_order = None - self._table_size = None # Size of above table - # This is a constant value which varies from language to language, - # used in calculating confidence. See - # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html - # for further detail. - self.typical_distribution_ratio = None - self._done = None - self._total_chars = None - self._freq_chars = None - self.reset() - - def reset(self): - """reset analyser, clear any state""" - # If this flag is set to True, detection is done and conclusion has - # been made - self._done = False - self._total_chars = 0 # Total characters encountered - # The number of characters whose frequency order is less than 512 - self._freq_chars = 0 - - def feed(self, char, char_len): - """feed a character with known length""" - if char_len == 2: - # we only care about 2-bytes character in our distribution analysis - order = self.get_order(char) - else: - order = -1 - if order >= 0: - self._total_chars += 1 - # order is valid - if order < self._table_size: - if 512 > self._char_to_freq_order[order]: - self._freq_chars += 1 - - def get_confidence(self): - """return confidence based on existing data""" - # if we didn't receive any character in our consideration range, - # return negative answer - if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: - return self.SURE_NO - - if self._total_chars != self._freq_chars: - r = (self._freq_chars / ((self._total_chars - self._freq_chars) - * self.typical_distribution_ratio)) - if r < self.SURE_YES: - return r - - # normalize confidence (we don't want to be 100% sure) - return self.SURE_YES - - def got_enough_data(self): - # It is not necessary to receive all data to draw conclusion. - # For charset detection, certain amount of data is enough - return self._total_chars > self.ENOUGH_DATA_THRESHOLD - - def get_order(self, byte_str): - # We do not handle characters based on the original encoding string, - # but convert this encoding string to a number, here called order. - # This allows multiple encodings of a language to share one frequency - # table. - return -1 - - -class EUCTWDistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(EUCTWDistributionAnalysis, self).__init__() - self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER - self._table_size = EUCTW_TABLE_SIZE - self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for euc-TW encoding, we are interested - # first byte range: 0xc4 -- 0xfe - # second byte range: 0xa1 -- 0xfe - # no validation needed here. State machine has done that - first_char = byte_str[0] - if first_char >= 0xC4: - return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 - else: - return -1 - - -class EUCKRDistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(EUCKRDistributionAnalysis, self).__init__() - self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER - self._table_size = EUCKR_TABLE_SIZE - self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for euc-KR encoding, we are interested - # first byte range: 0xb0 -- 0xfe - # second byte range: 0xa1 -- 0xfe - # no validation needed here. State machine has done that - first_char = byte_str[0] - if first_char >= 0xB0: - return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 - else: - return -1 - - -class GB2312DistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(GB2312DistributionAnalysis, self).__init__() - self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER - self._table_size = GB2312_TABLE_SIZE - self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for GB2312 encoding, we are interested - # first byte range: 0xb0 -- 0xfe - # second byte range: 0xa1 -- 0xfe - # no validation needed here. State machine has done that - first_char, second_char = byte_str[0], byte_str[1] - if (first_char >= 0xB0) and (second_char >= 0xA1): - return 94 * (first_char - 0xB0) + second_char - 0xA1 - else: - return -1 - - -class Big5DistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(Big5DistributionAnalysis, self).__init__() - self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER - self._table_size = BIG5_TABLE_SIZE - self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for big5 encoding, we are interested - # first byte range: 0xa4 -- 0xfe - # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe - # no validation needed here. State machine has done that - first_char, second_char = byte_str[0], byte_str[1] - if first_char >= 0xA4: - if second_char >= 0xA1: - return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 - else: - return 157 * (first_char - 0xA4) + second_char - 0x40 - else: - return -1 - - -class SJISDistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(SJISDistributionAnalysis, self).__init__() - self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER - self._table_size = JIS_TABLE_SIZE - self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for sjis encoding, we are interested - # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe - # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe - # no validation needed here. State machine has done that - first_char, second_char = byte_str[0], byte_str[1] - if (first_char >= 0x81) and (first_char <= 0x9F): - order = 188 * (first_char - 0x81) - elif (first_char >= 0xE0) and (first_char <= 0xEF): - order = 188 * (first_char - 0xE0 + 31) - else: - return -1 - order = order + second_char - 0x40 - if second_char > 0x7F: - order = -1 - return order - - -class EUCJPDistributionAnalysis(CharDistributionAnalysis): - def __init__(self): - super(EUCJPDistributionAnalysis, self).__init__() - self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER - self._table_size = JIS_TABLE_SIZE - self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO - - def get_order(self, byte_str): - # for euc-JP encoding, we are interested - # first byte range: 0xa0 -- 0xfe - # second byte range: 0xa1 -- 0xfe - # no validation needed here. State machine has done that - char = byte_str[0] - if char >= 0xA0: - return 94 * (char - 0xA1) + byte_str[1] - 0xa1 - else: - return -1 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/charsetgroupprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/charsetgroupprober.py deleted file mode 100644 index 8b3738e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/charsetgroupprober.py +++ /dev/null @@ -1,106 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .enums import ProbingState -from .charsetprober import CharSetProber - - -class CharSetGroupProber(CharSetProber): - def __init__(self, lang_filter=None): - super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) - self._active_num = 0 - self.probers = [] - self._best_guess_prober = None - - def reset(self): - super(CharSetGroupProber, self).reset() - self._active_num = 0 - for prober in self.probers: - if prober: - prober.reset() - prober.active = True - self._active_num += 1 - self._best_guess_prober = None - - @property - def charset_name(self): - if not self._best_guess_prober: - self.get_confidence() - if not self._best_guess_prober: - return None - return self._best_guess_prober.charset_name - - @property - def language(self): - if not self._best_guess_prober: - self.get_confidence() - if not self._best_guess_prober: - return None - return self._best_guess_prober.language - - def feed(self, byte_str): - for prober in self.probers: - if not prober: - continue - if not prober.active: - continue - state = prober.feed(byte_str) - if not state: - continue - if state == ProbingState.FOUND_IT: - self._best_guess_prober = prober - return self.state - elif state == ProbingState.NOT_ME: - prober.active = False - self._active_num -= 1 - if self._active_num <= 0: - self._state = ProbingState.NOT_ME - return self.state - return self.state - - def get_confidence(self): - state = self.state - if state == ProbingState.FOUND_IT: - return 0.99 - elif state == ProbingState.NOT_ME: - return 0.01 - best_conf = 0.0 - self._best_guess_prober = None - for prober in self.probers: - if not prober: - continue - if not prober.active: - self.logger.debug('%s not active', prober.charset_name) - continue - conf = prober.get_confidence() - self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) - if best_conf < conf: - best_conf = conf - self._best_guess_prober = prober - if not self._best_guess_prober: - return 0.0 - return best_conf diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/charsetprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/charsetprober.py deleted file mode 100644 index eac4e59..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/charsetprober.py +++ /dev/null @@ -1,145 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -import logging -import re - -from .enums import ProbingState - - -class CharSetProber(object): - - SHORTCUT_THRESHOLD = 0.95 - - def __init__(self, lang_filter=None): - self._state = None - self.lang_filter = lang_filter - self.logger = logging.getLogger(__name__) - - def reset(self): - self._state = ProbingState.DETECTING - - @property - def charset_name(self): - return None - - def feed(self, buf): - pass - - @property - def state(self): - return self._state - - def get_confidence(self): - return 0.0 - - @staticmethod - def filter_high_byte_only(buf): - buf = re.sub(b'([\x00-\x7F])+', b' ', buf) - return buf - - @staticmethod - def filter_international_words(buf): - """ - We define three types of bytes: - alphabet: english alphabets [a-zA-Z] - international: international characters [\x80-\xFF] - marker: everything else [^a-zA-Z\x80-\xFF] - - The input buffer can be thought to contain a series of words delimited - by markers. This function works to filter all words that contain at - least one international character. All contiguous sequences of markers - are replaced by a single space ascii character. - - This filter applies to all scripts which do not use English characters. - """ - filtered = bytearray() - - # This regex expression filters out only words that have at-least one - # international character. The word may include one marker character at - # the end. - words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', - buf) - - for word in words: - filtered.extend(word[:-1]) - - # If the last character in the word is a marker, replace it with a - # space as markers shouldn't affect our analysis (they are used - # similarly across all languages and may thus have similar - # frequencies). - last_char = word[-1:] - if not last_char.isalpha() and last_char < b'\x80': - last_char = b' ' - filtered.extend(last_char) - - return filtered - - @staticmethod - def filter_with_english_letters(buf): - """ - Returns a copy of ``buf`` that retains only the sequences of English - alphabet and high byte characters that are not between <> characters. - Also retains English alphabet and high byte characters immediately - before occurrences of >. - - This filter can be applied to all scripts which contain both English - characters and extended ASCII characters, but is currently only used by - ``Latin1Prober``. - """ - filtered = bytearray() - in_tag = False - prev = 0 - - for curr in range(len(buf)): - # Slice here to get bytes instead of an int with Python 3 - buf_char = buf[curr:curr + 1] - # Check if we're coming out of or entering an HTML tag - if buf_char == b'>': - in_tag = False - elif buf_char == b'<': - in_tag = True - - # If current character is not extended-ASCII and not alphabetic... - if buf_char < b'\x80' and not buf_char.isalpha(): - # ...and we're not in a tag - if curr > prev and not in_tag: - # Keep everything after last non-extended-ASCII, - # non-alphabetic character - filtered.extend(buf[prev:curr]) - # Output a space to delimit stretch we kept - filtered.extend(b' ') - prev = curr + 1 - - # If we're not in a tag... - if not in_tag: - # Keep everything after last non-extended-ASCII, non-alphabetic - # character - filtered.extend(buf[prev:]) - - return filtered diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cli/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cli/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cli/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cli/chardetect.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cli/chardetect.py deleted file mode 100644 index c61136b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cli/chardetect.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python -""" -Script which takes one or more file paths and reports on their detected -encodings - -Example:: - - % chardetect somefile someotherfile - somefile: windows-1252 with confidence 0.5 - someotherfile: ascii with confidence 1.0 - -If no paths are provided, it takes its input from stdin. - -""" - -from __future__ import absolute_import, print_function, unicode_literals - -import argparse -import sys - -from pip._vendor.chardet import __version__ -from pip._vendor.chardet.compat import PY2 -from pip._vendor.chardet.universaldetector import UniversalDetector - - -def description_of(lines, name='stdin'): - """ - Return a string describing the probable encoding of a file or - list of strings. - - :param lines: The lines to get the encoding of. - :type lines: Iterable of bytes - :param name: Name of file or collection of lines - :type name: str - """ - u = UniversalDetector() - for line in lines: - line = bytearray(line) - u.feed(line) - # shortcut out of the loop to save reading further - particularly useful if we read a BOM. - if u.done: - break - u.close() - result = u.result - if PY2: - name = name.decode(sys.getfilesystemencoding(), 'ignore') - if result['encoding']: - return '{0}: {1} with confidence {2}'.format(name, result['encoding'], - result['confidence']) - else: - return '{0}: no result'.format(name) - - -def main(argv=None): - """ - Handles command line arguments and gets things started. - - :param argv: List of arguments, as if specified on the command-line. - If None, ``sys.argv[1:]`` is used instead. - :type argv: list of str - """ - # Get command line arguments - parser = argparse.ArgumentParser( - description="Takes one or more file paths and reports their detected \ - encodings") - parser.add_argument('input', - help='File whose encoding we would like to determine. \ - (default: stdin)', - type=argparse.FileType('rb'), nargs='*', - default=[sys.stdin if PY2 else sys.stdin.buffer]) - parser.add_argument('--version', action='version', - version='%(prog)s {0}'.format(__version__)) - args = parser.parse_args(argv) - - for f in args.input: - if f.isatty(): - print("You are running chardetect interactively. Press " + - "CTRL-D twice at the start of a blank line to signal the " + - "end of your input. If you want help, run chardetect " + - "--help\n", file=sys.stderr) - print(description_of(f, f.name)) - - -if __name__ == '__main__': - main() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/codingstatemachine.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/codingstatemachine.py deleted file mode 100644 index 68fba44..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/codingstatemachine.py +++ /dev/null @@ -1,88 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -import logging - -from .enums import MachineState - - -class CodingStateMachine(object): - """ - A state machine to verify a byte sequence for a particular encoding. For - each byte the detector receives, it will feed that byte to every active - state machine available, one byte at a time. The state machine changes its - state based on its previous state and the byte it receives. There are 3 - states in a state machine that are of interest to an auto-detector: - - START state: This is the state to start with, or a legal byte sequence - (i.e. a valid code point) for character has been identified. - - ME state: This indicates that the state machine identified a byte sequence - that is specific to the charset it is designed for and that - there is no other possible encoding which can contain this byte - sequence. This will to lead to an immediate positive answer for - the detector. - - ERROR state: This indicates the state machine identified an illegal byte - sequence for that encoding. This will lead to an immediate - negative answer for this encoding. Detector will exclude this - encoding from consideration from here on. - """ - def __init__(self, sm): - self._model = sm - self._curr_byte_pos = 0 - self._curr_char_len = 0 - self._curr_state = None - self.logger = logging.getLogger(__name__) - self.reset() - - def reset(self): - self._curr_state = MachineState.START - - def next_state(self, c): - # for each byte we get its class - # if it is first byte, we also get byte length - byte_class = self._model['class_table'][c] - if self._curr_state == MachineState.START: - self._curr_byte_pos = 0 - self._curr_char_len = self._model['char_len_table'][byte_class] - # from byte's class and state_table, we get its next state - curr_state = (self._curr_state * self._model['class_factor'] - + byte_class) - self._curr_state = self._model['state_table'][curr_state] - self._curr_byte_pos += 1 - return self._curr_state - - def get_current_charlen(self): - return self._curr_char_len - - def get_coding_state_machine(self): - return self._model['name'] - - @property - def language(self): - return self._model['language'] diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/compat.py deleted file mode 100644 index ddd7468..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/compat.py +++ /dev/null @@ -1,34 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# Contributor(s): -# Dan Blanchard -# Ian Cordasco -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -import sys - - -if sys.version_info < (3, 0): - PY2 = True - PY3 = False - base_str = (str, unicode) - text_type = unicode -else: - PY2 = False - PY3 = True - base_str = (bytes, str) - text_type = str diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cp949prober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cp949prober.py deleted file mode 100644 index efd793a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/cp949prober.py +++ /dev/null @@ -1,49 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .chardistribution import EUCKRDistributionAnalysis -from .codingstatemachine import CodingStateMachine -from .mbcharsetprober import MultiByteCharSetProber -from .mbcssm import CP949_SM_MODEL - - -class CP949Prober(MultiByteCharSetProber): - def __init__(self): - super(CP949Prober, self).__init__() - self.coding_sm = CodingStateMachine(CP949_SM_MODEL) - # NOTE: CP949 is a superset of EUC-KR, so the distribution should be - # not different. - self.distribution_analyzer = EUCKRDistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "CP949" - - @property - def language(self): - return "Korean" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/enums.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/enums.py deleted file mode 100644 index 0451207..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/enums.py +++ /dev/null @@ -1,76 +0,0 @@ -""" -All of the Enums that are used throughout the chardet package. - -:author: Dan Blanchard (dan.blanchard@gmail.com) -""" - - -class InputState(object): - """ - This enum represents the different states a universal detector can be in. - """ - PURE_ASCII = 0 - ESC_ASCII = 1 - HIGH_BYTE = 2 - - -class LanguageFilter(object): - """ - This enum represents the different language filters we can apply to a - ``UniversalDetector``. - """ - CHINESE_SIMPLIFIED = 0x01 - CHINESE_TRADITIONAL = 0x02 - JAPANESE = 0x04 - KOREAN = 0x08 - NON_CJK = 0x10 - ALL = 0x1F - CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL - CJK = CHINESE | JAPANESE | KOREAN - - -class ProbingState(object): - """ - This enum represents the different states a prober can be in. - """ - DETECTING = 0 - FOUND_IT = 1 - NOT_ME = 2 - - -class MachineState(object): - """ - This enum represents the different states a state machine can be in. - """ - START = 0 - ERROR = 1 - ITS_ME = 2 - - -class SequenceLikelihood(object): - """ - This enum represents the likelihood of a character following the previous one. - """ - NEGATIVE = 0 - UNLIKELY = 1 - LIKELY = 2 - POSITIVE = 3 - - @classmethod - def get_num_categories(cls): - """:returns: The number of likelihood categories in the enum.""" - return 4 - - -class CharacterCategory(object): - """ - This enum represents the different categories language models for - ``SingleByteCharsetProber`` put characters into. - - Anything less than CONTROL is considered a letter. - """ - UNDEFINED = 255 - LINE_BREAK = 254 - SYMBOL = 253 - DIGIT = 252 - CONTROL = 251 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/escprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/escprober.py deleted file mode 100644 index c70493f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/escprober.py +++ /dev/null @@ -1,101 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .codingstatemachine import CodingStateMachine -from .enums import LanguageFilter, ProbingState, MachineState -from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, - ISO2022KR_SM_MODEL) - - -class EscCharSetProber(CharSetProber): - """ - This CharSetProber uses a "code scheme" approach for detecting encodings, - whereby easily recognizable escape or shift sequences are relied on to - identify these encodings. - """ - - def __init__(self, lang_filter=None): - super(EscCharSetProber, self).__init__(lang_filter=lang_filter) - self.coding_sm = [] - if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: - self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) - self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) - if self.lang_filter & LanguageFilter.JAPANESE: - self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) - if self.lang_filter & LanguageFilter.KOREAN: - self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) - self.active_sm_count = None - self._detected_charset = None - self._detected_language = None - self._state = None - self.reset() - - def reset(self): - super(EscCharSetProber, self).reset() - for coding_sm in self.coding_sm: - if not coding_sm: - continue - coding_sm.active = True - coding_sm.reset() - self.active_sm_count = len(self.coding_sm) - self._detected_charset = None - self._detected_language = None - - @property - def charset_name(self): - return self._detected_charset - - @property - def language(self): - return self._detected_language - - def get_confidence(self): - if self._detected_charset: - return 0.99 - else: - return 0.00 - - def feed(self, byte_str): - for c in byte_str: - for coding_sm in self.coding_sm: - if not coding_sm or not coding_sm.active: - continue - coding_state = coding_sm.next_state(c) - if coding_state == MachineState.ERROR: - coding_sm.active = False - self.active_sm_count -= 1 - if self.active_sm_count <= 0: - self._state = ProbingState.NOT_ME - return self.state - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - self._detected_charset = coding_sm.get_coding_state_machine() - self._detected_language = coding_sm.language - return self.state - - return self.state diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/escsm.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/escsm.py deleted file mode 100644 index 0069523..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/escsm.py +++ /dev/null @@ -1,246 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .enums import MachineState - -HZ_CLS = ( -1,0,0,0,0,0,0,0, # 00 - 07 -0,0,0,0,0,0,0,0, # 08 - 0f -0,0,0,0,0,0,0,0, # 10 - 17 -0,0,0,1,0,0,0,0, # 18 - 1f -0,0,0,0,0,0,0,0, # 20 - 27 -0,0,0,0,0,0,0,0, # 28 - 2f -0,0,0,0,0,0,0,0, # 30 - 37 -0,0,0,0,0,0,0,0, # 38 - 3f -0,0,0,0,0,0,0,0, # 40 - 47 -0,0,0,0,0,0,0,0, # 48 - 4f -0,0,0,0,0,0,0,0, # 50 - 57 -0,0,0,0,0,0,0,0, # 58 - 5f -0,0,0,0,0,0,0,0, # 60 - 67 -0,0,0,0,0,0,0,0, # 68 - 6f -0,0,0,0,0,0,0,0, # 70 - 77 -0,0,0,4,0,5,2,0, # 78 - 7f -1,1,1,1,1,1,1,1, # 80 - 87 -1,1,1,1,1,1,1,1, # 88 - 8f -1,1,1,1,1,1,1,1, # 90 - 97 -1,1,1,1,1,1,1,1, # 98 - 9f -1,1,1,1,1,1,1,1, # a0 - a7 -1,1,1,1,1,1,1,1, # a8 - af -1,1,1,1,1,1,1,1, # b0 - b7 -1,1,1,1,1,1,1,1, # b8 - bf -1,1,1,1,1,1,1,1, # c0 - c7 -1,1,1,1,1,1,1,1, # c8 - cf -1,1,1,1,1,1,1,1, # d0 - d7 -1,1,1,1,1,1,1,1, # d8 - df -1,1,1,1,1,1,1,1, # e0 - e7 -1,1,1,1,1,1,1,1, # e8 - ef -1,1,1,1,1,1,1,1, # f0 - f7 -1,1,1,1,1,1,1,1, # f8 - ff -) - -HZ_ST = ( -MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f -MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 - 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f - 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 - 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f -) - -HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) - -HZ_SM_MODEL = {'class_table': HZ_CLS, - 'class_factor': 6, - 'state_table': HZ_ST, - 'char_len_table': HZ_CHAR_LEN_TABLE, - 'name': "HZ-GB-2312", - 'language': 'Chinese'} - -ISO2022CN_CLS = ( -2,0,0,0,0,0,0,0, # 00 - 07 -0,0,0,0,0,0,0,0, # 08 - 0f -0,0,0,0,0,0,0,0, # 10 - 17 -0,0,0,1,0,0,0,0, # 18 - 1f -0,0,0,0,0,0,0,0, # 20 - 27 -0,3,0,0,0,0,0,0, # 28 - 2f -0,0,0,0,0,0,0,0, # 30 - 37 -0,0,0,0,0,0,0,0, # 38 - 3f -0,0,0,4,0,0,0,0, # 40 - 47 -0,0,0,0,0,0,0,0, # 48 - 4f -0,0,0,0,0,0,0,0, # 50 - 57 -0,0,0,0,0,0,0,0, # 58 - 5f -0,0,0,0,0,0,0,0, # 60 - 67 -0,0,0,0,0,0,0,0, # 68 - 6f -0,0,0,0,0,0,0,0, # 70 - 77 -0,0,0,0,0,0,0,0, # 78 - 7f -2,2,2,2,2,2,2,2, # 80 - 87 -2,2,2,2,2,2,2,2, # 88 - 8f -2,2,2,2,2,2,2,2, # 90 - 97 -2,2,2,2,2,2,2,2, # 98 - 9f -2,2,2,2,2,2,2,2, # a0 - a7 -2,2,2,2,2,2,2,2, # a8 - af -2,2,2,2,2,2,2,2, # b0 - b7 -2,2,2,2,2,2,2,2, # b8 - bf -2,2,2,2,2,2,2,2, # c0 - c7 -2,2,2,2,2,2,2,2, # c8 - cf -2,2,2,2,2,2,2,2, # d0 - d7 -2,2,2,2,2,2,2,2, # d8 - df -2,2,2,2,2,2,2,2, # e0 - e7 -2,2,2,2,2,2,2,2, # e8 - ef -2,2,2,2,2,2,2,2, # f0 - f7 -2,2,2,2,2,2,2,2, # f8 - ff -) - -ISO2022CN_ST = ( -MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 -MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f -MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 -MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 - 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f -) - -ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) - -ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, - 'class_factor': 9, - 'state_table': ISO2022CN_ST, - 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, - 'name': "ISO-2022-CN", - 'language': 'Chinese'} - -ISO2022JP_CLS = ( -2,0,0,0,0,0,0,0, # 00 - 07 -0,0,0,0,0,0,2,2, # 08 - 0f -0,0,0,0,0,0,0,0, # 10 - 17 -0,0,0,1,0,0,0,0, # 18 - 1f -0,0,0,0,7,0,0,0, # 20 - 27 -3,0,0,0,0,0,0,0, # 28 - 2f -0,0,0,0,0,0,0,0, # 30 - 37 -0,0,0,0,0,0,0,0, # 38 - 3f -6,0,4,0,8,0,0,0, # 40 - 47 -0,9,5,0,0,0,0,0, # 48 - 4f -0,0,0,0,0,0,0,0, # 50 - 57 -0,0,0,0,0,0,0,0, # 58 - 5f -0,0,0,0,0,0,0,0, # 60 - 67 -0,0,0,0,0,0,0,0, # 68 - 6f -0,0,0,0,0,0,0,0, # 70 - 77 -0,0,0,0,0,0,0,0, # 78 - 7f -2,2,2,2,2,2,2,2, # 80 - 87 -2,2,2,2,2,2,2,2, # 88 - 8f -2,2,2,2,2,2,2,2, # 90 - 97 -2,2,2,2,2,2,2,2, # 98 - 9f -2,2,2,2,2,2,2,2, # a0 - a7 -2,2,2,2,2,2,2,2, # a8 - af -2,2,2,2,2,2,2,2, # b0 - b7 -2,2,2,2,2,2,2,2, # b8 - bf -2,2,2,2,2,2,2,2, # c0 - c7 -2,2,2,2,2,2,2,2, # c8 - cf -2,2,2,2,2,2,2,2, # d0 - d7 -2,2,2,2,2,2,2,2, # d8 - df -2,2,2,2,2,2,2,2, # e0 - e7 -2,2,2,2,2,2,2,2, # e8 - ef -2,2,2,2,2,2,2,2, # f0 - f7 -2,2,2,2,2,2,2,2, # f8 - ff -) - -ISO2022JP_ST = ( -MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 -MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 -MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f -MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 -) - -ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - -ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, - 'class_factor': 10, - 'state_table': ISO2022JP_ST, - 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, - 'name': "ISO-2022-JP", - 'language': 'Japanese'} - -ISO2022KR_CLS = ( -2,0,0,0,0,0,0,0, # 00 - 07 -0,0,0,0,0,0,0,0, # 08 - 0f -0,0,0,0,0,0,0,0, # 10 - 17 -0,0,0,1,0,0,0,0, # 18 - 1f -0,0,0,0,3,0,0,0, # 20 - 27 -0,4,0,0,0,0,0,0, # 28 - 2f -0,0,0,0,0,0,0,0, # 30 - 37 -0,0,0,0,0,0,0,0, # 38 - 3f -0,0,0,5,0,0,0,0, # 40 - 47 -0,0,0,0,0,0,0,0, # 48 - 4f -0,0,0,0,0,0,0,0, # 50 - 57 -0,0,0,0,0,0,0,0, # 58 - 5f -0,0,0,0,0,0,0,0, # 60 - 67 -0,0,0,0,0,0,0,0, # 68 - 6f -0,0,0,0,0,0,0,0, # 70 - 77 -0,0,0,0,0,0,0,0, # 78 - 7f -2,2,2,2,2,2,2,2, # 80 - 87 -2,2,2,2,2,2,2,2, # 88 - 8f -2,2,2,2,2,2,2,2, # 90 - 97 -2,2,2,2,2,2,2,2, # 98 - 9f -2,2,2,2,2,2,2,2, # a0 - a7 -2,2,2,2,2,2,2,2, # a8 - af -2,2,2,2,2,2,2,2, # b0 - b7 -2,2,2,2,2,2,2,2, # b8 - bf -2,2,2,2,2,2,2,2, # c0 - c7 -2,2,2,2,2,2,2,2, # c8 - cf -2,2,2,2,2,2,2,2, # d0 - d7 -2,2,2,2,2,2,2,2, # d8 - df -2,2,2,2,2,2,2,2, # e0 - e7 -2,2,2,2,2,2,2,2, # e8 - ef -2,2,2,2,2,2,2,2, # f0 - f7 -2,2,2,2,2,2,2,2, # f8 - ff -) - -ISO2022KR_ST = ( -MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f -MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f -MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 -) - -ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) - -ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, - 'class_factor': 6, - 'state_table': ISO2022KR_ST, - 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, - 'name': "ISO-2022-KR", - 'language': 'Korean'} - - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/eucjpprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/eucjpprober.py deleted file mode 100644 index 20ce8f7..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/eucjpprober.py +++ /dev/null @@ -1,92 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .enums import ProbingState, MachineState -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import EUCJPDistributionAnalysis -from .jpcntx import EUCJPContextAnalysis -from .mbcssm import EUCJP_SM_MODEL - - -class EUCJPProber(MultiByteCharSetProber): - def __init__(self): - super(EUCJPProber, self).__init__() - self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) - self.distribution_analyzer = EUCJPDistributionAnalysis() - self.context_analyzer = EUCJPContextAnalysis() - self.reset() - - def reset(self): - super(EUCJPProber, self).reset() - self.context_analyzer.reset() - - @property - def charset_name(self): - return "EUC-JP" - - @property - def language(self): - return "Japanese" - - def feed(self, byte_str): - for i in range(len(byte_str)): - # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte - coding_state = self.coding_sm.next_state(byte_str[i]) - if coding_state == MachineState.ERROR: - self.logger.debug('%s %s prober hit error at byte %s', - self.charset_name, self.language, i) - self._state = ProbingState.NOT_ME - break - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - break - elif coding_state == MachineState.START: - char_len = self.coding_sm.get_current_charlen() - if i == 0: - self._last_char[1] = byte_str[0] - self.context_analyzer.feed(self._last_char, char_len) - self.distribution_analyzer.feed(self._last_char, char_len) - else: - self.context_analyzer.feed(byte_str[i - 1:i + 1], - char_len) - self.distribution_analyzer.feed(byte_str[i - 1:i + 1], - char_len) - - self._last_char[0] = byte_str[-1] - - if self.state == ProbingState.DETECTING: - if (self.context_analyzer.got_enough_data() and - (self.get_confidence() > self.SHORTCUT_THRESHOLD)): - self._state = ProbingState.FOUND_IT - - return self.state - - def get_confidence(self): - context_conf = self.context_analyzer.get_confidence() - distrib_conf = self.distribution_analyzer.get_confidence() - return max(context_conf, distrib_conf) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euckrfreq.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euckrfreq.py deleted file mode 100644 index b68078c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euckrfreq.py +++ /dev/null @@ -1,195 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# Sampling from about 20M text materials include literature and computer technology - -# 128 --> 0.79 -# 256 --> 0.92 -# 512 --> 0.986 -# 1024 --> 0.99944 -# 2048 --> 0.99999 -# -# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 -# Random Distribution Ration = 512 / (2350-512) = 0.279. -# -# Typical Distribution Ratio - -EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 - -EUCKR_TABLE_SIZE = 2352 - -# Char to FreqOrder table , -EUCKR_CHAR_TO_FREQ_ORDER = ( - 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, -1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, -1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, - 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, - 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, - 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, -1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, - 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, - 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, -1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, -1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, -1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, -1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, -1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, - 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, -1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, -1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, -1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, -1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, - 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, -1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, - 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, - 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, -1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, - 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, -1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, - 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, - 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, -1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, -1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, -1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, -1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, - 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, -1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, - 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, - 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, -1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, -1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, -1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, -1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, -1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, -1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, - 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, - 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, - 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, -1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, - 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, -1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, - 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, - 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, -2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, - 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, - 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, -2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, -2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, -2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, - 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, - 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, -2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, - 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, -1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, -2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, -1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, -2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, -2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, -1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, - 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, -2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, -2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, - 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, - 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, -2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, -1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, -2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, -2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, -2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, -2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, -2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, -2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, -1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, -2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, -2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, -2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, -2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, -2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, -1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, -1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, -2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, -1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, -2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, -1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, - 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, -2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, - 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, -2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, - 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, -2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, -2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, - 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, -2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, -1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, - 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, -1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, -2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, -1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, -2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, - 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, -2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, -1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, -2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, -1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, -2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, -1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, - 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, -2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, -2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, - 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, - 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, -1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, -1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, - 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, -2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, -2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, - 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, - 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, - 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, -2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, - 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, - 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, -2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, -2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, - 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, -2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, -1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, - 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, -2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, -2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, -2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, - 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, - 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, - 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, -2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, -2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, -2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, -1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, -2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, - 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 -) - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euckrprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euckrprober.py deleted file mode 100644 index 345a060..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euckrprober.py +++ /dev/null @@ -1,47 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import EUCKRDistributionAnalysis -from .mbcssm import EUCKR_SM_MODEL - - -class EUCKRProber(MultiByteCharSetProber): - def __init__(self): - super(EUCKRProber, self).__init__() - self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) - self.distribution_analyzer = EUCKRDistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "EUC-KR" - - @property - def language(self): - return "Korean" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euctwfreq.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euctwfreq.py deleted file mode 100644 index ed7a995..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euctwfreq.py +++ /dev/null @@ -1,387 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# EUCTW frequency table -# Converted from big5 work -# by Taiwan's Mandarin Promotion Council -# <http:#www.edu.tw:81/mandr/> - -# 128 --> 0.42261 -# 256 --> 0.57851 -# 512 --> 0.74851 -# 1024 --> 0.89384 -# 2048 --> 0.97583 -# -# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 -# Random Distribution Ration = 512/(5401-512)=0.105 -# -# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR - -EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 - -# Char to FreqOrder table , -EUCTW_TABLE_SIZE = 5376 - -EUCTW_CHAR_TO_FREQ_ORDER = ( - 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 -3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 -1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 - 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 -3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 -4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 -7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 - 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 - 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 - 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 -2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 -1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 -3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 - 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 -1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 -3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 -2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 - 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 -3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 -1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 -7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 - 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 -7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 -1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 - 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 - 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 -3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 -3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 - 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 -2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 -2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 - 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 - 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 -3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 -1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 -1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 -1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 -2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 - 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 -4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 -1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 -7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 -2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 - 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 - 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 - 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 - 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 -7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 - 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 -1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 - 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 - 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 -7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 -1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 - 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 -3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 -4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 -3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 - 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 - 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 -1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 -4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 -3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 -3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 -2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 -7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 -3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 -7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 -1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 -2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 -1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 - 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 -1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 -4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 -3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 - 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 - 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 - 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 -2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 -7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 -1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 -2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 -1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 -1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 -7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 -7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 -7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 -3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 -4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 -1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 -7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 -2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 -7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 -3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 -3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 -7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 -2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 -7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 - 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 -4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 -2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 -7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 -3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 -2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 -2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 - 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 -2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 -1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 -1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 -2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 -1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 -7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 -7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 -2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 -4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 -1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 -7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 - 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 -4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 - 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 -2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 - 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 -1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 -1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 - 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 -3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 -3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 -1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 -3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 -7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 -7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 -1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 -2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 -1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 -3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 -2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 -3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 -2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 -4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 -4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 -3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 - 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 -3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 - 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 -3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 -3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 -3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 -1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 -7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 - 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 -7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 -1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 - 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 -4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 -3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 - 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 -2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 -2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 -3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 -1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 -4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 -2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 -1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 -1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 -2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 -3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 -1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 -7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 -1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 -4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 -1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 - 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 -1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 -3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 -3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 -2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 -1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 -4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 - 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 -7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 -2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 -3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 -4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 - 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 -7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 -7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 -1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 -4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 -3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 -2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 -3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 -3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 -2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 -1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 -4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 -3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 -3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 -2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 -4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 -7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 -3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 -2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 -3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 -1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 -2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 -3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 -4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 -2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 -2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 -7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 -1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 -2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 -1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 -3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 -4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 -2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 -3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 -3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 -2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 -4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 -2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 -3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 -4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 -7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 -3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 - 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 -1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 -4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 -1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 -4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 -7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 - 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 -7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 -2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 -1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 -1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 -3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 - 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 - 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 - 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 -3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 -2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 - 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 -7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 -1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 -3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 -7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 -1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 -7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 -4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 -1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 -2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 -2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 -4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 - 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 - 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 -3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 -3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 -1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 -2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 -7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 -1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 -1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 -3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 - 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 -1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 -4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 -7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 -2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 -3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 - 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 -1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 -2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 -2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 -7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 -7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 -7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 -2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 -2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 -1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 -4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 -3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 -3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 -4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 -4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 -2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 -2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 -7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 -4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 -7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 -2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 -1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 -3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 -4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 -2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 - 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 -2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 -1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 -2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 -2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 -4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 -7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 -1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 -3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 -7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 -1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 -8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 -2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 -8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 -2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 -2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 -8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 -8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 -8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 - 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 -8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 -4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 -3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 -8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 -1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 -8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 - 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 -1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 - 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 -4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 -1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 -4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 -1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 - 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 -3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 -4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 -8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 - 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 -3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 - 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 -2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 -) - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euctwprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euctwprober.py deleted file mode 100644 index 35669cc..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/euctwprober.py +++ /dev/null @@ -1,46 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import EUCTWDistributionAnalysis -from .mbcssm import EUCTW_SM_MODEL - -class EUCTWProber(MultiByteCharSetProber): - def __init__(self): - super(EUCTWProber, self).__init__() - self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) - self.distribution_analyzer = EUCTWDistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "EUC-TW" - - @property - def language(self): - return "Taiwan" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/gb2312freq.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/gb2312freq.py deleted file mode 100644 index 697837b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/gb2312freq.py +++ /dev/null @@ -1,283 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# GB2312 most frequently used character table -# -# Char to FreqOrder table , from hz6763 - -# 512 --> 0.79 -- 0.79 -# 1024 --> 0.92 -- 0.13 -# 2048 --> 0.98 -- 0.06 -# 6768 --> 1.00 -- 0.02 -# -# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 -# Random Distribution Ration = 512 / (3755 - 512) = 0.157 -# -# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR - -GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 - -GB2312_TABLE_SIZE = 3760 - -GB2312_CHAR_TO_FREQ_ORDER = ( -1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, -2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, -2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, - 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, -1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, -1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, - 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, -1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, -2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, -3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, - 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, -1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, - 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, -2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, - 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, -2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, -1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, -3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, - 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, -1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, - 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, -2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, -1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, -3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, -1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, -2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, -1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, - 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, -3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, -3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, - 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, -3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, - 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, -1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, -3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, -2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, -1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, - 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, -1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, -4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, - 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, -3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, -3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, - 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, -1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, -2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, -1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, -1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, - 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, -3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, -3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, -4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, - 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, -3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, -1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, -1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, -4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, - 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, - 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, -3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, -1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, - 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, -1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, -2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, - 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, - 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, - 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, -3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, -4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, -3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, - 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, -2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, -2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, -2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, - 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, -2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, - 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, - 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, - 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, -3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, -2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, -2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, -1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, - 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, -2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, - 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, - 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, -1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, -1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, - 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, - 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, -1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, -2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, -3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, -2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, -2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, -2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, -3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, -1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, -1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, -2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, -1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, -3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, -1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, -1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, -3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, - 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, -2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, -1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, -4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, -1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, -1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, -3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, -1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, - 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, - 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, -1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, - 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, -1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, -1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, - 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, -3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, -4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, -3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, -2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, -2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, -1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, -3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, -2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, -1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, -1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, - 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, -2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, -2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, -3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, -4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, -3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, - 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, -3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, -2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, -1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, - 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, - 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, -3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, -4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, -2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, -1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, -1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, - 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, -1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, -3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, - 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, - 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, -1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, - 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, -1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, - 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, -2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, - 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, -2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, -2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, -1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, -1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, -2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, - 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, -1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, -1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, -2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, -2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, -3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, -1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, -4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, - 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, - 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, -3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, -1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, - 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, -3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, -1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, -4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, -1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, -2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, -1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, - 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, -1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, -3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, - 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, -2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, - 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, -1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, -1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, -1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, -3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, -2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, -3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, -3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, -3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, - 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, -2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, - 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, -2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, - 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, -1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, - 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, - 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, -1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, -3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, -3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, -1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, -1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, -3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, -2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, -2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, -1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, -3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, - 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, -4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, -1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, -2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, -3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, -3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, -1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, - 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, - 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, -2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, - 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, -1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, - 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, -1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, -1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, -1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, -1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, -1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, - 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, - 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 -) - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/gb2312prober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/gb2312prober.py deleted file mode 100644 index 8446d2d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/gb2312prober.py +++ /dev/null @@ -1,46 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import GB2312DistributionAnalysis -from .mbcssm import GB2312_SM_MODEL - -class GB2312Prober(MultiByteCharSetProber): - def __init__(self): - super(GB2312Prober, self).__init__() - self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) - self.distribution_analyzer = GB2312DistributionAnalysis() - self.reset() - - @property - def charset_name(self): - return "GB2312" - - @property - def language(self): - return "Chinese" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/hebrewprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/hebrewprober.py deleted file mode 100644 index b0e1bf4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/hebrewprober.py +++ /dev/null @@ -1,292 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Shy Shalom -# Portions created by the Initial Developer are Copyright (C) 2005 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import ProbingState - -# This prober doesn't actually recognize a language or a charset. -# It is a helper prober for the use of the Hebrew model probers - -### General ideas of the Hebrew charset recognition ### -# -# Four main charsets exist in Hebrew: -# "ISO-8859-8" - Visual Hebrew -# "windows-1255" - Logical Hebrew -# "ISO-8859-8-I" - Logical Hebrew -# "x-mac-hebrew" - ?? Logical Hebrew ?? -# -# Both "ISO" charsets use a completely identical set of code points, whereas -# "windows-1255" and "x-mac-hebrew" are two different proper supersets of -# these code points. windows-1255 defines additional characters in the range -# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific -# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. -# x-mac-hebrew defines similar additional code points but with a different -# mapping. -# -# As far as an average Hebrew text with no diacritics is concerned, all four -# charsets are identical with respect to code points. Meaning that for the -# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters -# (including final letters). -# -# The dominant difference between these charsets is their directionality. -# "Visual" directionality means that the text is ordered as if the renderer is -# not aware of a BIDI rendering algorithm. The renderer sees the text and -# draws it from left to right. The text itself when ordered naturally is read -# backwards. A buffer of Visual Hebrew generally looks like so: -# "[last word of first line spelled backwards] [whole line ordered backwards -# and spelled backwards] [first word of first line spelled backwards] -# [end of line] [last word of second line] ... etc' " -# adding punctuation marks, numbers and English text to visual text is -# naturally also "visual" and from left to right. -# -# "Logical" directionality means the text is ordered "naturally" according to -# the order it is read. It is the responsibility of the renderer to display -# the text from right to left. A BIDI algorithm is used to place general -# punctuation marks, numbers and English text in the text. -# -# Texts in x-mac-hebrew are almost impossible to find on the Internet. From -# what little evidence I could find, it seems that its general directionality -# is Logical. -# -# To sum up all of the above, the Hebrew probing mechanism knows about two -# charsets: -# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are -# backwards while line order is natural. For charset recognition purposes -# the line order is unimportant (In fact, for this implementation, even -# word order is unimportant). -# Logical Hebrew - "windows-1255" - normal, naturally ordered text. -# -# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be -# specifically identified. -# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew -# that contain special punctuation marks or diacritics is displayed with -# some unconverted characters showing as question marks. This problem might -# be corrected using another model prober for x-mac-hebrew. Due to the fact -# that x-mac-hebrew texts are so rare, writing another model prober isn't -# worth the effort and performance hit. -# -#### The Prober #### -# -# The prober is divided between two SBCharSetProbers and a HebrewProber, -# all of which are managed, created, fed data, inquired and deleted by the -# SBCSGroupProber. The two SBCharSetProbers identify that the text is in -# fact some kind of Hebrew, Logical or Visual. The final decision about which -# one is it is made by the HebrewProber by combining final-letter scores -# with the scores of the two SBCharSetProbers to produce a final answer. -# -# The SBCSGroupProber is responsible for stripping the original text of HTML -# tags, English characters, numbers, low-ASCII punctuation characters, spaces -# and new lines. It reduces any sequence of such characters to a single space. -# The buffer fed to each prober in the SBCS group prober is pure text in -# high-ASCII. -# The two SBCharSetProbers (model probers) share the same language model: -# Win1255Model. -# The first SBCharSetProber uses the model normally as any other -# SBCharSetProber does, to recognize windows-1255, upon which this model was -# built. The second SBCharSetProber is told to make the pair-of-letter -# lookup in the language model backwards. This in practice exactly simulates -# a visual Hebrew model using the windows-1255 logical Hebrew model. -# -# The HebrewProber is not using any language model. All it does is look for -# final-letter evidence suggesting the text is either logical Hebrew or visual -# Hebrew. Disjointed from the model probers, the results of the HebrewProber -# alone are meaningless. HebrewProber always returns 0.00 as confidence -# since it never identifies a charset by itself. Instead, the pointer to the -# HebrewProber is passed to the model probers as a helper "Name Prober". -# When the Group prober receives a positive identification from any prober, -# it asks for the name of the charset identified. If the prober queried is a -# Hebrew model prober, the model prober forwards the call to the -# HebrewProber to make the final decision. In the HebrewProber, the -# decision is made according to the final-letters scores maintained and Both -# model probers scores. The answer is returned in the form of the name of the -# charset identified, either "windows-1255" or "ISO-8859-8". - -class HebrewProber(CharSetProber): - # windows-1255 / ISO-8859-8 code points of interest - FINAL_KAF = 0xea - NORMAL_KAF = 0xeb - FINAL_MEM = 0xed - NORMAL_MEM = 0xee - FINAL_NUN = 0xef - NORMAL_NUN = 0xf0 - FINAL_PE = 0xf3 - NORMAL_PE = 0xf4 - FINAL_TSADI = 0xf5 - NORMAL_TSADI = 0xf6 - - # Minimum Visual vs Logical final letter score difference. - # If the difference is below this, don't rely solely on the final letter score - # distance. - MIN_FINAL_CHAR_DISTANCE = 5 - - # Minimum Visual vs Logical model score difference. - # If the difference is below this, don't rely at all on the model score - # distance. - MIN_MODEL_DISTANCE = 0.01 - - VISUAL_HEBREW_NAME = "ISO-8859-8" - LOGICAL_HEBREW_NAME = "windows-1255" - - def __init__(self): - super(HebrewProber, self).__init__() - self._final_char_logical_score = None - self._final_char_visual_score = None - self._prev = None - self._before_prev = None - self._logical_prober = None - self._visual_prober = None - self.reset() - - def reset(self): - self._final_char_logical_score = 0 - self._final_char_visual_score = 0 - # The two last characters seen in the previous buffer, - # mPrev and mBeforePrev are initialized to space in order to simulate - # a word delimiter at the beginning of the data - self._prev = ' ' - self._before_prev = ' ' - # These probers are owned by the group prober. - - def set_model_probers(self, logicalProber, visualProber): - self._logical_prober = logicalProber - self._visual_prober = visualProber - - def is_final(self, c): - return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, - self.FINAL_PE, self.FINAL_TSADI] - - def is_non_final(self, c): - # The normal Tsadi is not a good Non-Final letter due to words like - # 'lechotet' (to chat) containing an apostrophe after the tsadi. This - # apostrophe is converted to a space in FilterWithoutEnglishLetters - # causing the Non-Final tsadi to appear at an end of a word even - # though this is not the case in the original text. - # The letters Pe and Kaf rarely display a related behavior of not being - # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' - # for example legally end with a Non-Final Pe or Kaf. However, the - # benefit of these letters as Non-Final letters outweighs the damage - # since these words are quite rare. - return c in [self.NORMAL_KAF, self.NORMAL_MEM, - self.NORMAL_NUN, self.NORMAL_PE] - - def feed(self, byte_str): - # Final letter analysis for logical-visual decision. - # Look for evidence that the received buffer is either logical Hebrew - # or visual Hebrew. - # The following cases are checked: - # 1) A word longer than 1 letter, ending with a final letter. This is - # an indication that the text is laid out "naturally" since the - # final letter really appears at the end. +1 for logical score. - # 2) A word longer than 1 letter, ending with a Non-Final letter. In - # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, - # should not end with the Non-Final form of that letter. Exceptions - # to this rule are mentioned above in isNonFinal(). This is an - # indication that the text is laid out backwards. +1 for visual - # score - # 3) A word longer than 1 letter, starting with a final letter. Final - # letters should not appear at the beginning of a word. This is an - # indication that the text is laid out backwards. +1 for visual - # score. - # - # The visual score and logical score are accumulated throughout the - # text and are finally checked against each other in GetCharSetName(). - # No checking for final letters in the middle of words is done since - # that case is not an indication for either Logical or Visual text. - # - # We automatically filter out all 7-bit characters (replace them with - # spaces) so the word boundary detection works properly. [MAP] - - if self.state == ProbingState.NOT_ME: - # Both model probers say it's not them. No reason to continue. - return ProbingState.NOT_ME - - byte_str = self.filter_high_byte_only(byte_str) - - for cur in byte_str: - if cur == ' ': - # We stand on a space - a word just ended - if self._before_prev != ' ': - # next-to-last char was not a space so self._prev is not a - # 1 letter word - if self.is_final(self._prev): - # case (1) [-2:not space][-1:final letter][cur:space] - self._final_char_logical_score += 1 - elif self.is_non_final(self._prev): - # case (2) [-2:not space][-1:Non-Final letter][ - # cur:space] - self._final_char_visual_score += 1 - else: - # Not standing on a space - if ((self._before_prev == ' ') and - (self.is_final(self._prev)) and (cur != ' ')): - # case (3) [-2:space][-1:final letter][cur:not space] - self._final_char_visual_score += 1 - self._before_prev = self._prev - self._prev = cur - - # Forever detecting, till the end or until both model probers return - # ProbingState.NOT_ME (handled above) - return ProbingState.DETECTING - - @property - def charset_name(self): - # Make the decision: is it Logical or Visual? - # If the final letter score distance is dominant enough, rely on it. - finalsub = self._final_char_logical_score - self._final_char_visual_score - if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: - return self.LOGICAL_HEBREW_NAME - if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: - return self.VISUAL_HEBREW_NAME - - # It's not dominant enough, try to rely on the model scores instead. - modelsub = (self._logical_prober.get_confidence() - - self._visual_prober.get_confidence()) - if modelsub > self.MIN_MODEL_DISTANCE: - return self.LOGICAL_HEBREW_NAME - if modelsub < -self.MIN_MODEL_DISTANCE: - return self.VISUAL_HEBREW_NAME - - # Still no good, back to final letter distance, maybe it'll save the - # day. - if finalsub < 0.0: - return self.VISUAL_HEBREW_NAME - - # (finalsub > 0 - Logical) or (don't know what to do) default to - # Logical. - return self.LOGICAL_HEBREW_NAME - - @property - def language(self): - return 'Hebrew' - - @property - def state(self): - # Remain active as long as any of the model probers are active. - if (self._logical_prober.state == ProbingState.NOT_ME) and \ - (self._visual_prober.state == ProbingState.NOT_ME): - return ProbingState.NOT_ME - return ProbingState.DETECTING diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/jisfreq.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/jisfreq.py deleted file mode 100644 index 83fc082..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/jisfreq.py +++ /dev/null @@ -1,325 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# Sampling from about 20M text materials include literature and computer technology -# -# Japanese frequency table, applied to both S-JIS and EUC-JP -# They are sorted in order. - -# 128 --> 0.77094 -# 256 --> 0.85710 -# 512 --> 0.92635 -# 1024 --> 0.97130 -# 2048 --> 0.99431 -# -# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 -# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 -# -# Typical Distribution Ratio, 25% of IDR - -JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 - -# Char to FreqOrder table , -JIS_TABLE_SIZE = 4368 - -JIS_CHAR_TO_FREQ_ORDER = ( - 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 -3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 -1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 -2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 -2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 -5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 -1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 -5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 -5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 -5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 -5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 -5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 -5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 -1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 -1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 -1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 -2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 -3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 -3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 - 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 - 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 -1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 - 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 -5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 - 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 - 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 - 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 - 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 - 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 -5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 -5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 -5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 -4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 -5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 -5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 -5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 -5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 -5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 -5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 -5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 -5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 -5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 -3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 -5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 -5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 -5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 -5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 -5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 -5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 -5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 -5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 -5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 -5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 -5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 -5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 -5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 -5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 -5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 -5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 -5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 -5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 -5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 -5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 -5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 -5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 -5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 -5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 -5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 -5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 -5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 -5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 -5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 -5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 -5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 -5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 -5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 -5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 -5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 -5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 -5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 -5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 -6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 -6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 -6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 -6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 -6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 -6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 -6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 -6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 -4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 - 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 - 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 -1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 -1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 - 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 -3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 -3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 - 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 -3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 -3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 - 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 -2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 - 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 -3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 -1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 - 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 -1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 - 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 -2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 -2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 -2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 -2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 -1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 -1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 -1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 -1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 -2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 -1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 -2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 -1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 -1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 -1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 -1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 -1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 -1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 - 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 - 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 -1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 -2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 -2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 -2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 -3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 -3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 - 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 -3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 -1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 - 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 -2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 -1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 - 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 -3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 -4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 -2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 -1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 -2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 -1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 - 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 - 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 -1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 -2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 -2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 -2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 -3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 -1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 -2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 - 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 - 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 - 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 -1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 -2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 - 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 -1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 -1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 - 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 -1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 -1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 -1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 - 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 -2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 - 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 -2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 -3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 -2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 -1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 -6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 -1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 -2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 -1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 - 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 - 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 -3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 -3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 -1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 -1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 -1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 -1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 - 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 - 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 -2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 - 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 -3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 -2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 - 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 -1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 -2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 - 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 -1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 - 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 -4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 -2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 -1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 - 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 -1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 -2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 - 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 -6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 -1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 -1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 -2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 -3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 - 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 -3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 -1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 - 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 -1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 - 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 -3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 - 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 -2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 - 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 -4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 -2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 -1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 -1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 -1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 - 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 -1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 -3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 -1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 -3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 - 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 - 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 - 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 -2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 -1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 - 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 -1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 - 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 -1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 - 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 - 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 - 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 -1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 -1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 -2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 -4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 - 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 -1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 - 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 -1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 -3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 -1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 -2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 -2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 -1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 -1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 -2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 - 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 -2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 -1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 -1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 -1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 -1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 -3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 -2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 -2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 - 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 -3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 -3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 -1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 -2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 -1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 -2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 -) - - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/jpcntx.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/jpcntx.py deleted file mode 100644 index 20044e4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/jpcntx.py +++ /dev/null @@ -1,233 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - - -# This is hiragana 2-char sequence table, the number in each cell represents its frequency category -jp2CharContext = ( -(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), -(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), -(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), -(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), -(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), -(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), -(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), -(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), -(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), -(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), -(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), -(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), -(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), -(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), -(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), -(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), -(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), -(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), -(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), -(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), -(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), -(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), -(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), -(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), -(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), -(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), -(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), -(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), -(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), -(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), -(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), -(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), -(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), -(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), -(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), -(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), -(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), -(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), -(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), -(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), -(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), -(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), -(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), -(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), -(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), -(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), -(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), -(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), -(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), -(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), -(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), -(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), -(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), -(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), -(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), -(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), -(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), -(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), -(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), -(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), -(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), -(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), -(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), -(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), -(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), -(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), -(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), -(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), -(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), -(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), -(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), -(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), -(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), -(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), -(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), -) - -class JapaneseContextAnalysis(object): - NUM_OF_CATEGORY = 6 - DONT_KNOW = -1 - ENOUGH_REL_THRESHOLD = 100 - MAX_REL_THRESHOLD = 1000 - MINIMUM_DATA_THRESHOLD = 4 - - def __init__(self): - self._total_rel = None - self._rel_sample = None - self._need_to_skip_char_num = None - self._last_char_order = None - self._done = None - self.reset() - - def reset(self): - self._total_rel = 0 # total sequence received - # category counters, each integer counts sequence in its category - self._rel_sample = [0] * self.NUM_OF_CATEGORY - # if last byte in current buffer is not the last byte of a character, - # we need to know how many bytes to skip in next buffer - self._need_to_skip_char_num = 0 - self._last_char_order = -1 # The order of previous char - # If this flag is set to True, detection is done and conclusion has - # been made - self._done = False - - def feed(self, byte_str, num_bytes): - if self._done: - return - - # The buffer we got is byte oriented, and a character may span in more than one - # buffers. In case the last one or two byte in last buffer is not - # complete, we record how many byte needed to complete that character - # and skip these bytes here. We can choose to record those bytes as - # well and analyse the character once it is complete, but since a - # character will not make much difference, by simply skipping - # this character will simply our logic and improve performance. - i = self._need_to_skip_char_num - while i < num_bytes: - order, char_len = self.get_order(byte_str[i:i + 2]) - i += char_len - if i > num_bytes: - self._need_to_skip_char_num = i - num_bytes - self._last_char_order = -1 - else: - if (order != -1) and (self._last_char_order != -1): - self._total_rel += 1 - if self._total_rel > self.MAX_REL_THRESHOLD: - self._done = True - break - self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 - self._last_char_order = order - - def got_enough_data(self): - return self._total_rel > self.ENOUGH_REL_THRESHOLD - - def get_confidence(self): - # This is just one way to calculate confidence. It works well for me. - if self._total_rel > self.MINIMUM_DATA_THRESHOLD: - return (self._total_rel - self._rel_sample[0]) / self._total_rel - else: - return self.DONT_KNOW - - def get_order(self, byte_str): - return -1, 1 - -class SJISContextAnalysis(JapaneseContextAnalysis): - def __init__(self): - super(SJISContextAnalysis, self).__init__() - self._charset_name = "SHIFT_JIS" - - @property - def charset_name(self): - return self._charset_name - - def get_order(self, byte_str): - if not byte_str: - return -1, 1 - # find out current char's byte length - first_char = byte_str[0] - if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): - char_len = 2 - if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): - self._charset_name = "CP932" - else: - char_len = 1 - - # return its order if it is hiragana - if len(byte_str) > 1: - second_char = byte_str[1] - if (first_char == 202) and (0x9F <= second_char <= 0xF1): - return second_char - 0x9F, char_len - - return -1, char_len - -class EUCJPContextAnalysis(JapaneseContextAnalysis): - def get_order(self, byte_str): - if not byte_str: - return -1, 1 - # find out current char's byte length - first_char = byte_str[0] - if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): - char_len = 2 - elif first_char == 0x8F: - char_len = 3 - else: - char_len = 1 - - # return its order if it is hiragana - if len(byte_str) > 1: - second_char = byte_str[1] - if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): - return second_char - 0xA1, char_len - - return -1, char_len - - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langbulgarianmodel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langbulgarianmodel.py deleted file mode 100644 index 2aa4fb2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langbulgarianmodel.py +++ /dev/null @@ -1,228 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# 255: Control characters that usually does not exist in any text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 - -# Character Mapping Table: -# this table is modified base on win1251BulgarianCharToOrderMap, so -# only number <64 is sure valid - -Latin5_BulgarianCharToOrderMap = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 -110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 -253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 -116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 -194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, # 80 -210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, # 90 - 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, # a0 - 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # b0 - 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, # c0 - 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # d0 - 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, # e0 - 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, # f0 -) - -win1251BulgarianCharToOrderMap = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 -110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 -253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 -116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 -206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, # 80 -221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, # 90 - 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, # a0 - 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, # b0 - 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # c0 - 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, # d0 - 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # e0 - 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, # f0 -) - -# Model Table: -# total sequences: 100% -# first 512 sequences: 96.9392% -# first 1024 sequences:3.0618% -# rest sequences: 0.2992% -# negative sequences: 0.0020% -BulgarianLangModel = ( -0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, -3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, -0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, -0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, -0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, -1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, -0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, -0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, -2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, -3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, -3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, -1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, -3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, -1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, -2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, -2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, -3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, -1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, -2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, -2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, -3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, -1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, -2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, -2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, -2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, -1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, -2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, -1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, -3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, -1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, -3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, -1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, -2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, -1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, -2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, -1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, -2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, -1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, -3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, -1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, -1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, -2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, -1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, -2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, -1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, -1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, -0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, -1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, -1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, -2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, -1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, -1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, -0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, -1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, -0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, -0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, -2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, -1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, -0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, -0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, -1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, -1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, -1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -) - -Latin5BulgarianModel = { - 'char_to_order_map': Latin5_BulgarianCharToOrderMap, - 'precedence_matrix': BulgarianLangModel, - 'typical_positive_ratio': 0.969392, - 'keep_english_letter': False, - 'charset_name': "ISO-8859-5", - 'language': 'Bulgairan', -} - -Win1251BulgarianModel = { - 'char_to_order_map': win1251BulgarianCharToOrderMap, - 'precedence_matrix': BulgarianLangModel, - 'typical_positive_ratio': 0.969392, - 'keep_english_letter': False, - 'charset_name': "windows-1251", - 'language': 'Bulgarian', -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langcyrillicmodel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langcyrillicmodel.py deleted file mode 100644 index e5f9a1f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langcyrillicmodel.py +++ /dev/null @@ -1,333 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# KOI8-R language model -# Character Mapping Table: -KOI8R_char_to_order_map = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 -155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 -253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 - 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 -191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, # 80 -207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, # 90 -223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, # a0 -238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, # b0 - 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, # c0 - 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, # d0 - 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, # e0 - 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, # f0 -) - -win1251_char_to_order_map = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 -155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 -253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 - 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 -191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, -207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, -223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, -239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, - 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, - 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, - 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, - 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, -) - -latin5_char_to_order_map = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 -155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 -253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 - 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 -191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, -207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, -223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, - 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, - 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, - 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, - 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, -239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, -) - -macCyrillic_char_to_order_map = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 -155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 -253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 - 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 - 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, - 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, -191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, -207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, -223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, -239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, - 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, - 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255, -) - -IBM855_char_to_order_map = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 -155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 -253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 - 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 -191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, -206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, - 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, -220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, -230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, - 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, - 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, -250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255, -) - -IBM866_char_to_order_map = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 -155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 -253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 - 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 - 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, - 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, - 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, -191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, -207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, -223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, - 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, -239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, -) - -# Model Table: -# total sequences: 100% -# first 512 sequences: 97.6601% -# first 1024 sequences: 2.3389% -# rest sequences: 0.1237% -# negative sequences: 0.0009% -RussianLangModel = ( -0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, -3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, -0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, -0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, -3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, -0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, -2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, -3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, -0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, -1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, -2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, -1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, -2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, -1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, -3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, -1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, -2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, -1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, -1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, -1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, -2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, -1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, -3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, -1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, -2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, -1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, -2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, -1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, -1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, -1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, -3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, -2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, -3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, -1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, -1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, -0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, -2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, -1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, -1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, -0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, -1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, -2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, -2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, -1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, -1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, -2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, -1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, -0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, -2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, -1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, -1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, -0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, -0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, -0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, -0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, -1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, -0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, -1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, -0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, -1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, -0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, -2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, -0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, -) - -Koi8rModel = { - 'char_to_order_map': KOI8R_char_to_order_map, - 'precedence_matrix': RussianLangModel, - 'typical_positive_ratio': 0.976601, - 'keep_english_letter': False, - 'charset_name': "KOI8-R", - 'language': 'Russian', -} - -Win1251CyrillicModel = { - 'char_to_order_map': win1251_char_to_order_map, - 'precedence_matrix': RussianLangModel, - 'typical_positive_ratio': 0.976601, - 'keep_english_letter': False, - 'charset_name': "windows-1251", - 'language': 'Russian', -} - -Latin5CyrillicModel = { - 'char_to_order_map': latin5_char_to_order_map, - 'precedence_matrix': RussianLangModel, - 'typical_positive_ratio': 0.976601, - 'keep_english_letter': False, - 'charset_name': "ISO-8859-5", - 'language': 'Russian', -} - -MacCyrillicModel = { - 'char_to_order_map': macCyrillic_char_to_order_map, - 'precedence_matrix': RussianLangModel, - 'typical_positive_ratio': 0.976601, - 'keep_english_letter': False, - 'charset_name': "MacCyrillic", - 'language': 'Russian', -} - -Ibm866Model = { - 'char_to_order_map': IBM866_char_to_order_map, - 'precedence_matrix': RussianLangModel, - 'typical_positive_ratio': 0.976601, - 'keep_english_letter': False, - 'charset_name': "IBM866", - 'language': 'Russian', -} - -Ibm855Model = { - 'char_to_order_map': IBM855_char_to_order_map, - 'precedence_matrix': RussianLangModel, - 'typical_positive_ratio': 0.976601, - 'keep_english_letter': False, - 'charset_name': "IBM855", - 'language': 'Russian', -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langgreekmodel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langgreekmodel.py deleted file mode 100644 index 5332221..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langgreekmodel.py +++ /dev/null @@ -1,225 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# 255: Control characters that usually does not exist in any text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 - -# Character Mapping Table: -Latin7_char_to_order_map = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 - 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 -253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 - 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 -253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 -253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, # b0 -110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 - 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 -124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 - 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 -) - -win1253_char_to_order_map = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 - 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 -253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 - 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 -253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 -253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, # b0 -110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 - 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 -124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 - 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 -) - -# Model Table: -# total sequences: 100% -# first 512 sequences: 98.2851% -# first 1024 sequences:1.7001% -# rest sequences: 0.0359% -# negative sequences: 0.0148% -GreekLangModel = ( -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, -3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, -0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, -2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, -0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, -2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, -2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, -0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, -2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, -0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, -3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, -3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, -2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, -2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, -0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, -0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, -0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, -0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, -0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, -0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, -0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, -0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, -0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, -0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, -0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, -0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, -0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, -0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, -0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, -0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, -0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, -0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, -0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, -0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, -0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, -0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, -0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, -0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, -0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, -0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, -0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, -0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, -0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, -0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, -0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, -0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, -0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, -0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, -0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, -0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, -0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -) - -Latin7GreekModel = { - 'char_to_order_map': Latin7_char_to_order_map, - 'precedence_matrix': GreekLangModel, - 'typical_positive_ratio': 0.982851, - 'keep_english_letter': False, - 'charset_name': "ISO-8859-7", - 'language': 'Greek', -} - -Win1253GreekModel = { - 'char_to_order_map': win1253_char_to_order_map, - 'precedence_matrix': GreekLangModel, - 'typical_positive_ratio': 0.982851, - 'keep_english_letter': False, - 'charset_name': "windows-1253", - 'language': 'Greek', -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langhebrewmodel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langhebrewmodel.py deleted file mode 100644 index 58f4c87..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langhebrewmodel.py +++ /dev/null @@ -1,200 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Simon Montagu -# Portions created by the Initial Developer are Copyright (C) 2005 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# Shoshannah Forbes - original C code (?) -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# 255: Control characters that usually does not exist in any text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 - -# Windows-1255 language model -# Character Mapping Table: -WIN1255_CHAR_TO_ORDER_MAP = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, # 40 - 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, # 50 -253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, # 60 - 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, # 70 -124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, -215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, - 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, -106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, - 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, -238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, - 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, - 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253, -) - -# Model Table: -# total sequences: 100% -# first 512 sequences: 98.4004% -# first 1024 sequences: 1.5981% -# rest sequences: 0.087% -# negative sequences: 0.0015% -HEBREW_LANG_MODEL = ( -0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, -3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, -1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, -1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, -1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, -1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, -1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, -0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, -0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, -1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, -3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, -0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, -0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, -0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, -0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, -0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, -3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, -0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, -0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, -0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, -0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, -0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, -0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, -3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, -0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, -0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, -0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, -1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, -0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, -3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, -0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, -3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, -0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, -0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, -0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, -0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, -0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, -0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, -2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, -0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, -0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, -0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, -0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, -0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, -1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, -0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, -2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, -1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, -2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, -1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, -2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, -0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, -1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, -0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0, -) - -Win1255HebrewModel = { - 'char_to_order_map': WIN1255_CHAR_TO_ORDER_MAP, - 'precedence_matrix': HEBREW_LANG_MODEL, - 'typical_positive_ratio': 0.984004, - 'keep_english_letter': False, - 'charset_name': "windows-1255", - 'language': 'Hebrew', -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langhungarianmodel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langhungarianmodel.py deleted file mode 100644 index bb7c095..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langhungarianmodel.py +++ /dev/null @@ -1,225 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# 255: Control characters that usually does not exist in any text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 - -# Character Mapping Table: -Latin2_HungarianCharToOrderMap = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, - 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, -253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, - 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, -159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174, -175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, -191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205, - 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, -221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231, -232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241, - 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85, -245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253, -) - -win1250HungarianCharToOrderMap = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, - 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, -253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, - 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, -161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, -177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190, -191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205, - 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, -221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231, -232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241, - 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87, -245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253, -) - -# Model Table: -# total sequences: 100% -# first 512 sequences: 94.7368% -# first 1024 sequences:5.2623% -# rest sequences: 0.8894% -# negative sequences: 0.0009% -HungarianLangModel = ( -0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, -3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2, -3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, -3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3, -0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, -3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, -3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2, -0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0, -3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, -3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, -3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2, -0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, -3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, -2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1, -0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, -3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0, -1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0, -1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0, -1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1, -3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1, -2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1, -2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1, -2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1, -2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0, -2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, -3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1, -2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1, -2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1, -2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1, -1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1, -1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1, -3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0, -1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1, -1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1, -2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1, -2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0, -2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1, -3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1, -2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1, -1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0, -1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0, -2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1, -2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1, -1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0, -1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1, -2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0, -1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0, -1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0, -2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1, -2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1, -2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, -1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1, -1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1, -1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0, -0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0, -2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1, -2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1, -1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1, -2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1, -1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0, -1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0, -2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0, -2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1, -2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, -1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0, -2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0, -0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, -1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0, -0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0, -1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, -0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, -0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, -2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, -0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, -) - -Latin2HungarianModel = { - 'char_to_order_map': Latin2_HungarianCharToOrderMap, - 'precedence_matrix': HungarianLangModel, - 'typical_positive_ratio': 0.947368, - 'keep_english_letter': True, - 'charset_name': "ISO-8859-2", - 'language': 'Hungarian', -} - -Win1250HungarianModel = { - 'char_to_order_map': win1250HungarianCharToOrderMap, - 'precedence_matrix': HungarianLangModel, - 'typical_positive_ratio': 0.947368, - 'keep_english_letter': True, - 'charset_name': "windows-1250", - 'language': 'Hungarian', -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langthaimodel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langthaimodel.py deleted file mode 100644 index 15f94c2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langthaimodel.py +++ /dev/null @@ -1,199 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# 255: Control characters that usually does not exist in any text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 - -# The following result for thai was collected from a limited sample (1M). - -# Character Mapping Table: -TIS620CharToOrderMap = ( -255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 -252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 -253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, # 40 -188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, # 50 -253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, # 60 - 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, # 70 -209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222, -223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235, -236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57, - 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, - 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63, - 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244, - 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247, - 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253, -) - -# Model Table: -# total sequences: 100% -# first 512 sequences: 92.6386% -# first 1024 sequences:7.3177% -# rest sequences: 1.0230% -# negative sequences: 0.0436% -ThaiLangModel = ( -0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3, -0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2, -3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3, -0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1, -3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2, -3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1, -3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2, -3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1, -3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1, -3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, -3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1, -2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1, -3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1, -0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0, -3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1, -0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, -3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2, -1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0, -3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3, -3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0, -1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2, -0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0, -2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3, -0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0, -3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1, -2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0, -3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2, -0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2, -3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, -3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0, -2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, -3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1, -2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1, -3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1, -3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0, -3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1, -3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1, -3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1, -1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2, -0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3, -0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1, -3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0, -3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1, -1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0, -3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1, -3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0, -0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2, -0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, -0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0, -0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0, -1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1, -1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1, -3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1, -0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, -0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0, -0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, -3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0, -3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0, -0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1, -0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0, -0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1, -0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1, -0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0, -0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1, -0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0, -3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0, -0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0, -0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0, -3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1, -2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1, -0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0, -3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0, -0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, -2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0, -1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, -1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, -1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0, -1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -) - -TIS620ThaiModel = { - 'char_to_order_map': TIS620CharToOrderMap, - 'precedence_matrix': ThaiLangModel, - 'typical_positive_ratio': 0.926386, - 'keep_english_letter': False, - 'charset_name': "TIS-620", - 'language': 'Thai', -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langturkishmodel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langturkishmodel.py deleted file mode 100644 index a427a45..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/langturkishmodel.py +++ /dev/null @@ -1,193 +0,0 @@ -# -*- coding: utf-8 -*- -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Communicator client code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Özgür Baskın - Turkish Language Model -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -# 255: Control characters that usually does not exist in any text -# 254: Carriage/Return -# 253: symbol (punctuation) that does not belong to word -# 252: 0 - 9 - -# Character Mapping Table: -Latin5_TurkishCharToOrderMap = ( -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255, 23, 37, 47, 39, 29, 52, 36, 45, 53, 60, 16, 49, 20, 46, 42, - 48, 69, 44, 35, 31, 51, 38, 62, 65, 43, 56,255,255,255,255,255, -255, 1, 21, 28, 12, 2, 18, 27, 25, 3, 24, 10, 5, 13, 4, 15, - 26, 64, 7, 8, 9, 14, 32, 57, 58, 11, 22,255,255,255,255,255, -180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165, -164,163,162,161,160,159,101,158,157,156,155,154,153,152,151,106, -150,149,148,147,146,145,144,100,143,142,141,140,139,138,137,136, - 94, 80, 93,135,105,134,133, 63,132,131,130,129,128,127,126,125, -124,104, 73, 99, 79, 85,123, 54,122, 98, 92,121,120, 91,103,119, - 68,118,117, 97,116,115, 50, 90,114,113,112,111, 55, 41, 40, 86, - 89, 70, 59, 78, 71, 82, 88, 33, 77, 66, 84, 83,110, 75, 61, 96, - 30, 67,109, 74, 87,102, 34, 95, 81,108, 76, 72, 17, 6, 19,107, -) - -TurkishLangModel = ( -3,2,3,3,3,1,3,3,3,3,3,3,3,3,2,1,1,3,3,1,3,3,0,3,3,3,3,3,0,3,1,3, -3,2,1,0,0,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, -3,2,2,3,3,0,3,3,3,3,3,3,3,2,3,1,0,3,3,1,3,3,0,3,3,3,3,3,0,3,0,3, -3,1,1,0,1,0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,0,1,0,1, -3,3,2,3,3,0,3,3,3,3,3,3,3,2,3,1,1,3,3,0,3,3,1,2,3,3,3,3,0,3,0,3, -3,1,1,0,0,0,1,0,0,0,0,1,1,0,1,2,1,0,0,0,1,0,0,0,0,2,0,0,0,0,0,1, -3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,1,3,3,2,0,3,2,1,2,2,1,3,3,0,0,0,2, -2,2,0,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,1, -3,3,3,2,3,3,1,2,3,3,3,3,3,3,3,1,3,2,1,0,3,2,0,1,2,3,3,2,1,0,0,2, -2,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0, -1,0,1,3,3,1,3,3,3,3,3,3,3,1,2,0,0,2,3,0,2,3,0,0,2,2,2,3,0,3,0,1, -2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,0,3,2,0,2,3,2,3,3,1,0,0,2, -3,2,0,0,1,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,2,0,0,1, -3,3,3,2,3,3,2,3,3,3,3,2,3,3,3,0,3,3,0,0,2,1,0,0,2,3,2,2,0,0,0,2, -2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,0,2,0,0,1, -3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,0,1,3,2,1,1,3,2,3,2,1,0,0,2, -2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, -3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,2,0,2,3,0,0,2,2,2,2,0,0,0,2, -3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, -3,3,3,3,3,3,3,2,2,2,2,3,2,3,3,0,3,3,1,1,2,2,0,0,2,2,3,2,0,0,1,3, -0,3,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1, -3,3,3,2,3,3,3,2,1,2,2,3,2,3,3,0,3,2,0,0,1,1,0,1,1,2,1,2,0,0,0,1, -0,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0, -3,3,3,2,3,3,2,3,2,2,2,3,3,3,3,1,3,1,1,0,3,2,1,1,3,3,2,3,1,0,0,1, -1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,1, -3,2,2,3,3,0,3,3,3,3,3,3,3,2,2,1,0,3,3,1,3,3,0,1,3,3,2,3,0,3,0,3, -2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, -2,2,2,3,3,0,3,3,3,3,3,3,3,3,3,0,0,3,2,0,3,3,0,3,2,3,3,3,0,3,1,3, -2,0,0,0,0,0,0,0,0,0,0,1,0,1,2,0,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, -3,3,3,1,2,3,3,1,0,0,1,0,0,3,3,2,3,0,0,2,0,0,2,0,2,0,0,0,2,0,2,0, -0,3,1,0,1,0,0,0,2,2,1,0,1,1,2,1,2,2,2,0,2,1,1,0,0,0,2,0,0,0,0,0, -1,2,1,3,3,0,3,3,3,3,3,2,3,0,0,0,0,2,3,0,2,3,1,0,2,3,1,3,0,3,0,2, -3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,1,3,3,2,2,3,2,2,0,1,2,3,0,1,2,1,0,1,0,0,0,1,0,2,2,0,0,0,1, -1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0, -3,3,3,1,3,3,1,1,3,3,1,1,3,3,1,0,2,1,2,0,2,1,0,0,1,1,2,1,0,0,0,2, -2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,1,0,2,1,3,0,0,2,0,0,3,3,0,3,0,0,1,0,1,2,0,0,1,1,2,2,0,1,0, -0,1,2,1,1,0,1,0,1,1,1,1,1,0,1,1,1,2,2,1,2,0,1,0,0,0,0,0,0,1,0,0, -3,3,3,2,3,2,3,3,0,2,2,2,3,3,3,0,3,0,0,0,2,2,0,1,2,1,1,1,0,0,0,1, -0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, -3,3,3,3,3,3,2,1,2,2,3,3,3,3,2,0,2,0,0,0,2,2,0,0,2,1,3,3,0,0,1,1, -1,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0, -1,1,2,3,3,0,3,3,3,3,3,3,2,2,0,2,0,2,3,2,3,2,2,2,2,2,2,2,1,3,2,3, -2,0,2,1,2,2,2,2,1,1,2,2,1,2,2,1,2,0,0,2,1,1,0,2,1,0,0,1,0,0,0,1, -2,3,3,1,1,1,0,1,1,1,2,3,2,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0, -0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,2,2,2,3,2,3,2,2,1,3,3,3,0,2,1,2,0,2,1,0,0,1,1,1,1,1,0,0,1, -2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, -3,3,3,2,3,3,3,3,3,2,3,1,2,3,3,1,2,0,0,0,0,0,0,0,3,2,1,1,0,0,0,0, -2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, -3,3,3,2,2,3,3,2,1,1,1,1,1,3,3,0,3,1,0,0,1,1,0,0,3,1,2,1,0,0,0,0, -0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, -3,3,3,2,2,3,2,2,2,3,2,1,1,3,3,0,3,0,0,0,0,1,0,0,3,1,1,2,0,0,0,1, -1,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, -1,1,1,3,3,0,3,3,3,3,3,2,2,2,1,2,0,2,1,2,2,1,1,0,1,2,2,2,2,2,2,2, -0,0,2,1,2,1,2,1,0,1,1,3,1,2,1,1,2,0,0,2,0,1,0,1,0,1,0,0,0,1,0,1, -3,3,3,1,3,3,3,0,1,1,0,2,2,3,1,0,3,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,2,0,0,2,2,1,0,0,1,0,0,3,3,1,3,0,0,1,1,0,2,0,3,0,0,0,2,0,1,1, -0,1,2,0,1,2,2,0,2,2,2,2,1,0,2,1,1,0,2,0,2,1,2,0,0,0,0,0,0,0,0,0, -3,3,3,1,3,2,3,2,0,2,2,2,1,3,2,0,2,1,2,0,1,2,0,0,1,0,2,2,0,0,0,2, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0, -3,3,3,0,3,3,1,1,2,3,1,0,3,2,3,0,3,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0, -1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,3,3,0,3,3,2,3,3,2,2,0,0,0,0,1,2,0,1,3,0,0,0,3,1,1,0,3,0,2, -2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,1,2,2,1,0,3,1,1,1,1,3,3,2,3,0,0,1,0,1,2,0,2,2,0,2,2,0,2,1, -0,2,2,1,1,1,1,0,2,1,1,0,1,1,1,1,2,1,2,1,2,0,1,0,1,0,0,0,0,0,0,0, -3,3,3,0,1,1,3,0,0,1,1,0,0,2,2,0,3,0,0,1,1,0,1,0,0,0,0,0,2,0,0,0, -0,3,1,0,1,0,1,0,2,0,0,1,0,1,0,1,1,1,2,1,1,0,2,0,0,0,0,0,0,0,0,0, -3,3,3,0,2,0,2,0,1,1,1,0,0,3,3,0,2,0,0,1,0,0,2,1,1,0,1,0,1,0,1,0, -0,2,0,1,2,0,2,0,2,1,1,0,1,0,2,1,1,0,2,1,1,0,1,0,0,0,1,1,0,0,0,0, -3,2,3,0,1,0,0,0,0,0,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,0,2,0,0,0, -0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,2,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,0,0,2,3,0,0,1,0,1,0,2,3,2,3,0,0,1,3,0,2,1,0,0,0,0,2,0,1,0, -0,2,1,0,0,1,1,0,2,1,0,0,1,0,0,1,1,0,1,1,2,0,1,0,0,0,0,1,0,0,0,0, -3,2,2,0,0,1,1,0,0,0,0,0,0,3,1,1,1,0,0,0,0,0,1,0,0,0,0,0,2,0,1,0, -0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, -0,0,0,3,3,0,2,3,2,2,1,2,2,1,1,2,0,1,3,2,2,2,0,0,2,2,0,0,0,1,2,1, -3,0,2,1,1,0,1,1,1,0,1,2,2,2,1,1,2,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0, -0,1,1,2,3,0,3,3,3,2,2,2,2,1,0,1,0,1,0,1,2,2,0,0,2,2,1,3,1,1,2,1, -0,0,1,1,2,0,1,1,0,0,1,2,0,2,1,1,2,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0, -3,3,2,0,0,3,1,0,0,0,0,0,0,3,2,1,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, -0,2,1,1,0,0,1,0,1,2,0,0,1,1,0,0,2,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0, -3,3,2,0,0,1,0,0,0,0,1,0,0,3,3,2,2,0,0,1,0,0,2,0,1,0,0,0,2,0,1,0, -0,0,1,1,0,0,2,0,2,1,0,0,1,1,2,1,2,0,2,1,2,1,1,1,0,0,1,1,0,0,0,0, -3,3,2,0,0,2,2,0,0,0,1,1,0,2,2,1,3,1,0,1,0,1,2,0,0,0,0,0,1,0,1,0, -0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,2,0,0,0,1,0,0,1,0,0,2,3,1,2,0,0,1,0,0,2,0,0,0,1,0,2,0,2,0, -0,1,1,2,2,1,2,0,2,1,1,0,0,1,1,0,1,1,1,1,2,1,1,0,0,0,0,0,0,0,0,0, -3,3,3,0,2,1,2,1,0,0,1,1,0,3,3,1,2,0,0,1,0,0,2,0,2,0,1,1,2,0,0,0, -0,0,1,1,1,1,2,0,1,1,0,1,1,1,1,0,0,0,1,1,1,0,1,0,0,0,1,0,0,0,0,0, -3,3,3,0,2,2,3,2,0,0,1,0,0,2,3,1,0,0,0,0,0,0,2,0,2,0,0,0,2,0,0,0, -0,1,1,0,0,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, -3,2,3,0,0,0,0,0,0,0,1,0,0,2,2,2,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, -0,0,2,1,1,0,1,0,2,1,1,0,0,1,1,2,1,0,2,0,2,0,1,0,0,0,2,0,0,0,0,0, -0,0,0,2,2,0,2,1,1,1,1,2,2,0,0,1,0,1,0,0,1,3,0,0,0,0,1,0,0,2,1,0, -0,0,1,0,1,0,0,0,0,0,2,1,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, -2,0,0,2,3,0,2,3,1,2,2,0,2,0,0,2,0,2,1,1,1,2,1,0,0,1,2,1,1,2,1,0, -1,0,2,0,1,0,1,1,0,0,2,2,1,2,1,1,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, -3,3,3,0,2,1,2,0,0,0,1,0,0,3,2,0,1,0,0,1,0,0,2,0,0,0,1,2,1,0,1,0, -0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0, -0,0,0,2,2,0,2,2,1,1,0,1,1,1,1,1,0,0,1,2,1,1,1,0,1,0,0,0,1,1,1,1, -0,0,2,1,0,1,1,1,0,1,1,2,1,2,1,1,2,0,1,1,2,1,0,2,0,0,0,0,0,0,0,0, -3,2,2,0,0,2,0,0,0,0,0,0,0,2,2,0,2,0,0,1,0,0,2,0,0,0,0,0,2,0,0,0, -0,2,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, -0,0,0,3,2,0,2,2,0,1,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0, -2,0,1,0,1,0,1,1,0,0,1,2,0,1,0,1,1,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0, -2,2,2,0,1,1,0,0,0,1,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,1,2,0,1,0, -0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,2,1,0,1,1,1,0,0,0,0,1,2,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, -1,1,2,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1, -0,0,1,2,2,0,2,1,2,1,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,0,0,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, -2,2,2,0,0,0,1,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, -0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -2,2,2,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,1,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -) - -Latin5TurkishModel = { - 'char_to_order_map': Latin5_TurkishCharToOrderMap, - 'precedence_matrix': TurkishLangModel, - 'typical_positive_ratio': 0.970290, - 'keep_english_letter': True, - 'charset_name': "ISO-8859-9", - 'language': 'Turkish', -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/latin1prober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/latin1prober.py deleted file mode 100644 index 7d1e8c2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/latin1prober.py +++ /dev/null @@ -1,145 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import ProbingState - -FREQ_CAT_NUM = 4 - -UDF = 0 # undefined -OTH = 1 # other -ASC = 2 # ascii capital letter -ASS = 3 # ascii small letter -ACV = 4 # accent capital vowel -ACO = 5 # accent capital other -ASV = 6 # accent small vowel -ASO = 7 # accent small other -CLASS_NUM = 8 # total classes - -Latin1_CharToClass = ( - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F - OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 - ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F - OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 - ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F - ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 - ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F - OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 - OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F - UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 - OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 - OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF - ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 - ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF - ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 - ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF - ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 - ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF - ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 - ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF -) - -# 0 : illegal -# 1 : very unlikely -# 2 : normal -# 3 : very likely -Latin1ClassModel = ( -# UDF OTH ASC ASS ACV ACO ASV ASO - 0, 0, 0, 0, 0, 0, 0, 0, # UDF - 0, 3, 3, 3, 3, 3, 3, 3, # OTH - 0, 3, 3, 3, 3, 3, 3, 3, # ASC - 0, 3, 3, 3, 1, 1, 3, 3, # ASS - 0, 3, 3, 3, 1, 2, 1, 2, # ACV - 0, 3, 3, 3, 3, 3, 3, 3, # ACO - 0, 3, 1, 3, 1, 1, 1, 3, # ASV - 0, 3, 1, 3, 1, 1, 3, 3, # ASO -) - - -class Latin1Prober(CharSetProber): - def __init__(self): - super(Latin1Prober, self).__init__() - self._last_char_class = None - self._freq_counter = None - self.reset() - - def reset(self): - self._last_char_class = OTH - self._freq_counter = [0] * FREQ_CAT_NUM - CharSetProber.reset(self) - - @property - def charset_name(self): - return "ISO-8859-1" - - @property - def language(self): - return "" - - def feed(self, byte_str): - byte_str = self.filter_with_english_letters(byte_str) - for c in byte_str: - char_class = Latin1_CharToClass[c] - freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) - + char_class] - if freq == 0: - self._state = ProbingState.NOT_ME - break - self._freq_counter[freq] += 1 - self._last_char_class = char_class - - return self.state - - def get_confidence(self): - if self.state == ProbingState.NOT_ME: - return 0.01 - - total = sum(self._freq_counter) - if total < 0.01: - confidence = 0.0 - else: - confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) - / total) - if confidence < 0.0: - confidence = 0.0 - # lower the confidence of latin1 so that other more accurate - # detector can take priority. - confidence = confidence * 0.73 - return confidence diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcharsetprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcharsetprober.py deleted file mode 100644 index 6256ecf..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcharsetprober.py +++ /dev/null @@ -1,91 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# Proofpoint, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import ProbingState, MachineState - - -class MultiByteCharSetProber(CharSetProber): - """ - MultiByteCharSetProber - """ - - def __init__(self, lang_filter=None): - super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) - self.distribution_analyzer = None - self.coding_sm = None - self._last_char = [0, 0] - - def reset(self): - super(MultiByteCharSetProber, self).reset() - if self.coding_sm: - self.coding_sm.reset() - if self.distribution_analyzer: - self.distribution_analyzer.reset() - self._last_char = [0, 0] - - @property - def charset_name(self): - raise NotImplementedError - - @property - def language(self): - raise NotImplementedError - - def feed(self, byte_str): - for i in range(len(byte_str)): - coding_state = self.coding_sm.next_state(byte_str[i]) - if coding_state == MachineState.ERROR: - self.logger.debug('%s %s prober hit error at byte %s', - self.charset_name, self.language, i) - self._state = ProbingState.NOT_ME - break - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - break - elif coding_state == MachineState.START: - char_len = self.coding_sm.get_current_charlen() - if i == 0: - self._last_char[1] = byte_str[0] - self.distribution_analyzer.feed(self._last_char, char_len) - else: - self.distribution_analyzer.feed(byte_str[i - 1:i + 1], - char_len) - - self._last_char[0] = byte_str[-1] - - if self.state == ProbingState.DETECTING: - if (self.distribution_analyzer.got_enough_data() and - (self.get_confidence() > self.SHORTCUT_THRESHOLD)): - self._state = ProbingState.FOUND_IT - - return self.state - - def get_confidence(self): - return self.distribution_analyzer.get_confidence() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcsgroupprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcsgroupprober.py deleted file mode 100644 index 530abe7..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcsgroupprober.py +++ /dev/null @@ -1,54 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# Proofpoint, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetgroupprober import CharSetGroupProber -from .utf8prober import UTF8Prober -from .sjisprober import SJISProber -from .eucjpprober import EUCJPProber -from .gb2312prober import GB2312Prober -from .euckrprober import EUCKRProber -from .cp949prober import CP949Prober -from .big5prober import Big5Prober -from .euctwprober import EUCTWProber - - -class MBCSGroupProber(CharSetGroupProber): - def __init__(self, lang_filter=None): - super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) - self.probers = [ - UTF8Prober(), - SJISProber(), - EUCJPProber(), - GB2312Prober(), - EUCKRProber(), - CP949Prober(), - Big5Prober(), - EUCTWProber() - ] - self.reset() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcssm.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcssm.py deleted file mode 100644 index 8360d0f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/mbcssm.py +++ /dev/null @@ -1,572 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .enums import MachineState - -# BIG5 - -BIG5_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 1,1,1,1,1,1,1,1, # 30 - 37 - 1,1,1,1,1,1,1,1, # 38 - 3f - 2,2,2,2,2,2,2,2, # 40 - 47 - 2,2,2,2,2,2,2,2, # 48 - 4f - 2,2,2,2,2,2,2,2, # 50 - 57 - 2,2,2,2,2,2,2,2, # 58 - 5f - 2,2,2,2,2,2,2,2, # 60 - 67 - 2,2,2,2,2,2,2,2, # 68 - 6f - 2,2,2,2,2,2,2,2, # 70 - 77 - 2,2,2,2,2,2,2,1, # 78 - 7f - 4,4,4,4,4,4,4,4, # 80 - 87 - 4,4,4,4,4,4,4,4, # 88 - 8f - 4,4,4,4,4,4,4,4, # 90 - 97 - 4,4,4,4,4,4,4,4, # 98 - 9f - 4,3,3,3,3,3,3,3, # a0 - a7 - 3,3,3,3,3,3,3,3, # a8 - af - 3,3,3,3,3,3,3,3, # b0 - b7 - 3,3,3,3,3,3,3,3, # b8 - bf - 3,3,3,3,3,3,3,3, # c0 - c7 - 3,3,3,3,3,3,3,3, # c8 - cf - 3,3,3,3,3,3,3,3, # d0 - d7 - 3,3,3,3,3,3,3,3, # d8 - df - 3,3,3,3,3,3,3,3, # e0 - e7 - 3,3,3,3,3,3,3,3, # e8 - ef - 3,3,3,3,3,3,3,3, # f0 - f7 - 3,3,3,3,3,3,3,0 # f8 - ff -) - -BIG5_ST = ( - MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f - MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 -) - -BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) - -BIG5_SM_MODEL = {'class_table': BIG5_CLS, - 'class_factor': 5, - 'state_table': BIG5_ST, - 'char_len_table': BIG5_CHAR_LEN_TABLE, - 'name': 'Big5'} - -# CP949 - -CP949_CLS = ( - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f - 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f - 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f - 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f - 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f - 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f - 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f - 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f - 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af - 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf - 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf - 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df - 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef - 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff -) - -CP949_ST = ( -#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = - MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 - MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 - MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 -) - -CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) - -CP949_SM_MODEL = {'class_table': CP949_CLS, - 'class_factor': 10, - 'state_table': CP949_ST, - 'char_len_table': CP949_CHAR_LEN_TABLE, - 'name': 'CP949'} - -# EUC-JP - -EUCJP_CLS = ( - 4,4,4,4,4,4,4,4, # 00 - 07 - 4,4,4,4,4,4,5,5, # 08 - 0f - 4,4,4,4,4,4,4,4, # 10 - 17 - 4,4,4,5,4,4,4,4, # 18 - 1f - 4,4,4,4,4,4,4,4, # 20 - 27 - 4,4,4,4,4,4,4,4, # 28 - 2f - 4,4,4,4,4,4,4,4, # 30 - 37 - 4,4,4,4,4,4,4,4, # 38 - 3f - 4,4,4,4,4,4,4,4, # 40 - 47 - 4,4,4,4,4,4,4,4, # 48 - 4f - 4,4,4,4,4,4,4,4, # 50 - 57 - 4,4,4,4,4,4,4,4, # 58 - 5f - 4,4,4,4,4,4,4,4, # 60 - 67 - 4,4,4,4,4,4,4,4, # 68 - 6f - 4,4,4,4,4,4,4,4, # 70 - 77 - 4,4,4,4,4,4,4,4, # 78 - 7f - 5,5,5,5,5,5,5,5, # 80 - 87 - 5,5,5,5,5,5,1,3, # 88 - 8f - 5,5,5,5,5,5,5,5, # 90 - 97 - 5,5,5,5,5,5,5,5, # 98 - 9f - 5,2,2,2,2,2,2,2, # a0 - a7 - 2,2,2,2,2,2,2,2, # a8 - af - 2,2,2,2,2,2,2,2, # b0 - b7 - 2,2,2,2,2,2,2,2, # b8 - bf - 2,2,2,2,2,2,2,2, # c0 - c7 - 2,2,2,2,2,2,2,2, # c8 - cf - 2,2,2,2,2,2,2,2, # d0 - d7 - 2,2,2,2,2,2,2,2, # d8 - df - 0,0,0,0,0,0,0,0, # e0 - e7 - 0,0,0,0,0,0,0,0, # e8 - ef - 0,0,0,0,0,0,0,0, # f0 - f7 - 0,0,0,0,0,0,0,5 # f8 - ff -) - -EUCJP_ST = ( - 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f - 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 -) - -EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) - -EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, - 'class_factor': 6, - 'state_table': EUCJP_ST, - 'char_len_table': EUCJP_CHAR_LEN_TABLE, - 'name': 'EUC-JP'} - -# EUC-KR - -EUCKR_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 1,1,1,1,1,1,1,1, # 30 - 37 - 1,1,1,1,1,1,1,1, # 38 - 3f - 1,1,1,1,1,1,1,1, # 40 - 47 - 1,1,1,1,1,1,1,1, # 48 - 4f - 1,1,1,1,1,1,1,1, # 50 - 57 - 1,1,1,1,1,1,1,1, # 58 - 5f - 1,1,1,1,1,1,1,1, # 60 - 67 - 1,1,1,1,1,1,1,1, # 68 - 6f - 1,1,1,1,1,1,1,1, # 70 - 77 - 1,1,1,1,1,1,1,1, # 78 - 7f - 0,0,0,0,0,0,0,0, # 80 - 87 - 0,0,0,0,0,0,0,0, # 88 - 8f - 0,0,0,0,0,0,0,0, # 90 - 97 - 0,0,0,0,0,0,0,0, # 98 - 9f - 0,2,2,2,2,2,2,2, # a0 - a7 - 2,2,2,2,2,3,3,3, # a8 - af - 2,2,2,2,2,2,2,2, # b0 - b7 - 2,2,2,2,2,2,2,2, # b8 - bf - 2,2,2,2,2,2,2,2, # c0 - c7 - 2,3,2,2,2,2,2,2, # c8 - cf - 2,2,2,2,2,2,2,2, # d0 - d7 - 2,2,2,2,2,2,2,2, # d8 - df - 2,2,2,2,2,2,2,2, # e0 - e7 - 2,2,2,2,2,2,2,2, # e8 - ef - 2,2,2,2,2,2,2,2, # f0 - f7 - 2,2,2,2,2,2,2,0 # f8 - ff -) - -EUCKR_ST = ( - MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f -) - -EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) - -EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, - 'class_factor': 4, - 'state_table': EUCKR_ST, - 'char_len_table': EUCKR_CHAR_LEN_TABLE, - 'name': 'EUC-KR'} - -# EUC-TW - -EUCTW_CLS = ( - 2,2,2,2,2,2,2,2, # 00 - 07 - 2,2,2,2,2,2,0,0, # 08 - 0f - 2,2,2,2,2,2,2,2, # 10 - 17 - 2,2,2,0,2,2,2,2, # 18 - 1f - 2,2,2,2,2,2,2,2, # 20 - 27 - 2,2,2,2,2,2,2,2, # 28 - 2f - 2,2,2,2,2,2,2,2, # 30 - 37 - 2,2,2,2,2,2,2,2, # 38 - 3f - 2,2,2,2,2,2,2,2, # 40 - 47 - 2,2,2,2,2,2,2,2, # 48 - 4f - 2,2,2,2,2,2,2,2, # 50 - 57 - 2,2,2,2,2,2,2,2, # 58 - 5f - 2,2,2,2,2,2,2,2, # 60 - 67 - 2,2,2,2,2,2,2,2, # 68 - 6f - 2,2,2,2,2,2,2,2, # 70 - 77 - 2,2,2,2,2,2,2,2, # 78 - 7f - 0,0,0,0,0,0,0,0, # 80 - 87 - 0,0,0,0,0,0,6,0, # 88 - 8f - 0,0,0,0,0,0,0,0, # 90 - 97 - 0,0,0,0,0,0,0,0, # 98 - 9f - 0,3,4,4,4,4,4,4, # a0 - a7 - 5,5,1,1,1,1,1,1, # a8 - af - 1,1,1,1,1,1,1,1, # b0 - b7 - 1,1,1,1,1,1,1,1, # b8 - bf - 1,1,3,1,3,3,3,3, # c0 - c7 - 3,3,3,3,3,3,3,3, # c8 - cf - 3,3,3,3,3,3,3,3, # d0 - d7 - 3,3,3,3,3,3,3,3, # d8 - df - 3,3,3,3,3,3,3,3, # e0 - e7 - 3,3,3,3,3,3,3,3, # e8 - ef - 3,3,3,3,3,3,3,3, # f0 - f7 - 3,3,3,3,3,3,3,0 # f8 - ff -) - -EUCTW_ST = ( - MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 - MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f - 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 - MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f -) - -EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) - -EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, - 'class_factor': 7, - 'state_table': EUCTW_ST, - 'char_len_table': EUCTW_CHAR_LEN_TABLE, - 'name': 'x-euc-tw'} - -# GB2312 - -GB2312_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 3,3,3,3,3,3,3,3, # 30 - 37 - 3,3,1,1,1,1,1,1, # 38 - 3f - 2,2,2,2,2,2,2,2, # 40 - 47 - 2,2,2,2,2,2,2,2, # 48 - 4f - 2,2,2,2,2,2,2,2, # 50 - 57 - 2,2,2,2,2,2,2,2, # 58 - 5f - 2,2,2,2,2,2,2,2, # 60 - 67 - 2,2,2,2,2,2,2,2, # 68 - 6f - 2,2,2,2,2,2,2,2, # 70 - 77 - 2,2,2,2,2,2,2,4, # 78 - 7f - 5,6,6,6,6,6,6,6, # 80 - 87 - 6,6,6,6,6,6,6,6, # 88 - 8f - 6,6,6,6,6,6,6,6, # 90 - 97 - 6,6,6,6,6,6,6,6, # 98 - 9f - 6,6,6,6,6,6,6,6, # a0 - a7 - 6,6,6,6,6,6,6,6, # a8 - af - 6,6,6,6,6,6,6,6, # b0 - b7 - 6,6,6,6,6,6,6,6, # b8 - bf - 6,6,6,6,6,6,6,6, # c0 - c7 - 6,6,6,6,6,6,6,6, # c8 - cf - 6,6,6,6,6,6,6,6, # d0 - d7 - 6,6,6,6,6,6,6,6, # d8 - df - 6,6,6,6,6,6,6,6, # e0 - e7 - 6,6,6,6,6,6,6,6, # e8 - ef - 6,6,6,6,6,6,6,6, # f0 - f7 - 6,6,6,6,6,6,6,0 # f8 - ff -) - -GB2312_ST = ( - MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 - 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f - MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f -) - -# To be accurate, the length of class 6 can be either 2 or 4. -# But it is not necessary to discriminate between the two since -# it is used for frequency analysis only, and we are validating -# each code range there as well. So it is safe to set it to be -# 2 here. -GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) - -GB2312_SM_MODEL = {'class_table': GB2312_CLS, - 'class_factor': 7, - 'state_table': GB2312_ST, - 'char_len_table': GB2312_CHAR_LEN_TABLE, - 'name': 'GB2312'} - -# Shift_JIS - -SJIS_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 1,1,1,1,1,1,1,1, # 30 - 37 - 1,1,1,1,1,1,1,1, # 38 - 3f - 2,2,2,2,2,2,2,2, # 40 - 47 - 2,2,2,2,2,2,2,2, # 48 - 4f - 2,2,2,2,2,2,2,2, # 50 - 57 - 2,2,2,2,2,2,2,2, # 58 - 5f - 2,2,2,2,2,2,2,2, # 60 - 67 - 2,2,2,2,2,2,2,2, # 68 - 6f - 2,2,2,2,2,2,2,2, # 70 - 77 - 2,2,2,2,2,2,2,1, # 78 - 7f - 3,3,3,3,3,2,2,3, # 80 - 87 - 3,3,3,3,3,3,3,3, # 88 - 8f - 3,3,3,3,3,3,3,3, # 90 - 97 - 3,3,3,3,3,3,3,3, # 98 - 9f - #0xa0 is illegal in sjis encoding, but some pages does - #contain such byte. We need to be more error forgiven. - 2,2,2,2,2,2,2,2, # a0 - a7 - 2,2,2,2,2,2,2,2, # a8 - af - 2,2,2,2,2,2,2,2, # b0 - b7 - 2,2,2,2,2,2,2,2, # b8 - bf - 2,2,2,2,2,2,2,2, # c0 - c7 - 2,2,2,2,2,2,2,2, # c8 - cf - 2,2,2,2,2,2,2,2, # d0 - d7 - 2,2,2,2,2,2,2,2, # d8 - df - 3,3,3,3,3,3,3,3, # e0 - e7 - 3,3,3,3,3,4,4,4, # e8 - ef - 3,3,3,3,3,3,3,3, # f0 - f7 - 3,3,3,3,3,0,0,0) # f8 - ff - - -SJIS_ST = ( - MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 -) - -SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) - -SJIS_SM_MODEL = {'class_table': SJIS_CLS, - 'class_factor': 6, - 'state_table': SJIS_ST, - 'char_len_table': SJIS_CHAR_LEN_TABLE, - 'name': 'Shift_JIS'} - -# UCS2-BE - -UCS2BE_CLS = ( - 0,0,0,0,0,0,0,0, # 00 - 07 - 0,0,1,0,0,2,0,0, # 08 - 0f - 0,0,0,0,0,0,0,0, # 10 - 17 - 0,0,0,3,0,0,0,0, # 18 - 1f - 0,0,0,0,0,0,0,0, # 20 - 27 - 0,3,3,3,3,3,0,0, # 28 - 2f - 0,0,0,0,0,0,0,0, # 30 - 37 - 0,0,0,0,0,0,0,0, # 38 - 3f - 0,0,0,0,0,0,0,0, # 40 - 47 - 0,0,0,0,0,0,0,0, # 48 - 4f - 0,0,0,0,0,0,0,0, # 50 - 57 - 0,0,0,0,0,0,0,0, # 58 - 5f - 0,0,0,0,0,0,0,0, # 60 - 67 - 0,0,0,0,0,0,0,0, # 68 - 6f - 0,0,0,0,0,0,0,0, # 70 - 77 - 0,0,0,0,0,0,0,0, # 78 - 7f - 0,0,0,0,0,0,0,0, # 80 - 87 - 0,0,0,0,0,0,0,0, # 88 - 8f - 0,0,0,0,0,0,0,0, # 90 - 97 - 0,0,0,0,0,0,0,0, # 98 - 9f - 0,0,0,0,0,0,0,0, # a0 - a7 - 0,0,0,0,0,0,0,0, # a8 - af - 0,0,0,0,0,0,0,0, # b0 - b7 - 0,0,0,0,0,0,0,0, # b8 - bf - 0,0,0,0,0,0,0,0, # c0 - c7 - 0,0,0,0,0,0,0,0, # c8 - cf - 0,0,0,0,0,0,0,0, # d0 - d7 - 0,0,0,0,0,0,0,0, # d8 - df - 0,0,0,0,0,0,0,0, # e0 - e7 - 0,0,0,0,0,0,0,0, # e8 - ef - 0,0,0,0,0,0,0,0, # f0 - f7 - 0,0,0,0,0,0,4,5 # f8 - ff -) - -UCS2BE_ST = ( - 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 - 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f - 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 - 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f - 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 -) - -UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) - -UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, - 'class_factor': 6, - 'state_table': UCS2BE_ST, - 'char_len_table': UCS2BE_CHAR_LEN_TABLE, - 'name': 'UTF-16BE'} - -# UCS2-LE - -UCS2LE_CLS = ( - 0,0,0,0,0,0,0,0, # 00 - 07 - 0,0,1,0,0,2,0,0, # 08 - 0f - 0,0,0,0,0,0,0,0, # 10 - 17 - 0,0,0,3,0,0,0,0, # 18 - 1f - 0,0,0,0,0,0,0,0, # 20 - 27 - 0,3,3,3,3,3,0,0, # 28 - 2f - 0,0,0,0,0,0,0,0, # 30 - 37 - 0,0,0,0,0,0,0,0, # 38 - 3f - 0,0,0,0,0,0,0,0, # 40 - 47 - 0,0,0,0,0,0,0,0, # 48 - 4f - 0,0,0,0,0,0,0,0, # 50 - 57 - 0,0,0,0,0,0,0,0, # 58 - 5f - 0,0,0,0,0,0,0,0, # 60 - 67 - 0,0,0,0,0,0,0,0, # 68 - 6f - 0,0,0,0,0,0,0,0, # 70 - 77 - 0,0,0,0,0,0,0,0, # 78 - 7f - 0,0,0,0,0,0,0,0, # 80 - 87 - 0,0,0,0,0,0,0,0, # 88 - 8f - 0,0,0,0,0,0,0,0, # 90 - 97 - 0,0,0,0,0,0,0,0, # 98 - 9f - 0,0,0,0,0,0,0,0, # a0 - a7 - 0,0,0,0,0,0,0,0, # a8 - af - 0,0,0,0,0,0,0,0, # b0 - b7 - 0,0,0,0,0,0,0,0, # b8 - bf - 0,0,0,0,0,0,0,0, # c0 - c7 - 0,0,0,0,0,0,0,0, # c8 - cf - 0,0,0,0,0,0,0,0, # d0 - d7 - 0,0,0,0,0,0,0,0, # d8 - df - 0,0,0,0,0,0,0,0, # e0 - e7 - 0,0,0,0,0,0,0,0, # e8 - ef - 0,0,0,0,0,0,0,0, # f0 - f7 - 0,0,0,0,0,0,4,5 # f8 - ff -) - -UCS2LE_ST = ( - 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f - MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 - 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f - 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 - 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f - 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 -) - -UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) - -UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, - 'class_factor': 6, - 'state_table': UCS2LE_ST, - 'char_len_table': UCS2LE_CHAR_LEN_TABLE, - 'name': 'UTF-16LE'} - -# UTF-8 - -UTF8_CLS = ( - 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value - 1,1,1,1,1,1,0,0, # 08 - 0f - 1,1,1,1,1,1,1,1, # 10 - 17 - 1,1,1,0,1,1,1,1, # 18 - 1f - 1,1,1,1,1,1,1,1, # 20 - 27 - 1,1,1,1,1,1,1,1, # 28 - 2f - 1,1,1,1,1,1,1,1, # 30 - 37 - 1,1,1,1,1,1,1,1, # 38 - 3f - 1,1,1,1,1,1,1,1, # 40 - 47 - 1,1,1,1,1,1,1,1, # 48 - 4f - 1,1,1,1,1,1,1,1, # 50 - 57 - 1,1,1,1,1,1,1,1, # 58 - 5f - 1,1,1,1,1,1,1,1, # 60 - 67 - 1,1,1,1,1,1,1,1, # 68 - 6f - 1,1,1,1,1,1,1,1, # 70 - 77 - 1,1,1,1,1,1,1,1, # 78 - 7f - 2,2,2,2,3,3,3,3, # 80 - 87 - 4,4,4,4,4,4,4,4, # 88 - 8f - 4,4,4,4,4,4,4,4, # 90 - 97 - 4,4,4,4,4,4,4,4, # 98 - 9f - 5,5,5,5,5,5,5,5, # a0 - a7 - 5,5,5,5,5,5,5,5, # a8 - af - 5,5,5,5,5,5,5,5, # b0 - b7 - 5,5,5,5,5,5,5,5, # b8 - bf - 0,0,6,6,6,6,6,6, # c0 - c7 - 6,6,6,6,6,6,6,6, # c8 - cf - 6,6,6,6,6,6,6,6, # d0 - d7 - 6,6,6,6,6,6,6,6, # d8 - df - 7,8,8,8,8,8,8,8, # e0 - e7 - 8,8,8,8,8,9,8,8, # e8 - ef - 10,11,11,11,11,11,11,11, # f0 - f7 - 12,13,13,13,14,15,0,0 # f8 - ff -) - -UTF8_ST = ( - MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 - 9, 11, 8, 7, 6, 5, 4, 3,#08-0f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 - MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f - MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f - MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f - MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f - MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af - MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf - MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 - MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf -) - -UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) - -UTF8_SM_MODEL = {'class_table': UTF8_CLS, - 'class_factor': 16, - 'state_table': UTF8_ST, - 'char_len_table': UTF8_CHAR_LEN_TABLE, - 'name': 'UTF-8'} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sbcharsetprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sbcharsetprober.py deleted file mode 100644 index 0adb51d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sbcharsetprober.py +++ /dev/null @@ -1,132 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import CharacterCategory, ProbingState, SequenceLikelihood - - -class SingleByteCharSetProber(CharSetProber): - SAMPLE_SIZE = 64 - SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 - POSITIVE_SHORTCUT_THRESHOLD = 0.95 - NEGATIVE_SHORTCUT_THRESHOLD = 0.05 - - def __init__(self, model, reversed=False, name_prober=None): - super(SingleByteCharSetProber, self).__init__() - self._model = model - # TRUE if we need to reverse every pair in the model lookup - self._reversed = reversed - # Optional auxiliary prober for name decision - self._name_prober = name_prober - self._last_order = None - self._seq_counters = None - self._total_seqs = None - self._total_char = None - self._freq_char = None - self.reset() - - def reset(self): - super(SingleByteCharSetProber, self).reset() - # char order of last character - self._last_order = 255 - self._seq_counters = [0] * SequenceLikelihood.get_num_categories() - self._total_seqs = 0 - self._total_char = 0 - # characters that fall in our sampling range - self._freq_char = 0 - - @property - def charset_name(self): - if self._name_prober: - return self._name_prober.charset_name - else: - return self._model['charset_name'] - - @property - def language(self): - if self._name_prober: - return self._name_prober.language - else: - return self._model.get('language') - - def feed(self, byte_str): - if not self._model['keep_english_letter']: - byte_str = self.filter_international_words(byte_str) - if not byte_str: - return self.state - char_to_order_map = self._model['char_to_order_map'] - for i, c in enumerate(byte_str): - # XXX: Order is in range 1-64, so one would think we want 0-63 here, - # but that leads to 27 more test failures than before. - order = char_to_order_map[c] - # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but - # CharacterCategory.SYMBOL is actually 253, so we use CONTROL - # to make it closer to the original intent. The only difference - # is whether or not we count digits and control characters for - # _total_char purposes. - if order < CharacterCategory.CONTROL: - self._total_char += 1 - if order < self.SAMPLE_SIZE: - self._freq_char += 1 - if self._last_order < self.SAMPLE_SIZE: - self._total_seqs += 1 - if not self._reversed: - i = (self._last_order * self.SAMPLE_SIZE) + order - model = self._model['precedence_matrix'][i] - else: # reverse the order of the letters in the lookup - i = (order * self.SAMPLE_SIZE) + self._last_order - model = self._model['precedence_matrix'][i] - self._seq_counters[model] += 1 - self._last_order = order - - charset_name = self._model['charset_name'] - if self.state == ProbingState.DETECTING: - if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: - confidence = self.get_confidence() - if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: - self.logger.debug('%s confidence = %s, we have a winner', - charset_name, confidence) - self._state = ProbingState.FOUND_IT - elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: - self.logger.debug('%s confidence = %s, below negative ' - 'shortcut threshhold %s', charset_name, - confidence, - self.NEGATIVE_SHORTCUT_THRESHOLD) - self._state = ProbingState.NOT_ME - - return self.state - - def get_confidence(self): - r = 0.01 - if self._total_seqs > 0: - r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / - self._total_seqs / self._model['typical_positive_ratio']) - r = r * self._freq_char / self._total_char - if r >= 1.0: - r = 0.99 - return r diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sbcsgroupprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sbcsgroupprober.py deleted file mode 100644 index 98e95dc..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sbcsgroupprober.py +++ /dev/null @@ -1,73 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetgroupprober import CharSetGroupProber -from .sbcharsetprober import SingleByteCharSetProber -from .langcyrillicmodel import (Win1251CyrillicModel, Koi8rModel, - Latin5CyrillicModel, MacCyrillicModel, - Ibm866Model, Ibm855Model) -from .langgreekmodel import Latin7GreekModel, Win1253GreekModel -from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel -# from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel -from .langthaimodel import TIS620ThaiModel -from .langhebrewmodel import Win1255HebrewModel -from .hebrewprober import HebrewProber -from .langturkishmodel import Latin5TurkishModel - - -class SBCSGroupProber(CharSetGroupProber): - def __init__(self): - super(SBCSGroupProber, self).__init__() - self.probers = [ - SingleByteCharSetProber(Win1251CyrillicModel), - SingleByteCharSetProber(Koi8rModel), - SingleByteCharSetProber(Latin5CyrillicModel), - SingleByteCharSetProber(MacCyrillicModel), - SingleByteCharSetProber(Ibm866Model), - SingleByteCharSetProber(Ibm855Model), - SingleByteCharSetProber(Latin7GreekModel), - SingleByteCharSetProber(Win1253GreekModel), - SingleByteCharSetProber(Latin5BulgarianModel), - SingleByteCharSetProber(Win1251BulgarianModel), - # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) - # after we retrain model. - # SingleByteCharSetProber(Latin2HungarianModel), - # SingleByteCharSetProber(Win1250HungarianModel), - SingleByteCharSetProber(TIS620ThaiModel), - SingleByteCharSetProber(Latin5TurkishModel), - ] - hebrew_prober = HebrewProber() - logical_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, - False, hebrew_prober) - visual_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, True, - hebrew_prober) - hebrew_prober.set_model_probers(logical_hebrew_prober, visual_hebrew_prober) - self.probers.extend([hebrew_prober, logical_hebrew_prober, - visual_hebrew_prober]) - - self.reset() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sjisprober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sjisprober.py deleted file mode 100644 index 9e29623..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/sjisprober.py +++ /dev/null @@ -1,92 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .mbcharsetprober import MultiByteCharSetProber -from .codingstatemachine import CodingStateMachine -from .chardistribution import SJISDistributionAnalysis -from .jpcntx import SJISContextAnalysis -from .mbcssm import SJIS_SM_MODEL -from .enums import ProbingState, MachineState - - -class SJISProber(MultiByteCharSetProber): - def __init__(self): - super(SJISProber, self).__init__() - self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) - self.distribution_analyzer = SJISDistributionAnalysis() - self.context_analyzer = SJISContextAnalysis() - self.reset() - - def reset(self): - super(SJISProber, self).reset() - self.context_analyzer.reset() - - @property - def charset_name(self): - return self.context_analyzer.charset_name - - @property - def language(self): - return "Japanese" - - def feed(self, byte_str): - for i in range(len(byte_str)): - coding_state = self.coding_sm.next_state(byte_str[i]) - if coding_state == MachineState.ERROR: - self.logger.debug('%s %s prober hit error at byte %s', - self.charset_name, self.language, i) - self._state = ProbingState.NOT_ME - break - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - break - elif coding_state == MachineState.START: - char_len = self.coding_sm.get_current_charlen() - if i == 0: - self._last_char[1] = byte_str[0] - self.context_analyzer.feed(self._last_char[2 - char_len:], - char_len) - self.distribution_analyzer.feed(self._last_char, char_len) - else: - self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 - - char_len], char_len) - self.distribution_analyzer.feed(byte_str[i - 1:i + 1], - char_len) - - self._last_char[0] = byte_str[-1] - - if self.state == ProbingState.DETECTING: - if (self.context_analyzer.got_enough_data() and - (self.get_confidence() > self.SHORTCUT_THRESHOLD)): - self._state = ProbingState.FOUND_IT - - return self.state - - def get_confidence(self): - context_conf = self.context_analyzer.get_confidence() - distrib_conf = self.distribution_analyzer.get_confidence() - return max(context_conf, distrib_conf) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/universaldetector.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/universaldetector.py deleted file mode 100644 index 7b4e92d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/universaldetector.py +++ /dev/null @@ -1,286 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is Mozilla Universal charset detector code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# Shy Shalom - original C code -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### -""" -Module containing the UniversalDetector detector class, which is the primary -class a user of ``chardet`` should use. - -:author: Mark Pilgrim (initial port to Python) -:author: Shy Shalom (original C code) -:author: Dan Blanchard (major refactoring for 3.0) -:author: Ian Cordasco -""" - - -import codecs -import logging -import re - -from .charsetgroupprober import CharSetGroupProber -from .enums import InputState, LanguageFilter, ProbingState -from .escprober import EscCharSetProber -from .latin1prober import Latin1Prober -from .mbcsgroupprober import MBCSGroupProber -from .sbcsgroupprober import SBCSGroupProber - - -class UniversalDetector(object): - """ - The ``UniversalDetector`` class underlies the ``chardet.detect`` function - and coordinates all of the different charset probers. - - To get a ``dict`` containing an encoding and its confidence, you can simply - run: - - .. code:: - - u = UniversalDetector() - u.feed(some_bytes) - u.close() - detected = u.result - - """ - - MINIMUM_THRESHOLD = 0.20 - HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') - ESC_DETECTOR = re.compile(b'(\033|~{)') - WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') - ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', - 'iso-8859-2': 'Windows-1250', - 'iso-8859-5': 'Windows-1251', - 'iso-8859-6': 'Windows-1256', - 'iso-8859-7': 'Windows-1253', - 'iso-8859-8': 'Windows-1255', - 'iso-8859-9': 'Windows-1254', - 'iso-8859-13': 'Windows-1257'} - - def __init__(self, lang_filter=LanguageFilter.ALL): - self._esc_charset_prober = None - self._charset_probers = [] - self.result = None - self.done = None - self._got_data = None - self._input_state = None - self._last_char = None - self.lang_filter = lang_filter - self.logger = logging.getLogger(__name__) - self._has_win_bytes = None - self.reset() - - def reset(self): - """ - Reset the UniversalDetector and all of its probers back to their - initial states. This is called by ``__init__``, so you only need to - call this directly in between analyses of different documents. - """ - self.result = {'encoding': None, 'confidence': 0.0, 'language': None} - self.done = False - self._got_data = False - self._has_win_bytes = False - self._input_state = InputState.PURE_ASCII - self._last_char = b'' - if self._esc_charset_prober: - self._esc_charset_prober.reset() - for prober in self._charset_probers: - prober.reset() - - def feed(self, byte_str): - """ - Takes a chunk of a document and feeds it through all of the relevant - charset probers. - - After calling ``feed``, you can check the value of the ``done`` - attribute to see if you need to continue feeding the - ``UniversalDetector`` more data, or if it has made a prediction - (in the ``result`` attribute). - - .. note:: - You should always call ``close`` when you're done feeding in your - document if ``done`` is not already ``True``. - """ - if self.done: - return - - if not len(byte_str): - return - - if not isinstance(byte_str, bytearray): - byte_str = bytearray(byte_str) - - # First check for known BOMs, since these are guaranteed to be correct - if not self._got_data: - # If the data starts with BOM, we know it is UTF - if byte_str.startswith(codecs.BOM_UTF8): - # EF BB BF UTF-8 with BOM - self.result = {'encoding': "UTF-8-SIG", - 'confidence': 1.0, - 'language': ''} - elif byte_str.startswith((codecs.BOM_UTF32_LE, - codecs.BOM_UTF32_BE)): - # FF FE 00 00 UTF-32, little-endian BOM - # 00 00 FE FF UTF-32, big-endian BOM - self.result = {'encoding': "UTF-32", - 'confidence': 1.0, - 'language': ''} - elif byte_str.startswith(b'\xFE\xFF\x00\x00'): - # FE FF 00 00 UCS-4, unusual octet order BOM (3412) - self.result = {'encoding': "X-ISO-10646-UCS-4-3412", - 'confidence': 1.0, - 'language': ''} - elif byte_str.startswith(b'\x00\x00\xFF\xFE'): - # 00 00 FF FE UCS-4, unusual octet order BOM (2143) - self.result = {'encoding': "X-ISO-10646-UCS-4-2143", - 'confidence': 1.0, - 'language': ''} - elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): - # FF FE UTF-16, little endian BOM - # FE FF UTF-16, big endian BOM - self.result = {'encoding': "UTF-16", - 'confidence': 1.0, - 'language': ''} - - self._got_data = True - if self.result['encoding'] is not None: - self.done = True - return - - # If none of those matched and we've only see ASCII so far, check - # for high bytes and escape sequences - if self._input_state == InputState.PURE_ASCII: - if self.HIGH_BYTE_DETECTOR.search(byte_str): - self._input_state = InputState.HIGH_BYTE - elif self._input_state == InputState.PURE_ASCII and \ - self.ESC_DETECTOR.search(self._last_char + byte_str): - self._input_state = InputState.ESC_ASCII - - self._last_char = byte_str[-1:] - - # If we've seen escape sequences, use the EscCharSetProber, which - # uses a simple state machine to check for known escape sequences in - # HZ and ISO-2022 encodings, since those are the only encodings that - # use such sequences. - if self._input_state == InputState.ESC_ASCII: - if not self._esc_charset_prober: - self._esc_charset_prober = EscCharSetProber(self.lang_filter) - if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: - self.result = {'encoding': - self._esc_charset_prober.charset_name, - 'confidence': - self._esc_charset_prober.get_confidence(), - 'language': - self._esc_charset_prober.language} - self.done = True - # If we've seen high bytes (i.e., those with values greater than 127), - # we need to do more complicated checks using all our multi-byte and - # single-byte probers that are left. The single-byte probers - # use character bigram distributions to determine the encoding, whereas - # the multi-byte probers use a combination of character unigram and - # bigram distributions. - elif self._input_state == InputState.HIGH_BYTE: - if not self._charset_probers: - self._charset_probers = [MBCSGroupProber(self.lang_filter)] - # If we're checking non-CJK encodings, use single-byte prober - if self.lang_filter & LanguageFilter.NON_CJK: - self._charset_probers.append(SBCSGroupProber()) - self._charset_probers.append(Latin1Prober()) - for prober in self._charset_probers: - if prober.feed(byte_str) == ProbingState.FOUND_IT: - self.result = {'encoding': prober.charset_name, - 'confidence': prober.get_confidence(), - 'language': prober.language} - self.done = True - break - if self.WIN_BYTE_DETECTOR.search(byte_str): - self._has_win_bytes = True - - def close(self): - """ - Stop analyzing the current document and come up with a final - prediction. - - :returns: The ``result`` attribute, a ``dict`` with the keys - `encoding`, `confidence`, and `language`. - """ - # Don't bother with checks if we're already done - if self.done: - return self.result - self.done = True - - if not self._got_data: - self.logger.debug('no data received!') - - # Default to ASCII if it is all we've seen so far - elif self._input_state == InputState.PURE_ASCII: - self.result = {'encoding': 'ascii', - 'confidence': 1.0, - 'language': ''} - - # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD - elif self._input_state == InputState.HIGH_BYTE: - prober_confidence = None - max_prober_confidence = 0.0 - max_prober = None - for prober in self._charset_probers: - if not prober: - continue - prober_confidence = prober.get_confidence() - if prober_confidence > max_prober_confidence: - max_prober_confidence = prober_confidence - max_prober = prober - if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): - charset_name = max_prober.charset_name - lower_charset_name = max_prober.charset_name.lower() - confidence = max_prober.get_confidence() - # Use Windows encoding name instead of ISO-8859 if we saw any - # extra Windows-specific bytes - if lower_charset_name.startswith('iso-8859'): - if self._has_win_bytes: - charset_name = self.ISO_WIN_MAP.get(lower_charset_name, - charset_name) - self.result = {'encoding': charset_name, - 'confidence': confidence, - 'language': max_prober.language} - - # Log all prober confidences if none met MINIMUM_THRESHOLD - if self.logger.getEffectiveLevel() == logging.DEBUG: - if self.result['encoding'] is None: - self.logger.debug('no probers hit minimum threshold') - for group_prober in self._charset_probers: - if not group_prober: - continue - if isinstance(group_prober, CharSetGroupProber): - for prober in group_prober.probers: - self.logger.debug('%s %s confidence = %s', - prober.charset_name, - prober.language, - prober.get_confidence()) - else: - self.logger.debug('%s %s confidence = %s', - prober.charset_name, - prober.language, - prober.get_confidence()) - return self.result diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/utf8prober.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/utf8prober.py deleted file mode 100644 index 6c3196c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/utf8prober.py +++ /dev/null @@ -1,82 +0,0 @@ -######################## BEGIN LICENSE BLOCK ######################## -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Pilgrim - port to Python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA -######################### END LICENSE BLOCK ######################### - -from .charsetprober import CharSetProber -from .enums import ProbingState, MachineState -from .codingstatemachine import CodingStateMachine -from .mbcssm import UTF8_SM_MODEL - - - -class UTF8Prober(CharSetProber): - ONE_CHAR_PROB = 0.5 - - def __init__(self): - super(UTF8Prober, self).__init__() - self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) - self._num_mb_chars = None - self.reset() - - def reset(self): - super(UTF8Prober, self).reset() - self.coding_sm.reset() - self._num_mb_chars = 0 - - @property - def charset_name(self): - return "utf-8" - - @property - def language(self): - return "" - - def feed(self, byte_str): - for c in byte_str: - coding_state = self.coding_sm.next_state(c) - if coding_state == MachineState.ERROR: - self._state = ProbingState.NOT_ME - break - elif coding_state == MachineState.ITS_ME: - self._state = ProbingState.FOUND_IT - break - elif coding_state == MachineState.START: - if self.coding_sm.get_current_charlen() >= 2: - self._num_mb_chars += 1 - - if self.state == ProbingState.DETECTING: - if self.get_confidence() > self.SHORTCUT_THRESHOLD: - self._state = ProbingState.FOUND_IT - - return self.state - - def get_confidence(self): - unlike = 0.99 - if self._num_mb_chars < 6: - unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars - return 1.0 - unlike - else: - return unlike diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/version.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/version.py deleted file mode 100644 index bb2a34a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/chardet/version.py +++ /dev/null @@ -1,9 +0,0 @@ -""" -This module exists only to simplify retrieving the version number of chardet -from within setup.py and from chardet subpackages. - -:author: Dan Blanchard (dan.blanchard@gmail.com) -""" - -__version__ = "3.0.4" -VERSION = __version__.split('.') diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/__init__.py deleted file mode 100644 index 2a3bf47..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -from .initialise import init, deinit, reinit, colorama_text -from .ansi import Fore, Back, Style, Cursor -from .ansitowin32 import AnsiToWin32 - -__version__ = '0.4.1' diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/ansi.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/ansi.py deleted file mode 100644 index 7877658..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/ansi.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -''' -This module generates ANSI character codes to printing colors to terminals. -See: http://en.wikipedia.org/wiki/ANSI_escape_code -''' - -CSI = '\033[' -OSC = '\033]' -BEL = '\007' - - -def code_to_chars(code): - return CSI + str(code) + 'm' - -def set_title(title): - return OSC + '2;' + title + BEL - -def clear_screen(mode=2): - return CSI + str(mode) + 'J' - -def clear_line(mode=2): - return CSI + str(mode) + 'K' - - -class AnsiCodes(object): - def __init__(self): - # the subclasses declare class attributes which are numbers. - # Upon instantiation we define instance attributes, which are the same - # as the class attributes but wrapped with the ANSI escape sequence - for name in dir(self): - if not name.startswith('_'): - value = getattr(self, name) - setattr(self, name, code_to_chars(value)) - - -class AnsiCursor(object): - def UP(self, n=1): - return CSI + str(n) + 'A' - def DOWN(self, n=1): - return CSI + str(n) + 'B' - def FORWARD(self, n=1): - return CSI + str(n) + 'C' - def BACK(self, n=1): - return CSI + str(n) + 'D' - def POS(self, x=1, y=1): - return CSI + str(y) + ';' + str(x) + 'H' - - -class AnsiFore(AnsiCodes): - BLACK = 30 - RED = 31 - GREEN = 32 - YELLOW = 33 - BLUE = 34 - MAGENTA = 35 - CYAN = 36 - WHITE = 37 - RESET = 39 - - # These are fairly well supported, but not part of the standard. - LIGHTBLACK_EX = 90 - LIGHTRED_EX = 91 - LIGHTGREEN_EX = 92 - LIGHTYELLOW_EX = 93 - LIGHTBLUE_EX = 94 - LIGHTMAGENTA_EX = 95 - LIGHTCYAN_EX = 96 - LIGHTWHITE_EX = 97 - - -class AnsiBack(AnsiCodes): - BLACK = 40 - RED = 41 - GREEN = 42 - YELLOW = 43 - BLUE = 44 - MAGENTA = 45 - CYAN = 46 - WHITE = 47 - RESET = 49 - - # These are fairly well supported, but not part of the standard. - LIGHTBLACK_EX = 100 - LIGHTRED_EX = 101 - LIGHTGREEN_EX = 102 - LIGHTYELLOW_EX = 103 - LIGHTBLUE_EX = 104 - LIGHTMAGENTA_EX = 105 - LIGHTCYAN_EX = 106 - LIGHTWHITE_EX = 107 - - -class AnsiStyle(AnsiCodes): - BRIGHT = 1 - DIM = 2 - NORMAL = 22 - RESET_ALL = 0 - -Fore = AnsiFore() -Back = AnsiBack() -Style = AnsiStyle() -Cursor = AnsiCursor() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/ansitowin32.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/ansitowin32.py deleted file mode 100644 index 359c92b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/ansitowin32.py +++ /dev/null @@ -1,257 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -import re -import sys -import os - -from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style -from .winterm import WinTerm, WinColor, WinStyle -from .win32 import windll, winapi_test - - -winterm = None -if windll is not None: - winterm = WinTerm() - - -class StreamWrapper(object): - ''' - Wraps a stream (such as stdout), acting as a transparent proxy for all - attribute access apart from method 'write()', which is delegated to our - Converter instance. - ''' - def __init__(self, wrapped, converter): - # double-underscore everything to prevent clashes with names of - # attributes on the wrapped stream object. - self.__wrapped = wrapped - self.__convertor = converter - - def __getattr__(self, name): - return getattr(self.__wrapped, name) - - def __enter__(self, *args, **kwargs): - # special method lookup bypasses __getattr__/__getattribute__, see - # https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit - # thus, contextlib magic methods are not proxied via __getattr__ - return self.__wrapped.__enter__(*args, **kwargs) - - def __exit__(self, *args, **kwargs): - return self.__wrapped.__exit__(*args, **kwargs) - - def write(self, text): - self.__convertor.write(text) - - def isatty(self): - stream = self.__wrapped - if 'PYCHARM_HOSTED' in os.environ: - if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__): - return True - try: - stream_isatty = stream.isatty - except AttributeError: - return False - else: - return stream_isatty() - - @property - def closed(self): - stream = self.__wrapped - try: - return stream.closed - except AttributeError: - return True - - -class AnsiToWin32(object): - ''' - Implements a 'write()' method which, on Windows, will strip ANSI character - sequences from the text, and if outputting to a tty, will convert them into - win32 function calls. - ''' - ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer - ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command - - def __init__(self, wrapped, convert=None, strip=None, autoreset=False): - # The wrapped stream (normally sys.stdout or sys.stderr) - self.wrapped = wrapped - - # should we reset colors to defaults after every .write() - self.autoreset = autoreset - - # create the proxy wrapping our output stream - self.stream = StreamWrapper(wrapped, self) - - on_windows = os.name == 'nt' - # We test if the WinAPI works, because even if we are on Windows - # we may be using a terminal that doesn't support the WinAPI - # (e.g. Cygwin Terminal). In this case it's up to the terminal - # to support the ANSI codes. - conversion_supported = on_windows and winapi_test() - - # should we strip ANSI sequences from our output? - if strip is None: - strip = conversion_supported or (not self.stream.closed and not self.stream.isatty()) - self.strip = strip - - # should we should convert ANSI sequences into win32 calls? - if convert is None: - convert = conversion_supported and not self.stream.closed and self.stream.isatty() - self.convert = convert - - # dict of ansi codes to win32 functions and parameters - self.win32_calls = self.get_win32_calls() - - # are we wrapping stderr? - self.on_stderr = self.wrapped is sys.stderr - - def should_wrap(self): - ''' - True if this class is actually needed. If false, then the output - stream will not be affected, nor will win32 calls be issued, so - wrapping stdout is not actually required. This will generally be - False on non-Windows platforms, unless optional functionality like - autoreset has been requested using kwargs to init() - ''' - return self.convert or self.strip or self.autoreset - - def get_win32_calls(self): - if self.convert and winterm: - return { - AnsiStyle.RESET_ALL: (winterm.reset_all, ), - AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), - AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), - AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), - AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), - AnsiFore.RED: (winterm.fore, WinColor.RED), - AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), - AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), - AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), - AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), - AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), - AnsiFore.WHITE: (winterm.fore, WinColor.GREY), - AnsiFore.RESET: (winterm.fore, ), - AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), - AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), - AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), - AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), - AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), - AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), - AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), - AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), - AnsiBack.BLACK: (winterm.back, WinColor.BLACK), - AnsiBack.RED: (winterm.back, WinColor.RED), - AnsiBack.GREEN: (winterm.back, WinColor.GREEN), - AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), - AnsiBack.BLUE: (winterm.back, WinColor.BLUE), - AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), - AnsiBack.CYAN: (winterm.back, WinColor.CYAN), - AnsiBack.WHITE: (winterm.back, WinColor.GREY), - AnsiBack.RESET: (winterm.back, ), - AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), - AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), - AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), - AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), - AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), - AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), - AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), - AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), - } - return dict() - - def write(self, text): - if self.strip or self.convert: - self.write_and_convert(text) - else: - self.wrapped.write(text) - self.wrapped.flush() - if self.autoreset: - self.reset_all() - - - def reset_all(self): - if self.convert: - self.call_win32('m', (0,)) - elif not self.strip and not self.stream.closed: - self.wrapped.write(Style.RESET_ALL) - - - def write_and_convert(self, text): - ''' - Write the given text to our wrapped stream, stripping any ANSI - sequences from the text, and optionally converting them into win32 - calls. - ''' - cursor = 0 - text = self.convert_osc(text) - for match in self.ANSI_CSI_RE.finditer(text): - start, end = match.span() - self.write_plain_text(text, cursor, start) - self.convert_ansi(*match.groups()) - cursor = end - self.write_plain_text(text, cursor, len(text)) - - - def write_plain_text(self, text, start, end): - if start < end: - self.wrapped.write(text[start:end]) - self.wrapped.flush() - - - def convert_ansi(self, paramstring, command): - if self.convert: - params = self.extract_params(command, paramstring) - self.call_win32(command, params) - - - def extract_params(self, command, paramstring): - if command in 'Hf': - params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) - while len(params) < 2: - # defaults: - params = params + (1,) - else: - params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) - if len(params) == 0: - # defaults: - if command in 'JKm': - params = (0,) - elif command in 'ABCD': - params = (1,) - - return params - - - def call_win32(self, command, params): - if command == 'm': - for param in params: - if param in self.win32_calls: - func_args = self.win32_calls[param] - func = func_args[0] - args = func_args[1:] - kwargs = dict(on_stderr=self.on_stderr) - func(*args, **kwargs) - elif command in 'J': - winterm.erase_screen(params[0], on_stderr=self.on_stderr) - elif command in 'K': - winterm.erase_line(params[0], on_stderr=self.on_stderr) - elif command in 'Hf': # cursor position - absolute - winterm.set_cursor_position(params, on_stderr=self.on_stderr) - elif command in 'ABCD': # cursor position - relative - n = params[0] - # A - up, B - down, C - forward, D - back - x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] - winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) - - - def convert_osc(self, text): - for match in self.ANSI_OSC_RE.finditer(text): - start, end = match.span() - text = text[:start] + text[end:] - paramstring, command = match.groups() - if command in '\x07': # \x07 = BEL - params = paramstring.split(";") - # 0 - change title and icon (we will only change title) - # 1 - change icon (we don't support this) - # 2 - change title - if params[0] in '02': - winterm.set_title(params[1]) - return text diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/initialise.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/initialise.py deleted file mode 100644 index 430d066..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/initialise.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -import atexit -import contextlib -import sys - -from .ansitowin32 import AnsiToWin32 - - -orig_stdout = None -orig_stderr = None - -wrapped_stdout = None -wrapped_stderr = None - -atexit_done = False - - -def reset_all(): - if AnsiToWin32 is not None: # Issue #74: objects might become None at exit - AnsiToWin32(orig_stdout).reset_all() - - -def init(autoreset=False, convert=None, strip=None, wrap=True): - - if not wrap and any([autoreset, convert, strip]): - raise ValueError('wrap=False conflicts with any other arg=True') - - global wrapped_stdout, wrapped_stderr - global orig_stdout, orig_stderr - - orig_stdout = sys.stdout - orig_stderr = sys.stderr - - if sys.stdout is None: - wrapped_stdout = None - else: - sys.stdout = wrapped_stdout = \ - wrap_stream(orig_stdout, convert, strip, autoreset, wrap) - if sys.stderr is None: - wrapped_stderr = None - else: - sys.stderr = wrapped_stderr = \ - wrap_stream(orig_stderr, convert, strip, autoreset, wrap) - - global atexit_done - if not atexit_done: - atexit.register(reset_all) - atexit_done = True - - -def deinit(): - if orig_stdout is not None: - sys.stdout = orig_stdout - if orig_stderr is not None: - sys.stderr = orig_stderr - - -@contextlib.contextmanager -def colorama_text(*args, **kwargs): - init(*args, **kwargs) - try: - yield - finally: - deinit() - - -def reinit(): - if wrapped_stdout is not None: - sys.stdout = wrapped_stdout - if wrapped_stderr is not None: - sys.stderr = wrapped_stderr - - -def wrap_stream(stream, convert, strip, autoreset, wrap): - if wrap: - wrapper = AnsiToWin32(stream, - convert=convert, strip=strip, autoreset=autoreset) - if wrapper.should_wrap(): - stream = wrapper.stream - return stream diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/win32.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/win32.py deleted file mode 100644 index c2d8360..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/win32.py +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. - -# from winbase.h -STDOUT = -11 -STDERR = -12 - -try: - import ctypes - from ctypes import LibraryLoader - windll = LibraryLoader(ctypes.WinDLL) - from ctypes import wintypes -except (AttributeError, ImportError): - windll = None - SetConsoleTextAttribute = lambda *_: None - winapi_test = lambda *_: None -else: - from ctypes import byref, Structure, c_char, POINTER - - COORD = wintypes._COORD - - class CONSOLE_SCREEN_BUFFER_INFO(Structure): - """struct in wincon.h.""" - _fields_ = [ - ("dwSize", COORD), - ("dwCursorPosition", COORD), - ("wAttributes", wintypes.WORD), - ("srWindow", wintypes.SMALL_RECT), - ("dwMaximumWindowSize", COORD), - ] - def __str__(self): - return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( - self.dwSize.Y, self.dwSize.X - , self.dwCursorPosition.Y, self.dwCursorPosition.X - , self.wAttributes - , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right - , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X - ) - - _GetStdHandle = windll.kernel32.GetStdHandle - _GetStdHandle.argtypes = [ - wintypes.DWORD, - ] - _GetStdHandle.restype = wintypes.HANDLE - - _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo - _GetConsoleScreenBufferInfo.argtypes = [ - wintypes.HANDLE, - POINTER(CONSOLE_SCREEN_BUFFER_INFO), - ] - _GetConsoleScreenBufferInfo.restype = wintypes.BOOL - - _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute - _SetConsoleTextAttribute.argtypes = [ - wintypes.HANDLE, - wintypes.WORD, - ] - _SetConsoleTextAttribute.restype = wintypes.BOOL - - _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition - _SetConsoleCursorPosition.argtypes = [ - wintypes.HANDLE, - COORD, - ] - _SetConsoleCursorPosition.restype = wintypes.BOOL - - _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA - _FillConsoleOutputCharacterA.argtypes = [ - wintypes.HANDLE, - c_char, - wintypes.DWORD, - COORD, - POINTER(wintypes.DWORD), - ] - _FillConsoleOutputCharacterA.restype = wintypes.BOOL - - _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute - _FillConsoleOutputAttribute.argtypes = [ - wintypes.HANDLE, - wintypes.WORD, - wintypes.DWORD, - COORD, - POINTER(wintypes.DWORD), - ] - _FillConsoleOutputAttribute.restype = wintypes.BOOL - - _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW - _SetConsoleTitleW.argtypes = [ - wintypes.LPCWSTR - ] - _SetConsoleTitleW.restype = wintypes.BOOL - - def _winapi_test(handle): - csbi = CONSOLE_SCREEN_BUFFER_INFO() - success = _GetConsoleScreenBufferInfo( - handle, byref(csbi)) - return bool(success) - - def winapi_test(): - return any(_winapi_test(h) for h in - (_GetStdHandle(STDOUT), _GetStdHandle(STDERR))) - - def GetConsoleScreenBufferInfo(stream_id=STDOUT): - handle = _GetStdHandle(stream_id) - csbi = CONSOLE_SCREEN_BUFFER_INFO() - success = _GetConsoleScreenBufferInfo( - handle, byref(csbi)) - return csbi - - def SetConsoleTextAttribute(stream_id, attrs): - handle = _GetStdHandle(stream_id) - return _SetConsoleTextAttribute(handle, attrs) - - def SetConsoleCursorPosition(stream_id, position, adjust=True): - position = COORD(*position) - # If the position is out of range, do nothing. - if position.Y <= 0 or position.X <= 0: - return - # Adjust for Windows' SetConsoleCursorPosition: - # 1. being 0-based, while ANSI is 1-based. - # 2. expecting (x,y), while ANSI uses (y,x). - adjusted_position = COORD(position.Y - 1, position.X - 1) - if adjust: - # Adjust for viewport's scroll position - sr = GetConsoleScreenBufferInfo(STDOUT).srWindow - adjusted_position.Y += sr.Top - adjusted_position.X += sr.Left - # Resume normal processing - handle = _GetStdHandle(stream_id) - return _SetConsoleCursorPosition(handle, adjusted_position) - - def FillConsoleOutputCharacter(stream_id, char, length, start): - handle = _GetStdHandle(stream_id) - char = c_char(char.encode()) - length = wintypes.DWORD(length) - num_written = wintypes.DWORD(0) - # Note that this is hard-coded for ANSI (vs wide) bytes. - success = _FillConsoleOutputCharacterA( - handle, char, length, start, byref(num_written)) - return num_written.value - - def FillConsoleOutputAttribute(stream_id, attr, length, start): - ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' - handle = _GetStdHandle(stream_id) - attribute = wintypes.WORD(attr) - length = wintypes.DWORD(length) - num_written = wintypes.DWORD(0) - # Note that this is hard-coded for ANSI (vs wide) bytes. - return _FillConsoleOutputAttribute( - handle, attribute, length, start, byref(num_written)) - - def SetConsoleTitle(title): - return _SetConsoleTitleW(title) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/winterm.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/winterm.py deleted file mode 100644 index 0fdb4ec..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/colorama/winterm.py +++ /dev/null @@ -1,169 +0,0 @@ -# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. -from . import win32 - - -# from wincon.h -class WinColor(object): - BLACK = 0 - BLUE = 1 - GREEN = 2 - CYAN = 3 - RED = 4 - MAGENTA = 5 - YELLOW = 6 - GREY = 7 - -# from wincon.h -class WinStyle(object): - NORMAL = 0x00 # dim text, dim background - BRIGHT = 0x08 # bright text, dim background - BRIGHT_BACKGROUND = 0x80 # dim text, bright background - -class WinTerm(object): - - def __init__(self): - self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes - self.set_attrs(self._default) - self._default_fore = self._fore - self._default_back = self._back - self._default_style = self._style - # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. - # So that LIGHT_EX colors and BRIGHT style do not clobber each other, - # we track them separately, since LIGHT_EX is overwritten by Fore/Back - # and BRIGHT is overwritten by Style codes. - self._light = 0 - - def get_attrs(self): - return self._fore + self._back * 16 + (self._style | self._light) - - def set_attrs(self, value): - self._fore = value & 7 - self._back = (value >> 4) & 7 - self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) - - def reset_all(self, on_stderr=None): - self.set_attrs(self._default) - self.set_console(attrs=self._default) - self._light = 0 - - def fore(self, fore=None, light=False, on_stderr=False): - if fore is None: - fore = self._default_fore - self._fore = fore - # Emulate LIGHT_EX with BRIGHT Style - if light: - self._light |= WinStyle.BRIGHT - else: - self._light &= ~WinStyle.BRIGHT - self.set_console(on_stderr=on_stderr) - - def back(self, back=None, light=False, on_stderr=False): - if back is None: - back = self._default_back - self._back = back - # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style - if light: - self._light |= WinStyle.BRIGHT_BACKGROUND - else: - self._light &= ~WinStyle.BRIGHT_BACKGROUND - self.set_console(on_stderr=on_stderr) - - def style(self, style=None, on_stderr=False): - if style is None: - style = self._default_style - self._style = style - self.set_console(on_stderr=on_stderr) - - def set_console(self, attrs=None, on_stderr=False): - if attrs is None: - attrs = self.get_attrs() - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - win32.SetConsoleTextAttribute(handle, attrs) - - def get_position(self, handle): - position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition - # Because Windows coordinates are 0-based, - # and win32.SetConsoleCursorPosition expects 1-based. - position.X += 1 - position.Y += 1 - return position - - def set_cursor_position(self, position=None, on_stderr=False): - if position is None: - # I'm not currently tracking the position, so there is no default. - # position = self.get_position() - return - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - win32.SetConsoleCursorPosition(handle, position) - - def cursor_adjust(self, x, y, on_stderr=False): - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - position = self.get_position(handle) - adjusted_position = (position.Y + y, position.X + x) - win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) - - def erase_screen(self, mode=0, on_stderr=False): - # 0 should clear from the cursor to the end of the screen. - # 1 should clear from the cursor to the beginning of the screen. - # 2 should clear the entire screen, and move cursor to (1,1) - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - csbi = win32.GetConsoleScreenBufferInfo(handle) - # get the number of character cells in the current buffer - cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y - # get number of character cells before current cursor position - cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X - if mode == 0: - from_coord = csbi.dwCursorPosition - cells_to_erase = cells_in_screen - cells_before_cursor - elif mode == 1: - from_coord = win32.COORD(0, 0) - cells_to_erase = cells_before_cursor - elif mode == 2: - from_coord = win32.COORD(0, 0) - cells_to_erase = cells_in_screen - else: - # invalid mode - return - # fill the entire screen with blanks - win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) - # now set the buffer's attributes accordingly - win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) - if mode == 2: - # put the cursor where needed - win32.SetConsoleCursorPosition(handle, (1, 1)) - - def erase_line(self, mode=0, on_stderr=False): - # 0 should clear from the cursor to the end of the line. - # 1 should clear from the cursor to the beginning of the line. - # 2 should clear the entire line. - handle = win32.STDOUT - if on_stderr: - handle = win32.STDERR - csbi = win32.GetConsoleScreenBufferInfo(handle) - if mode == 0: - from_coord = csbi.dwCursorPosition - cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X - elif mode == 1: - from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) - cells_to_erase = csbi.dwCursorPosition.X - elif mode == 2: - from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) - cells_to_erase = csbi.dwSize.X - else: - # invalid mode - return - # fill the entire screen with blanks - win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) - # now set the buffer's attributes accordingly - win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) - - def set_title(self, title): - win32.SetConsoleTitle(title) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/__init__.py deleted file mode 100644 index a786b4d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2017 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -import logging - -__version__ = '0.2.8' - -class DistlibException(Exception): - pass - -try: - from logging import NullHandler -except ImportError: # pragma: no cover - class NullHandler(logging.Handler): - def handle(self, record): pass - def emit(self, record): pass - def createLock(self): self.lock = None - -logger = logging.getLogger(__name__) -logger.addHandler(NullHandler()) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/__init__.py deleted file mode 100644 index f7dbf4c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -"""Modules copied from Python 3 standard libraries, for internal use only. - -Individual classes and functions are found in d2._backport.misc. Intended -usage is to always import things missing from 3.1 from that module: the -built-in/stdlib objects will be used if found. -""" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/misc.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/misc.py deleted file mode 100644 index cfb318d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/misc.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012 The Python Software Foundation. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -"""Backports for individual classes and functions.""" - -import os -import sys - -__all__ = ['cache_from_source', 'callable', 'fsencode'] - - -try: - from imp import cache_from_source -except ImportError: - def cache_from_source(py_file, debug=__debug__): - ext = debug and 'c' or 'o' - return py_file + ext - - -try: - callable = callable -except NameError: - from collections import Callable - - def callable(obj): - return isinstance(obj, Callable) - - -try: - fsencode = os.fsencode -except AttributeError: - def fsencode(filename): - if isinstance(filename, bytes): - return filename - elif isinstance(filename, str): - return filename.encode(sys.getfilesystemencoding()) - else: - raise TypeError("expect bytes or str, not %s" % - type(filename).__name__) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/shutil.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/shutil.py deleted file mode 100644 index 159e49e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/shutil.py +++ /dev/null @@ -1,761 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012 The Python Software Foundation. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -"""Utility functions for copying and archiving files and directory trees. - -XXX The functions here don't copy the resource fork or other metadata on Mac. - -""" - -import os -import sys -import stat -from os.path import abspath -import fnmatch -import collections -import errno -from . import tarfile - -try: - import bz2 - _BZ2_SUPPORTED = True -except ImportError: - _BZ2_SUPPORTED = False - -try: - from pwd import getpwnam -except ImportError: - getpwnam = None - -try: - from grp import getgrnam -except ImportError: - getgrnam = None - -__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", - "copytree", "move", "rmtree", "Error", "SpecialFileError", - "ExecError", "make_archive", "get_archive_formats", - "register_archive_format", "unregister_archive_format", - "get_unpack_formats", "register_unpack_format", - "unregister_unpack_format", "unpack_archive", "ignore_patterns"] - -class Error(EnvironmentError): - pass - -class SpecialFileError(EnvironmentError): - """Raised when trying to do a kind of operation (e.g. copying) which is - not supported on a special file (e.g. a named pipe)""" - -class ExecError(EnvironmentError): - """Raised when a command could not be executed""" - -class ReadError(EnvironmentError): - """Raised when an archive cannot be read""" - -class RegistryError(Exception): - """Raised when a registry operation with the archiving - and unpacking registries fails""" - - -try: - WindowsError -except NameError: - WindowsError = None - -def copyfileobj(fsrc, fdst, length=16*1024): - """copy data from file-like object fsrc to file-like object fdst""" - while 1: - buf = fsrc.read(length) - if not buf: - break - fdst.write(buf) - -def _samefile(src, dst): - # Macintosh, Unix. - if hasattr(os.path, 'samefile'): - try: - return os.path.samefile(src, dst) - except OSError: - return False - - # All other platforms: check for same pathname. - return (os.path.normcase(os.path.abspath(src)) == - os.path.normcase(os.path.abspath(dst))) - -def copyfile(src, dst): - """Copy data from src to dst""" - if _samefile(src, dst): - raise Error("`%s` and `%s` are the same file" % (src, dst)) - - for fn in [src, dst]: - try: - st = os.stat(fn) - except OSError: - # File most likely does not exist - pass - else: - # XXX What about other special files? (sockets, devices...) - if stat.S_ISFIFO(st.st_mode): - raise SpecialFileError("`%s` is a named pipe" % fn) - - with open(src, 'rb') as fsrc: - with open(dst, 'wb') as fdst: - copyfileobj(fsrc, fdst) - -def copymode(src, dst): - """Copy mode bits from src to dst""" - if hasattr(os, 'chmod'): - st = os.stat(src) - mode = stat.S_IMODE(st.st_mode) - os.chmod(dst, mode) - -def copystat(src, dst): - """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" - st = os.stat(src) - mode = stat.S_IMODE(st.st_mode) - if hasattr(os, 'utime'): - os.utime(dst, (st.st_atime, st.st_mtime)) - if hasattr(os, 'chmod'): - os.chmod(dst, mode) - if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): - try: - os.chflags(dst, st.st_flags) - except OSError as why: - if (not hasattr(errno, 'EOPNOTSUPP') or - why.errno != errno.EOPNOTSUPP): - raise - -def copy(src, dst): - """Copy data and mode bits ("cp src dst"). - - The destination may be a directory. - - """ - if os.path.isdir(dst): - dst = os.path.join(dst, os.path.basename(src)) - copyfile(src, dst) - copymode(src, dst) - -def copy2(src, dst): - """Copy data and all stat info ("cp -p src dst"). - - The destination may be a directory. - - """ - if os.path.isdir(dst): - dst = os.path.join(dst, os.path.basename(src)) - copyfile(src, dst) - copystat(src, dst) - -def ignore_patterns(*patterns): - """Function that can be used as copytree() ignore parameter. - - Patterns is a sequence of glob-style patterns - that are used to exclude files""" - def _ignore_patterns(path, names): - ignored_names = [] - for pattern in patterns: - ignored_names.extend(fnmatch.filter(names, pattern)) - return set(ignored_names) - return _ignore_patterns - -def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, - ignore_dangling_symlinks=False): - """Recursively copy a directory tree. - - The destination directory must not already exist. - If exception(s) occur, an Error is raised with a list of reasons. - - If the optional symlinks flag is true, symbolic links in the - source tree result in symbolic links in the destination tree; if - it is false, the contents of the files pointed to by symbolic - links are copied. If the file pointed by the symlink doesn't - exist, an exception will be added in the list of errors raised in - an Error exception at the end of the copy process. - - You can set the optional ignore_dangling_symlinks flag to true if you - want to silence this exception. Notice that this has no effect on - platforms that don't support os.symlink. - - The optional ignore argument is a callable. If given, it - is called with the `src` parameter, which is the directory - being visited by copytree(), and `names` which is the list of - `src` contents, as returned by os.listdir(): - - callable(src, names) -> ignored_names - - Since copytree() is called recursively, the callable will be - called once for each directory that is copied. It returns a - list of names relative to the `src` directory that should - not be copied. - - The optional copy_function argument is a callable that will be used - to copy each file. It will be called with the source path and the - destination path as arguments. By default, copy2() is used, but any - function that supports the same signature (like copy()) can be used. - - """ - names = os.listdir(src) - if ignore is not None: - ignored_names = ignore(src, names) - else: - ignored_names = set() - - os.makedirs(dst) - errors = [] - for name in names: - if name in ignored_names: - continue - srcname = os.path.join(src, name) - dstname = os.path.join(dst, name) - try: - if os.path.islink(srcname): - linkto = os.readlink(srcname) - if symlinks: - os.symlink(linkto, dstname) - else: - # ignore dangling symlink if the flag is on - if not os.path.exists(linkto) and ignore_dangling_symlinks: - continue - # otherwise let the copy occurs. copy2 will raise an error - copy_function(srcname, dstname) - elif os.path.isdir(srcname): - copytree(srcname, dstname, symlinks, ignore, copy_function) - else: - # Will raise a SpecialFileError for unsupported file types - copy_function(srcname, dstname) - # catch the Error from the recursive copytree so that we can - # continue with other files - except Error as err: - errors.extend(err.args[0]) - except EnvironmentError as why: - errors.append((srcname, dstname, str(why))) - try: - copystat(src, dst) - except OSError as why: - if WindowsError is not None and isinstance(why, WindowsError): - # Copying file access times may fail on Windows - pass - else: - errors.extend((src, dst, str(why))) - if errors: - raise Error(errors) - -def rmtree(path, ignore_errors=False, onerror=None): - """Recursively delete a directory tree. - - If ignore_errors is set, errors are ignored; otherwise, if onerror - is set, it is called to handle the error with arguments (func, - path, exc_info) where func is os.listdir, os.remove, or os.rmdir; - path is the argument to that function that caused it to fail; and - exc_info is a tuple returned by sys.exc_info(). If ignore_errors - is false and onerror is None, an exception is raised. - - """ - if ignore_errors: - def onerror(*args): - pass - elif onerror is None: - def onerror(*args): - raise - try: - if os.path.islink(path): - # symlinks to directories are forbidden, see bug #1669 - raise OSError("Cannot call rmtree on a symbolic link") - except OSError: - onerror(os.path.islink, path, sys.exc_info()) - # can't continue even if onerror hook returns - return - names = [] - try: - names = os.listdir(path) - except os.error: - onerror(os.listdir, path, sys.exc_info()) - for name in names: - fullname = os.path.join(path, name) - try: - mode = os.lstat(fullname).st_mode - except os.error: - mode = 0 - if stat.S_ISDIR(mode): - rmtree(fullname, ignore_errors, onerror) - else: - try: - os.remove(fullname) - except os.error: - onerror(os.remove, fullname, sys.exc_info()) - try: - os.rmdir(path) - except os.error: - onerror(os.rmdir, path, sys.exc_info()) - - -def _basename(path): - # A basename() variant which first strips the trailing slash, if present. - # Thus we always get the last component of the path, even for directories. - return os.path.basename(path.rstrip(os.path.sep)) - -def move(src, dst): - """Recursively move a file or directory to another location. This is - similar to the Unix "mv" command. - - If the destination is a directory or a symlink to a directory, the source - is moved inside the directory. The destination path must not already - exist. - - If the destination already exists but is not a directory, it may be - overwritten depending on os.rename() semantics. - - If the destination is on our current filesystem, then rename() is used. - Otherwise, src is copied to the destination and then removed. - A lot more could be done here... A look at a mv.c shows a lot of - the issues this implementation glosses over. - - """ - real_dst = dst - if os.path.isdir(dst): - if _samefile(src, dst): - # We might be on a case insensitive filesystem, - # perform the rename anyway. - os.rename(src, dst) - return - - real_dst = os.path.join(dst, _basename(src)) - if os.path.exists(real_dst): - raise Error("Destination path '%s' already exists" % real_dst) - try: - os.rename(src, real_dst) - except OSError: - if os.path.isdir(src): - if _destinsrc(src, dst): - raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) - copytree(src, real_dst, symlinks=True) - rmtree(src) - else: - copy2(src, real_dst) - os.unlink(src) - -def _destinsrc(src, dst): - src = abspath(src) - dst = abspath(dst) - if not src.endswith(os.path.sep): - src += os.path.sep - if not dst.endswith(os.path.sep): - dst += os.path.sep - return dst.startswith(src) - -def _get_gid(name): - """Returns a gid, given a group name.""" - if getgrnam is None or name is None: - return None - try: - result = getgrnam(name) - except KeyError: - result = None - if result is not None: - return result[2] - return None - -def _get_uid(name): - """Returns an uid, given a user name.""" - if getpwnam is None or name is None: - return None - try: - result = getpwnam(name) - except KeyError: - result = None - if result is not None: - return result[2] - return None - -def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, - owner=None, group=None, logger=None): - """Create a (possibly compressed) tar file from all the files under - 'base_dir'. - - 'compress' must be "gzip" (the default), "bzip2", or None. - - 'owner' and 'group' can be used to define an owner and a group for the - archive that is being built. If not provided, the current owner and group - will be used. - - The output tar file will be named 'base_name' + ".tar", possibly plus - the appropriate compression extension (".gz", or ".bz2"). - - Returns the output filename. - """ - tar_compression = {'gzip': 'gz', None: ''} - compress_ext = {'gzip': '.gz'} - - if _BZ2_SUPPORTED: - tar_compression['bzip2'] = 'bz2' - compress_ext['bzip2'] = '.bz2' - - # flags for compression program, each element of list will be an argument - if compress is not None and compress not in compress_ext: - raise ValueError("bad value for 'compress', or compression format not " - "supported : {0}".format(compress)) - - archive_name = base_name + '.tar' + compress_ext.get(compress, '') - archive_dir = os.path.dirname(archive_name) - - if not os.path.exists(archive_dir): - if logger is not None: - logger.info("creating %s", archive_dir) - if not dry_run: - os.makedirs(archive_dir) - - # creating the tarball - if logger is not None: - logger.info('Creating tar archive') - - uid = _get_uid(owner) - gid = _get_gid(group) - - def _set_uid_gid(tarinfo): - if gid is not None: - tarinfo.gid = gid - tarinfo.gname = group - if uid is not None: - tarinfo.uid = uid - tarinfo.uname = owner - return tarinfo - - if not dry_run: - tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) - try: - tar.add(base_dir, filter=_set_uid_gid) - finally: - tar.close() - - return archive_name - -def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): - # XXX see if we want to keep an external call here - if verbose: - zipoptions = "-r" - else: - zipoptions = "-rq" - from distutils.errors import DistutilsExecError - from distutils.spawn import spawn - try: - spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) - except DistutilsExecError: - # XXX really should distinguish between "couldn't find - # external 'zip' command" and "zip failed". - raise ExecError("unable to create zip file '%s': " - "could neither import the 'zipfile' module nor " - "find a standalone zip utility") % zip_filename - -def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): - """Create a zip file from all the files under 'base_dir'. - - The output zip file will be named 'base_name' + ".zip". Uses either the - "zipfile" Python module (if available) or the InfoZIP "zip" utility - (if installed and found on the default search path). If neither tool is - available, raises ExecError. Returns the name of the output zip - file. - """ - zip_filename = base_name + ".zip" - archive_dir = os.path.dirname(base_name) - - if not os.path.exists(archive_dir): - if logger is not None: - logger.info("creating %s", archive_dir) - if not dry_run: - os.makedirs(archive_dir) - - # If zipfile module is not available, try spawning an external 'zip' - # command. - try: - import zipfile - except ImportError: - zipfile = None - - if zipfile is None: - _call_external_zip(base_dir, zip_filename, verbose, dry_run) - else: - if logger is not None: - logger.info("creating '%s' and adding '%s' to it", - zip_filename, base_dir) - - if not dry_run: - zip = zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_DEFLATED) - - for dirpath, dirnames, filenames in os.walk(base_dir): - for name in filenames: - path = os.path.normpath(os.path.join(dirpath, name)) - if os.path.isfile(path): - zip.write(path, path) - if logger is not None: - logger.info("adding '%s'", path) - zip.close() - - return zip_filename - -_ARCHIVE_FORMATS = { - 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), - 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), - 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), - 'zip': (_make_zipfile, [], "ZIP file"), - } - -if _BZ2_SUPPORTED: - _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], - "bzip2'ed tar-file") - -def get_archive_formats(): - """Returns a list of supported formats for archiving and unarchiving. - - Each element of the returned sequence is a tuple (name, description) - """ - formats = [(name, registry[2]) for name, registry in - _ARCHIVE_FORMATS.items()] - formats.sort() - return formats - -def register_archive_format(name, function, extra_args=None, description=''): - """Registers an archive format. - - name is the name of the format. function is the callable that will be - used to create archives. If provided, extra_args is a sequence of - (name, value) tuples that will be passed as arguments to the callable. - description can be provided to describe the format, and will be returned - by the get_archive_formats() function. - """ - if extra_args is None: - extra_args = [] - if not isinstance(function, collections.Callable): - raise TypeError('The %s object is not callable' % function) - if not isinstance(extra_args, (tuple, list)): - raise TypeError('extra_args needs to be a sequence') - for element in extra_args: - if not isinstance(element, (tuple, list)) or len(element) !=2: - raise TypeError('extra_args elements are : (arg_name, value)') - - _ARCHIVE_FORMATS[name] = (function, extra_args, description) - -def unregister_archive_format(name): - del _ARCHIVE_FORMATS[name] - -def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, - dry_run=0, owner=None, group=None, logger=None): - """Create an archive file (eg. zip or tar). - - 'base_name' is the name of the file to create, minus any format-specific - extension; 'format' is the archive format: one of "zip", "tar", "bztar" - or "gztar". - - 'root_dir' is a directory that will be the root directory of the - archive; ie. we typically chdir into 'root_dir' before creating the - archive. 'base_dir' is the directory where we start archiving from; - ie. 'base_dir' will be the common prefix of all files and - directories in the archive. 'root_dir' and 'base_dir' both default - to the current directory. Returns the name of the archive file. - - 'owner' and 'group' are used when creating a tar archive. By default, - uses the current owner and group. - """ - save_cwd = os.getcwd() - if root_dir is not None: - if logger is not None: - logger.debug("changing into '%s'", root_dir) - base_name = os.path.abspath(base_name) - if not dry_run: - os.chdir(root_dir) - - if base_dir is None: - base_dir = os.curdir - - kwargs = {'dry_run': dry_run, 'logger': logger} - - try: - format_info = _ARCHIVE_FORMATS[format] - except KeyError: - raise ValueError("unknown archive format '%s'" % format) - - func = format_info[0] - for arg, val in format_info[1]: - kwargs[arg] = val - - if format != 'zip': - kwargs['owner'] = owner - kwargs['group'] = group - - try: - filename = func(base_name, base_dir, **kwargs) - finally: - if root_dir is not None: - if logger is not None: - logger.debug("changing back to '%s'", save_cwd) - os.chdir(save_cwd) - - return filename - - -def get_unpack_formats(): - """Returns a list of supported formats for unpacking. - - Each element of the returned sequence is a tuple - (name, extensions, description) - """ - formats = [(name, info[0], info[3]) for name, info in - _UNPACK_FORMATS.items()] - formats.sort() - return formats - -def _check_unpack_options(extensions, function, extra_args): - """Checks what gets registered as an unpacker.""" - # first make sure no other unpacker is registered for this extension - existing_extensions = {} - for name, info in _UNPACK_FORMATS.items(): - for ext in info[0]: - existing_extensions[ext] = name - - for extension in extensions: - if extension in existing_extensions: - msg = '%s is already registered for "%s"' - raise RegistryError(msg % (extension, - existing_extensions[extension])) - - if not isinstance(function, collections.Callable): - raise TypeError('The registered function must be a callable') - - -def register_unpack_format(name, extensions, function, extra_args=None, - description=''): - """Registers an unpack format. - - `name` is the name of the format. `extensions` is a list of extensions - corresponding to the format. - - `function` is the callable that will be - used to unpack archives. The callable will receive archives to unpack. - If it's unable to handle an archive, it needs to raise a ReadError - exception. - - If provided, `extra_args` is a sequence of - (name, value) tuples that will be passed as arguments to the callable. - description can be provided to describe the format, and will be returned - by the get_unpack_formats() function. - """ - if extra_args is None: - extra_args = [] - _check_unpack_options(extensions, function, extra_args) - _UNPACK_FORMATS[name] = extensions, function, extra_args, description - -def unregister_unpack_format(name): - """Removes the pack format from the registry.""" - del _UNPACK_FORMATS[name] - -def _ensure_directory(path): - """Ensure that the parent directory of `path` exists""" - dirname = os.path.dirname(path) - if not os.path.isdir(dirname): - os.makedirs(dirname) - -def _unpack_zipfile(filename, extract_dir): - """Unpack zip `filename` to `extract_dir` - """ - try: - import zipfile - except ImportError: - raise ReadError('zlib not supported, cannot unpack this archive.') - - if not zipfile.is_zipfile(filename): - raise ReadError("%s is not a zip file" % filename) - - zip = zipfile.ZipFile(filename) - try: - for info in zip.infolist(): - name = info.filename - - # don't extract absolute paths or ones with .. in them - if name.startswith('/') or '..' in name: - continue - - target = os.path.join(extract_dir, *name.split('/')) - if not target: - continue - - _ensure_directory(target) - if not name.endswith('/'): - # file - data = zip.read(info.filename) - f = open(target, 'wb') - try: - f.write(data) - finally: - f.close() - del data - finally: - zip.close() - -def _unpack_tarfile(filename, extract_dir): - """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` - """ - try: - tarobj = tarfile.open(filename) - except tarfile.TarError: - raise ReadError( - "%s is not a compressed or uncompressed tar file" % filename) - try: - tarobj.extractall(extract_dir) - finally: - tarobj.close() - -_UNPACK_FORMATS = { - 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), - 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), - 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") - } - -if _BZ2_SUPPORTED: - _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], - "bzip2'ed tar-file") - -def _find_unpack_format(filename): - for name, info in _UNPACK_FORMATS.items(): - for extension in info[0]: - if filename.endswith(extension): - return name - return None - -def unpack_archive(filename, extract_dir=None, format=None): - """Unpack an archive. - - `filename` is the name of the archive. - - `extract_dir` is the name of the target directory, where the archive - is unpacked. If not provided, the current working directory is used. - - `format` is the archive format: one of "zip", "tar", or "gztar". Or any - other registered format. If not provided, unpack_archive will use the - filename extension and see if an unpacker was registered for that - extension. - - In case none is found, a ValueError is raised. - """ - if extract_dir is None: - extract_dir = os.getcwd() - - if format is not None: - try: - format_info = _UNPACK_FORMATS[format] - except KeyError: - raise ValueError("Unknown unpack format '{0}'".format(format)) - - func = format_info[1] - func(filename, extract_dir, **dict(format_info[2])) - else: - # we need to look at the registered unpackers supported extensions - format = _find_unpack_format(filename) - if format is None: - raise ReadError("Unknown archive format '{0}'".format(filename)) - - func = _UNPACK_FORMATS[format][1] - kwargs = dict(_UNPACK_FORMATS[format][2]) - func(filename, extract_dir, **kwargs) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/sysconfig.cfg b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/sysconfig.cfg deleted file mode 100644 index 1746bd0..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/sysconfig.cfg +++ /dev/null @@ -1,84 +0,0 @@ -[posix_prefix] -# Configuration directories. Some of these come straight out of the -# configure script. They are for implementing the other variables, not to -# be used directly in [resource_locations]. -confdir = /etc -datadir = /usr/share -libdir = /usr/lib -statedir = /var -# User resource directory -local = ~/.local/{distribution.name} - -stdlib = {base}/lib/python{py_version_short} -platstdlib = {platbase}/lib/python{py_version_short} -purelib = {base}/lib/python{py_version_short}/site-packages -platlib = {platbase}/lib/python{py_version_short}/site-packages -include = {base}/include/python{py_version_short}{abiflags} -platinclude = {platbase}/include/python{py_version_short}{abiflags} -data = {base} - -[posix_home] -stdlib = {base}/lib/python -platstdlib = {base}/lib/python -purelib = {base}/lib/python -platlib = {base}/lib/python -include = {base}/include/python -platinclude = {base}/include/python -scripts = {base}/bin -data = {base} - -[nt] -stdlib = {base}/Lib -platstdlib = {base}/Lib -purelib = {base}/Lib/site-packages -platlib = {base}/Lib/site-packages -include = {base}/Include -platinclude = {base}/Include -scripts = {base}/Scripts -data = {base} - -[os2] -stdlib = {base}/Lib -platstdlib = {base}/Lib -purelib = {base}/Lib/site-packages -platlib = {base}/Lib/site-packages -include = {base}/Include -platinclude = {base}/Include -scripts = {base}/Scripts -data = {base} - -[os2_home] -stdlib = {userbase}/lib/python{py_version_short} -platstdlib = {userbase}/lib/python{py_version_short} -purelib = {userbase}/lib/python{py_version_short}/site-packages -platlib = {userbase}/lib/python{py_version_short}/site-packages -include = {userbase}/include/python{py_version_short} -scripts = {userbase}/bin -data = {userbase} - -[nt_user] -stdlib = {userbase}/Python{py_version_nodot} -platstdlib = {userbase}/Python{py_version_nodot} -purelib = {userbase}/Python{py_version_nodot}/site-packages -platlib = {userbase}/Python{py_version_nodot}/site-packages -include = {userbase}/Python{py_version_nodot}/Include -scripts = {userbase}/Scripts -data = {userbase} - -[posix_user] -stdlib = {userbase}/lib/python{py_version_short} -platstdlib = {userbase}/lib/python{py_version_short} -purelib = {userbase}/lib/python{py_version_short}/site-packages -platlib = {userbase}/lib/python{py_version_short}/site-packages -include = {userbase}/include/python{py_version_short} -scripts = {userbase}/bin -data = {userbase} - -[osx_framework_user] -stdlib = {userbase}/lib/python -platstdlib = {userbase}/lib/python -purelib = {userbase}/lib/python/site-packages -platlib = {userbase}/lib/python/site-packages -include = {userbase}/include -scripts = {userbase}/bin -data = {userbase} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/sysconfig.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/sysconfig.py deleted file mode 100644 index 1df3aba..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/sysconfig.py +++ /dev/null @@ -1,788 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012 The Python Software Foundation. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -"""Access to Python's configuration information.""" - -import codecs -import os -import re -import sys -from os.path import pardir, realpath -try: - import configparser -except ImportError: - import ConfigParser as configparser - - -__all__ = [ - 'get_config_h_filename', - 'get_config_var', - 'get_config_vars', - 'get_makefile_filename', - 'get_path', - 'get_path_names', - 'get_paths', - 'get_platform', - 'get_python_version', - 'get_scheme_names', - 'parse_config_h', -] - - -def _safe_realpath(path): - try: - return realpath(path) - except OSError: - return path - - -if sys.executable: - _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) -else: - # sys.executable can be empty if argv[0] has been changed and Python is - # unable to retrieve the real program name - _PROJECT_BASE = _safe_realpath(os.getcwd()) - -if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): - _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) -# PC/VS7.1 -if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): - _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) -# PC/AMD64 -if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): - _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) - - -def is_python_build(): - for fn in ("Setup.dist", "Setup.local"): - if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): - return True - return False - -_PYTHON_BUILD = is_python_build() - -_cfg_read = False - -def _ensure_cfg_read(): - global _cfg_read - if not _cfg_read: - from ..resources import finder - backport_package = __name__.rsplit('.', 1)[0] - _finder = finder(backport_package) - _cfgfile = _finder.find('sysconfig.cfg') - assert _cfgfile, 'sysconfig.cfg exists' - with _cfgfile.as_stream() as s: - _SCHEMES.readfp(s) - if _PYTHON_BUILD: - for scheme in ('posix_prefix', 'posix_home'): - _SCHEMES.set(scheme, 'include', '{srcdir}/Include') - _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') - - _cfg_read = True - - -_SCHEMES = configparser.RawConfigParser() -_VAR_REPL = re.compile(r'\{([^{]*?)\}') - -def _expand_globals(config): - _ensure_cfg_read() - if config.has_section('globals'): - globals = config.items('globals') - else: - globals = tuple() - - sections = config.sections() - for section in sections: - if section == 'globals': - continue - for option, value in globals: - if config.has_option(section, option): - continue - config.set(section, option, value) - config.remove_section('globals') - - # now expanding local variables defined in the cfg file - # - for section in config.sections(): - variables = dict(config.items(section)) - - def _replacer(matchobj): - name = matchobj.group(1) - if name in variables: - return variables[name] - return matchobj.group(0) - - for option, value in config.items(section): - config.set(section, option, _VAR_REPL.sub(_replacer, value)) - -#_expand_globals(_SCHEMES) - - # FIXME don't rely on sys.version here, its format is an implementation detail - # of CPython, use sys.version_info or sys.hexversion -_PY_VERSION = sys.version.split()[0] -_PY_VERSION_SHORT = sys.version[:3] -_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] -_PREFIX = os.path.normpath(sys.prefix) -_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) -_CONFIG_VARS = None -_USER_BASE = None - - -def _subst_vars(path, local_vars): - """In the string `path`, replace tokens like {some.thing} with the - corresponding value from the map `local_vars`. - - If there is no corresponding value, leave the token unchanged. - """ - def _replacer(matchobj): - name = matchobj.group(1) - if name in local_vars: - return local_vars[name] - elif name in os.environ: - return os.environ[name] - return matchobj.group(0) - return _VAR_REPL.sub(_replacer, path) - - -def _extend_dict(target_dict, other_dict): - target_keys = target_dict.keys() - for key, value in other_dict.items(): - if key in target_keys: - continue - target_dict[key] = value - - -def _expand_vars(scheme, vars): - res = {} - if vars is None: - vars = {} - _extend_dict(vars, get_config_vars()) - - for key, value in _SCHEMES.items(scheme): - if os.name in ('posix', 'nt'): - value = os.path.expanduser(value) - res[key] = os.path.normpath(_subst_vars(value, vars)) - return res - - -def format_value(value, vars): - def _replacer(matchobj): - name = matchobj.group(1) - if name in vars: - return vars[name] - return matchobj.group(0) - return _VAR_REPL.sub(_replacer, value) - - -def _get_default_scheme(): - if os.name == 'posix': - # the default scheme for posix is posix_prefix - return 'posix_prefix' - return os.name - - -def _getuserbase(): - env_base = os.environ.get("PYTHONUSERBASE", None) - - def joinuser(*args): - return os.path.expanduser(os.path.join(*args)) - - # what about 'os2emx', 'riscos' ? - if os.name == "nt": - base = os.environ.get("APPDATA") or "~" - if env_base: - return env_base - else: - return joinuser(base, "Python") - - if sys.platform == "darwin": - framework = get_config_var("PYTHONFRAMEWORK") - if framework: - if env_base: - return env_base - else: - return joinuser("~", "Library", framework, "%d.%d" % - sys.version_info[:2]) - - if env_base: - return env_base - else: - return joinuser("~", ".local") - - -def _parse_makefile(filename, vars=None): - """Parse a Makefile-style file. - - A dictionary containing name/value pairs is returned. If an - optional dictionary is passed in as the second argument, it is - used instead of a new dictionary. - """ - # Regexes needed for parsing Makefile (and similar syntaxes, - # like old-style Setup files). - _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") - _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") - _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") - - if vars is None: - vars = {} - done = {} - notdone = {} - - with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: - lines = f.readlines() - - for line in lines: - if line.startswith('#') or line.strip() == '': - continue - m = _variable_rx.match(line) - if m: - n, v = m.group(1, 2) - v = v.strip() - # `$$' is a literal `$' in make - tmpv = v.replace('$$', '') - - if "$" in tmpv: - notdone[n] = v - else: - try: - v = int(v) - except ValueError: - # insert literal `$' - done[n] = v.replace('$$', '$') - else: - done[n] = v - - # do variable interpolation here - variables = list(notdone.keys()) - - # Variables with a 'PY_' prefix in the makefile. These need to - # be made available without that prefix through sysconfig. - # Special care is needed to ensure that variable expansion works, even - # if the expansion uses the name without a prefix. - renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') - - while len(variables) > 0: - for name in tuple(variables): - value = notdone[name] - m = _findvar1_rx.search(value) or _findvar2_rx.search(value) - if m is not None: - n = m.group(1) - found = True - if n in done: - item = str(done[n]) - elif n in notdone: - # get it on a subsequent round - found = False - elif n in os.environ: - # do it like make: fall back to environment - item = os.environ[n] - - elif n in renamed_variables: - if (name.startswith('PY_') and - name[3:] in renamed_variables): - item = "" - - elif 'PY_' + n in notdone: - found = False - - else: - item = str(done['PY_' + n]) - - else: - done[n] = item = "" - - if found: - after = value[m.end():] - value = value[:m.start()] + item + after - if "$" in after: - notdone[name] = value - else: - try: - value = int(value) - except ValueError: - done[name] = value.strip() - else: - done[name] = value - variables.remove(name) - - if (name.startswith('PY_') and - name[3:] in renamed_variables): - - name = name[3:] - if name not in done: - done[name] = value - - else: - # bogus variable reference (e.g. "prefix=$/opt/python"); - # just drop it since we can't deal - done[name] = value - variables.remove(name) - - # strip spurious spaces - for k, v in done.items(): - if isinstance(v, str): - done[k] = v.strip() - - # save the results in the global dictionary - vars.update(done) - return vars - - -def get_makefile_filename(): - """Return the path of the Makefile.""" - if _PYTHON_BUILD: - return os.path.join(_PROJECT_BASE, "Makefile") - if hasattr(sys, 'abiflags'): - config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) - else: - config_dir_name = 'config' - return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') - - -def _init_posix(vars): - """Initialize the module as appropriate for POSIX systems.""" - # load the installed Makefile: - makefile = get_makefile_filename() - try: - _parse_makefile(makefile, vars) - except IOError as e: - msg = "invalid Python installation: unable to open %s" % makefile - if hasattr(e, "strerror"): - msg = msg + " (%s)" % e.strerror - raise IOError(msg) - # load the installed pyconfig.h: - config_h = get_config_h_filename() - try: - with open(config_h) as f: - parse_config_h(f, vars) - except IOError as e: - msg = "invalid Python installation: unable to open %s" % config_h - if hasattr(e, "strerror"): - msg = msg + " (%s)" % e.strerror - raise IOError(msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile - # -- these paths are relative to the Python source, but when installed - # the scripts are in another directory. - if _PYTHON_BUILD: - vars['LDSHARED'] = vars['BLDSHARED'] - - -def _init_non_posix(vars): - """Initialize the module as appropriate for NT""" - # set basic install directories - vars['LIBDEST'] = get_path('stdlib') - vars['BINLIBDEST'] = get_path('platstdlib') - vars['INCLUDEPY'] = get_path('include') - vars['SO'] = '.pyd' - vars['EXE'] = '.exe' - vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT - vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) - -# -# public APIs -# - - -def parse_config_h(fp, vars=None): - """Parse a config.h-style file. - - A dictionary containing name/value pairs is returned. If an - optional dictionary is passed in as the second argument, it is - used instead of a new dictionary. - """ - if vars is None: - vars = {} - define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") - undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") - - while True: - line = fp.readline() - if not line: - break - m = define_rx.match(line) - if m: - n, v = m.group(1, 2) - try: - v = int(v) - except ValueError: - pass - vars[n] = v - else: - m = undef_rx.match(line) - if m: - vars[m.group(1)] = 0 - return vars - - -def get_config_h_filename(): - """Return the path of pyconfig.h.""" - if _PYTHON_BUILD: - if os.name == "nt": - inc_dir = os.path.join(_PROJECT_BASE, "PC") - else: - inc_dir = _PROJECT_BASE - else: - inc_dir = get_path('platinclude') - return os.path.join(inc_dir, 'pyconfig.h') - - -def get_scheme_names(): - """Return a tuple containing the schemes names.""" - return tuple(sorted(_SCHEMES.sections())) - - -def get_path_names(): - """Return a tuple containing the paths names.""" - # xxx see if we want a static list - return _SCHEMES.options('posix_prefix') - - -def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): - """Return a mapping containing an install scheme. - - ``scheme`` is the install scheme name. If not provided, it will - return the default scheme for the current platform. - """ - _ensure_cfg_read() - if expand: - return _expand_vars(scheme, vars) - else: - return dict(_SCHEMES.items(scheme)) - - -def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): - """Return a path corresponding to the scheme. - - ``scheme`` is the install scheme name. - """ - return get_paths(scheme, vars, expand)[name] - - -def get_config_vars(*args): - """With no arguments, return a dictionary of all configuration - variables relevant for the current platform. - - On Unix, this means every variable defined in Python's installed Makefile; - On Windows and Mac OS it's a much smaller set. - - With arguments, return a list of values that result from looking up - each argument in the configuration variable dictionary. - """ - global _CONFIG_VARS - if _CONFIG_VARS is None: - _CONFIG_VARS = {} - # Normalized versions of prefix and exec_prefix are handy to have; - # in fact, these are the standard versions used most places in the - # distutils2 module. - _CONFIG_VARS['prefix'] = _PREFIX - _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX - _CONFIG_VARS['py_version'] = _PY_VERSION - _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT - _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] - _CONFIG_VARS['base'] = _PREFIX - _CONFIG_VARS['platbase'] = _EXEC_PREFIX - _CONFIG_VARS['projectbase'] = _PROJECT_BASE - try: - _CONFIG_VARS['abiflags'] = sys.abiflags - except AttributeError: - # sys.abiflags may not be defined on all platforms. - _CONFIG_VARS['abiflags'] = '' - - if os.name in ('nt', 'os2'): - _init_non_posix(_CONFIG_VARS) - if os.name == 'posix': - _init_posix(_CONFIG_VARS) - # Setting 'userbase' is done below the call to the - # init function to enable using 'get_config_var' in - # the init-function. - if sys.version >= '2.6': - _CONFIG_VARS['userbase'] = _getuserbase() - - if 'srcdir' not in _CONFIG_VARS: - _CONFIG_VARS['srcdir'] = _PROJECT_BASE - else: - _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) - - # Convert srcdir into an absolute path if it appears necessary. - # Normally it is relative to the build directory. However, during - # testing, for example, we might be running a non-installed python - # from a different directory. - if _PYTHON_BUILD and os.name == "posix": - base = _PROJECT_BASE - try: - cwd = os.getcwd() - except OSError: - cwd = None - if (not os.path.isabs(_CONFIG_VARS['srcdir']) and - base != cwd): - # srcdir is relative and we are not in the same directory - # as the executable. Assume executable is in the build - # directory and make srcdir absolute. - srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) - _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) - - if sys.platform == 'darwin': - kernel_version = os.uname()[2] # Kernel version (8.4.3) - major_version = int(kernel_version.split('.')[0]) - - if major_version < 8: - # On Mac OS X before 10.4, check if -arch and -isysroot - # are in CFLAGS or LDFLAGS and remove them if they are. - # This is needed when building extensions on a 10.3 system - # using a universal build of python. - for key in ('LDFLAGS', 'BASECFLAGS', - # a number of derived variables. These need to be - # patched up as well. - 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): - flags = _CONFIG_VARS[key] - flags = re.sub(r'-arch\s+\w+\s', ' ', flags) - flags = re.sub('-isysroot [^ \t]*', ' ', flags) - _CONFIG_VARS[key] = flags - else: - # Allow the user to override the architecture flags using - # an environment variable. - # NOTE: This name was introduced by Apple in OSX 10.5 and - # is used by several scripting languages distributed with - # that OS release. - if 'ARCHFLAGS' in os.environ: - arch = os.environ['ARCHFLAGS'] - for key in ('LDFLAGS', 'BASECFLAGS', - # a number of derived variables. These need to be - # patched up as well. - 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): - - flags = _CONFIG_VARS[key] - flags = re.sub(r'-arch\s+\w+\s', ' ', flags) - flags = flags + ' ' + arch - _CONFIG_VARS[key] = flags - - # If we're on OSX 10.5 or later and the user tries to - # compiles an extension using an SDK that is not present - # on the current machine it is better to not use an SDK - # than to fail. - # - # The major usecase for this is users using a Python.org - # binary installer on OSX 10.6: that installer uses - # the 10.4u SDK, but that SDK is not installed by default - # when you install Xcode. - # - CFLAGS = _CONFIG_VARS.get('CFLAGS', '') - m = re.search(r'-isysroot\s+(\S+)', CFLAGS) - if m is not None: - sdk = m.group(1) - if not os.path.exists(sdk): - for key in ('LDFLAGS', 'BASECFLAGS', - # a number of derived variables. These need to be - # patched up as well. - 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): - - flags = _CONFIG_VARS[key] - flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) - _CONFIG_VARS[key] = flags - - if args: - vals = [] - for name in args: - vals.append(_CONFIG_VARS.get(name)) - return vals - else: - return _CONFIG_VARS - - -def get_config_var(name): - """Return the value of a single variable using the dictionary returned by - 'get_config_vars()'. - - Equivalent to get_config_vars().get(name) - """ - return get_config_vars().get(name) - - -def get_platform(): - """Return a string that identifies the current platform. - - This is used mainly to distinguish platform-specific build directories and - platform-specific built distributions. Typically includes the OS name - and version and the architecture (as supplied by 'os.uname()'), - although the exact information included depends on the OS; eg. for IRIX - the architecture isn't particularly important (IRIX only runs on SGI - hardware), but for Linux the kernel version isn't particularly - important. - - Examples of returned values: - linux-i586 - linux-alpha (?) - solaris-2.6-sun4u - irix-5.3 - irix64-6.2 - - Windows will return one of: - win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) - win-ia64 (64bit Windows on Itanium) - win32 (all others - specifically, sys.platform is returned) - - For other non-POSIX platforms, currently just returns 'sys.platform'. - """ - if os.name == 'nt': - # sniff sys.version for architecture. - prefix = " bit (" - i = sys.version.find(prefix) - if i == -1: - return sys.platform - j = sys.version.find(")", i) - look = sys.version[i+len(prefix):j].lower() - if look == 'amd64': - return 'win-amd64' - if look == 'itanium': - return 'win-ia64' - return sys.platform - - if os.name != "posix" or not hasattr(os, 'uname'): - # XXX what about the architecture? NT is Intel or Alpha, - # Mac OS is M68k or PPC, etc. - return sys.platform - - # Try to distinguish various flavours of Unix - osname, host, release, version, machine = os.uname() - - # Convert the OS name to lowercase, remove '/' characters - # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") - osname = osname.lower().replace('/', '') - machine = machine.replace(' ', '_') - machine = machine.replace('/', '-') - - if osname[:5] == "linux": - # At least on Linux/Intel, 'machine' is the processor -- - # i386, etc. - # XXX what about Alpha, SPARC, etc? - return "%s-%s" % (osname, machine) - elif osname[:5] == "sunos": - if release[0] >= "5": # SunOS 5 == Solaris 2 - osname = "solaris" - release = "%d.%s" % (int(release[0]) - 3, release[2:]) - # fall through to standard osname-release-machine representation - elif osname[:4] == "irix": # could be "irix64"! - return "%s-%s" % (osname, release) - elif osname[:3] == "aix": - return "%s-%s.%s" % (osname, version, release) - elif osname[:6] == "cygwin": - osname = "cygwin" - rel_re = re.compile(r'[\d.]+') - m = rel_re.match(release) - if m: - release = m.group() - elif osname[:6] == "darwin": - # - # For our purposes, we'll assume that the system version from - # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set - # to. This makes the compatibility story a bit more sane because the - # machine is going to compile and link as if it were - # MACOSX_DEPLOYMENT_TARGET. - cfgvars = get_config_vars() - macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') - - if True: - # Always calculate the release of the running machine, - # needed to determine if we can build fat binaries or not. - - macrelease = macver - # Get the system version. Reading this plist is a documented - # way to get the system version (see the documentation for - # the Gestalt Manager) - try: - f = open('/System/Library/CoreServices/SystemVersion.plist') - except IOError: - # We're on a plain darwin box, fall back to the default - # behaviour. - pass - else: - try: - m = re.search(r'<key>ProductUserVisibleVersion</key>\s*' - r'<string>(.*?)</string>', f.read()) - finally: - f.close() - if m is not None: - macrelease = '.'.join(m.group(1).split('.')[:2]) - # else: fall back to the default behaviour - - if not macver: - macver = macrelease - - if macver: - release = macver - osname = "macosx" - - if ((macrelease + '.') >= '10.4.' and - '-arch' in get_config_vars().get('CFLAGS', '').strip()): - # The universal build will build fat binaries, but not on - # systems before 10.4 - # - # Try to detect 4-way universal builds, those have machine-type - # 'universal' instead of 'fat'. - - machine = 'fat' - cflags = get_config_vars().get('CFLAGS') - - archs = re.findall(r'-arch\s+(\S+)', cflags) - archs = tuple(sorted(set(archs))) - - if len(archs) == 1: - machine = archs[0] - elif archs == ('i386', 'ppc'): - machine = 'fat' - elif archs == ('i386', 'x86_64'): - machine = 'intel' - elif archs == ('i386', 'ppc', 'x86_64'): - machine = 'fat3' - elif archs == ('ppc64', 'x86_64'): - machine = 'fat64' - elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): - machine = 'universal' - else: - raise ValueError( - "Don't know machine value for archs=%r" % (archs,)) - - elif machine == 'i386': - # On OSX the machine type returned by uname is always the - # 32-bit variant, even if the executable architecture is - # the 64-bit variant - if sys.maxsize >= 2**32: - machine = 'x86_64' - - elif machine in ('PowerPC', 'Power_Macintosh'): - # Pick a sane name for the PPC architecture. - # See 'i386' case - if sys.maxsize >= 2**32: - machine = 'ppc64' - else: - machine = 'ppc' - - return "%s-%s-%s" % (osname, release, machine) - - -def get_python_version(): - return _PY_VERSION_SHORT - - -def _print_dict(title, data): - for index, (key, value) in enumerate(sorted(data.items())): - if index == 0: - print('%s: ' % (title)) - print('\t%s = "%s"' % (key, value)) - - -def _main(): - """Display all information sysconfig detains.""" - print('Platform: "%s"' % get_platform()) - print('Python version: "%s"' % get_python_version()) - print('Current installation scheme: "%s"' % _get_default_scheme()) - print() - _print_dict('Paths', get_paths()) - print() - _print_dict('Variables', get_config_vars()) - - -if __name__ == '__main__': - _main() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/tarfile.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/tarfile.py deleted file mode 100644 index d66d856..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/_backport/tarfile.py +++ /dev/null @@ -1,2607 +0,0 @@ -#------------------------------------------------------------------- -# tarfile.py -#------------------------------------------------------------------- -# Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de> -# 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. -# -from __future__ import print_function - -"""Read from and write to tar format archives. -""" - -__version__ = "$Revision$" - -version = "0.9.0" -__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" -__date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $" -__cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $" -__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." - -#--------- -# Imports -#--------- -import sys -import os -import stat -import errno -import time -import struct -import copy -import re - -try: - import grp, pwd -except ImportError: - grp = pwd = None - -# os.symlink on Windows prior to 6.0 raises NotImplementedError -symlink_exception = (AttributeError, NotImplementedError) -try: - # WindowsError (1314) will be raised if the caller does not hold the - # SeCreateSymbolicLinkPrivilege privilege - symlink_exception += (WindowsError,) -except NameError: - pass - -# from tarfile import * -__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] - -if sys.version_info[0] < 3: - import __builtin__ as builtins -else: - import builtins - -_open = builtins.open # Since 'open' is TarFile.open - -#--------------------------------------------------------- -# tar constants -#--------------------------------------------------------- -NUL = b"\0" # the null character -BLOCKSIZE = 512 # length of processing blocks -RECORDSIZE = BLOCKSIZE * 20 # length of records -GNU_MAGIC = b"ustar \0" # magic gnu tar string -POSIX_MAGIC = b"ustar\x0000" # magic posix tar string - -LENGTH_NAME = 100 # maximum length of a filename -LENGTH_LINK = 100 # maximum length of a linkname -LENGTH_PREFIX = 155 # maximum length of the prefix field - -REGTYPE = b"0" # regular file -AREGTYPE = b"\0" # regular file -LNKTYPE = b"1" # link (inside tarfile) -SYMTYPE = b"2" # symbolic link -CHRTYPE = b"3" # character special device -BLKTYPE = b"4" # block special device -DIRTYPE = b"5" # directory -FIFOTYPE = b"6" # fifo special device -CONTTYPE = b"7" # contiguous file - -GNUTYPE_LONGNAME = b"L" # GNU tar longname -GNUTYPE_LONGLINK = b"K" # GNU tar longlink -GNUTYPE_SPARSE = b"S" # GNU tar sparse file - -XHDTYPE = b"x" # POSIX.1-2001 extended header -XGLTYPE = b"g" # POSIX.1-2001 global header -SOLARIS_XHDTYPE = b"X" # Solaris extended header - -USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format -GNU_FORMAT = 1 # GNU tar format -PAX_FORMAT = 2 # POSIX.1-2001 (pax) format -DEFAULT_FORMAT = GNU_FORMAT - -#--------------------------------------------------------- -# tarfile constants -#--------------------------------------------------------- -# File types that tarfile supports: -SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, - SYMTYPE, DIRTYPE, FIFOTYPE, - CONTTYPE, CHRTYPE, BLKTYPE, - GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, - GNUTYPE_SPARSE) - -# File types that will be treated as a regular file. -REGULAR_TYPES = (REGTYPE, AREGTYPE, - CONTTYPE, GNUTYPE_SPARSE) - -# File types that are part of the GNU tar format. -GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, - GNUTYPE_SPARSE) - -# Fields from a pax header that override a TarInfo attribute. -PAX_FIELDS = ("path", "linkpath", "size", "mtime", - "uid", "gid", "uname", "gname") - -# Fields from a pax header that are affected by hdrcharset. -PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname")) - -# Fields in a pax header that are numbers, all other fields -# are treated as strings. -PAX_NUMBER_FIELDS = { - "atime": float, - "ctime": float, - "mtime": float, - "uid": int, - "gid": int, - "size": int -} - -#--------------------------------------------------------- -# Bits used in the mode field, values in octal. -#--------------------------------------------------------- -S_IFLNK = 0o120000 # symbolic link -S_IFREG = 0o100000 # regular file -S_IFBLK = 0o060000 # block device -S_IFDIR = 0o040000 # directory -S_IFCHR = 0o020000 # character device -S_IFIFO = 0o010000 # fifo - -TSUID = 0o4000 # set UID on execution -TSGID = 0o2000 # set GID on execution -TSVTX = 0o1000 # reserved - -TUREAD = 0o400 # read by owner -TUWRITE = 0o200 # write by owner -TUEXEC = 0o100 # execute/search by owner -TGREAD = 0o040 # read by group -TGWRITE = 0o020 # write by group -TGEXEC = 0o010 # execute/search by group -TOREAD = 0o004 # read by other -TOWRITE = 0o002 # write by other -TOEXEC = 0o001 # execute/search by other - -#--------------------------------------------------------- -# initialization -#--------------------------------------------------------- -if os.name in ("nt", "ce"): - ENCODING = "utf-8" -else: - ENCODING = sys.getfilesystemencoding() - -#--------------------------------------------------------- -# Some useful functions -#--------------------------------------------------------- - -def stn(s, length, encoding, errors): - """Convert a string to a null-terminated bytes object. - """ - s = s.encode(encoding, errors) - return s[:length] + (length - len(s)) * NUL - -def nts(s, encoding, errors): - """Convert a null-terminated bytes object to a string. - """ - p = s.find(b"\0") - if p != -1: - s = s[:p] - return s.decode(encoding, errors) - -def nti(s): - """Convert a number field to a python number. - """ - # There are two possible encodings for a number field, see - # itn() below. - if s[0] != chr(0o200): - try: - n = int(nts(s, "ascii", "strict") or "0", 8) - except ValueError: - raise InvalidHeaderError("invalid header") - else: - n = 0 - for i in range(len(s) - 1): - n <<= 8 - n += ord(s[i + 1]) - return n - -def itn(n, digits=8, format=DEFAULT_FORMAT): - """Convert a python number to a number field. - """ - # POSIX 1003.1-1988 requires numbers to be encoded as a string of - # octal digits followed by a null-byte, this allows values up to - # (8**(digits-1))-1. GNU tar allows storing numbers greater than - # that if necessary. A leading 0o200 byte indicates this particular - # encoding, the following digits-1 bytes are a big-endian - # representation. This allows values up to (256**(digits-1))-1. - if 0 <= n < 8 ** (digits - 1): - s = ("%0*o" % (digits - 1, n)).encode("ascii") + NUL - else: - if format != GNU_FORMAT or n >= 256 ** (digits - 1): - raise ValueError("overflow in number field") - - if n < 0: - # XXX We mimic GNU tar's behaviour with negative numbers, - # this could raise OverflowError. - n = struct.unpack("L", struct.pack("l", n))[0] - - s = bytearray() - for i in range(digits - 1): - s.insert(0, n & 0o377) - n >>= 8 - s.insert(0, 0o200) - return s - -def calc_chksums(buf): - """Calculate the checksum for a member's header by summing up all - characters except for the chksum field which is treated as if - it was filled with spaces. According to the GNU tar sources, - some tars (Sun and NeXT) calculate chksum with signed char, - which will be different if there are chars in the buffer with - the high bit set. So we calculate two checksums, unsigned and - signed. - """ - unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) - signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) - return unsigned_chksum, signed_chksum - -def copyfileobj(src, dst, length=None): - """Copy length bytes from fileobj src to fileobj dst. - If length is None, copy the entire content. - """ - if length == 0: - return - if length is None: - while True: - buf = src.read(16*1024) - if not buf: - break - dst.write(buf) - return - - BUFSIZE = 16 * 1024 - blocks, remainder = divmod(length, BUFSIZE) - for b in range(blocks): - buf = src.read(BUFSIZE) - if len(buf) < BUFSIZE: - raise IOError("end of file reached") - dst.write(buf) - - if remainder != 0: - buf = src.read(remainder) - if len(buf) < remainder: - raise IOError("end of file reached") - dst.write(buf) - return - -filemode_table = ( - ((S_IFLNK, "l"), - (S_IFREG, "-"), - (S_IFBLK, "b"), - (S_IFDIR, "d"), - (S_IFCHR, "c"), - (S_IFIFO, "p")), - - ((TUREAD, "r"),), - ((TUWRITE, "w"),), - ((TUEXEC|TSUID, "s"), - (TSUID, "S"), - (TUEXEC, "x")), - - ((TGREAD, "r"),), - ((TGWRITE, "w"),), - ((TGEXEC|TSGID, "s"), - (TSGID, "S"), - (TGEXEC, "x")), - - ((TOREAD, "r"),), - ((TOWRITE, "w"),), - ((TOEXEC|TSVTX, "t"), - (TSVTX, "T"), - (TOEXEC, "x")) -) - -def filemode(mode): - """Convert a file's mode to a string of the form - -rwxrwxrwx. - Used by TarFile.list() - """ - perm = [] - for table in filemode_table: - for bit, char in table: - if mode & bit == bit: - perm.append(char) - break - else: - perm.append("-") - return "".join(perm) - -class TarError(Exception): - """Base exception.""" - pass -class ExtractError(TarError): - """General exception for extract errors.""" - pass -class ReadError(TarError): - """Exception for unreadable tar archives.""" - pass -class CompressionError(TarError): - """Exception for unavailable compression methods.""" - pass -class StreamError(TarError): - """Exception for unsupported operations on stream-like TarFiles.""" - pass -class HeaderError(TarError): - """Base exception for header errors.""" - pass -class EmptyHeaderError(HeaderError): - """Exception for empty headers.""" - pass -class TruncatedHeaderError(HeaderError): - """Exception for truncated headers.""" - pass -class EOFHeaderError(HeaderError): - """Exception for end of file headers.""" - pass -class InvalidHeaderError(HeaderError): - """Exception for invalid headers.""" - pass -class SubsequentHeaderError(HeaderError): - """Exception for missing and invalid extended headers.""" - pass - -#--------------------------- -# internal stream interface -#--------------------------- -class _LowLevelFile(object): - """Low-level file object. Supports reading and writing. - It is used instead of a regular file object for streaming - access. - """ - - def __init__(self, name, mode): - mode = { - "r": os.O_RDONLY, - "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, - }[mode] - if hasattr(os, "O_BINARY"): - mode |= os.O_BINARY - self.fd = os.open(name, mode, 0o666) - - def close(self): - os.close(self.fd) - - def read(self, size): - return os.read(self.fd, size) - - def write(self, s): - os.write(self.fd, s) - -class _Stream(object): - """Class that serves as an adapter between TarFile and - a stream-like object. The stream-like object only - needs to have a read() or write() method and is accessed - blockwise. Use of gzip or bzip2 compression is possible. - A stream-like object could be for example: sys.stdin, - sys.stdout, a socket, a tape device etc. - - _Stream is intended to be used only internally. - """ - - def __init__(self, name, mode, comptype, fileobj, bufsize): - """Construct a _Stream object. - """ - self._extfileobj = True - if fileobj is None: - fileobj = _LowLevelFile(name, mode) - self._extfileobj = False - - if comptype == '*': - # Enable transparent compression detection for the - # stream interface - fileobj = _StreamProxy(fileobj) - comptype = fileobj.getcomptype() - - self.name = name or "" - self.mode = mode - self.comptype = comptype - self.fileobj = fileobj - self.bufsize = bufsize - self.buf = b"" - self.pos = 0 - self.closed = False - - try: - if comptype == "gz": - try: - import zlib - except ImportError: - raise CompressionError("zlib module is not available") - self.zlib = zlib - self.crc = zlib.crc32(b"") - if mode == "r": - self._init_read_gz() - else: - self._init_write_gz() - - if comptype == "bz2": - try: - import bz2 - except ImportError: - raise CompressionError("bz2 module is not available") - if mode == "r": - self.dbuf = b"" - self.cmp = bz2.BZ2Decompressor() - else: - self.cmp = bz2.BZ2Compressor() - except: - if not self._extfileobj: - self.fileobj.close() - self.closed = True - raise - - def __del__(self): - if hasattr(self, "closed") and not self.closed: - self.close() - - def _init_write_gz(self): - """Initialize for writing with gzip compression. - """ - self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, - -self.zlib.MAX_WBITS, - self.zlib.DEF_MEM_LEVEL, - 0) - timestamp = struct.pack("<L", int(time.time())) - self.__write(b"\037\213\010\010" + timestamp + b"\002\377") - if self.name.endswith(".gz"): - self.name = self.name[:-3] - # RFC1952 says we must use ISO-8859-1 for the FNAME field. - self.__write(self.name.encode("iso-8859-1", "replace") + NUL) - - def write(self, s): - """Write string s to the stream. - """ - if self.comptype == "gz": - self.crc = self.zlib.crc32(s, self.crc) - self.pos += len(s) - if self.comptype != "tar": - s = self.cmp.compress(s) - self.__write(s) - - def __write(self, s): - """Write string s to the stream if a whole new block - is ready to be written. - """ - self.buf += s - while len(self.buf) > self.bufsize: - self.fileobj.write(self.buf[:self.bufsize]) - self.buf = self.buf[self.bufsize:] - - def close(self): - """Close the _Stream object. No operation should be - done on it afterwards. - """ - if self.closed: - return - - if self.mode == "w" and self.comptype != "tar": - self.buf += self.cmp.flush() - - if self.mode == "w" and self.buf: - self.fileobj.write(self.buf) - self.buf = b"" - if self.comptype == "gz": - # The native zlib crc is an unsigned 32-bit integer, but - # the Python wrapper implicitly casts that to a signed C - # long. So, on a 32-bit box self.crc may "look negative", - # while the same crc on a 64-bit box may "look positive". - # To avoid irksome warnings from the `struct` module, force - # it to look positive on all boxes. - self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff)) - self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF)) - - if not self._extfileobj: - self.fileobj.close() - - self.closed = True - - def _init_read_gz(self): - """Initialize for reading a gzip compressed fileobj. - """ - self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS) - self.dbuf = b"" - - # taken from gzip.GzipFile with some alterations - if self.__read(2) != b"\037\213": - raise ReadError("not a gzip file") - if self.__read(1) != b"\010": - raise CompressionError("unsupported compression method") - - flag = ord(self.__read(1)) - self.__read(6) - - if flag & 4: - xlen = ord(self.__read(1)) + 256 * ord(self.__read(1)) - self.read(xlen) - if flag & 8: - while True: - s = self.__read(1) - if not s or s == NUL: - break - if flag & 16: - while True: - s = self.__read(1) - if not s or s == NUL: - break - if flag & 2: - self.__read(2) - - def tell(self): - """Return the stream's file pointer position. - """ - return self.pos - - def seek(self, pos=0): - """Set the stream's file pointer to pos. Negative seeking - is forbidden. - """ - if pos - self.pos >= 0: - blocks, remainder = divmod(pos - self.pos, self.bufsize) - for i in range(blocks): - self.read(self.bufsize) - self.read(remainder) - else: - raise StreamError("seeking backwards is not allowed") - return self.pos - - def read(self, size=None): - """Return the next size number of bytes from the stream. - If size is not defined, return all bytes of the stream - up to EOF. - """ - if size is None: - t = [] - while True: - buf = self._read(self.bufsize) - if not buf: - break - t.append(buf) - buf = "".join(t) - else: - buf = self._read(size) - self.pos += len(buf) - return buf - - def _read(self, size): - """Return size bytes from the stream. - """ - if self.comptype == "tar": - return self.__read(size) - - c = len(self.dbuf) - while c < size: - buf = self.__read(self.bufsize) - if not buf: - break - try: - buf = self.cmp.decompress(buf) - except IOError: - raise ReadError("invalid compressed data") - self.dbuf += buf - c += len(buf) - buf = self.dbuf[:size] - self.dbuf = self.dbuf[size:] - return buf - - def __read(self, size): - """Return size bytes from stream. If internal buffer is empty, - read another block from the stream. - """ - c = len(self.buf) - while c < size: - buf = self.fileobj.read(self.bufsize) - if not buf: - break - self.buf += buf - c += len(buf) - buf = self.buf[:size] - self.buf = self.buf[size:] - return buf -# class _Stream - -class _StreamProxy(object): - """Small proxy class that enables transparent compression - detection for the Stream interface (mode 'r|*'). - """ - - def __init__(self, fileobj): - self.fileobj = fileobj - self.buf = self.fileobj.read(BLOCKSIZE) - - def read(self, size): - self.read = self.fileobj.read - return self.buf - - def getcomptype(self): - if self.buf.startswith(b"\037\213\010"): - return "gz" - if self.buf.startswith(b"BZh91"): - return "bz2" - return "tar" - - def close(self): - self.fileobj.close() -# class StreamProxy - -class _BZ2Proxy(object): - """Small proxy class that enables external file object - support for "r:bz2" and "w:bz2" modes. This is actually - a workaround for a limitation in bz2 module's BZ2File - class which (unlike gzip.GzipFile) has no support for - a file object argument. - """ - - blocksize = 16 * 1024 - - def __init__(self, fileobj, mode): - self.fileobj = fileobj - self.mode = mode - self.name = getattr(self.fileobj, "name", None) - self.init() - - def init(self): - import bz2 - self.pos = 0 - if self.mode == "r": - self.bz2obj = bz2.BZ2Decompressor() - self.fileobj.seek(0) - self.buf = b"" - else: - self.bz2obj = bz2.BZ2Compressor() - - def read(self, size): - x = len(self.buf) - while x < size: - raw = self.fileobj.read(self.blocksize) - if not raw: - break - data = self.bz2obj.decompress(raw) - self.buf += data - x += len(data) - - buf = self.buf[:size] - self.buf = self.buf[size:] - self.pos += len(buf) - return buf - - def seek(self, pos): - if pos < self.pos: - self.init() - self.read(pos - self.pos) - - def tell(self): - return self.pos - - def write(self, data): - self.pos += len(data) - raw = self.bz2obj.compress(data) - self.fileobj.write(raw) - - def close(self): - if self.mode == "w": - raw = self.bz2obj.flush() - self.fileobj.write(raw) -# class _BZ2Proxy - -#------------------------ -# Extraction file object -#------------------------ -class _FileInFile(object): - """A thin wrapper around an existing file object that - provides a part of its data as an individual file - object. - """ - - def __init__(self, fileobj, offset, size, blockinfo=None): - self.fileobj = fileobj - self.offset = offset - self.size = size - self.position = 0 - - if blockinfo is None: - blockinfo = [(0, size)] - - # Construct a map with data and zero blocks. - self.map_index = 0 - self.map = [] - lastpos = 0 - realpos = self.offset - for offset, size in blockinfo: - if offset > lastpos: - self.map.append((False, lastpos, offset, None)) - self.map.append((True, offset, offset + size, realpos)) - realpos += size - lastpos = offset + size - if lastpos < self.size: - self.map.append((False, lastpos, self.size, None)) - - def seekable(self): - if not hasattr(self.fileobj, "seekable"): - # XXX gzip.GzipFile and bz2.BZ2File - return True - return self.fileobj.seekable() - - def tell(self): - """Return the current file position. - """ - return self.position - - def seek(self, position): - """Seek to a position in the file. - """ - self.position = position - - def read(self, size=None): - """Read data from the file. - """ - if size is None: - size = self.size - self.position - else: - size = min(size, self.size - self.position) - - buf = b"" - while size > 0: - while True: - data, start, stop, offset = self.map[self.map_index] - if start <= self.position < stop: - break - else: - self.map_index += 1 - if self.map_index == len(self.map): - self.map_index = 0 - length = min(size, stop - self.position) - if data: - self.fileobj.seek(offset + (self.position - start)) - buf += self.fileobj.read(length) - else: - buf += NUL * length - size -= length - self.position += length - return buf -#class _FileInFile - - -class ExFileObject(object): - """File-like object for reading an archive member. - Is returned by TarFile.extractfile(). - """ - blocksize = 1024 - - def __init__(self, tarfile, tarinfo): - self.fileobj = _FileInFile(tarfile.fileobj, - tarinfo.offset_data, - tarinfo.size, - tarinfo.sparse) - self.name = tarinfo.name - self.mode = "r" - self.closed = False - self.size = tarinfo.size - - self.position = 0 - self.buffer = b"" - - def readable(self): - return True - - def writable(self): - return False - - def seekable(self): - return self.fileobj.seekable() - - def read(self, size=None): - """Read at most size bytes from the file. If size is not - present or None, read all data until EOF is reached. - """ - if self.closed: - raise ValueError("I/O operation on closed file") - - buf = b"" - if self.buffer: - if size is None: - buf = self.buffer - self.buffer = b"" - else: - buf = self.buffer[:size] - self.buffer = self.buffer[size:] - - if size is None: - buf += self.fileobj.read() - else: - buf += self.fileobj.read(size - len(buf)) - - self.position += len(buf) - return buf - - # XXX TextIOWrapper uses the read1() method. - read1 = read - - def readline(self, size=-1): - """Read one entire line from the file. If size is present - and non-negative, return a string with at most that - size, which may be an incomplete line. - """ - if self.closed: - raise ValueError("I/O operation on closed file") - - pos = self.buffer.find(b"\n") + 1 - if pos == 0: - # no newline found. - while True: - buf = self.fileobj.read(self.blocksize) - self.buffer += buf - if not buf or b"\n" in buf: - pos = self.buffer.find(b"\n") + 1 - if pos == 0: - # no newline found. - pos = len(self.buffer) - break - - if size != -1: - pos = min(size, pos) - - buf = self.buffer[:pos] - self.buffer = self.buffer[pos:] - self.position += len(buf) - return buf - - def readlines(self): - """Return a list with all remaining lines. - """ - result = [] - while True: - line = self.readline() - if not line: break - result.append(line) - return result - - def tell(self): - """Return the current file position. - """ - if self.closed: - raise ValueError("I/O operation on closed file") - - return self.position - - def seek(self, pos, whence=os.SEEK_SET): - """Seek to a position in the file. - """ - if self.closed: - raise ValueError("I/O operation on closed file") - - if whence == os.SEEK_SET: - self.position = min(max(pos, 0), self.size) - elif whence == os.SEEK_CUR: - if pos < 0: - self.position = max(self.position + pos, 0) - else: - self.position = min(self.position + pos, self.size) - elif whence == os.SEEK_END: - self.position = max(min(self.size + pos, self.size), 0) - else: - raise ValueError("Invalid argument") - - self.buffer = b"" - self.fileobj.seek(self.position) - - def close(self): - """Close the file object. - """ - self.closed = True - - def __iter__(self): - """Get an iterator over the file's lines. - """ - while True: - line = self.readline() - if not line: - break - yield line -#class ExFileObject - -#------------------ -# Exported Classes -#------------------ -class TarInfo(object): - """Informational class which holds the details about an - archive member given by a tar header block. - TarInfo objects are returned by TarFile.getmember(), - TarFile.getmembers() and TarFile.gettarinfo() and are - usually created internally. - """ - - __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", - "chksum", "type", "linkname", "uname", "gname", - "devmajor", "devminor", - "offset", "offset_data", "pax_headers", "sparse", - "tarfile", "_sparse_structs", "_link_target") - - def __init__(self, name=""): - """Construct a TarInfo object. name is the optional name - of the member. - """ - self.name = name # member name - self.mode = 0o644 # file permissions - self.uid = 0 # user id - self.gid = 0 # group id - self.size = 0 # file size - self.mtime = 0 # modification time - self.chksum = 0 # header checksum - self.type = REGTYPE # member type - self.linkname = "" # link name - self.uname = "" # user name - self.gname = "" # group name - self.devmajor = 0 # device major number - self.devminor = 0 # device minor number - - self.offset = 0 # the tar header starts here - self.offset_data = 0 # the file's data starts here - - self.sparse = None # sparse member information - self.pax_headers = {} # pax header information - - # In pax headers the "name" and "linkname" field are called - # "path" and "linkpath". - def _getpath(self): - return self.name - def _setpath(self, name): - self.name = name - path = property(_getpath, _setpath) - - def _getlinkpath(self): - return self.linkname - def _setlinkpath(self, linkname): - self.linkname = linkname - linkpath = property(_getlinkpath, _setlinkpath) - - def __repr__(self): - return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) - - def get_info(self): - """Return the TarInfo's attributes as a dictionary. - """ - info = { - "name": self.name, - "mode": self.mode & 0o7777, - "uid": self.uid, - "gid": self.gid, - "size": self.size, - "mtime": self.mtime, - "chksum": self.chksum, - "type": self.type, - "linkname": self.linkname, - "uname": self.uname, - "gname": self.gname, - "devmajor": self.devmajor, - "devminor": self.devminor - } - - if info["type"] == DIRTYPE and not info["name"].endswith("/"): - info["name"] += "/" - - return info - - def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): - """Return a tar header as a string of 512 byte blocks. - """ - info = self.get_info() - - if format == USTAR_FORMAT: - return self.create_ustar_header(info, encoding, errors) - elif format == GNU_FORMAT: - return self.create_gnu_header(info, encoding, errors) - elif format == PAX_FORMAT: - return self.create_pax_header(info, encoding) - else: - raise ValueError("invalid format") - - def create_ustar_header(self, info, encoding, errors): - """Return the object as a ustar header block. - """ - info["magic"] = POSIX_MAGIC - - if len(info["linkname"]) > LENGTH_LINK: - raise ValueError("linkname is too long") - - if len(info["name"]) > LENGTH_NAME: - info["prefix"], info["name"] = self._posix_split_name(info["name"]) - - return self._create_header(info, USTAR_FORMAT, encoding, errors) - - def create_gnu_header(self, info, encoding, errors): - """Return the object as a GNU header block sequence. - """ - info["magic"] = GNU_MAGIC - - buf = b"" - if len(info["linkname"]) > LENGTH_LINK: - buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) - - if len(info["name"]) > LENGTH_NAME: - buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) - - return buf + self._create_header(info, GNU_FORMAT, encoding, errors) - - def create_pax_header(self, info, encoding): - """Return the object as a ustar header block. If it cannot be - represented this way, prepend a pax extended header sequence - with supplement information. - """ - info["magic"] = POSIX_MAGIC - pax_headers = self.pax_headers.copy() - - # Test string fields for values that exceed the field length or cannot - # be represented in ASCII encoding. - for name, hname, length in ( - ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), - ("uname", "uname", 32), ("gname", "gname", 32)): - - if hname in pax_headers: - # The pax header has priority. - continue - - # Try to encode the string as ASCII. - try: - info[name].encode("ascii", "strict") - except UnicodeEncodeError: - pax_headers[hname] = info[name] - continue - - if len(info[name]) > length: - pax_headers[hname] = info[name] - - # Test number fields for values that exceed the field limit or values - # that like to be stored as float. - for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): - if name in pax_headers: - # The pax header has priority. Avoid overflow. - info[name] = 0 - continue - - val = info[name] - if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): - pax_headers[name] = str(val) - info[name] = 0 - - # Create a pax extended header if necessary. - if pax_headers: - buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) - else: - buf = b"" - - return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") - - @classmethod - def create_pax_global_header(cls, pax_headers): - """Return the object as a pax global header block sequence. - """ - return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf8") - - def _posix_split_name(self, name): - """Split a name longer than 100 chars into a prefix - and a name part. - """ - prefix = name[:LENGTH_PREFIX + 1] - while prefix and prefix[-1] != "/": - prefix = prefix[:-1] - - name = name[len(prefix):] - prefix = prefix[:-1] - - if not prefix or len(name) > LENGTH_NAME: - raise ValueError("name is too long") - return prefix, name - - @staticmethod - def _create_header(info, format, encoding, errors): - """Return a header block. info is a dictionary with file - information, format must be one of the *_FORMAT constants. - """ - parts = [ - stn(info.get("name", ""), 100, encoding, errors), - itn(info.get("mode", 0) & 0o7777, 8, format), - itn(info.get("uid", 0), 8, format), - itn(info.get("gid", 0), 8, format), - itn(info.get("size", 0), 12, format), - itn(info.get("mtime", 0), 12, format), - b" ", # checksum field - info.get("type", REGTYPE), - stn(info.get("linkname", ""), 100, encoding, errors), - info.get("magic", POSIX_MAGIC), - stn(info.get("uname", ""), 32, encoding, errors), - stn(info.get("gname", ""), 32, encoding, errors), - itn(info.get("devmajor", 0), 8, format), - itn(info.get("devminor", 0), 8, format), - stn(info.get("prefix", ""), 155, encoding, errors) - ] - - buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) - chksum = calc_chksums(buf[-BLOCKSIZE:])[0] - buf = buf[:-364] + ("%06o\0" % chksum).encode("ascii") + buf[-357:] - return buf - - @staticmethod - def _create_payload(payload): - """Return the string payload filled with zero bytes - up to the next 512 byte border. - """ - blocks, remainder = divmod(len(payload), BLOCKSIZE) - if remainder > 0: - payload += (BLOCKSIZE - remainder) * NUL - return payload - - @classmethod - def _create_gnu_long_header(cls, name, type, encoding, errors): - """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence - for name. - """ - name = name.encode(encoding, errors) + NUL - - info = {} - info["name"] = "././@LongLink" - info["type"] = type - info["size"] = len(name) - info["magic"] = GNU_MAGIC - - # create extended header + name blocks. - return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ - cls._create_payload(name) - - @classmethod - def _create_pax_generic_header(cls, pax_headers, type, encoding): - """Return a POSIX.1-2008 extended or global header sequence - that contains a list of keyword, value pairs. The values - must be strings. - """ - # Check if one of the fields contains surrogate characters and thereby - # forces hdrcharset=BINARY, see _proc_pax() for more information. - binary = False - for keyword, value in pax_headers.items(): - try: - value.encode("utf8", "strict") - except UnicodeEncodeError: - binary = True - break - - records = b"" - if binary: - # Put the hdrcharset field at the beginning of the header. - records += b"21 hdrcharset=BINARY\n" - - for keyword, value in pax_headers.items(): - keyword = keyword.encode("utf8") - if binary: - # Try to restore the original byte representation of `value'. - # Needless to say, that the encoding must match the string. - value = value.encode(encoding, "surrogateescape") - else: - value = value.encode("utf8") - - l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' - n = p = 0 - while True: - n = l + len(str(p)) - if n == p: - break - p = n - records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" - - # We use a hardcoded "././@PaxHeader" name like star does - # instead of the one that POSIX recommends. - info = {} - info["name"] = "././@PaxHeader" - info["type"] = type - info["size"] = len(records) - info["magic"] = POSIX_MAGIC - - # Create pax header + record blocks. - return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ - cls._create_payload(records) - - @classmethod - def frombuf(cls, buf, encoding, errors): - """Construct a TarInfo object from a 512 byte bytes object. - """ - if len(buf) == 0: - raise EmptyHeaderError("empty header") - if len(buf) != BLOCKSIZE: - raise TruncatedHeaderError("truncated header") - if buf.count(NUL) == BLOCKSIZE: - raise EOFHeaderError("end of file header") - - chksum = nti(buf[148:156]) - if chksum not in calc_chksums(buf): - raise InvalidHeaderError("bad checksum") - - obj = cls() - obj.name = nts(buf[0:100], encoding, errors) - obj.mode = nti(buf[100:108]) - obj.uid = nti(buf[108:116]) - obj.gid = nti(buf[116:124]) - obj.size = nti(buf[124:136]) - obj.mtime = nti(buf[136:148]) - obj.chksum = chksum - obj.type = buf[156:157] - obj.linkname = nts(buf[157:257], encoding, errors) - obj.uname = nts(buf[265:297], encoding, errors) - obj.gname = nts(buf[297:329], encoding, errors) - obj.devmajor = nti(buf[329:337]) - obj.devminor = nti(buf[337:345]) - prefix = nts(buf[345:500], encoding, errors) - - # Old V7 tar format represents a directory as a regular - # file with a trailing slash. - if obj.type == AREGTYPE and obj.name.endswith("/"): - obj.type = DIRTYPE - - # The old GNU sparse format occupies some of the unused - # space in the buffer for up to 4 sparse structures. - # Save the them for later processing in _proc_sparse(). - if obj.type == GNUTYPE_SPARSE: - pos = 386 - structs = [] - for i in range(4): - try: - offset = nti(buf[pos:pos + 12]) - numbytes = nti(buf[pos + 12:pos + 24]) - except ValueError: - break - structs.append((offset, numbytes)) - pos += 24 - isextended = bool(buf[482]) - origsize = nti(buf[483:495]) - obj._sparse_structs = (structs, isextended, origsize) - - # Remove redundant slashes from directories. - if obj.isdir(): - obj.name = obj.name.rstrip("/") - - # Reconstruct a ustar longname. - if prefix and obj.type not in GNU_TYPES: - obj.name = prefix + "/" + obj.name - return obj - - @classmethod - def fromtarfile(cls, tarfile): - """Return the next TarInfo object from TarFile object - tarfile. - """ - buf = tarfile.fileobj.read(BLOCKSIZE) - obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) - obj.offset = tarfile.fileobj.tell() - BLOCKSIZE - return obj._proc_member(tarfile) - - #-------------------------------------------------------------------------- - # The following are methods that are called depending on the type of a - # member. The entry point is _proc_member() which can be overridden in a - # subclass to add custom _proc_*() methods. A _proc_*() method MUST - # implement the following - # operations: - # 1. Set self.offset_data to the position where the data blocks begin, - # if there is data that follows. - # 2. Set tarfile.offset to the position where the next member's header will - # begin. - # 3. Return self or another valid TarInfo object. - def _proc_member(self, tarfile): - """Choose the right processing method depending on - the type and call it. - """ - if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): - return self._proc_gnulong(tarfile) - elif self.type == GNUTYPE_SPARSE: - return self._proc_sparse(tarfile) - elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): - return self._proc_pax(tarfile) - else: - return self._proc_builtin(tarfile) - - def _proc_builtin(self, tarfile): - """Process a builtin type or an unknown type which - will be treated as a regular file. - """ - self.offset_data = tarfile.fileobj.tell() - offset = self.offset_data - if self.isreg() or self.type not in SUPPORTED_TYPES: - # Skip the following data blocks. - offset += self._block(self.size) - tarfile.offset = offset - - # Patch the TarInfo object with saved global - # header information. - self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) - - return self - - def _proc_gnulong(self, tarfile): - """Process the blocks that hold a GNU longname - or longlink member. - """ - buf = tarfile.fileobj.read(self._block(self.size)) - - # Fetch the next header and process it. - try: - next = self.fromtarfile(tarfile) - except HeaderError: - raise SubsequentHeaderError("missing or bad subsequent header") - - # Patch the TarInfo object from the next header with - # the longname information. - next.offset = self.offset - if self.type == GNUTYPE_LONGNAME: - next.name = nts(buf, tarfile.encoding, tarfile.errors) - elif self.type == GNUTYPE_LONGLINK: - next.linkname = nts(buf, tarfile.encoding, tarfile.errors) - - return next - - def _proc_sparse(self, tarfile): - """Process a GNU sparse header plus extra headers. - """ - # We already collected some sparse structures in frombuf(). - structs, isextended, origsize = self._sparse_structs - del self._sparse_structs - - # Collect sparse structures from extended header blocks. - while isextended: - buf = tarfile.fileobj.read(BLOCKSIZE) - pos = 0 - for i in range(21): - try: - offset = nti(buf[pos:pos + 12]) - numbytes = nti(buf[pos + 12:pos + 24]) - except ValueError: - break - if offset and numbytes: - structs.append((offset, numbytes)) - pos += 24 - isextended = bool(buf[504]) - self.sparse = structs - - self.offset_data = tarfile.fileobj.tell() - tarfile.offset = self.offset_data + self._block(self.size) - self.size = origsize - return self - - def _proc_pax(self, tarfile): - """Process an extended or global header as described in - POSIX.1-2008. - """ - # Read the header information. - buf = tarfile.fileobj.read(self._block(self.size)) - - # A pax header stores supplemental information for either - # the following file (extended) or all following files - # (global). - if self.type == XGLTYPE: - pax_headers = tarfile.pax_headers - else: - pax_headers = tarfile.pax_headers.copy() - - # Check if the pax header contains a hdrcharset field. This tells us - # the encoding of the path, linkpath, uname and gname fields. Normally, - # these fields are UTF-8 encoded but since POSIX.1-2008 tar - # implementations are allowed to store them as raw binary strings if - # the translation to UTF-8 fails. - match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) - if match is not None: - pax_headers["hdrcharset"] = match.group(1).decode("utf8") - - # For the time being, we don't care about anything other than "BINARY". - # The only other value that is currently allowed by the standard is - # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. - hdrcharset = pax_headers.get("hdrcharset") - if hdrcharset == "BINARY": - encoding = tarfile.encoding - else: - encoding = "utf8" - - # Parse pax header information. A record looks like that: - # "%d %s=%s\n" % (length, keyword, value). length is the size - # of the complete record including the length field itself and - # the newline. keyword and value are both UTF-8 encoded strings. - regex = re.compile(br"(\d+) ([^=]+)=") - pos = 0 - while True: - match = regex.match(buf, pos) - if not match: - break - - length, keyword = match.groups() - length = int(length) - value = buf[match.end(2) + 1:match.start(1) + length - 1] - - # Normally, we could just use "utf8" as the encoding and "strict" - # as the error handler, but we better not take the risk. For - # example, GNU tar <= 1.23 is known to store filenames it cannot - # translate to UTF-8 as raw strings (unfortunately without a - # hdrcharset=BINARY header). - # We first try the strict standard encoding, and if that fails we - # fall back on the user's encoding and error handler. - keyword = self._decode_pax_field(keyword, "utf8", "utf8", - tarfile.errors) - if keyword in PAX_NAME_FIELDS: - value = self._decode_pax_field(value, encoding, tarfile.encoding, - tarfile.errors) - else: - value = self._decode_pax_field(value, "utf8", "utf8", - tarfile.errors) - - pax_headers[keyword] = value - pos += length - - # Fetch the next header. - try: - next = self.fromtarfile(tarfile) - except HeaderError: - raise SubsequentHeaderError("missing or bad subsequent header") - - # Process GNU sparse information. - if "GNU.sparse.map" in pax_headers: - # GNU extended sparse format version 0.1. - self._proc_gnusparse_01(next, pax_headers) - - elif "GNU.sparse.size" in pax_headers: - # GNU extended sparse format version 0.0. - self._proc_gnusparse_00(next, pax_headers, buf) - - elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": - # GNU extended sparse format version 1.0. - self._proc_gnusparse_10(next, pax_headers, tarfile) - - if self.type in (XHDTYPE, SOLARIS_XHDTYPE): - # Patch the TarInfo object with the extended header info. - next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) - next.offset = self.offset - - if "size" in pax_headers: - # If the extended header replaces the size field, - # we need to recalculate the offset where the next - # header starts. - offset = next.offset_data - if next.isreg() or next.type not in SUPPORTED_TYPES: - offset += next._block(next.size) - tarfile.offset = offset - - return next - - def _proc_gnusparse_00(self, next, pax_headers, buf): - """Process a GNU tar extended sparse header, version 0.0. - """ - offsets = [] - for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): - offsets.append(int(match.group(1))) - numbytes = [] - for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): - numbytes.append(int(match.group(1))) - next.sparse = list(zip(offsets, numbytes)) - - def _proc_gnusparse_01(self, next, pax_headers): - """Process a GNU tar extended sparse header, version 0.1. - """ - sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] - next.sparse = list(zip(sparse[::2], sparse[1::2])) - - def _proc_gnusparse_10(self, next, pax_headers, tarfile): - """Process a GNU tar extended sparse header, version 1.0. - """ - fields = None - sparse = [] - buf = tarfile.fileobj.read(BLOCKSIZE) - fields, buf = buf.split(b"\n", 1) - fields = int(fields) - while len(sparse) < fields * 2: - if b"\n" not in buf: - buf += tarfile.fileobj.read(BLOCKSIZE) - number, buf = buf.split(b"\n", 1) - sparse.append(int(number)) - next.offset_data = tarfile.fileobj.tell() - next.sparse = list(zip(sparse[::2], sparse[1::2])) - - def _apply_pax_info(self, pax_headers, encoding, errors): - """Replace fields with supplemental information from a previous - pax extended or global header. - """ - for keyword, value in pax_headers.items(): - if keyword == "GNU.sparse.name": - setattr(self, "path", value) - elif keyword == "GNU.sparse.size": - setattr(self, "size", int(value)) - elif keyword == "GNU.sparse.realsize": - setattr(self, "size", int(value)) - elif keyword in PAX_FIELDS: - if keyword in PAX_NUMBER_FIELDS: - try: - value = PAX_NUMBER_FIELDS[keyword](value) - except ValueError: - value = 0 - if keyword == "path": - value = value.rstrip("/") - setattr(self, keyword, value) - - self.pax_headers = pax_headers.copy() - - def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): - """Decode a single field from a pax record. - """ - try: - return value.decode(encoding, "strict") - except UnicodeDecodeError: - return value.decode(fallback_encoding, fallback_errors) - - def _block(self, count): - """Round up a byte count by BLOCKSIZE and return it, - e.g. _block(834) => 1024. - """ - blocks, remainder = divmod(count, BLOCKSIZE) - if remainder: - blocks += 1 - return blocks * BLOCKSIZE - - def isreg(self): - return self.type in REGULAR_TYPES - def isfile(self): - return self.isreg() - def isdir(self): - return self.type == DIRTYPE - def issym(self): - return self.type == SYMTYPE - def islnk(self): - return self.type == LNKTYPE - def ischr(self): - return self.type == CHRTYPE - def isblk(self): - return self.type == BLKTYPE - def isfifo(self): - return self.type == FIFOTYPE - def issparse(self): - return self.sparse is not None - def isdev(self): - return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) -# class TarInfo - -class TarFile(object): - """The TarFile Class provides an interface to tar archives. - """ - - debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) - - dereference = False # If true, add content of linked file to the - # tar file, else the link. - - ignore_zeros = False # If true, skips empty or invalid blocks and - # continues processing. - - errorlevel = 1 # If 0, fatal errors only appear in debug - # messages (if debug >= 0). If > 0, errors - # are passed to the caller as exceptions. - - format = DEFAULT_FORMAT # The format to use when creating an archive. - - encoding = ENCODING # Encoding for 8-bit character strings. - - errors = None # Error handler for unicode conversion. - - tarinfo = TarInfo # The default TarInfo class to use. - - fileobject = ExFileObject # The default ExFileObject class to use. - - def __init__(self, name=None, mode="r", fileobj=None, format=None, - tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, - errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None): - """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to - read from an existing archive, 'a' to append data to an existing - file or 'w' to create a new file overwriting an existing one. `mode' - defaults to 'r'. - If `fileobj' is given, it is used for reading or writing data. If it - can be determined, `mode' is overridden by `fileobj's mode. - `fileobj' is not closed, when TarFile is closed. - """ - if len(mode) > 1 or mode not in "raw": - raise ValueError("mode must be 'r', 'a' or 'w'") - self.mode = mode - self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] - - if not fileobj: - if self.mode == "a" and not os.path.exists(name): - # Create nonexistent files in append mode. - self.mode = "w" - self._mode = "wb" - fileobj = bltn_open(name, self._mode) - self._extfileobj = False - else: - if name is None and hasattr(fileobj, "name"): - name = fileobj.name - if hasattr(fileobj, "mode"): - self._mode = fileobj.mode - self._extfileobj = True - self.name = os.path.abspath(name) if name else None - self.fileobj = fileobj - - # Init attributes. - if format is not None: - self.format = format - if tarinfo is not None: - self.tarinfo = tarinfo - if dereference is not None: - self.dereference = dereference - if ignore_zeros is not None: - self.ignore_zeros = ignore_zeros - if encoding is not None: - self.encoding = encoding - self.errors = errors - - if pax_headers is not None and self.format == PAX_FORMAT: - self.pax_headers = pax_headers - else: - self.pax_headers = {} - - if debug is not None: - self.debug = debug - if errorlevel is not None: - self.errorlevel = errorlevel - - # Init datastructures. - self.closed = False - self.members = [] # list of members as TarInfo objects - self._loaded = False # flag if all members have been read - self.offset = self.fileobj.tell() - # current position in the archive file - self.inodes = {} # dictionary caching the inodes of - # archive members already added - - try: - if self.mode == "r": - self.firstmember = None - self.firstmember = self.next() - - if self.mode == "a": - # Move to the end of the archive, - # before the first empty block. - while True: - self.fileobj.seek(self.offset) - try: - tarinfo = self.tarinfo.fromtarfile(self) - self.members.append(tarinfo) - except EOFHeaderError: - self.fileobj.seek(self.offset) - break - except HeaderError as e: - raise ReadError(str(e)) - - if self.mode in "aw": - self._loaded = True - - if self.pax_headers: - buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) - self.fileobj.write(buf) - self.offset += len(buf) - except: - if not self._extfileobj: - self.fileobj.close() - self.closed = True - raise - - #-------------------------------------------------------------------------- - # Below are the classmethods which act as alternate constructors to the - # TarFile class. The open() method is the only one that is needed for - # public use; it is the "super"-constructor and is able to select an - # adequate "sub"-constructor for a particular compression using the mapping - # from OPEN_METH. - # - # This concept allows one to subclass TarFile without losing the comfort of - # the super-constructor. A sub-constructor is registered and made available - # by adding it to the mapping in OPEN_METH. - - @classmethod - def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): - """Open a tar archive for reading, writing or appending. Return - an appropriate TarFile class. - - mode: - 'r' or 'r:*' open for reading with transparent compression - 'r:' open for reading exclusively uncompressed - 'r:gz' open for reading with gzip compression - 'r:bz2' open for reading with bzip2 compression - 'a' or 'a:' open for appending, creating the file if necessary - 'w' or 'w:' open for writing without compression - 'w:gz' open for writing with gzip compression - 'w:bz2' open for writing with bzip2 compression - - 'r|*' open a stream of tar blocks with transparent compression - 'r|' open an uncompressed stream of tar blocks for reading - 'r|gz' open a gzip compressed stream of tar blocks - 'r|bz2' open a bzip2 compressed stream of tar blocks - 'w|' open an uncompressed stream for writing - 'w|gz' open a gzip compressed stream for writing - 'w|bz2' open a bzip2 compressed stream for writing - """ - - if not name and not fileobj: - raise ValueError("nothing to open") - - if mode in ("r", "r:*"): - # Find out which *open() is appropriate for opening the file. - for comptype in cls.OPEN_METH: - func = getattr(cls, cls.OPEN_METH[comptype]) - if fileobj is not None: - saved_pos = fileobj.tell() - try: - return func(name, "r", fileobj, **kwargs) - except (ReadError, CompressionError) as e: - if fileobj is not None: - fileobj.seek(saved_pos) - continue - raise ReadError("file could not be opened successfully") - - elif ":" in mode: - filemode, comptype = mode.split(":", 1) - filemode = filemode or "r" - comptype = comptype or "tar" - - # Select the *open() function according to - # given compression. - if comptype in cls.OPEN_METH: - func = getattr(cls, cls.OPEN_METH[comptype]) - else: - raise CompressionError("unknown compression type %r" % comptype) - return func(name, filemode, fileobj, **kwargs) - - elif "|" in mode: - filemode, comptype = mode.split("|", 1) - filemode = filemode or "r" - comptype = comptype or "tar" - - if filemode not in "rw": - raise ValueError("mode must be 'r' or 'w'") - - stream = _Stream(name, filemode, comptype, fileobj, bufsize) - try: - t = cls(name, filemode, stream, **kwargs) - except: - stream.close() - raise - t._extfileobj = False - return t - - elif mode in "aw": - return cls.taropen(name, mode, fileobj, **kwargs) - - raise ValueError("undiscernible mode") - - @classmethod - def taropen(cls, name, mode="r", fileobj=None, **kwargs): - """Open uncompressed tar archive name for reading or writing. - """ - if len(mode) > 1 or mode not in "raw": - raise ValueError("mode must be 'r', 'a' or 'w'") - return cls(name, mode, fileobj, **kwargs) - - @classmethod - def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): - """Open gzip compressed tar archive name for reading or writing. - Appending is not allowed. - """ - if len(mode) > 1 or mode not in "rw": - raise ValueError("mode must be 'r' or 'w'") - - try: - import gzip - gzip.GzipFile - except (ImportError, AttributeError): - raise CompressionError("gzip module is not available") - - extfileobj = fileobj is not None - try: - fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) - t = cls.taropen(name, mode, fileobj, **kwargs) - except IOError: - if not extfileobj and fileobj is not None: - fileobj.close() - if fileobj is None: - raise - raise ReadError("not a gzip file") - except: - if not extfileobj and fileobj is not None: - fileobj.close() - raise - t._extfileobj = extfileobj - return t - - @classmethod - def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): - """Open bzip2 compressed tar archive name for reading or writing. - Appending is not allowed. - """ - if len(mode) > 1 or mode not in "rw": - raise ValueError("mode must be 'r' or 'w'.") - - try: - import bz2 - except ImportError: - raise CompressionError("bz2 module is not available") - - if fileobj is not None: - fileobj = _BZ2Proxy(fileobj, mode) - else: - fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) - - try: - t = cls.taropen(name, mode, fileobj, **kwargs) - except (IOError, EOFError): - fileobj.close() - raise ReadError("not a bzip2 file") - t._extfileobj = False - return t - - # All *open() methods are registered here. - OPEN_METH = { - "tar": "taropen", # uncompressed tar - "gz": "gzopen", # gzip compressed tar - "bz2": "bz2open" # bzip2 compressed tar - } - - #-------------------------------------------------------------------------- - # The public methods which TarFile provides: - - def close(self): - """Close the TarFile. In write-mode, two finishing zero blocks are - appended to the archive. - """ - if self.closed: - return - - if self.mode in "aw": - self.fileobj.write(NUL * (BLOCKSIZE * 2)) - self.offset += (BLOCKSIZE * 2) - # fill up the end with zero-blocks - # (like option -b20 for tar does) - blocks, remainder = divmod(self.offset, RECORDSIZE) - if remainder > 0: - self.fileobj.write(NUL * (RECORDSIZE - remainder)) - - if not self._extfileobj: - self.fileobj.close() - self.closed = True - - def getmember(self, name): - """Return a TarInfo object for member `name'. If `name' can not be - found in the archive, KeyError is raised. If a member occurs more - than once in the archive, its last occurrence is assumed to be the - most up-to-date version. - """ - tarinfo = self._getmember(name) - if tarinfo is None: - raise KeyError("filename %r not found" % name) - return tarinfo - - def getmembers(self): - """Return the members of the archive as a list of TarInfo objects. The - list has the same order as the members in the archive. - """ - self._check() - if not self._loaded: # if we want to obtain a list of - self._load() # all members, we first have to - # scan the whole archive. - return self.members - - def getnames(self): - """Return the members of the archive as a list of their names. It has - the same order as the list returned by getmembers(). - """ - return [tarinfo.name for tarinfo in self.getmembers()] - - def gettarinfo(self, name=None, arcname=None, fileobj=None): - """Create a TarInfo object for either the file `name' or the file - object `fileobj' (using os.fstat on its file descriptor). You can - modify some of the TarInfo's attributes before you add it using - addfile(). If given, `arcname' specifies an alternative name for the - file in the archive. - """ - self._check("aw") - - # When fileobj is given, replace name by - # fileobj's real name. - if fileobj is not None: - name = fileobj.name - - # Building the name of the member in the archive. - # Backward slashes are converted to forward slashes, - # Absolute paths are turned to relative paths. - if arcname is None: - arcname = name - drv, arcname = os.path.splitdrive(arcname) - arcname = arcname.replace(os.sep, "/") - arcname = arcname.lstrip("/") - - # Now, fill the TarInfo object with - # information specific for the file. - tarinfo = self.tarinfo() - tarinfo.tarfile = self - - # Use os.stat or os.lstat, depending on platform - # and if symlinks shall be resolved. - if fileobj is None: - if hasattr(os, "lstat") and not self.dereference: - statres = os.lstat(name) - else: - statres = os.stat(name) - else: - statres = os.fstat(fileobj.fileno()) - linkname = "" - - stmd = statres.st_mode - if stat.S_ISREG(stmd): - inode = (statres.st_ino, statres.st_dev) - if not self.dereference and statres.st_nlink > 1 and \ - inode in self.inodes and arcname != self.inodes[inode]: - # Is it a hardlink to an already - # archived file? - type = LNKTYPE - linkname = self.inodes[inode] - else: - # The inode is added only if its valid. - # For win32 it is always 0. - type = REGTYPE - if inode[0]: - self.inodes[inode] = arcname - elif stat.S_ISDIR(stmd): - type = DIRTYPE - elif stat.S_ISFIFO(stmd): - type = FIFOTYPE - elif stat.S_ISLNK(stmd): - type = SYMTYPE - linkname = os.readlink(name) - elif stat.S_ISCHR(stmd): - type = CHRTYPE - elif stat.S_ISBLK(stmd): - type = BLKTYPE - else: - return None - - # Fill the TarInfo object with all - # information we can get. - tarinfo.name = arcname - tarinfo.mode = stmd - tarinfo.uid = statres.st_uid - tarinfo.gid = statres.st_gid - if type == REGTYPE: - tarinfo.size = statres.st_size - else: - tarinfo.size = 0 - tarinfo.mtime = statres.st_mtime - tarinfo.type = type - tarinfo.linkname = linkname - if pwd: - try: - tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] - except KeyError: - pass - if grp: - try: - tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] - except KeyError: - pass - - if type in (CHRTYPE, BLKTYPE): - if hasattr(os, "major") and hasattr(os, "minor"): - tarinfo.devmajor = os.major(statres.st_rdev) - tarinfo.devminor = os.minor(statres.st_rdev) - return tarinfo - - def list(self, verbose=True): - """Print a table of contents to sys.stdout. If `verbose' is False, only - the names of the members are printed. If it is True, an `ls -l'-like - output is produced. - """ - self._check() - - for tarinfo in self: - if verbose: - print(filemode(tarinfo.mode), end=' ') - print("%s/%s" % (tarinfo.uname or tarinfo.uid, - tarinfo.gname or tarinfo.gid), end=' ') - if tarinfo.ischr() or tarinfo.isblk(): - print("%10s" % ("%d,%d" \ - % (tarinfo.devmajor, tarinfo.devminor)), end=' ') - else: - print("%10d" % tarinfo.size, end=' ') - print("%d-%02d-%02d %02d:%02d:%02d" \ - % time.localtime(tarinfo.mtime)[:6], end=' ') - - print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') - - if verbose: - if tarinfo.issym(): - print("->", tarinfo.linkname, end=' ') - if tarinfo.islnk(): - print("link to", tarinfo.linkname, end=' ') - print() - - def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): - """Add the file `name' to the archive. `name' may be any type of file - (directory, fifo, symbolic link, etc.). If given, `arcname' - specifies an alternative name for the file in the archive. - Directories are added recursively by default. This can be avoided by - setting `recursive' to False. `exclude' is a function that should - return True for each filename to be excluded. `filter' is a function - that expects a TarInfo object argument and returns the changed - TarInfo object, if it returns None the TarInfo object will be - excluded from the archive. - """ - self._check("aw") - - if arcname is None: - arcname = name - - # Exclude pathnames. - if exclude is not None: - import warnings - warnings.warn("use the filter argument instead", - DeprecationWarning, 2) - if exclude(name): - self._dbg(2, "tarfile: Excluded %r" % name) - return - - # Skip if somebody tries to archive the archive... - if self.name is not None and os.path.abspath(name) == self.name: - self._dbg(2, "tarfile: Skipped %r" % name) - return - - self._dbg(1, name) - - # Create a TarInfo object from the file. - tarinfo = self.gettarinfo(name, arcname) - - if tarinfo is None: - self._dbg(1, "tarfile: Unsupported type %r" % name) - return - - # Change or exclude the TarInfo object. - if filter is not None: - tarinfo = filter(tarinfo) - if tarinfo is None: - self._dbg(2, "tarfile: Excluded %r" % name) - return - - # Append the tar header and data to the archive. - if tarinfo.isreg(): - f = bltn_open(name, "rb") - self.addfile(tarinfo, f) - f.close() - - elif tarinfo.isdir(): - self.addfile(tarinfo) - if recursive: - for f in os.listdir(name): - self.add(os.path.join(name, f), os.path.join(arcname, f), - recursive, exclude, filter=filter) - - else: - self.addfile(tarinfo) - - def addfile(self, tarinfo, fileobj=None): - """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is - given, tarinfo.size bytes are read from it and added to the archive. - You can create TarInfo objects using gettarinfo(). - On Windows platforms, `fileobj' should always be opened with mode - 'rb' to avoid irritation about the file size. - """ - self._check("aw") - - tarinfo = copy.copy(tarinfo) - - buf = tarinfo.tobuf(self.format, self.encoding, self.errors) - self.fileobj.write(buf) - self.offset += len(buf) - - # If there's data to follow, append it. - if fileobj is not None: - copyfileobj(fileobj, self.fileobj, tarinfo.size) - blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) - if remainder > 0: - self.fileobj.write(NUL * (BLOCKSIZE - remainder)) - blocks += 1 - self.offset += blocks * BLOCKSIZE - - self.members.append(tarinfo) - - def extractall(self, path=".", members=None): - """Extract all members from the archive to the current working - directory and set owner, modification time and permissions on - directories afterwards. `path' specifies a different directory - to extract to. `members' is optional and must be a subset of the - list returned by getmembers(). - """ - directories = [] - - if members is None: - members = self - - for tarinfo in members: - if tarinfo.isdir(): - # Extract directories with a safe mode. - directories.append(tarinfo) - tarinfo = copy.copy(tarinfo) - tarinfo.mode = 0o700 - # Do not set_attrs directories, as we will do that further down - self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) - - # Reverse sort directories. - directories.sort(key=lambda a: a.name) - directories.reverse() - - # Set correct owner, mtime and filemode on directories. - for tarinfo in directories: - dirpath = os.path.join(path, tarinfo.name) - try: - self.chown(tarinfo, dirpath) - self.utime(tarinfo, dirpath) - self.chmod(tarinfo, dirpath) - except ExtractError as e: - if self.errorlevel > 1: - raise - else: - self._dbg(1, "tarfile: %s" % e) - - def extract(self, member, path="", set_attrs=True): - """Extract a member from the archive to the current working directory, - using its full name. Its file information is extracted as accurately - as possible. `member' may be a filename or a TarInfo object. You can - specify a different directory using `path'. File attributes (owner, - mtime, mode) are set unless `set_attrs' is False. - """ - self._check("r") - - if isinstance(member, str): - tarinfo = self.getmember(member) - else: - tarinfo = member - - # Prepare the link target for makelink(). - if tarinfo.islnk(): - tarinfo._link_target = os.path.join(path, tarinfo.linkname) - - try: - self._extract_member(tarinfo, os.path.join(path, tarinfo.name), - set_attrs=set_attrs) - except EnvironmentError as e: - if self.errorlevel > 0: - raise - else: - if e.filename is None: - self._dbg(1, "tarfile: %s" % e.strerror) - else: - self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) - except ExtractError as e: - if self.errorlevel > 1: - raise - else: - self._dbg(1, "tarfile: %s" % e) - - def extractfile(self, member): - """Extract a member from the archive as a file object. `member' may be - a filename or a TarInfo object. If `member' is a regular file, a - file-like object is returned. If `member' is a link, a file-like - object is constructed from the link's target. If `member' is none of - the above, None is returned. - The file-like object is read-only and provides the following - methods: read(), readline(), readlines(), seek() and tell() - """ - self._check("r") - - if isinstance(member, str): - tarinfo = self.getmember(member) - else: - tarinfo = member - - if tarinfo.isreg(): - return self.fileobject(self, tarinfo) - - elif tarinfo.type not in SUPPORTED_TYPES: - # If a member's type is unknown, it is treated as a - # regular file. - return self.fileobject(self, tarinfo) - - elif tarinfo.islnk() or tarinfo.issym(): - if isinstance(self.fileobj, _Stream): - # A small but ugly workaround for the case that someone tries - # to extract a (sym)link as a file-object from a non-seekable - # stream of tar blocks. - raise StreamError("cannot extract (sym)link as file object") - else: - # A (sym)link's file object is its target's file object. - return self.extractfile(self._find_link_target(tarinfo)) - else: - # If there's no data associated with the member (directory, chrdev, - # blkdev, etc.), return None instead of a file object. - return None - - def _extract_member(self, tarinfo, targetpath, set_attrs=True): - """Extract the TarInfo object tarinfo to a physical - file called targetpath. - """ - # Fetch the TarInfo object for the given name - # and build the destination pathname, replacing - # forward slashes to platform specific separators. - targetpath = targetpath.rstrip("/") - targetpath = targetpath.replace("/", os.sep) - - # Create all upper directories. - upperdirs = os.path.dirname(targetpath) - if upperdirs and not os.path.exists(upperdirs): - # Create directories that are not part of the archive with - # default permissions. - os.makedirs(upperdirs) - - if tarinfo.islnk() or tarinfo.issym(): - self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) - else: - self._dbg(1, tarinfo.name) - - if tarinfo.isreg(): - self.makefile(tarinfo, targetpath) - elif tarinfo.isdir(): - self.makedir(tarinfo, targetpath) - elif tarinfo.isfifo(): - self.makefifo(tarinfo, targetpath) - elif tarinfo.ischr() or tarinfo.isblk(): - self.makedev(tarinfo, targetpath) - elif tarinfo.islnk() or tarinfo.issym(): - self.makelink(tarinfo, targetpath) - elif tarinfo.type not in SUPPORTED_TYPES: - self.makeunknown(tarinfo, targetpath) - else: - self.makefile(tarinfo, targetpath) - - if set_attrs: - self.chown(tarinfo, targetpath) - if not tarinfo.issym(): - self.chmod(tarinfo, targetpath) - self.utime(tarinfo, targetpath) - - #-------------------------------------------------------------------------- - # Below are the different file methods. They are called via - # _extract_member() when extract() is called. They can be replaced in a - # subclass to implement other functionality. - - def makedir(self, tarinfo, targetpath): - """Make a directory called targetpath. - """ - try: - # Use a safe mode for the directory, the real mode is set - # later in _extract_member(). - os.mkdir(targetpath, 0o700) - except EnvironmentError as e: - if e.errno != errno.EEXIST: - raise - - def makefile(self, tarinfo, targetpath): - """Make a file called targetpath. - """ - source = self.fileobj - source.seek(tarinfo.offset_data) - target = bltn_open(targetpath, "wb") - if tarinfo.sparse is not None: - for offset, size in tarinfo.sparse: - target.seek(offset) - copyfileobj(source, target, size) - else: - copyfileobj(source, target, tarinfo.size) - target.seek(tarinfo.size) - target.truncate() - target.close() - - def makeunknown(self, tarinfo, targetpath): - """Make a file from a TarInfo object with an unknown type - at targetpath. - """ - self.makefile(tarinfo, targetpath) - self._dbg(1, "tarfile: Unknown file type %r, " \ - "extracted as regular file." % tarinfo.type) - - def makefifo(self, tarinfo, targetpath): - """Make a fifo called targetpath. - """ - if hasattr(os, "mkfifo"): - os.mkfifo(targetpath) - else: - raise ExtractError("fifo not supported by system") - - def makedev(self, tarinfo, targetpath): - """Make a character or block device called targetpath. - """ - if not hasattr(os, "mknod") or not hasattr(os, "makedev"): - raise ExtractError("special devices not supported by system") - - mode = tarinfo.mode - if tarinfo.isblk(): - mode |= stat.S_IFBLK - else: - mode |= stat.S_IFCHR - - os.mknod(targetpath, mode, - os.makedev(tarinfo.devmajor, tarinfo.devminor)) - - def makelink(self, tarinfo, targetpath): - """Make a (symbolic) link called targetpath. If it cannot be created - (platform limitation), we try to make a copy of the referenced file - instead of a link. - """ - try: - # For systems that support symbolic and hard links. - if tarinfo.issym(): - os.symlink(tarinfo.linkname, targetpath) - else: - # See extract(). - if os.path.exists(tarinfo._link_target): - os.link(tarinfo._link_target, targetpath) - else: - self._extract_member(self._find_link_target(tarinfo), - targetpath) - except symlink_exception: - if tarinfo.issym(): - linkpath = os.path.join(os.path.dirname(tarinfo.name), - tarinfo.linkname) - else: - linkpath = tarinfo.linkname - else: - try: - self._extract_member(self._find_link_target(tarinfo), - targetpath) - except KeyError: - raise ExtractError("unable to resolve link inside archive") - - def chown(self, tarinfo, targetpath): - """Set owner of targetpath according to tarinfo. - """ - if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: - # We have to be root to do so. - try: - g = grp.getgrnam(tarinfo.gname)[2] - except KeyError: - g = tarinfo.gid - try: - u = pwd.getpwnam(tarinfo.uname)[2] - except KeyError: - u = tarinfo.uid - try: - if tarinfo.issym() and hasattr(os, "lchown"): - os.lchown(targetpath, u, g) - else: - if sys.platform != "os2emx": - os.chown(targetpath, u, g) - except EnvironmentError as e: - raise ExtractError("could not change owner") - - def chmod(self, tarinfo, targetpath): - """Set file permissions of targetpath according to tarinfo. - """ - if hasattr(os, 'chmod'): - try: - os.chmod(targetpath, tarinfo.mode) - except EnvironmentError as e: - raise ExtractError("could not change mode") - - def utime(self, tarinfo, targetpath): - """Set modification time of targetpath according to tarinfo. - """ - if not hasattr(os, 'utime'): - return - try: - os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) - except EnvironmentError as e: - raise ExtractError("could not change modification time") - - #-------------------------------------------------------------------------- - def next(self): - """Return the next member of the archive as a TarInfo object, when - TarFile is opened for reading. Return None if there is no more - available. - """ - self._check("ra") - if self.firstmember is not None: - m = self.firstmember - self.firstmember = None - return m - - # Read the next block. - self.fileobj.seek(self.offset) - tarinfo = None - while True: - try: - tarinfo = self.tarinfo.fromtarfile(self) - except EOFHeaderError as e: - if self.ignore_zeros: - self._dbg(2, "0x%X: %s" % (self.offset, e)) - self.offset += BLOCKSIZE - continue - except InvalidHeaderError as e: - if self.ignore_zeros: - self._dbg(2, "0x%X: %s" % (self.offset, e)) - self.offset += BLOCKSIZE - continue - elif self.offset == 0: - raise ReadError(str(e)) - except EmptyHeaderError: - if self.offset == 0: - raise ReadError("empty file") - except TruncatedHeaderError as e: - if self.offset == 0: - raise ReadError(str(e)) - except SubsequentHeaderError as e: - raise ReadError(str(e)) - break - - if tarinfo is not None: - self.members.append(tarinfo) - else: - self._loaded = True - - return tarinfo - - #-------------------------------------------------------------------------- - # Little helper methods: - - def _getmember(self, name, tarinfo=None, normalize=False): - """Find an archive member by name from bottom to top. - If tarinfo is given, it is used as the starting point. - """ - # Ensure that all members have been loaded. - members = self.getmembers() - - # Limit the member search list up to tarinfo. - if tarinfo is not None: - members = members[:members.index(tarinfo)] - - if normalize: - name = os.path.normpath(name) - - for member in reversed(members): - if normalize: - member_name = os.path.normpath(member.name) - else: - member_name = member.name - - if name == member_name: - return member - - def _load(self): - """Read through the entire archive file and look for readable - members. - """ - while True: - tarinfo = self.next() - if tarinfo is None: - break - self._loaded = True - - def _check(self, mode=None): - """Check if TarFile is still open, and if the operation's mode - corresponds to TarFile's mode. - """ - if self.closed: - raise IOError("%s is closed" % self.__class__.__name__) - if mode is not None and self.mode not in mode: - raise IOError("bad operation for mode %r" % self.mode) - - def _find_link_target(self, tarinfo): - """Find the target member of a symlink or hardlink member in the - archive. - """ - if tarinfo.issym(): - # Always search the entire archive. - linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname - limit = None - else: - # Search the archive before the link, because a hard link is - # just a reference to an already archived file. - linkname = tarinfo.linkname - limit = tarinfo - - member = self._getmember(linkname, tarinfo=limit, normalize=True) - if member is None: - raise KeyError("linkname %r not found" % linkname) - return member - - def __iter__(self): - """Provide an iterator object. - """ - if self._loaded: - return iter(self.members) - else: - return TarIter(self) - - def _dbg(self, level, msg): - """Write debugging output to sys.stderr. - """ - if level <= self.debug: - print(msg, file=sys.stderr) - - def __enter__(self): - self._check() - return self - - def __exit__(self, type, value, traceback): - if type is None: - self.close() - else: - # An exception occurred. We must not call close() because - # it would try to write end-of-archive blocks and padding. - if not self._extfileobj: - self.fileobj.close() - self.closed = True -# class TarFile - -class TarIter(object): - """Iterator Class. - - for tarinfo in TarFile(...): - suite... - """ - - def __init__(self, tarfile): - """Construct a TarIter object. - """ - self.tarfile = tarfile - self.index = 0 - def __iter__(self): - """Return iterator object. - """ - return self - - def __next__(self): - """Return the next item using TarFile's next() method. - When all members have been read, set TarFile as _loaded. - """ - # Fix for SF #1100429: Under rare circumstances it can - # happen that getmembers() is called during iteration, - # which will cause TarIter to stop prematurely. - if not self.tarfile._loaded: - tarinfo = self.tarfile.next() - if not tarinfo: - self.tarfile._loaded = True - raise StopIteration - else: - try: - tarinfo = self.tarfile.members[self.index] - except IndexError: - raise StopIteration - self.index += 1 - return tarinfo - - next = __next__ # for Python 2.x - -#-------------------- -# exported functions -#-------------------- -def is_tarfile(name): - """Return True if name points to a tar archive that we - are able to handle, else return False. - """ - try: - t = open(name) - t.close() - return True - except TarError: - return False - -bltn_open = open -open = TarFile.open diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/compat.py deleted file mode 100644 index ff328c8..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/compat.py +++ /dev/null @@ -1,1120 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2017 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -from __future__ import absolute_import - -import os -import re -import sys - -try: - import ssl -except ImportError: # pragma: no cover - ssl = None - -if sys.version_info[0] < 3: # pragma: no cover - from StringIO import StringIO - string_types = basestring, - text_type = unicode - from types import FileType as file_type - import __builtin__ as builtins - import ConfigParser as configparser - from ._backport import shutil - from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit - from urllib import (urlretrieve, quote as _quote, unquote, url2pathname, - pathname2url, ContentTooShortError, splittype) - - def quote(s): - if isinstance(s, unicode): - s = s.encode('utf-8') - return _quote(s) - - import urllib2 - from urllib2 import (Request, urlopen, URLError, HTTPError, - HTTPBasicAuthHandler, HTTPPasswordMgr, - HTTPHandler, HTTPRedirectHandler, - build_opener) - if ssl: - from urllib2 import HTTPSHandler - import httplib - import xmlrpclib - import Queue as queue - from HTMLParser import HTMLParser - import htmlentitydefs - raw_input = raw_input - from itertools import ifilter as filter - from itertools import ifilterfalse as filterfalse - - _userprog = None - def splituser(host): - """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" - global _userprog - if _userprog is None: - import re - _userprog = re.compile('^(.*)@(.*)$') - - match = _userprog.match(host) - if match: return match.group(1, 2) - return None, host - -else: # pragma: no cover - from io import StringIO - string_types = str, - text_type = str - from io import TextIOWrapper as file_type - import builtins - import configparser - import shutil - from urllib.parse import (urlparse, urlunparse, urljoin, splituser, quote, - unquote, urlsplit, urlunsplit, splittype) - from urllib.request import (urlopen, urlretrieve, Request, url2pathname, - pathname2url, - HTTPBasicAuthHandler, HTTPPasswordMgr, - HTTPHandler, HTTPRedirectHandler, - build_opener) - if ssl: - from urllib.request import HTTPSHandler - from urllib.error import HTTPError, URLError, ContentTooShortError - import http.client as httplib - import urllib.request as urllib2 - import xmlrpc.client as xmlrpclib - import queue - from html.parser import HTMLParser - import html.entities as htmlentitydefs - raw_input = input - from itertools import filterfalse - filter = filter - -try: - from ssl import match_hostname, CertificateError -except ImportError: # pragma: no cover - class CertificateError(ValueError): - pass - - - def _dnsname_match(dn, hostname, max_wildcards=1): - """Matching according to RFC 6125, section 6.4.3 - - http://tools.ietf.org/html/rfc6125#section-6.4.3 - """ - pats = [] - if not dn: - return False - - parts = dn.split('.') - leftmost, remainder = parts[0], parts[1:] - - wildcards = leftmost.count('*') - if wildcards > max_wildcards: - # Issue #17980: avoid denials of service by refusing more - # than one wildcard per fragment. A survey of established - # policy among SSL implementations showed it to be a - # reasonable choice. - raise CertificateError( - "too many wildcards in certificate DNS name: " + repr(dn)) - - # speed up common case w/o wildcards - if not wildcards: - return dn.lower() == hostname.lower() - - # RFC 6125, section 6.4.3, subitem 1. - # The client SHOULD NOT attempt to match a presented identifier in which - # the wildcard character comprises a label other than the left-most label. - if leftmost == '*': - # When '*' is a fragment by itself, it matches a non-empty dotless - # fragment. - pats.append('[^.]+') - elif leftmost.startswith('xn--') or hostname.startswith('xn--'): - # RFC 6125, section 6.4.3, subitem 3. - # The client SHOULD NOT attempt to match a presented identifier - # where the wildcard character is embedded within an A-label or - # U-label of an internationalized domain name. - pats.append(re.escape(leftmost)) - else: - # Otherwise, '*' matches any dotless string, e.g. www* - pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) - - # add the remaining fragments, ignore any wildcards - for frag in remainder: - pats.append(re.escape(frag)) - - pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) - return pat.match(hostname) - - - def match_hostname(cert, hostname): - """Verify that *cert* (in decoded format as returned by - SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 - rules are followed, but IP addresses are not accepted for *hostname*. - - CertificateError is raised on failure. On success, the function - returns nothing. - """ - if not cert: - raise ValueError("empty or no certificate, match_hostname needs a " - "SSL socket or SSL context with either " - "CERT_OPTIONAL or CERT_REQUIRED") - dnsnames = [] - san = cert.get('subjectAltName', ()) - for key, value in san: - if key == 'DNS': - if _dnsname_match(value, hostname): - return - dnsnames.append(value) - if not dnsnames: - # The subject is only checked when there is no dNSName entry - # in subjectAltName - for sub in cert.get('subject', ()): - for key, value in sub: - # XXX according to RFC 2818, the most specific Common Name - # must be used. - if key == 'commonName': - if _dnsname_match(value, hostname): - return - dnsnames.append(value) - if len(dnsnames) > 1: - raise CertificateError("hostname %r " - "doesn't match either of %s" - % (hostname, ', '.join(map(repr, dnsnames)))) - elif len(dnsnames) == 1: - raise CertificateError("hostname %r " - "doesn't match %r" - % (hostname, dnsnames[0])) - else: - raise CertificateError("no appropriate commonName or " - "subjectAltName fields were found") - - -try: - from types import SimpleNamespace as Container -except ImportError: # pragma: no cover - class Container(object): - """ - A generic container for when multiple values need to be returned - """ - def __init__(self, **kwargs): - self.__dict__.update(kwargs) - - -try: - from shutil import which -except ImportError: # pragma: no cover - # Implementation from Python 3.3 - def which(cmd, mode=os.F_OK | os.X_OK, path=None): - """Given a command, mode, and a PATH string, return the path which - conforms to the given mode on the PATH, or None if there is no such - file. - - `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result - of os.environ.get("PATH"), or can be overridden with a custom search - path. - - """ - # Check that a given file can be accessed with the correct mode. - # Additionally check that `file` is not a directory, as on Windows - # directories pass the os.access check. - def _access_check(fn, mode): - return (os.path.exists(fn) and os.access(fn, mode) - and not os.path.isdir(fn)) - - # If we're given a path with a directory part, look it up directly rather - # than referring to PATH directories. This includes checking relative to the - # current directory, e.g. ./script - if os.path.dirname(cmd): - if _access_check(cmd, mode): - return cmd - return None - - if path is None: - path = os.environ.get("PATH", os.defpath) - if not path: - return None - path = path.split(os.pathsep) - - if sys.platform == "win32": - # The current directory takes precedence on Windows. - if not os.curdir in path: - path.insert(0, os.curdir) - - # PATHEXT is necessary to check on Windows. - pathext = os.environ.get("PATHEXT", "").split(os.pathsep) - # See if the given file matches any of the expected path extensions. - # This will allow us to short circuit when given "python.exe". - # If it does match, only test that one, otherwise we have to try - # others. - if any(cmd.lower().endswith(ext.lower()) for ext in pathext): - files = [cmd] - else: - files = [cmd + ext for ext in pathext] - else: - # On other platforms you don't have things like PATHEXT to tell you - # what file suffixes are executable, so just pass on cmd as-is. - files = [cmd] - - seen = set() - for dir in path: - normdir = os.path.normcase(dir) - if not normdir in seen: - seen.add(normdir) - for thefile in files: - name = os.path.join(dir, thefile) - if _access_check(name, mode): - return name - return None - - -# ZipFile is a context manager in 2.7, but not in 2.6 - -from zipfile import ZipFile as BaseZipFile - -if hasattr(BaseZipFile, '__enter__'): # pragma: no cover - ZipFile = BaseZipFile -else: # pragma: no cover - from zipfile import ZipExtFile as BaseZipExtFile - - class ZipExtFile(BaseZipExtFile): - def __init__(self, base): - self.__dict__.update(base.__dict__) - - def __enter__(self): - return self - - def __exit__(self, *exc_info): - self.close() - # return None, so if an exception occurred, it will propagate - - class ZipFile(BaseZipFile): - def __enter__(self): - return self - - def __exit__(self, *exc_info): - self.close() - # return None, so if an exception occurred, it will propagate - - def open(self, *args, **kwargs): - base = BaseZipFile.open(self, *args, **kwargs) - return ZipExtFile(base) - -try: - from platform import python_implementation -except ImportError: # pragma: no cover - def python_implementation(): - """Return a string identifying the Python implementation.""" - if 'PyPy' in sys.version: - return 'PyPy' - if os.name == 'java': - return 'Jython' - if sys.version.startswith('IronPython'): - return 'IronPython' - return 'CPython' - -try: - import sysconfig -except ImportError: # pragma: no cover - from ._backport import sysconfig - -try: - callable = callable -except NameError: # pragma: no cover - from collections import Callable - - def callable(obj): - return isinstance(obj, Callable) - - -try: - fsencode = os.fsencode - fsdecode = os.fsdecode -except AttributeError: # pragma: no cover - # Issue #99: on some systems (e.g. containerised), - # sys.getfilesystemencoding() returns None, and we need a real value, - # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and - # sys.getfilesystemencoding(): the return value is "the user’s preference - # according to the result of nl_langinfo(CODESET), or None if the - # nl_langinfo(CODESET) failed." - _fsencoding = sys.getfilesystemencoding() or 'utf-8' - if _fsencoding == 'mbcs': - _fserrors = 'strict' - else: - _fserrors = 'surrogateescape' - - def fsencode(filename): - if isinstance(filename, bytes): - return filename - elif isinstance(filename, text_type): - return filename.encode(_fsencoding, _fserrors) - else: - raise TypeError("expect bytes or str, not %s" % - type(filename).__name__) - - def fsdecode(filename): - if isinstance(filename, text_type): - return filename - elif isinstance(filename, bytes): - return filename.decode(_fsencoding, _fserrors) - else: - raise TypeError("expect bytes or str, not %s" % - type(filename).__name__) - -try: - from tokenize import detect_encoding -except ImportError: # pragma: no cover - from codecs import BOM_UTF8, lookup - import re - - cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)") - - def _get_normal_name(orig_enc): - """Imitates get_normal_name in tokenizer.c.""" - # Only care about the first 12 characters. - enc = orig_enc[:12].lower().replace("_", "-") - if enc == "utf-8" or enc.startswith("utf-8-"): - return "utf-8" - if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ - enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): - return "iso-8859-1" - return orig_enc - - def detect_encoding(readline): - """ - The detect_encoding() function is used to detect the encoding that should - be used to decode a Python source file. It requires one argument, readline, - in the same way as the tokenize() generator. - - It will call readline a maximum of twice, and return the encoding used - (as a string) and a list of any lines (left as bytes) it has read in. - - It detects the encoding from the presence of a utf-8 bom or an encoding - cookie as specified in pep-0263. If both a bom and a cookie are present, - but disagree, a SyntaxError will be raised. If the encoding cookie is an - invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, - 'utf-8-sig' is returned. - - If no encoding is specified, then the default of 'utf-8' will be returned. - """ - try: - filename = readline.__self__.name - except AttributeError: - filename = None - bom_found = False - encoding = None - default = 'utf-8' - def read_or_stop(): - try: - return readline() - except StopIteration: - return b'' - - def find_cookie(line): - try: - # Decode as UTF-8. Either the line is an encoding declaration, - # in which case it should be pure ASCII, or it must be UTF-8 - # per default encoding. - line_string = line.decode('utf-8') - except UnicodeDecodeError: - msg = "invalid or missing encoding declaration" - if filename is not None: - msg = '{} for {!r}'.format(msg, filename) - raise SyntaxError(msg) - - matches = cookie_re.findall(line_string) - if not matches: - return None - encoding = _get_normal_name(matches[0]) - try: - codec = lookup(encoding) - except LookupError: - # This behaviour mimics the Python interpreter - if filename is None: - msg = "unknown encoding: " + encoding - else: - msg = "unknown encoding for {!r}: {}".format(filename, - encoding) - raise SyntaxError(msg) - - if bom_found: - if codec.name != 'utf-8': - # This behaviour mimics the Python interpreter - if filename is None: - msg = 'encoding problem: utf-8' - else: - msg = 'encoding problem for {!r}: utf-8'.format(filename) - raise SyntaxError(msg) - encoding += '-sig' - return encoding - - first = read_or_stop() - if first.startswith(BOM_UTF8): - bom_found = True - first = first[3:] - default = 'utf-8-sig' - if not first: - return default, [] - - encoding = find_cookie(first) - if encoding: - return encoding, [first] - - second = read_or_stop() - if not second: - return default, [first] - - encoding = find_cookie(second) - if encoding: - return encoding, [first, second] - - return default, [first, second] - -# For converting & <-> & etc. -try: - from html import escape -except ImportError: - from cgi import escape -if sys.version_info[:2] < (3, 4): - unescape = HTMLParser().unescape -else: - from html import unescape - -try: - from collections import ChainMap -except ImportError: # pragma: no cover - from collections import MutableMapping - - try: - from reprlib import recursive_repr as _recursive_repr - except ImportError: - def _recursive_repr(fillvalue='...'): - ''' - Decorator to make a repr function return fillvalue for a recursive - call - ''' - - def decorating_function(user_function): - repr_running = set() - - def wrapper(self): - key = id(self), get_ident() - if key in repr_running: - return fillvalue - repr_running.add(key) - try: - result = user_function(self) - finally: - repr_running.discard(key) - return result - - # Can't use functools.wraps() here because of bootstrap issues - wrapper.__module__ = getattr(user_function, '__module__') - wrapper.__doc__ = getattr(user_function, '__doc__') - wrapper.__name__ = getattr(user_function, '__name__') - wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) - return wrapper - - return decorating_function - - class ChainMap(MutableMapping): - ''' A ChainMap groups multiple dicts (or other mappings) together - to create a single, updateable view. - - The underlying mappings are stored in a list. That list is public and can - accessed or updated using the *maps* attribute. There is no other state. - - Lookups search the underlying mappings successively until a key is found. - In contrast, writes, updates, and deletions only operate on the first - mapping. - - ''' - - def __init__(self, *maps): - '''Initialize a ChainMap by setting *maps* to the given mappings. - If no mappings are provided, a single empty dictionary is used. - - ''' - self.maps = list(maps) or [{}] # always at least one map - - def __missing__(self, key): - raise KeyError(key) - - def __getitem__(self, key): - for mapping in self.maps: - try: - return mapping[key] # can't use 'key in mapping' with defaultdict - except KeyError: - pass - return self.__missing__(key) # support subclasses that define __missing__ - - def get(self, key, default=None): - return self[key] if key in self else default - - def __len__(self): - return len(set().union(*self.maps)) # reuses stored hash values if possible - - def __iter__(self): - return iter(set().union(*self.maps)) - - def __contains__(self, key): - return any(key in m for m in self.maps) - - def __bool__(self): - return any(self.maps) - - @_recursive_repr() - def __repr__(self): - return '{0.__class__.__name__}({1})'.format( - self, ', '.join(map(repr, self.maps))) - - @classmethod - def fromkeys(cls, iterable, *args): - 'Create a ChainMap with a single dict created from the iterable.' - return cls(dict.fromkeys(iterable, *args)) - - def copy(self): - 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' - return self.__class__(self.maps[0].copy(), *self.maps[1:]) - - __copy__ = copy - - def new_child(self): # like Django's Context.push() - 'New ChainMap with a new dict followed by all previous maps.' - return self.__class__({}, *self.maps) - - @property - def parents(self): # like Django's Context.pop() - 'New ChainMap from maps[1:].' - return self.__class__(*self.maps[1:]) - - def __setitem__(self, key, value): - self.maps[0][key] = value - - def __delitem__(self, key): - try: - del self.maps[0][key] - except KeyError: - raise KeyError('Key not found in the first mapping: {!r}'.format(key)) - - def popitem(self): - 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' - try: - return self.maps[0].popitem() - except KeyError: - raise KeyError('No keys found in the first mapping.') - - def pop(self, key, *args): - 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' - try: - return self.maps[0].pop(key, *args) - except KeyError: - raise KeyError('Key not found in the first mapping: {!r}'.format(key)) - - def clear(self): - 'Clear maps[0], leaving maps[1:] intact.' - self.maps[0].clear() - -try: - from importlib.util import cache_from_source # Python >= 3.4 -except ImportError: # pragma: no cover - try: - from imp import cache_from_source - except ImportError: # pragma: no cover - def cache_from_source(path, debug_override=None): - assert path.endswith('.py') - if debug_override is None: - debug_override = __debug__ - if debug_override: - suffix = 'c' - else: - suffix = 'o' - return path + suffix - -try: - from collections import OrderedDict -except ImportError: # pragma: no cover -## {{{ http://code.activestate.com/recipes/576693/ (r9) -# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. -# Passes Python2.7's test suite and incorporates all the latest updates. - try: - from thread import get_ident as _get_ident - except ImportError: - from dummy_thread import get_ident as _get_ident - - try: - from _abcoll import KeysView, ValuesView, ItemsView - except ImportError: - pass - - - class OrderedDict(dict): - 'Dictionary that remembers insertion order' - # An inherited dict maps keys to values. - # The inherited dict provides __getitem__, __len__, __contains__, and get. - # The remaining methods are order-aware. - # Big-O running times for all methods are the same as for regular dictionaries. - - # The internal self.__map dictionary maps keys to links in a doubly linked list. - # The circular doubly linked list starts and ends with a sentinel element. - # The sentinel element never gets deleted (this simplifies the algorithm). - # Each link is stored as a list of length three: [PREV, NEXT, KEY]. - - def __init__(self, *args, **kwds): - '''Initialize an ordered dictionary. Signature is the same as for - regular dictionaries, but keyword arguments are not recommended - because their insertion order is arbitrary. - - ''' - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) - try: - self.__root - except AttributeError: - self.__root = root = [] # sentinel node - root[:] = [root, root, None] - self.__map = {} - self.__update(*args, **kwds) - - def __setitem__(self, key, value, dict_setitem=dict.__setitem__): - 'od.__setitem__(i, y) <==> od[i]=y' - # Setting a new item creates a new link which goes at the end of the linked - # list, and the inherited dictionary is updated with the new key/value pair. - if key not in self: - root = self.__root - last = root[0] - last[1] = root[0] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) - - def __delitem__(self, key, dict_delitem=dict.__delitem__): - 'od.__delitem__(y) <==> del od[y]' - # Deleting an existing item uses self.__map to find the link which is - # then removed by updating the links in the predecessor and successor nodes. - dict_delitem(self, key) - link_prev, link_next, key = self.__map.pop(key) - link_prev[1] = link_next - link_next[0] = link_prev - - def __iter__(self): - 'od.__iter__() <==> iter(od)' - root = self.__root - curr = root[1] - while curr is not root: - yield curr[2] - curr = curr[1] - - def __reversed__(self): - 'od.__reversed__() <==> reversed(od)' - root = self.__root - curr = root[0] - while curr is not root: - yield curr[2] - curr = curr[0] - - def clear(self): - 'od.clear() -> None. Remove all items from od.' - try: - for node in self.__map.itervalues(): - del node[:] - root = self.__root - root[:] = [root, root, None] - self.__map.clear() - except AttributeError: - pass - dict.clear(self) - - def popitem(self, last=True): - '''od.popitem() -> (k, v), return and remove a (key, value) pair. - Pairs are returned in LIFO order if last is true or FIFO order if false. - - ''' - if not self: - raise KeyError('dictionary is empty') - root = self.__root - if last: - link = root[0] - link_prev = link[0] - link_prev[1] = root - root[0] = link_prev - else: - link = root[1] - link_next = link[1] - root[1] = link_next - link_next[0] = root - key = link[2] - del self.__map[key] - value = dict.pop(self, key) - return key, value - - # -- the following methods do not depend on the internal structure -- - - def keys(self): - 'od.keys() -> list of keys in od' - return list(self) - - def values(self): - 'od.values() -> list of values in od' - return [self[key] for key in self] - - def items(self): - 'od.items() -> list of (key, value) pairs in od' - return [(key, self[key]) for key in self] - - def iterkeys(self): - 'od.iterkeys() -> an iterator over the keys in od' - return iter(self) - - def itervalues(self): - 'od.itervalues -> an iterator over the values in od' - for k in self: - yield self[k] - - def iteritems(self): - 'od.iteritems -> an iterator over the (key, value) items in od' - for k in self: - yield (k, self[k]) - - def update(*args, **kwds): - '''od.update(E, **F) -> None. Update od from dict/iterable E and F. - - If E is a dict instance, does: for k in E: od[k] = E[k] - If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] - Or if E is an iterable of items, does: for k, v in E: od[k] = v - In either case, this is followed by: for k, v in F.items(): od[k] = v - - ''' - if len(args) > 2: - raise TypeError('update() takes at most 2 positional ' - 'arguments (%d given)' % (len(args),)) - elif not args: - raise TypeError('update() takes at least 1 argument (0 given)') - self = args[0] - # Make progressively weaker assumptions about "other" - other = () - if len(args) == 2: - other = args[1] - if isinstance(other, dict): - for key in other: - self[key] = other[key] - elif hasattr(other, 'keys'): - for key in other.keys(): - self[key] = other[key] - else: - for key, value in other: - self[key] = value - for key, value in kwds.items(): - self[key] = value - - __update = update # let subclasses override update without breaking __init__ - - __marker = object() - - def pop(self, key, default=__marker): - '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. - If key is not found, d is returned if given, otherwise KeyError is raised. - - ''' - if key in self: - result = self[key] - del self[key] - return result - if default is self.__marker: - raise KeyError(key) - return default - - def setdefault(self, key, default=None): - 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' - if key in self: - return self[key] - self[key] = default - return default - - def __repr__(self, _repr_running=None): - 'od.__repr__() <==> repr(od)' - if not _repr_running: _repr_running = {} - call_key = id(self), _get_ident() - if call_key in _repr_running: - return '...' - _repr_running[call_key] = 1 - try: - if not self: - return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, self.items()) - finally: - del _repr_running[call_key] - - def __reduce__(self): - 'Return state information for pickling' - items = [[k, self[k]] for k in self] - inst_dict = vars(self).copy() - for k in vars(OrderedDict()): - inst_dict.pop(k, None) - if inst_dict: - return (self.__class__, (items,), inst_dict) - return self.__class__, (items,) - - def copy(self): - 'od.copy() -> a shallow copy of od' - return self.__class__(self) - - @classmethod - def fromkeys(cls, iterable, value=None): - '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S - and values equal to v (which defaults to None). - - ''' - d = cls() - for key in iterable: - d[key] = value - return d - - def __eq__(self, other): - '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive - while comparison to a regular mapping is order-insensitive. - - ''' - if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() - return dict.__eq__(self, other) - - def __ne__(self, other): - return not self == other - - # -- the following methods are only used in Python 2.7 -- - - def viewkeys(self): - "od.viewkeys() -> a set-like object providing a view on od's keys" - return KeysView(self) - - def viewvalues(self): - "od.viewvalues() -> an object providing a view on od's values" - return ValuesView(self) - - def viewitems(self): - "od.viewitems() -> a set-like object providing a view on od's items" - return ItemsView(self) - -try: - from logging.config import BaseConfigurator, valid_ident -except ImportError: # pragma: no cover - IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) - - - def valid_ident(s): - m = IDENTIFIER.match(s) - if not m: - raise ValueError('Not a valid Python identifier: %r' % s) - return True - - - # The ConvertingXXX classes are wrappers around standard Python containers, - # and they serve to convert any suitable values in the container. The - # conversion converts base dicts, lists and tuples to their wrapped - # equivalents, whereas strings which match a conversion format are converted - # appropriately. - # - # Each wrapper should have a configurator attribute holding the actual - # configurator to use for conversion. - - class ConvertingDict(dict): - """A converting dictionary wrapper.""" - - def __getitem__(self, key): - value = dict.__getitem__(self, key) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result - - def get(self, key, default=None): - value = dict.get(self, key, default) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result - - def pop(self, key, default=None): - value = dict.pop(self, key, default) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result - - class ConvertingList(list): - """A converting list wrapper.""" - def __getitem__(self, key): - value = list.__getitem__(self, key) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result - - def pop(self, idx=-1): - value = list.pop(self, idx) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - return result - - class ConvertingTuple(tuple): - """A converting tuple wrapper.""" - def __getitem__(self, key): - value = tuple.__getitem__(self, key) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result - - class BaseConfigurator(object): - """ - The configurator base class which defines some useful defaults. - """ - - CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$') - - WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') - DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') - INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') - DIGIT_PATTERN = re.compile(r'^\d+$') - - value_converters = { - 'ext' : 'ext_convert', - 'cfg' : 'cfg_convert', - } - - # We might want to use a different one, e.g. importlib - importer = staticmethod(__import__) - - def __init__(self, config): - self.config = ConvertingDict(config) - self.config.configurator = self - - def resolve(self, s): - """ - Resolve strings to objects using standard import and attribute - syntax. - """ - name = s.split('.') - used = name.pop(0) - try: - found = self.importer(used) - for frag in name: - used += '.' + frag - try: - found = getattr(found, frag) - except AttributeError: - self.importer(used) - found = getattr(found, frag) - return found - except ImportError: - e, tb = sys.exc_info()[1:] - v = ValueError('Cannot resolve %r: %s' % (s, e)) - v.__cause__, v.__traceback__ = e, tb - raise v - - def ext_convert(self, value): - """Default converter for the ext:// protocol.""" - return self.resolve(value) - - def cfg_convert(self, value): - """Default converter for the cfg:// protocol.""" - rest = value - m = self.WORD_PATTERN.match(rest) - if m is None: - raise ValueError("Unable to convert %r" % value) - else: - rest = rest[m.end():] - d = self.config[m.groups()[0]] - #print d, rest - while rest: - m = self.DOT_PATTERN.match(rest) - if m: - d = d[m.groups()[0]] - else: - m = self.INDEX_PATTERN.match(rest) - if m: - idx = m.groups()[0] - if not self.DIGIT_PATTERN.match(idx): - d = d[idx] - else: - try: - n = int(idx) # try as number first (most likely) - d = d[n] - except TypeError: - d = d[idx] - if m: - rest = rest[m.end():] - else: - raise ValueError('Unable to convert ' - '%r at %r' % (value, rest)) - #rest should be empty - return d - - def convert(self, value): - """ - Convert values to an appropriate type. dicts, lists and tuples are - replaced by their converting alternatives. Strings are checked to - see if they have a conversion format and are converted if they do. - """ - if not isinstance(value, ConvertingDict) and isinstance(value, dict): - value = ConvertingDict(value) - value.configurator = self - elif not isinstance(value, ConvertingList) and isinstance(value, list): - value = ConvertingList(value) - value.configurator = self - elif not isinstance(value, ConvertingTuple) and\ - isinstance(value, tuple): - value = ConvertingTuple(value) - value.configurator = self - elif isinstance(value, string_types): - m = self.CONVERT_PATTERN.match(value) - if m: - d = m.groupdict() - prefix = d['prefix'] - converter = self.value_converters.get(prefix, None) - if converter: - suffix = d['suffix'] - converter = getattr(self, converter) - value = converter(suffix) - return value - - def configure_custom(self, config): - """Configure an object with a user-supplied factory.""" - c = config.pop('()') - if not callable(c): - c = self.resolve(c) - props = config.pop('.', None) - # Check for valid identifiers - kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) - result = c(**kwargs) - if props: - for name, value in props.items(): - setattr(result, name, value) - return result - - def as_tuple(self, value): - """Utility function which converts lists to tuples.""" - if isinstance(value, list): - value = tuple(value) - return value diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/database.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/database.py deleted file mode 100644 index b13cdac..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/database.py +++ /dev/null @@ -1,1339 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2017 The Python Software Foundation. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -"""PEP 376 implementation.""" - -from __future__ import unicode_literals - -import base64 -import codecs -import contextlib -import hashlib -import logging -import os -import posixpath -import sys -import zipimport - -from . import DistlibException, resources -from .compat import StringIO -from .version import get_scheme, UnsupportedVersionError -from .metadata import (Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME, - LEGACY_METADATA_FILENAME) -from .util import (parse_requirement, cached_property, parse_name_and_version, - read_exports, write_exports, CSVReader, CSVWriter) - - -__all__ = ['Distribution', 'BaseInstalledDistribution', - 'InstalledDistribution', 'EggInfoDistribution', - 'DistributionPath'] - - -logger = logging.getLogger(__name__) - -EXPORTS_FILENAME = 'pydist-exports.json' -COMMANDS_FILENAME = 'pydist-commands.json' - -DIST_FILES = ('INSTALLER', METADATA_FILENAME, 'RECORD', 'REQUESTED', - 'RESOURCES', EXPORTS_FILENAME, 'SHARED') - -DISTINFO_EXT = '.dist-info' - - -class _Cache(object): - """ - A simple cache mapping names and .dist-info paths to distributions - """ - def __init__(self): - """ - Initialise an instance. There is normally one for each DistributionPath. - """ - self.name = {} - self.path = {} - self.generated = False - - def clear(self): - """ - Clear the cache, setting it to its initial state. - """ - self.name.clear() - self.path.clear() - self.generated = False - - def add(self, dist): - """ - Add a distribution to the cache. - :param dist: The distribution to add. - """ - if dist.path not in self.path: - self.path[dist.path] = dist - self.name.setdefault(dist.key, []).append(dist) - - -class DistributionPath(object): - """ - Represents a set of distributions installed on a path (typically sys.path). - """ - def __init__(self, path=None, include_egg=False): - """ - Create an instance from a path, optionally including legacy (distutils/ - setuptools/distribute) distributions. - :param path: The path to use, as a list of directories. If not specified, - sys.path is used. - :param include_egg: If True, this instance will look for and return legacy - distributions as well as those based on PEP 376. - """ - if path is None: - path = sys.path - self.path = path - self._include_dist = True - self._include_egg = include_egg - - self._cache = _Cache() - self._cache_egg = _Cache() - self._cache_enabled = True - self._scheme = get_scheme('default') - - def _get_cache_enabled(self): - return self._cache_enabled - - def _set_cache_enabled(self, value): - self._cache_enabled = value - - cache_enabled = property(_get_cache_enabled, _set_cache_enabled) - - def clear_cache(self): - """ - Clears the internal cache. - """ - self._cache.clear() - self._cache_egg.clear() - - - def _yield_distributions(self): - """ - Yield .dist-info and/or .egg(-info) distributions. - """ - # We need to check if we've seen some resources already, because on - # some Linux systems (e.g. some Debian/Ubuntu variants) there are - # symlinks which alias other files in the environment. - seen = set() - for path in self.path: - finder = resources.finder_for_path(path) - if finder is None: - continue - r = finder.find('') - if not r or not r.is_container: - continue - rset = sorted(r.resources) - for entry in rset: - r = finder.find(entry) - if not r or r.path in seen: - continue - if self._include_dist and entry.endswith(DISTINFO_EXT): - possible_filenames = [METADATA_FILENAME, - WHEEL_METADATA_FILENAME, - LEGACY_METADATA_FILENAME] - for metadata_filename in possible_filenames: - metadata_path = posixpath.join(entry, metadata_filename) - pydist = finder.find(metadata_path) - if pydist: - break - else: - continue - - with contextlib.closing(pydist.as_stream()) as stream: - metadata = Metadata(fileobj=stream, scheme='legacy') - logger.debug('Found %s', r.path) - seen.add(r.path) - yield new_dist_class(r.path, metadata=metadata, - env=self) - elif self._include_egg and entry.endswith(('.egg-info', - '.egg')): - logger.debug('Found %s', r.path) - seen.add(r.path) - yield old_dist_class(r.path, self) - - def _generate_cache(self): - """ - Scan the path for distributions and populate the cache with - those that are found. - """ - gen_dist = not self._cache.generated - gen_egg = self._include_egg and not self._cache_egg.generated - if gen_dist or gen_egg: - for dist in self._yield_distributions(): - if isinstance(dist, InstalledDistribution): - self._cache.add(dist) - else: - self._cache_egg.add(dist) - - if gen_dist: - self._cache.generated = True - if gen_egg: - self._cache_egg.generated = True - - @classmethod - def distinfo_dirname(cls, name, version): - """ - The *name* and *version* parameters are converted into their - filename-escaped form, i.e. any ``'-'`` characters are replaced - with ``'_'`` other than the one in ``'dist-info'`` and the one - separating the name from the version number. - - :parameter name: is converted to a standard distribution name by replacing - any runs of non- alphanumeric characters with a single - ``'-'``. - :type name: string - :parameter version: is converted to a standard version string. Spaces - become dots, and all other non-alphanumeric characters - (except dots) become dashes, with runs of multiple - dashes condensed to a single dash. - :type version: string - :returns: directory name - :rtype: string""" - name = name.replace('-', '_') - return '-'.join([name, version]) + DISTINFO_EXT - - def get_distributions(self): - """ - Provides an iterator that looks for distributions and returns - :class:`InstalledDistribution` or - :class:`EggInfoDistribution` instances for each one of them. - - :rtype: iterator of :class:`InstalledDistribution` and - :class:`EggInfoDistribution` instances - """ - if not self._cache_enabled: - for dist in self._yield_distributions(): - yield dist - else: - self._generate_cache() - - for dist in self._cache.path.values(): - yield dist - - if self._include_egg: - for dist in self._cache_egg.path.values(): - yield dist - - def get_distribution(self, name): - """ - Looks for a named distribution on the path. - - This function only returns the first result found, as no more than one - value is expected. If nothing is found, ``None`` is returned. - - :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` - or ``None`` - """ - result = None - name = name.lower() - if not self._cache_enabled: - for dist in self._yield_distributions(): - if dist.key == name: - result = dist - break - else: - self._generate_cache() - - if name in self._cache.name: - result = self._cache.name[name][0] - elif self._include_egg and name in self._cache_egg.name: - result = self._cache_egg.name[name][0] - return result - - def provides_distribution(self, name, version=None): - """ - Iterates over all distributions to find which distributions provide *name*. - If a *version* is provided, it will be used to filter the results. - - This function only returns the first result found, since no more than - one values are expected. If the directory is not found, returns ``None``. - - :parameter version: a version specifier that indicates the version - required, conforming to the format in ``PEP-345`` - - :type name: string - :type version: string - """ - matcher = None - if version is not None: - try: - matcher = self._scheme.matcher('%s (%s)' % (name, version)) - except ValueError: - raise DistlibException('invalid name or version: %r, %r' % - (name, version)) - - for dist in self.get_distributions(): - # We hit a problem on Travis where enum34 was installed and doesn't - # have a provides attribute ... - if not hasattr(dist, 'provides'): - logger.debug('No "provides": %s', dist) - else: - provided = dist.provides - - for p in provided: - p_name, p_ver = parse_name_and_version(p) - if matcher is None: - if p_name == name: - yield dist - break - else: - if p_name == name and matcher.match(p_ver): - yield dist - break - - def get_file_path(self, name, relative_path): - """ - Return the path to a resource file. - """ - dist = self.get_distribution(name) - if dist is None: - raise LookupError('no distribution named %r found' % name) - return dist.get_resource_path(relative_path) - - def get_exported_entries(self, category, name=None): - """ - Return all of the exported entries in a particular category. - - :param category: The category to search for entries. - :param name: If specified, only entries with that name are returned. - """ - for dist in self.get_distributions(): - r = dist.exports - if category in r: - d = r[category] - if name is not None: - if name in d: - yield d[name] - else: - for v in d.values(): - yield v - - -class Distribution(object): - """ - A base class for distributions, whether installed or from indexes. - Either way, it must have some metadata, so that's all that's needed - for construction. - """ - - build_time_dependency = False - """ - Set to True if it's known to be only a build-time dependency (i.e. - not needed after installation). - """ - - requested = False - """A boolean that indicates whether the ``REQUESTED`` metadata file is - present (in other words, whether the package was installed by user - request or it was installed as a dependency).""" - - def __init__(self, metadata): - """ - Initialise an instance. - :param metadata: The instance of :class:`Metadata` describing this - distribution. - """ - self.metadata = metadata - self.name = metadata.name - self.key = self.name.lower() # for case-insensitive comparisons - self.version = metadata.version - self.locator = None - self.digest = None - self.extras = None # additional features requested - self.context = None # environment marker overrides - self.download_urls = set() - self.digests = {} - - @property - def source_url(self): - """ - The source archive download URL for this distribution. - """ - return self.metadata.source_url - - download_url = source_url # Backward compatibility - - @property - def name_and_version(self): - """ - A utility property which displays the name and version in parentheses. - """ - return '%s (%s)' % (self.name, self.version) - - @property - def provides(self): - """ - A set of distribution names and versions provided by this distribution. - :return: A set of "name (version)" strings. - """ - plist = self.metadata.provides - s = '%s (%s)' % (self.name, self.version) - if s not in plist: - plist.append(s) - return plist - - def _get_requirements(self, req_attr): - md = self.metadata - logger.debug('Getting requirements from metadata %r', md.todict()) - reqts = getattr(md, req_attr) - return set(md.get_requirements(reqts, extras=self.extras, - env=self.context)) - - @property - def run_requires(self): - return self._get_requirements('run_requires') - - @property - def meta_requires(self): - return self._get_requirements('meta_requires') - - @property - def build_requires(self): - return self._get_requirements('build_requires') - - @property - def test_requires(self): - return self._get_requirements('test_requires') - - @property - def dev_requires(self): - return self._get_requirements('dev_requires') - - def matches_requirement(self, req): - """ - Say if this instance matches (fulfills) a requirement. - :param req: The requirement to match. - :rtype req: str - :return: True if it matches, else False. - """ - # Requirement may contain extras - parse to lose those - # from what's passed to the matcher - r = parse_requirement(req) - scheme = get_scheme(self.metadata.scheme) - try: - matcher = scheme.matcher(r.requirement) - except UnsupportedVersionError: - # XXX compat-mode if cannot read the version - logger.warning('could not read version %r - using name only', - req) - name = req.split()[0] - matcher = scheme.matcher(name) - - name = matcher.key # case-insensitive - - result = False - for p in self.provides: - p_name, p_ver = parse_name_and_version(p) - if p_name != name: - continue - try: - result = matcher.match(p_ver) - break - except UnsupportedVersionError: - pass - return result - - def __repr__(self): - """ - Return a textual representation of this instance, - """ - if self.source_url: - suffix = ' [%s]' % self.source_url - else: - suffix = '' - return '<Distribution %s (%s)%s>' % (self.name, self.version, suffix) - - def __eq__(self, other): - """ - See if this distribution is the same as another. - :param other: The distribution to compare with. To be equal to one - another. distributions must have the same type, name, - version and source_url. - :return: True if it is the same, else False. - """ - if type(other) is not type(self): - result = False - else: - result = (self.name == other.name and - self.version == other.version and - self.source_url == other.source_url) - return result - - def __hash__(self): - """ - Compute hash in a way which matches the equality test. - """ - return hash(self.name) + hash(self.version) + hash(self.source_url) - - -class BaseInstalledDistribution(Distribution): - """ - This is the base class for installed distributions (whether PEP 376 or - legacy). - """ - - hasher = None - - def __init__(self, metadata, path, env=None): - """ - Initialise an instance. - :param metadata: An instance of :class:`Metadata` which describes the - distribution. This will normally have been initialised - from a metadata file in the ``path``. - :param path: The path of the ``.dist-info`` or ``.egg-info`` - directory for the distribution. - :param env: This is normally the :class:`DistributionPath` - instance where this distribution was found. - """ - super(BaseInstalledDistribution, self).__init__(metadata) - self.path = path - self.dist_path = env - - def get_hash(self, data, hasher=None): - """ - Get the hash of some data, using a particular hash algorithm, if - specified. - - :param data: The data to be hashed. - :type data: bytes - :param hasher: The name of a hash implementation, supported by hashlib, - or ``None``. Examples of valid values are ``'sha1'``, - ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and - ``'sha512'``. If no hasher is specified, the ``hasher`` - attribute of the :class:`InstalledDistribution` instance - is used. If the hasher is determined to be ``None``, MD5 - is used as the hashing algorithm. - :returns: The hash of the data. If a hasher was explicitly specified, - the returned hash will be prefixed with the specified hasher - followed by '='. - :rtype: str - """ - if hasher is None: - hasher = self.hasher - if hasher is None: - hasher = hashlib.md5 - prefix = '' - else: - hasher = getattr(hashlib, hasher) - prefix = '%s=' % self.hasher - digest = hasher(data).digest() - digest = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii') - return '%s%s' % (prefix, digest) - - -class InstalledDistribution(BaseInstalledDistribution): - """ - Created with the *path* of the ``.dist-info`` directory provided to the - constructor. It reads the metadata contained in ``pydist.json`` when it is - instantiated., or uses a passed in Metadata instance (useful for when - dry-run mode is being used). - """ - - hasher = 'sha256' - - def __init__(self, path, metadata=None, env=None): - self.modules = [] - self.finder = finder = resources.finder_for_path(path) - if finder is None: - raise ValueError('finder unavailable for %s' % path) - if env and env._cache_enabled and path in env._cache.path: - metadata = env._cache.path[path].metadata - elif metadata is None: - r = finder.find(METADATA_FILENAME) - # Temporary - for Wheel 0.23 support - if r is None: - r = finder.find(WHEEL_METADATA_FILENAME) - # Temporary - for legacy support - if r is None: - r = finder.find('METADATA') - if r is None: - raise ValueError('no %s found in %s' % (METADATA_FILENAME, - path)) - with contextlib.closing(r.as_stream()) as stream: - metadata = Metadata(fileobj=stream, scheme='legacy') - - super(InstalledDistribution, self).__init__(metadata, path, env) - - if env and env._cache_enabled: - env._cache.add(self) - - r = finder.find('REQUESTED') - self.requested = r is not None - p = os.path.join(path, 'top_level.txt') - if os.path.exists(p): - with open(p, 'rb') as f: - data = f.read() - self.modules = data.splitlines() - - def __repr__(self): - return '<InstalledDistribution %r %s at %r>' % ( - self.name, self.version, self.path) - - def __str__(self): - return "%s %s" % (self.name, self.version) - - def _get_records(self): - """ - Get the list of installed files for the distribution - :return: A list of tuples of path, hash and size. Note that hash and - size might be ``None`` for some entries. The path is exactly - as stored in the file (which is as in PEP 376). - """ - results = [] - r = self.get_distinfo_resource('RECORD') - with contextlib.closing(r.as_stream()) as stream: - with CSVReader(stream=stream) as record_reader: - # Base location is parent dir of .dist-info dir - #base_location = os.path.dirname(self.path) - #base_location = os.path.abspath(base_location) - for row in record_reader: - missing = [None for i in range(len(row), 3)] - path, checksum, size = row + missing - #if not os.path.isabs(path): - # path = path.replace('/', os.sep) - # path = os.path.join(base_location, path) - results.append((path, checksum, size)) - return results - - @cached_property - def exports(self): - """ - Return the information exported by this distribution. - :return: A dictionary of exports, mapping an export category to a dict - of :class:`ExportEntry` instances describing the individual - export entries, and keyed by name. - """ - result = {} - r = self.get_distinfo_resource(EXPORTS_FILENAME) - if r: - result = self.read_exports() - return result - - def read_exports(self): - """ - Read exports data from a file in .ini format. - - :return: A dictionary of exports, mapping an export category to a list - of :class:`ExportEntry` instances describing the individual - export entries. - """ - result = {} - r = self.get_distinfo_resource(EXPORTS_FILENAME) - if r: - with contextlib.closing(r.as_stream()) as stream: - result = read_exports(stream) - return result - - def write_exports(self, exports): - """ - Write a dictionary of exports to a file in .ini format. - :param exports: A dictionary of exports, mapping an export category to - a list of :class:`ExportEntry` instances describing the - individual export entries. - """ - rf = self.get_distinfo_file(EXPORTS_FILENAME) - with open(rf, 'w') as f: - write_exports(exports, f) - - def get_resource_path(self, relative_path): - """ - NOTE: This API may change in the future. - - Return the absolute path to a resource file with the given relative - path. - - :param relative_path: The path, relative to .dist-info, of the resource - of interest. - :return: The absolute path where the resource is to be found. - """ - r = self.get_distinfo_resource('RESOURCES') - with contextlib.closing(r.as_stream()) as stream: - with CSVReader(stream=stream) as resources_reader: - for relative, destination in resources_reader: - if relative == relative_path: - return destination - raise KeyError('no resource file with relative path %r ' - 'is installed' % relative_path) - - def list_installed_files(self): - """ - Iterates over the ``RECORD`` entries and returns a tuple - ``(path, hash, size)`` for each line. - - :returns: iterator of (path, hash, size) - """ - for result in self._get_records(): - yield result - - def write_installed_files(self, paths, prefix, dry_run=False): - """ - Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any - existing ``RECORD`` file is silently overwritten. - - prefix is used to determine when to write absolute paths. - """ - prefix = os.path.join(prefix, '') - base = os.path.dirname(self.path) - base_under_prefix = base.startswith(prefix) - base = os.path.join(base, '') - record_path = self.get_distinfo_file('RECORD') - logger.info('creating %s', record_path) - if dry_run: - return None - with CSVWriter(record_path) as writer: - for path in paths: - if os.path.isdir(path) or path.endswith(('.pyc', '.pyo')): - # do not put size and hash, as in PEP-376 - hash_value = size = '' - else: - size = '%d' % os.path.getsize(path) - with open(path, 'rb') as fp: - hash_value = self.get_hash(fp.read()) - if path.startswith(base) or (base_under_prefix and - path.startswith(prefix)): - path = os.path.relpath(path, base) - writer.writerow((path, hash_value, size)) - - # add the RECORD file itself - if record_path.startswith(base): - record_path = os.path.relpath(record_path, base) - writer.writerow((record_path, '', '')) - return record_path - - def check_installed_files(self): - """ - Checks that the hashes and sizes of the files in ``RECORD`` are - matched by the files themselves. Returns a (possibly empty) list of - mismatches. Each entry in the mismatch list will be a tuple consisting - of the path, 'exists', 'size' or 'hash' according to what didn't match - (existence is checked first, then size, then hash), the expected - value and the actual value. - """ - mismatches = [] - base = os.path.dirname(self.path) - record_path = self.get_distinfo_file('RECORD') - for path, hash_value, size in self.list_installed_files(): - if not os.path.isabs(path): - path = os.path.join(base, path) - if path == record_path: - continue - if not os.path.exists(path): - mismatches.append((path, 'exists', True, False)) - elif os.path.isfile(path): - actual_size = str(os.path.getsize(path)) - if size and actual_size != size: - mismatches.append((path, 'size', size, actual_size)) - elif hash_value: - if '=' in hash_value: - hasher = hash_value.split('=', 1)[0] - else: - hasher = None - - with open(path, 'rb') as f: - actual_hash = self.get_hash(f.read(), hasher) - if actual_hash != hash_value: - mismatches.append((path, 'hash', hash_value, actual_hash)) - return mismatches - - @cached_property - def shared_locations(self): - """ - A dictionary of shared locations whose keys are in the set 'prefix', - 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. - The corresponding value is the absolute path of that category for - this distribution, and takes into account any paths selected by the - user at installation time (e.g. via command-line arguments). In the - case of the 'namespace' key, this would be a list of absolute paths - for the roots of namespace packages in this distribution. - - The first time this property is accessed, the relevant information is - read from the SHARED file in the .dist-info directory. - """ - result = {} - shared_path = os.path.join(self.path, 'SHARED') - if os.path.isfile(shared_path): - with codecs.open(shared_path, 'r', encoding='utf-8') as f: - lines = f.read().splitlines() - for line in lines: - key, value = line.split('=', 1) - if key == 'namespace': - result.setdefault(key, []).append(value) - else: - result[key] = value - return result - - def write_shared_locations(self, paths, dry_run=False): - """ - Write shared location information to the SHARED file in .dist-info. - :param paths: A dictionary as described in the documentation for - :meth:`shared_locations`. - :param dry_run: If True, the action is logged but no file is actually - written. - :return: The path of the file written to. - """ - shared_path = os.path.join(self.path, 'SHARED') - logger.info('creating %s', shared_path) - if dry_run: - return None - lines = [] - for key in ('prefix', 'lib', 'headers', 'scripts', 'data'): - path = paths[key] - if os.path.isdir(paths[key]): - lines.append('%s=%s' % (key, path)) - for ns in paths.get('namespace', ()): - lines.append('namespace=%s' % ns) - - with codecs.open(shared_path, 'w', encoding='utf-8') as f: - f.write('\n'.join(lines)) - return shared_path - - def get_distinfo_resource(self, path): - if path not in DIST_FILES: - raise DistlibException('invalid path for a dist-info file: ' - '%r at %r' % (path, self.path)) - finder = resources.finder_for_path(self.path) - if finder is None: - raise DistlibException('Unable to get a finder for %s' % self.path) - return finder.find(path) - - def get_distinfo_file(self, path): - """ - Returns a path located under the ``.dist-info`` directory. Returns a - string representing the path. - - :parameter path: a ``'/'``-separated path relative to the - ``.dist-info`` directory or an absolute path; - If *path* is an absolute path and doesn't start - with the ``.dist-info`` directory path, - a :class:`DistlibException` is raised - :type path: str - :rtype: str - """ - # Check if it is an absolute path # XXX use relpath, add tests - if path.find(os.sep) >= 0: - # it's an absolute path? - distinfo_dirname, path = path.split(os.sep)[-2:] - if distinfo_dirname != self.path.split(os.sep)[-1]: - raise DistlibException( - 'dist-info file %r does not belong to the %r %s ' - 'distribution' % (path, self.name, self.version)) - - # The file must be relative - if path not in DIST_FILES: - raise DistlibException('invalid path for a dist-info file: ' - '%r at %r' % (path, self.path)) - - return os.path.join(self.path, path) - - def list_distinfo_files(self): - """ - Iterates over the ``RECORD`` entries and returns paths for each line if - the path is pointing to a file located in the ``.dist-info`` directory - or one of its subdirectories. - - :returns: iterator of paths - """ - base = os.path.dirname(self.path) - for path, checksum, size in self._get_records(): - # XXX add separator or use real relpath algo - if not os.path.isabs(path): - path = os.path.join(base, path) - if path.startswith(self.path): - yield path - - def __eq__(self, other): - return (isinstance(other, InstalledDistribution) and - self.path == other.path) - - # See http://docs.python.org/reference/datamodel#object.__hash__ - __hash__ = object.__hash__ - - -class EggInfoDistribution(BaseInstalledDistribution): - """Created with the *path* of the ``.egg-info`` directory or file provided - to the constructor. It reads the metadata contained in the file itself, or - if the given path happens to be a directory, the metadata is read from the - file ``PKG-INFO`` under that directory.""" - - requested = True # as we have no way of knowing, assume it was - shared_locations = {} - - def __init__(self, path, env=None): - def set_name_and_version(s, n, v): - s.name = n - s.key = n.lower() # for case-insensitive comparisons - s.version = v - - self.path = path - self.dist_path = env - if env and env._cache_enabled and path in env._cache_egg.path: - metadata = env._cache_egg.path[path].metadata - set_name_and_version(self, metadata.name, metadata.version) - else: - metadata = self._get_metadata(path) - - # Need to be set before caching - set_name_and_version(self, metadata.name, metadata.version) - - if env and env._cache_enabled: - env._cache_egg.add(self) - super(EggInfoDistribution, self).__init__(metadata, path, env) - - def _get_metadata(self, path): - requires = None - - def parse_requires_data(data): - """Create a list of dependencies from a requires.txt file. - - *data*: the contents of a setuptools-produced requires.txt file. - """ - reqs = [] - lines = data.splitlines() - for line in lines: - line = line.strip() - if line.startswith('['): - logger.warning('Unexpected line: quitting requirement scan: %r', - line) - break - r = parse_requirement(line) - if not r: - logger.warning('Not recognised as a requirement: %r', line) - continue - if r.extras: - logger.warning('extra requirements in requires.txt are ' - 'not supported') - if not r.constraints: - reqs.append(r.name) - else: - cons = ', '.join('%s%s' % c for c in r.constraints) - reqs.append('%s (%s)' % (r.name, cons)) - return reqs - - def parse_requires_path(req_path): - """Create a list of dependencies from a requires.txt file. - - *req_path*: the path to a setuptools-produced requires.txt file. - """ - - reqs = [] - try: - with codecs.open(req_path, 'r', 'utf-8') as fp: - reqs = parse_requires_data(fp.read()) - except IOError: - pass - return reqs - - tl_path = tl_data = None - if path.endswith('.egg'): - if os.path.isdir(path): - p = os.path.join(path, 'EGG-INFO') - meta_path = os.path.join(p, 'PKG-INFO') - metadata = Metadata(path=meta_path, scheme='legacy') - req_path = os.path.join(p, 'requires.txt') - tl_path = os.path.join(p, 'top_level.txt') - requires = parse_requires_path(req_path) - else: - # FIXME handle the case where zipfile is not available - zipf = zipimport.zipimporter(path) - fileobj = StringIO( - zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8')) - metadata = Metadata(fileobj=fileobj, scheme='legacy') - try: - data = zipf.get_data('EGG-INFO/requires.txt') - tl_data = zipf.get_data('EGG-INFO/top_level.txt').decode('utf-8') - requires = parse_requires_data(data.decode('utf-8')) - except IOError: - requires = None - elif path.endswith('.egg-info'): - if os.path.isdir(path): - req_path = os.path.join(path, 'requires.txt') - requires = parse_requires_path(req_path) - path = os.path.join(path, 'PKG-INFO') - tl_path = os.path.join(path, 'top_level.txt') - metadata = Metadata(path=path, scheme='legacy') - else: - raise DistlibException('path must end with .egg-info or .egg, ' - 'got %r' % path) - - if requires: - metadata.add_requirements(requires) - # look for top-level modules in top_level.txt, if present - if tl_data is None: - if tl_path is not None and os.path.exists(tl_path): - with open(tl_path, 'rb') as f: - tl_data = f.read().decode('utf-8') - if not tl_data: - tl_data = [] - else: - tl_data = tl_data.splitlines() - self.modules = tl_data - return metadata - - def __repr__(self): - return '<EggInfoDistribution %r %s at %r>' % ( - self.name, self.version, self.path) - - def __str__(self): - return "%s %s" % (self.name, self.version) - - def check_installed_files(self): - """ - Checks that the hashes and sizes of the files in ``RECORD`` are - matched by the files themselves. Returns a (possibly empty) list of - mismatches. Each entry in the mismatch list will be a tuple consisting - of the path, 'exists', 'size' or 'hash' according to what didn't match - (existence is checked first, then size, then hash), the expected - value and the actual value. - """ - mismatches = [] - record_path = os.path.join(self.path, 'installed-files.txt') - if os.path.exists(record_path): - for path, _, _ in self.list_installed_files(): - if path == record_path: - continue - if not os.path.exists(path): - mismatches.append((path, 'exists', True, False)) - return mismatches - - def list_installed_files(self): - """ - Iterates over the ``installed-files.txt`` entries and returns a tuple - ``(path, hash, size)`` for each line. - - :returns: a list of (path, hash, size) - """ - - def _md5(path): - f = open(path, 'rb') - try: - content = f.read() - finally: - f.close() - return hashlib.md5(content).hexdigest() - - def _size(path): - return os.stat(path).st_size - - record_path = os.path.join(self.path, 'installed-files.txt') - result = [] - if os.path.exists(record_path): - with codecs.open(record_path, 'r', encoding='utf-8') as f: - for line in f: - line = line.strip() - p = os.path.normpath(os.path.join(self.path, line)) - # "./" is present as a marker between installed files - # and installation metadata files - if not os.path.exists(p): - logger.warning('Non-existent file: %s', p) - if p.endswith(('.pyc', '.pyo')): - continue - #otherwise fall through and fail - if not os.path.isdir(p): - result.append((p, _md5(p), _size(p))) - result.append((record_path, None, None)) - return result - - def list_distinfo_files(self, absolute=False): - """ - Iterates over the ``installed-files.txt`` entries and returns paths for - each line if the path is pointing to a file located in the - ``.egg-info`` directory or one of its subdirectories. - - :parameter absolute: If *absolute* is ``True``, each returned path is - transformed into a local absolute path. Otherwise the - raw value from ``installed-files.txt`` is returned. - :type absolute: boolean - :returns: iterator of paths - """ - record_path = os.path.join(self.path, 'installed-files.txt') - if os.path.exists(record_path): - skip = True - with codecs.open(record_path, 'r', encoding='utf-8') as f: - for line in f: - line = line.strip() - if line == './': - skip = False - continue - if not skip: - p = os.path.normpath(os.path.join(self.path, line)) - if p.startswith(self.path): - if absolute: - yield p - else: - yield line - - def __eq__(self, other): - return (isinstance(other, EggInfoDistribution) and - self.path == other.path) - - # See http://docs.python.org/reference/datamodel#object.__hash__ - __hash__ = object.__hash__ - -new_dist_class = InstalledDistribution -old_dist_class = EggInfoDistribution - - -class DependencyGraph(object): - """ - Represents a dependency graph between distributions. - - The dependency relationships are stored in an ``adjacency_list`` that maps - distributions to a list of ``(other, label)`` tuples where ``other`` - is a distribution and the edge is labeled with ``label`` (i.e. the version - specifier, if such was provided). Also, for more efficient traversal, for - every distribution ``x``, a list of predecessors is kept in - ``reverse_list[x]``. An edge from distribution ``a`` to - distribution ``b`` means that ``a`` depends on ``b``. If any missing - dependencies are found, they are stored in ``missing``, which is a - dictionary that maps distributions to a list of requirements that were not - provided by any other distributions. - """ - - def __init__(self): - self.adjacency_list = {} - self.reverse_list = {} - self.missing = {} - - def add_distribution(self, distribution): - """Add the *distribution* to the graph. - - :type distribution: :class:`distutils2.database.InstalledDistribution` - or :class:`distutils2.database.EggInfoDistribution` - """ - self.adjacency_list[distribution] = [] - self.reverse_list[distribution] = [] - #self.missing[distribution] = [] - - def add_edge(self, x, y, label=None): - """Add an edge from distribution *x* to distribution *y* with the given - *label*. - - :type x: :class:`distutils2.database.InstalledDistribution` or - :class:`distutils2.database.EggInfoDistribution` - :type y: :class:`distutils2.database.InstalledDistribution` or - :class:`distutils2.database.EggInfoDistribution` - :type label: ``str`` or ``None`` - """ - self.adjacency_list[x].append((y, label)) - # multiple edges are allowed, so be careful - if x not in self.reverse_list[y]: - self.reverse_list[y].append(x) - - def add_missing(self, distribution, requirement): - """ - Add a missing *requirement* for the given *distribution*. - - :type distribution: :class:`distutils2.database.InstalledDistribution` - or :class:`distutils2.database.EggInfoDistribution` - :type requirement: ``str`` - """ - logger.debug('%s missing %r', distribution, requirement) - self.missing.setdefault(distribution, []).append(requirement) - - def _repr_dist(self, dist): - return '%s %s' % (dist.name, dist.version) - - def repr_node(self, dist, level=1): - """Prints only a subgraph""" - output = [self._repr_dist(dist)] - for other, label in self.adjacency_list[dist]: - dist = self._repr_dist(other) - if label is not None: - dist = '%s [%s]' % (dist, label) - output.append(' ' * level + str(dist)) - suboutput = self.repr_node(other, level + 1) - subs = suboutput.split('\n') - output.extend(subs[1:]) - return '\n'.join(output) - - def to_dot(self, f, skip_disconnected=True): - """Writes a DOT output for the graph to the provided file *f*. - - If *skip_disconnected* is set to ``True``, then all distributions - that are not dependent on any other distribution are skipped. - - :type f: has to support ``file``-like operations - :type skip_disconnected: ``bool`` - """ - disconnected = [] - - f.write("digraph dependencies {\n") - for dist, adjs in self.adjacency_list.items(): - if len(adjs) == 0 and not skip_disconnected: - disconnected.append(dist) - for other, label in adjs: - if not label is None: - f.write('"%s" -> "%s" [label="%s"]\n' % - (dist.name, other.name, label)) - else: - f.write('"%s" -> "%s"\n' % (dist.name, other.name)) - if not skip_disconnected and len(disconnected) > 0: - f.write('subgraph disconnected {\n') - f.write('label = "Disconnected"\n') - f.write('bgcolor = red\n') - - for dist in disconnected: - f.write('"%s"' % dist.name) - f.write('\n') - f.write('}\n') - f.write('}\n') - - def topological_sort(self): - """ - Perform a topological sort of the graph. - :return: A tuple, the first element of which is a topologically sorted - list of distributions, and the second element of which is a - list of distributions that cannot be sorted because they have - circular dependencies and so form a cycle. - """ - result = [] - # Make a shallow copy of the adjacency list - alist = {} - for k, v in self.adjacency_list.items(): - alist[k] = v[:] - while True: - # See what we can remove in this run - to_remove = [] - for k, v in list(alist.items())[:]: - if not v: - to_remove.append(k) - del alist[k] - if not to_remove: - # What's left in alist (if anything) is a cycle. - break - # Remove from the adjacency list of others - for k, v in alist.items(): - alist[k] = [(d, r) for d, r in v if d not in to_remove] - logger.debug('Moving to result: %s', - ['%s (%s)' % (d.name, d.version) for d in to_remove]) - result.extend(to_remove) - return result, list(alist.keys()) - - def __repr__(self): - """Representation of the graph""" - output = [] - for dist, adjs in self.adjacency_list.items(): - output.append(self.repr_node(dist)) - return '\n'.join(output) - - -def make_graph(dists, scheme='default'): - """Makes a dependency graph from the given distributions. - - :parameter dists: a list of distributions - :type dists: list of :class:`distutils2.database.InstalledDistribution` and - :class:`distutils2.database.EggInfoDistribution` instances - :rtype: a :class:`DependencyGraph` instance - """ - scheme = get_scheme(scheme) - graph = DependencyGraph() - provided = {} # maps names to lists of (version, dist) tuples - - # first, build the graph and find out what's provided - for dist in dists: - graph.add_distribution(dist) - - for p in dist.provides: - name, version = parse_name_and_version(p) - logger.debug('Add to provided: %s, %s, %s', name, version, dist) - provided.setdefault(name, []).append((version, dist)) - - # now make the edges - for dist in dists: - requires = (dist.run_requires | dist.meta_requires | - dist.build_requires | dist.dev_requires) - for req in requires: - try: - matcher = scheme.matcher(req) - except UnsupportedVersionError: - # XXX compat-mode if cannot read the version - logger.warning('could not read version %r - using name only', - req) - name = req.split()[0] - matcher = scheme.matcher(name) - - name = matcher.key # case-insensitive - - matched = False - if name in provided: - for version, provider in provided[name]: - try: - match = matcher.match(version) - except UnsupportedVersionError: - match = False - - if match: - graph.add_edge(dist, provider, req) - matched = True - break - if not matched: - graph.add_missing(dist, req) - return graph - - -def get_dependent_dists(dists, dist): - """Recursively generate a list of distributions from *dists* that are - dependent on *dist*. - - :param dists: a list of distributions - :param dist: a distribution, member of *dists* for which we are interested - """ - if dist not in dists: - raise DistlibException('given distribution %r is not a member ' - 'of the list' % dist.name) - graph = make_graph(dists) - - dep = [dist] # dependent distributions - todo = graph.reverse_list[dist] # list of nodes we should inspect - - while todo: - d = todo.pop() - dep.append(d) - for succ in graph.reverse_list[d]: - if succ not in dep: - todo.append(succ) - - dep.pop(0) # remove dist from dep, was there to prevent infinite loops - return dep - - -def get_required_dists(dists, dist): - """Recursively generate a list of distributions from *dists* that are - required by *dist*. - - :param dists: a list of distributions - :param dist: a distribution, member of *dists* for which we are interested - """ - if dist not in dists: - raise DistlibException('given distribution %r is not a member ' - 'of the list' % dist.name) - graph = make_graph(dists) - - req = [] # required distributions - todo = graph.adjacency_list[dist] # list of nodes we should inspect - - while todo: - d = todo.pop()[0] - req.append(d) - for pred in graph.adjacency_list[d]: - if pred not in req: - todo.append(pred) - - return req - - -def make_dist(name, version, **kwargs): - """ - A convenience method for making a dist given just a name and version. - """ - summary = kwargs.pop('summary', 'Placeholder for summary') - md = Metadata(**kwargs) - md.name = name - md.version = version - md.summary = summary or 'Placeholder for summary' - return Distribution(md) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/index.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/index.py deleted file mode 100644 index 2406be2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/index.py +++ /dev/null @@ -1,516 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -import hashlib -import logging -import os -import shutil -import subprocess -import tempfile -try: - from threading import Thread -except ImportError: - from dummy_threading import Thread - -from . import DistlibException -from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr, - urlparse, build_opener, string_types) -from .util import cached_property, zip_dir, ServerProxy - -logger = logging.getLogger(__name__) - -DEFAULT_INDEX = 'https://pypi.python.org/pypi' -DEFAULT_REALM = 'pypi' - -class PackageIndex(object): - """ - This class represents a package index compatible with PyPI, the Python - Package Index. - """ - - boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$' - - def __init__(self, url=None): - """ - Initialise an instance. - - :param url: The URL of the index. If not specified, the URL for PyPI is - used. - """ - self.url = url or DEFAULT_INDEX - self.read_configuration() - scheme, netloc, path, params, query, frag = urlparse(self.url) - if params or query or frag or scheme not in ('http', 'https'): - raise DistlibException('invalid repository: %s' % self.url) - self.password_handler = None - self.ssl_verifier = None - self.gpg = None - self.gpg_home = None - with open(os.devnull, 'w') as sink: - # Use gpg by default rather than gpg2, as gpg2 insists on - # prompting for passwords - for s in ('gpg', 'gpg2'): - try: - rc = subprocess.check_call([s, '--version'], stdout=sink, - stderr=sink) - if rc == 0: - self.gpg = s - break - except OSError: - pass - - def _get_pypirc_command(self): - """ - Get the distutils command for interacting with PyPI configurations. - :return: the command. - """ - from distutils.core import Distribution - from distutils.config import PyPIRCCommand - d = Distribution() - return PyPIRCCommand(d) - - def read_configuration(self): - """ - Read the PyPI access configuration as supported by distutils, getting - PyPI to do the actual work. This populates ``username``, ``password``, - ``realm`` and ``url`` attributes from the configuration. - """ - # get distutils to do the work - c = self._get_pypirc_command() - c.repository = self.url - cfg = c._read_pypirc() - self.username = cfg.get('username') - self.password = cfg.get('password') - self.realm = cfg.get('realm', 'pypi') - self.url = cfg.get('repository', self.url) - - def save_configuration(self): - """ - Save the PyPI access configuration. You must have set ``username`` and - ``password`` attributes before calling this method. - - Again, distutils is used to do the actual work. - """ - self.check_credentials() - # get distutils to do the work - c = self._get_pypirc_command() - c._store_pypirc(self.username, self.password) - - def check_credentials(self): - """ - Check that ``username`` and ``password`` have been set, and raise an - exception if not. - """ - if self.username is None or self.password is None: - raise DistlibException('username and password must be set') - pm = HTTPPasswordMgr() - _, netloc, _, _, _, _ = urlparse(self.url) - pm.add_password(self.realm, netloc, self.username, self.password) - self.password_handler = HTTPBasicAuthHandler(pm) - - def register(self, metadata): - """ - Register a distribution on PyPI, using the provided metadata. - - :param metadata: A :class:`Metadata` instance defining at least a name - and version number for the distribution to be - registered. - :return: The HTTP response received from PyPI upon submission of the - request. - """ - self.check_credentials() - metadata.validate() - d = metadata.todict() - d[':action'] = 'verify' - request = self.encode_request(d.items(), []) - response = self.send_request(request) - d[':action'] = 'submit' - request = self.encode_request(d.items(), []) - return self.send_request(request) - - def _reader(self, name, stream, outbuf): - """ - Thread runner for reading lines of from a subprocess into a buffer. - - :param name: The logical name of the stream (used for logging only). - :param stream: The stream to read from. This will typically a pipe - connected to the output stream of a subprocess. - :param outbuf: The list to append the read lines to. - """ - while True: - s = stream.readline() - if not s: - break - s = s.decode('utf-8').rstrip() - outbuf.append(s) - logger.debug('%s: %s' % (name, s)) - stream.close() - - def get_sign_command(self, filename, signer, sign_password, - keystore=None): - """ - Return a suitable command for signing a file. - - :param filename: The pathname to the file to be signed. - :param signer: The identifier of the signer of the file. - :param sign_password: The passphrase for the signer's - private key used for signing. - :param keystore: The path to a directory which contains the keys - used in verification. If not specified, the - instance's ``gpg_home`` attribute is used instead. - :return: The signing command as a list suitable to be - passed to :class:`subprocess.Popen`. - """ - cmd = [self.gpg, '--status-fd', '2', '--no-tty'] - if keystore is None: - keystore = self.gpg_home - if keystore: - cmd.extend(['--homedir', keystore]) - if sign_password is not None: - cmd.extend(['--batch', '--passphrase-fd', '0']) - td = tempfile.mkdtemp() - sf = os.path.join(td, os.path.basename(filename) + '.asc') - cmd.extend(['--detach-sign', '--armor', '--local-user', - signer, '--output', sf, filename]) - logger.debug('invoking: %s', ' '.join(cmd)) - return cmd, sf - - def run_command(self, cmd, input_data=None): - """ - Run a command in a child process , passing it any input data specified. - - :param cmd: The command to run. - :param input_data: If specified, this must be a byte string containing - data to be sent to the child process. - :return: A tuple consisting of the subprocess' exit code, a list of - lines read from the subprocess' ``stdout``, and a list of - lines read from the subprocess' ``stderr``. - """ - kwargs = { - 'stdout': subprocess.PIPE, - 'stderr': subprocess.PIPE, - } - if input_data is not None: - kwargs['stdin'] = subprocess.PIPE - stdout = [] - stderr = [] - p = subprocess.Popen(cmd, **kwargs) - # We don't use communicate() here because we may need to - # get clever with interacting with the command - t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout)) - t1.start() - t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr)) - t2.start() - if input_data is not None: - p.stdin.write(input_data) - p.stdin.close() - - p.wait() - t1.join() - t2.join() - return p.returncode, stdout, stderr - - def sign_file(self, filename, signer, sign_password, keystore=None): - """ - Sign a file. - - :param filename: The pathname to the file to be signed. - :param signer: The identifier of the signer of the file. - :param sign_password: The passphrase for the signer's - private key used for signing. - :param keystore: The path to a directory which contains the keys - used in signing. If not specified, the instance's - ``gpg_home`` attribute is used instead. - :return: The absolute pathname of the file where the signature is - stored. - """ - cmd, sig_file = self.get_sign_command(filename, signer, sign_password, - keystore) - rc, stdout, stderr = self.run_command(cmd, - sign_password.encode('utf-8')) - if rc != 0: - raise DistlibException('sign command failed with error ' - 'code %s' % rc) - return sig_file - - def upload_file(self, metadata, filename, signer=None, sign_password=None, - filetype='sdist', pyversion='source', keystore=None): - """ - Upload a release file to the index. - - :param metadata: A :class:`Metadata` instance defining at least a name - and version number for the file to be uploaded. - :param filename: The pathname of the file to be uploaded. - :param signer: The identifier of the signer of the file. - :param sign_password: The passphrase for the signer's - private key used for signing. - :param filetype: The type of the file being uploaded. This is the - distutils command which produced that file, e.g. - ``sdist`` or ``bdist_wheel``. - :param pyversion: The version of Python which the release relates - to. For code compatible with any Python, this would - be ``source``, otherwise it would be e.g. ``3.2``. - :param keystore: The path to a directory which contains the keys - used in signing. If not specified, the instance's - ``gpg_home`` attribute is used instead. - :return: The HTTP response received from PyPI upon submission of the - request. - """ - self.check_credentials() - if not os.path.exists(filename): - raise DistlibException('not found: %s' % filename) - metadata.validate() - d = metadata.todict() - sig_file = None - if signer: - if not self.gpg: - logger.warning('no signing program available - not signed') - else: - sig_file = self.sign_file(filename, signer, sign_password, - keystore) - with open(filename, 'rb') as f: - file_data = f.read() - md5_digest = hashlib.md5(file_data).hexdigest() - sha256_digest = hashlib.sha256(file_data).hexdigest() - d.update({ - ':action': 'file_upload', - 'protocol_version': '1', - 'filetype': filetype, - 'pyversion': pyversion, - 'md5_digest': md5_digest, - 'sha256_digest': sha256_digest, - }) - files = [('content', os.path.basename(filename), file_data)] - if sig_file: - with open(sig_file, 'rb') as f: - sig_data = f.read() - files.append(('gpg_signature', os.path.basename(sig_file), - sig_data)) - shutil.rmtree(os.path.dirname(sig_file)) - request = self.encode_request(d.items(), files) - return self.send_request(request) - - def upload_documentation(self, metadata, doc_dir): - """ - Upload documentation to the index. - - :param metadata: A :class:`Metadata` instance defining at least a name - and version number for the documentation to be - uploaded. - :param doc_dir: The pathname of the directory which contains the - documentation. This should be the directory that - contains the ``index.html`` for the documentation. - :return: The HTTP response received from PyPI upon submission of the - request. - """ - self.check_credentials() - if not os.path.isdir(doc_dir): - raise DistlibException('not a directory: %r' % doc_dir) - fn = os.path.join(doc_dir, 'index.html') - if not os.path.exists(fn): - raise DistlibException('not found: %r' % fn) - metadata.validate() - name, version = metadata.name, metadata.version - zip_data = zip_dir(doc_dir).getvalue() - fields = [(':action', 'doc_upload'), - ('name', name), ('version', version)] - files = [('content', name, zip_data)] - request = self.encode_request(fields, files) - return self.send_request(request) - - def get_verify_command(self, signature_filename, data_filename, - keystore=None): - """ - Return a suitable command for verifying a file. - - :param signature_filename: The pathname to the file containing the - signature. - :param data_filename: The pathname to the file containing the - signed data. - :param keystore: The path to a directory which contains the keys - used in verification. If not specified, the - instance's ``gpg_home`` attribute is used instead. - :return: The verifying command as a list suitable to be - passed to :class:`subprocess.Popen`. - """ - cmd = [self.gpg, '--status-fd', '2', '--no-tty'] - if keystore is None: - keystore = self.gpg_home - if keystore: - cmd.extend(['--homedir', keystore]) - cmd.extend(['--verify', signature_filename, data_filename]) - logger.debug('invoking: %s', ' '.join(cmd)) - return cmd - - def verify_signature(self, signature_filename, data_filename, - keystore=None): - """ - Verify a signature for a file. - - :param signature_filename: The pathname to the file containing the - signature. - :param data_filename: The pathname to the file containing the - signed data. - :param keystore: The path to a directory which contains the keys - used in verification. If not specified, the - instance's ``gpg_home`` attribute is used instead. - :return: True if the signature was verified, else False. - """ - if not self.gpg: - raise DistlibException('verification unavailable because gpg ' - 'unavailable') - cmd = self.get_verify_command(signature_filename, data_filename, - keystore) - rc, stdout, stderr = self.run_command(cmd) - if rc not in (0, 1): - raise DistlibException('verify command failed with error ' - 'code %s' % rc) - return rc == 0 - - def download_file(self, url, destfile, digest=None, reporthook=None): - """ - This is a convenience method for downloading a file from an URL. - Normally, this will be a file from the index, though currently - no check is made for this (i.e. a file can be downloaded from - anywhere). - - The method is just like the :func:`urlretrieve` function in the - standard library, except that it allows digest computation to be - done during download and checking that the downloaded data - matched any expected value. - - :param url: The URL of the file to be downloaded (assumed to be - available via an HTTP GET request). - :param destfile: The pathname where the downloaded file is to be - saved. - :param digest: If specified, this must be a (hasher, value) - tuple, where hasher is the algorithm used (e.g. - ``'md5'``) and ``value`` is the expected value. - :param reporthook: The same as for :func:`urlretrieve` in the - standard library. - """ - if digest is None: - digester = None - logger.debug('No digest specified') - else: - if isinstance(digest, (list, tuple)): - hasher, digest = digest - else: - hasher = 'md5' - digester = getattr(hashlib, hasher)() - logger.debug('Digest specified: %s' % digest) - # The following code is equivalent to urlretrieve. - # We need to do it this way so that we can compute the - # digest of the file as we go. - with open(destfile, 'wb') as dfp: - # addinfourl is not a context manager on 2.x - # so we have to use try/finally - sfp = self.send_request(Request(url)) - try: - headers = sfp.info() - blocksize = 8192 - size = -1 - read = 0 - blocknum = 0 - if "content-length" in headers: - size = int(headers["Content-Length"]) - if reporthook: - reporthook(blocknum, blocksize, size) - while True: - block = sfp.read(blocksize) - if not block: - break - read += len(block) - dfp.write(block) - if digester: - digester.update(block) - blocknum += 1 - if reporthook: - reporthook(blocknum, blocksize, size) - finally: - sfp.close() - - # check that we got the whole file, if we can - if size >= 0 and read < size: - raise DistlibException( - 'retrieval incomplete: got only %d out of %d bytes' - % (read, size)) - # if we have a digest, it must match. - if digester: - actual = digester.hexdigest() - if digest != actual: - raise DistlibException('%s digest mismatch for %s: expected ' - '%s, got %s' % (hasher, destfile, - digest, actual)) - logger.debug('Digest verified: %s', digest) - - def send_request(self, req): - """ - Send a standard library :class:`Request` to PyPI and return its - response. - - :param req: The request to send. - :return: The HTTP response from PyPI (a standard library HTTPResponse). - """ - handlers = [] - if self.password_handler: - handlers.append(self.password_handler) - if self.ssl_verifier: - handlers.append(self.ssl_verifier) - opener = build_opener(*handlers) - return opener.open(req) - - def encode_request(self, fields, files): - """ - Encode fields and files for posting to an HTTP server. - - :param fields: The fields to send as a list of (fieldname, value) - tuples. - :param files: The files to send as a list of (fieldname, filename, - file_bytes) tuple. - """ - # Adapted from packaging, which in turn was adapted from - # http://code.activestate.com/recipes/146306 - - parts = [] - boundary = self.boundary - for k, values in fields: - if not isinstance(values, (list, tuple)): - values = [values] - - for v in values: - parts.extend(( - b'--' + boundary, - ('Content-Disposition: form-data; name="%s"' % - k).encode('utf-8'), - b'', - v.encode('utf-8'))) - for key, filename, value in files: - parts.extend(( - b'--' + boundary, - ('Content-Disposition: form-data; name="%s"; filename="%s"' % - (key, filename)).encode('utf-8'), - b'', - value)) - - parts.extend((b'--' + boundary + b'--', b'')) - - body = b'\r\n'.join(parts) - ct = b'multipart/form-data; boundary=' + boundary - headers = { - 'Content-type': ct, - 'Content-length': str(len(body)) - } - return Request(self.url, body, headers) - - def search(self, terms, operator=None): - if isinstance(terms, string_types): - terms = {'name': terms} - rpc_proxy = ServerProxy(self.url, timeout=3.0) - try: - return rpc_proxy.search(terms, operator or 'and') - finally: - rpc_proxy('close')() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/locators.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/locators.py deleted file mode 100644 index 5c655c3..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/locators.py +++ /dev/null @@ -1,1295 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2015 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# - -import gzip -from io import BytesIO -import json -import logging -import os -import posixpath -import re -try: - import threading -except ImportError: # pragma: no cover - import dummy_threading as threading -import zlib - -from . import DistlibException -from .compat import (urljoin, urlparse, urlunparse, url2pathname, pathname2url, - queue, quote, unescape, string_types, build_opener, - HTTPRedirectHandler as BaseRedirectHandler, text_type, - Request, HTTPError, URLError) -from .database import Distribution, DistributionPath, make_dist -from .metadata import Metadata, MetadataInvalidError -from .util import (cached_property, parse_credentials, ensure_slash, - split_filename, get_project_data, parse_requirement, - parse_name_and_version, ServerProxy, normalize_name) -from .version import get_scheme, UnsupportedVersionError -from .wheel import Wheel, is_compatible - -logger = logging.getLogger(__name__) - -HASHER_HASH = re.compile(r'^(\w+)=([a-f0-9]+)') -CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) -HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') -DEFAULT_INDEX = 'https://pypi.python.org/pypi' - -def get_all_distribution_names(url=None): - """ - Return all distribution names known by an index. - :param url: The URL of the index. - :return: A list of all known distribution names. - """ - if url is None: - url = DEFAULT_INDEX - client = ServerProxy(url, timeout=3.0) - try: - return client.list_packages() - finally: - client('close')() - -class RedirectHandler(BaseRedirectHandler): - """ - A class to work around a bug in some Python 3.2.x releases. - """ - # There's a bug in the base version for some 3.2.x - # (e.g. 3.2.2 on Ubuntu Oneiric). If a Location header - # returns e.g. /abc, it bails because it says the scheme '' - # is bogus, when actually it should use the request's - # URL for the scheme. See Python issue #13696. - def http_error_302(self, req, fp, code, msg, headers): - # Some servers (incorrectly) return multiple Location headers - # (so probably same goes for URI). Use first header. - newurl = None - for key in ('location', 'uri'): - if key in headers: - newurl = headers[key] - break - if newurl is None: # pragma: no cover - return - urlparts = urlparse(newurl) - if urlparts.scheme == '': - newurl = urljoin(req.get_full_url(), newurl) - if hasattr(headers, 'replace_header'): - headers.replace_header(key, newurl) - else: - headers[key] = newurl - return BaseRedirectHandler.http_error_302(self, req, fp, code, msg, - headers) - - http_error_301 = http_error_303 = http_error_307 = http_error_302 - -class Locator(object): - """ - A base class for locators - things that locate distributions. - """ - source_extensions = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz') - binary_extensions = ('.egg', '.exe', '.whl') - excluded_extensions = ('.pdf',) - - # A list of tags indicating which wheels you want to match. The default - # value of None matches against the tags compatible with the running - # Python. If you want to match other values, set wheel_tags on a locator - # instance to a list of tuples (pyver, abi, arch) which you want to match. - wheel_tags = None - - downloadable_extensions = source_extensions + ('.whl',) - - def __init__(self, scheme='default'): - """ - Initialise an instance. - :param scheme: Because locators look for most recent versions, they - need to know the version scheme to use. This specifies - the current PEP-recommended scheme - use ``'legacy'`` - if you need to support existing distributions on PyPI. - """ - self._cache = {} - self.scheme = scheme - # Because of bugs in some of the handlers on some of the platforms, - # we use our own opener rather than just using urlopen. - self.opener = build_opener(RedirectHandler()) - # If get_project() is called from locate(), the matcher instance - # is set from the requirement passed to locate(). See issue #18 for - # why this can be useful to know. - self.matcher = None - self.errors = queue.Queue() - - def get_errors(self): - """ - Return any errors which have occurred. - """ - result = [] - while not self.errors.empty(): # pragma: no cover - try: - e = self.errors.get(False) - result.append(e) - except self.errors.Empty: - continue - self.errors.task_done() - return result - - def clear_errors(self): - """ - Clear any errors which may have been logged. - """ - # Just get the errors and throw them away - self.get_errors() - - def clear_cache(self): - self._cache.clear() - - def _get_scheme(self): - return self._scheme - - def _set_scheme(self, value): - self._scheme = value - - scheme = property(_get_scheme, _set_scheme) - - def _get_project(self, name): - """ - For a given project, get a dictionary mapping available versions to Distribution - instances. - - This should be implemented in subclasses. - - If called from a locate() request, self.matcher will be set to a - matcher for the requirement to satisfy, otherwise it will be None. - """ - raise NotImplementedError('Please implement in the subclass') - - def get_distribution_names(self): - """ - Return all the distribution names known to this locator. - """ - raise NotImplementedError('Please implement in the subclass') - - def get_project(self, name): - """ - For a given project, get a dictionary mapping available versions to Distribution - instances. - - This calls _get_project to do all the work, and just implements a caching layer on top. - """ - if self._cache is None: # pragma: no cover - result = self._get_project(name) - elif name in self._cache: - result = self._cache[name] - else: - self.clear_errors() - result = self._get_project(name) - self._cache[name] = result - return result - - def score_url(self, url): - """ - Give an url a score which can be used to choose preferred URLs - for a given project release. - """ - t = urlparse(url) - basename = posixpath.basename(t.path) - compatible = True - is_wheel = basename.endswith('.whl') - is_downloadable = basename.endswith(self.downloadable_extensions) - if is_wheel: - compatible = is_compatible(Wheel(basename), self.wheel_tags) - return (t.scheme == 'https', 'pypi.python.org' in t.netloc, - is_downloadable, is_wheel, compatible, basename) - - def prefer_url(self, url1, url2): - """ - Choose one of two URLs where both are candidates for distribution - archives for the same version of a distribution (for example, - .tar.gz vs. zip). - - The current implementation favours https:// URLs over http://, archives - from PyPI over those from other locations, wheel compatibility (if a - wheel) and then the archive name. - """ - result = url2 - if url1: - s1 = self.score_url(url1) - s2 = self.score_url(url2) - if s1 > s2: - result = url1 - if result != url2: - logger.debug('Not replacing %r with %r', url1, url2) - else: - logger.debug('Replacing %r with %r', url1, url2) - return result - - def split_filename(self, filename, project_name): - """ - Attempt to split a filename in project name, version and Python version. - """ - return split_filename(filename, project_name) - - def convert_url_to_download_info(self, url, project_name): - """ - See if a URL is a candidate for a download URL for a project (the URL - has typically been scraped from an HTML page). - - If it is, a dictionary is returned with keys "name", "version", - "filename" and "url"; otherwise, None is returned. - """ - def same_project(name1, name2): - return normalize_name(name1) == normalize_name(name2) - - result = None - scheme, netloc, path, params, query, frag = urlparse(url) - if frag.lower().startswith('egg='): # pragma: no cover - logger.debug('%s: version hint in fragment: %r', - project_name, frag) - m = HASHER_HASH.match(frag) - if m: - algo, digest = m.groups() - else: - algo, digest = None, None - origpath = path - if path and path[-1] == '/': # pragma: no cover - path = path[:-1] - if path.endswith('.whl'): - try: - wheel = Wheel(path) - if not is_compatible(wheel, self.wheel_tags): - logger.debug('Wheel not compatible: %s', path) - else: - if project_name is None: - include = True - else: - include = same_project(wheel.name, project_name) - if include: - result = { - 'name': wheel.name, - 'version': wheel.version, - 'filename': wheel.filename, - 'url': urlunparse((scheme, netloc, origpath, - params, query, '')), - 'python-version': ', '.join( - ['.'.join(list(v[2:])) for v in wheel.pyver]), - } - except Exception as e: # pragma: no cover - logger.warning('invalid path for wheel: %s', path) - elif not path.endswith(self.downloadable_extensions): # pragma: no cover - logger.debug('Not downloadable: %s', path) - else: # downloadable extension - path = filename = posixpath.basename(path) - for ext in self.downloadable_extensions: - if path.endswith(ext): - path = path[:-len(ext)] - t = self.split_filename(path, project_name) - if not t: # pragma: no cover - logger.debug('No match for project/version: %s', path) - else: - name, version, pyver = t - if not project_name or same_project(project_name, name): - result = { - 'name': name, - 'version': version, - 'filename': filename, - 'url': urlunparse((scheme, netloc, origpath, - params, query, '')), - #'packagetype': 'sdist', - } - if pyver: # pragma: no cover - result['python-version'] = pyver - break - if result and algo: - result['%s_digest' % algo] = digest - return result - - def _get_digest(self, info): - """ - Get a digest from a dictionary by looking at keys of the form - 'algo_digest'. - - Returns a 2-tuple (algo, digest) if found, else None. Currently - looks only for SHA256, then MD5. - """ - result = None - for algo in ('sha256', 'md5'): - key = '%s_digest' % algo - if key in info: - result = (algo, info[key]) - break - return result - - def _update_version_data(self, result, info): - """ - Update a result dictionary (the final result from _get_project) with a - dictionary for a specific version, which typically holds information - gleaned from a filename or URL for an archive for the distribution. - """ - name = info.pop('name') - version = info.pop('version') - if version in result: - dist = result[version] - md = dist.metadata - else: - dist = make_dist(name, version, scheme=self.scheme) - md = dist.metadata - dist.digest = digest = self._get_digest(info) - url = info['url'] - result['digests'][url] = digest - if md.source_url != info['url']: - md.source_url = self.prefer_url(md.source_url, url) - result['urls'].setdefault(version, set()).add(url) - dist.locator = self - result[version] = dist - - def locate(self, requirement, prereleases=False): - """ - Find the most recent distribution which matches the given - requirement. - - :param requirement: A requirement of the form 'foo (1.0)' or perhaps - 'foo (>= 1.0, < 2.0, != 1.3)' - :param prereleases: If ``True``, allow pre-release versions - to be located. Otherwise, pre-release versions - are not returned. - :return: A :class:`Distribution` instance, or ``None`` if no such - distribution could be located. - """ - result = None - r = parse_requirement(requirement) - if r is None: # pragma: no cover - raise DistlibException('Not a valid requirement: %r' % requirement) - scheme = get_scheme(self.scheme) - self.matcher = matcher = scheme.matcher(r.requirement) - logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__) - versions = self.get_project(r.name) - if len(versions) > 2: # urls and digests keys are present - # sometimes, versions are invalid - slist = [] - vcls = matcher.version_class - for k in versions: - if k in ('urls', 'digests'): - continue - try: - if not matcher.match(k): - logger.debug('%s did not match %r', matcher, k) - else: - if prereleases or not vcls(k).is_prerelease: - slist.append(k) - else: - logger.debug('skipping pre-release ' - 'version %s of %s', k, matcher.name) - except Exception: # pragma: no cover - logger.warning('error matching %s with %r', matcher, k) - pass # slist.append(k) - if len(slist) > 1: - slist = sorted(slist, key=scheme.key) - if slist: - logger.debug('sorted list: %s', slist) - version = slist[-1] - result = versions[version] - if result: - if r.extras: - result.extras = r.extras - result.download_urls = versions.get('urls', {}).get(version, set()) - d = {} - sd = versions.get('digests', {}) - for url in result.download_urls: - if url in sd: # pragma: no cover - d[url] = sd[url] - result.digests = d - self.matcher = None - return result - - -class PyPIRPCLocator(Locator): - """ - This locator uses XML-RPC to locate distributions. It therefore - cannot be used with simple mirrors (that only mirror file content). - """ - def __init__(self, url, **kwargs): - """ - Initialise an instance. - - :param url: The URL to use for XML-RPC. - :param kwargs: Passed to the superclass constructor. - """ - super(PyPIRPCLocator, self).__init__(**kwargs) - self.base_url = url - self.client = ServerProxy(url, timeout=3.0) - - def get_distribution_names(self): - """ - Return all the distribution names known to this locator. - """ - return set(self.client.list_packages()) - - def _get_project(self, name): - result = {'urls': {}, 'digests': {}} - versions = self.client.package_releases(name, True) - for v in versions: - urls = self.client.release_urls(name, v) - data = self.client.release_data(name, v) - metadata = Metadata(scheme=self.scheme) - metadata.name = data['name'] - metadata.version = data['version'] - metadata.license = data.get('license') - metadata.keywords = data.get('keywords', []) - metadata.summary = data.get('summary') - dist = Distribution(metadata) - if urls: - info = urls[0] - metadata.source_url = info['url'] - dist.digest = self._get_digest(info) - dist.locator = self - result[v] = dist - for info in urls: - url = info['url'] - digest = self._get_digest(info) - result['urls'].setdefault(v, set()).add(url) - result['digests'][url] = digest - return result - -class PyPIJSONLocator(Locator): - """ - This locator uses PyPI's JSON interface. It's very limited in functionality - and probably not worth using. - """ - def __init__(self, url, **kwargs): - super(PyPIJSONLocator, self).__init__(**kwargs) - self.base_url = ensure_slash(url) - - def get_distribution_names(self): - """ - Return all the distribution names known to this locator. - """ - raise NotImplementedError('Not available from this locator') - - def _get_project(self, name): - result = {'urls': {}, 'digests': {}} - url = urljoin(self.base_url, '%s/json' % quote(name)) - try: - resp = self.opener.open(url) - data = resp.read().decode() # for now - d = json.loads(data) - md = Metadata(scheme=self.scheme) - data = d['info'] - md.name = data['name'] - md.version = data['version'] - md.license = data.get('license') - md.keywords = data.get('keywords', []) - md.summary = data.get('summary') - dist = Distribution(md) - dist.locator = self - urls = d['urls'] - result[md.version] = dist - for info in d['urls']: - url = info['url'] - dist.download_urls.add(url) - dist.digests[url] = self._get_digest(info) - result['urls'].setdefault(md.version, set()).add(url) - result['digests'][url] = self._get_digest(info) - # Now get other releases - for version, infos in d['releases'].items(): - if version == md.version: - continue # already done - omd = Metadata(scheme=self.scheme) - omd.name = md.name - omd.version = version - odist = Distribution(omd) - odist.locator = self - result[version] = odist - for info in infos: - url = info['url'] - odist.download_urls.add(url) - odist.digests[url] = self._get_digest(info) - result['urls'].setdefault(version, set()).add(url) - result['digests'][url] = self._get_digest(info) -# for info in urls: -# md.source_url = info['url'] -# dist.digest = self._get_digest(info) -# dist.locator = self -# for info in urls: -# url = info['url'] -# result['urls'].setdefault(md.version, set()).add(url) -# result['digests'][url] = self._get_digest(info) - except Exception as e: - self.errors.put(text_type(e)) - logger.exception('JSON fetch failed: %s', e) - return result - - -class Page(object): - """ - This class represents a scraped HTML page. - """ - # The following slightly hairy-looking regex just looks for the contents of - # an anchor link, which has an attribute "href" either immediately preceded - # or immediately followed by a "rel" attribute. The attribute values can be - # declared with double quotes, single quotes or no quotes - which leads to - # the length of the expression. - _href = re.compile(""" -(rel\\s*=\\s*(?:"(?P<rel1>[^"]*)"|'(?P<rel2>[^']*)'|(?P<rel3>[^>\\s\n]*))\\s+)? -href\\s*=\\s*(?:"(?P<url1>[^"]*)"|'(?P<url2>[^']*)'|(?P<url3>[^>\\s\n]*)) -(\\s+rel\\s*=\\s*(?:"(?P<rel4>[^"]*)"|'(?P<rel5>[^']*)'|(?P<rel6>[^>\\s\n]*)))? -""", re.I | re.S | re.X) - _base = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I | re.S) - - def __init__(self, data, url): - """ - Initialise an instance with the Unicode page contents and the URL they - came from. - """ - self.data = data - self.base_url = self.url = url - m = self._base.search(self.data) - if m: - self.base_url = m.group(1) - - _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) - - @cached_property - def links(self): - """ - Return the URLs of all the links on a page together with information - about their "rel" attribute, for determining which ones to treat as - downloads and which ones to queue for further scraping. - """ - def clean(url): - "Tidy up an URL." - scheme, netloc, path, params, query, frag = urlparse(url) - return urlunparse((scheme, netloc, quote(path), - params, query, frag)) - - result = set() - for match in self._href.finditer(self.data): - d = match.groupdict('') - rel = (d['rel1'] or d['rel2'] or d['rel3'] or - d['rel4'] or d['rel5'] or d['rel6']) - url = d['url1'] or d['url2'] or d['url3'] - url = urljoin(self.base_url, url) - url = unescape(url) - url = self._clean_re.sub(lambda m: '%%%2x' % ord(m.group(0)), url) - result.add((url, rel)) - # We sort the result, hoping to bring the most recent versions - # to the front - result = sorted(result, key=lambda t: t[0], reverse=True) - return result - - -class SimpleScrapingLocator(Locator): - """ - A locator which scrapes HTML pages to locate downloads for a distribution. - This runs multiple threads to do the I/O; performance is at least as good - as pip's PackageFinder, which works in an analogous fashion. - """ - - # These are used to deal with various Content-Encoding schemes. - decoders = { - 'deflate': zlib.decompress, - 'gzip': lambda b: gzip.GzipFile(fileobj=BytesIO(d)).read(), - 'none': lambda b: b, - } - - def __init__(self, url, timeout=None, num_workers=10, **kwargs): - """ - Initialise an instance. - :param url: The root URL to use for scraping. - :param timeout: The timeout, in seconds, to be applied to requests. - This defaults to ``None`` (no timeout specified). - :param num_workers: The number of worker threads you want to do I/O, - This defaults to 10. - :param kwargs: Passed to the superclass. - """ - super(SimpleScrapingLocator, self).__init__(**kwargs) - self.base_url = ensure_slash(url) - self.timeout = timeout - self._page_cache = {} - self._seen = set() - self._to_fetch = queue.Queue() - self._bad_hosts = set() - self.skip_externals = False - self.num_workers = num_workers - self._lock = threading.RLock() - # See issue #45: we need to be resilient when the locator is used - # in a thread, e.g. with concurrent.futures. We can't use self._lock - # as it is for coordinating our internal threads - the ones created - # in _prepare_threads. - self._gplock = threading.RLock() - self.platform_check = False # See issue #112 - - def _prepare_threads(self): - """ - Threads are created only when get_project is called, and terminate - before it returns. They are there primarily to parallelise I/O (i.e. - fetching web pages). - """ - self._threads = [] - for i in range(self.num_workers): - t = threading.Thread(target=self._fetch) - t.setDaemon(True) - t.start() - self._threads.append(t) - - def _wait_threads(self): - """ - Tell all the threads to terminate (by sending a sentinel value) and - wait for them to do so. - """ - # Note that you need two loops, since you can't say which - # thread will get each sentinel - for t in self._threads: - self._to_fetch.put(None) # sentinel - for t in self._threads: - t.join() - self._threads = [] - - def _get_project(self, name): - result = {'urls': {}, 'digests': {}} - with self._gplock: - self.result = result - self.project_name = name - url = urljoin(self.base_url, '%s/' % quote(name)) - self._seen.clear() - self._page_cache.clear() - self._prepare_threads() - try: - logger.debug('Queueing %s', url) - self._to_fetch.put(url) - self._to_fetch.join() - finally: - self._wait_threads() - del self.result - return result - - platform_dependent = re.compile(r'\b(linux_(i\d86|x86_64|arm\w+)|' - r'win(32|_amd64)|macosx_?\d+)\b', re.I) - - def _is_platform_dependent(self, url): - """ - Does an URL refer to a platform-specific download? - """ - return self.platform_dependent.search(url) - - def _process_download(self, url): - """ - See if an URL is a suitable download for a project. - - If it is, register information in the result dictionary (for - _get_project) about the specific version it's for. - - Note that the return value isn't actually used other than as a boolean - value. - """ - if self.platform_check and self._is_platform_dependent(url): - info = None - else: - info = self.convert_url_to_download_info(url, self.project_name) - logger.debug('process_download: %s -> %s', url, info) - if info: - with self._lock: # needed because self.result is shared - self._update_version_data(self.result, info) - return info - - def _should_queue(self, link, referrer, rel): - """ - Determine whether a link URL from a referring page and with a - particular "rel" attribute should be queued for scraping. - """ - scheme, netloc, path, _, _, _ = urlparse(link) - if path.endswith(self.source_extensions + self.binary_extensions + - self.excluded_extensions): - result = False - elif self.skip_externals and not link.startswith(self.base_url): - result = False - elif not referrer.startswith(self.base_url): - result = False - elif rel not in ('homepage', 'download'): - result = False - elif scheme not in ('http', 'https', 'ftp'): - result = False - elif self._is_platform_dependent(link): - result = False - else: - host = netloc.split(':', 1)[0] - if host.lower() == 'localhost': - result = False - else: - result = True - logger.debug('should_queue: %s (%s) from %s -> %s', link, rel, - referrer, result) - return result - - def _fetch(self): - """ - Get a URL to fetch from the work queue, get the HTML page, examine its - links for download candidates and candidates for further scraping. - - This is a handy method to run in a thread. - """ - while True: - url = self._to_fetch.get() - try: - if url: - page = self.get_page(url) - if page is None: # e.g. after an error - continue - for link, rel in page.links: - if link not in self._seen: - try: - self._seen.add(link) - if (not self._process_download(link) and - self._should_queue(link, url, rel)): - logger.debug('Queueing %s from %s', link, url) - self._to_fetch.put(link) - except MetadataInvalidError: # e.g. invalid versions - pass - except Exception as e: # pragma: no cover - self.errors.put(text_type(e)) - finally: - # always do this, to avoid hangs :-) - self._to_fetch.task_done() - if not url: - #logger.debug('Sentinel seen, quitting.') - break - - def get_page(self, url): - """ - Get the HTML for an URL, possibly from an in-memory cache. - - XXX TODO Note: this cache is never actually cleared. It's assumed that - the data won't get stale over the lifetime of a locator instance (not - necessarily true for the default_locator). - """ - # http://peak.telecommunity.com/DevCenter/EasyInstall#package-index-api - scheme, netloc, path, _, _, _ = urlparse(url) - if scheme == 'file' and os.path.isdir(url2pathname(path)): - url = urljoin(ensure_slash(url), 'index.html') - - if url in self._page_cache: - result = self._page_cache[url] - logger.debug('Returning %s from cache: %s', url, result) - else: - host = netloc.split(':', 1)[0] - result = None - if host in self._bad_hosts: - logger.debug('Skipping %s due to bad host %s', url, host) - else: - req = Request(url, headers={'Accept-encoding': 'identity'}) - try: - logger.debug('Fetching %s', url) - resp = self.opener.open(req, timeout=self.timeout) - logger.debug('Fetched %s', url) - headers = resp.info() - content_type = headers.get('Content-Type', '') - if HTML_CONTENT_TYPE.match(content_type): - final_url = resp.geturl() - data = resp.read() - encoding = headers.get('Content-Encoding') - if encoding: - decoder = self.decoders[encoding] # fail if not found - data = decoder(data) - encoding = 'utf-8' - m = CHARSET.search(content_type) - if m: - encoding = m.group(1) - try: - data = data.decode(encoding) - except UnicodeError: # pragma: no cover - data = data.decode('latin-1') # fallback - result = Page(data, final_url) - self._page_cache[final_url] = result - except HTTPError as e: - if e.code != 404: - logger.exception('Fetch failed: %s: %s', url, e) - except URLError as e: # pragma: no cover - logger.exception('Fetch failed: %s: %s', url, e) - with self._lock: - self._bad_hosts.add(host) - except Exception as e: # pragma: no cover - logger.exception('Fetch failed: %s: %s', url, e) - finally: - self._page_cache[url] = result # even if None (failure) - return result - - _distname_re = re.compile('<a href=[^>]*>([^<]+)<') - - def get_distribution_names(self): - """ - Return all the distribution names known to this locator. - """ - result = set() - page = self.get_page(self.base_url) - if not page: - raise DistlibException('Unable to get %s' % self.base_url) - for match in self._distname_re.finditer(page.data): - result.add(match.group(1)) - return result - -class DirectoryLocator(Locator): - """ - This class locates distributions in a directory tree. - """ - - def __init__(self, path, **kwargs): - """ - Initialise an instance. - :param path: The root of the directory tree to search. - :param kwargs: Passed to the superclass constructor, - except for: - * recursive - if True (the default), subdirectories are - recursed into. If False, only the top-level directory - is searched, - """ - self.recursive = kwargs.pop('recursive', True) - super(DirectoryLocator, self).__init__(**kwargs) - path = os.path.abspath(path) - if not os.path.isdir(path): # pragma: no cover - raise DistlibException('Not a directory: %r' % path) - self.base_dir = path - - def should_include(self, filename, parent): - """ - Should a filename be considered as a candidate for a distribution - archive? As well as the filename, the directory which contains it - is provided, though not used by the current implementation. - """ - return filename.endswith(self.downloadable_extensions) - - def _get_project(self, name): - result = {'urls': {}, 'digests': {}} - for root, dirs, files in os.walk(self.base_dir): - for fn in files: - if self.should_include(fn, root): - fn = os.path.join(root, fn) - url = urlunparse(('file', '', - pathname2url(os.path.abspath(fn)), - '', '', '')) - info = self.convert_url_to_download_info(url, name) - if info: - self._update_version_data(result, info) - if not self.recursive: - break - return result - - def get_distribution_names(self): - """ - Return all the distribution names known to this locator. - """ - result = set() - for root, dirs, files in os.walk(self.base_dir): - for fn in files: - if self.should_include(fn, root): - fn = os.path.join(root, fn) - url = urlunparse(('file', '', - pathname2url(os.path.abspath(fn)), - '', '', '')) - info = self.convert_url_to_download_info(url, None) - if info: - result.add(info['name']) - if not self.recursive: - break - return result - -class JSONLocator(Locator): - """ - This locator uses special extended metadata (not available on PyPI) and is - the basis of performant dependency resolution in distlib. Other locators - require archive downloads before dependencies can be determined! As you - might imagine, that can be slow. - """ - def get_distribution_names(self): - """ - Return all the distribution names known to this locator. - """ - raise NotImplementedError('Not available from this locator') - - def _get_project(self, name): - result = {'urls': {}, 'digests': {}} - data = get_project_data(name) - if data: - for info in data.get('files', []): - if info['ptype'] != 'sdist' or info['pyversion'] != 'source': - continue - # We don't store summary in project metadata as it makes - # the data bigger for no benefit during dependency - # resolution - dist = make_dist(data['name'], info['version'], - summary=data.get('summary', - 'Placeholder for summary'), - scheme=self.scheme) - md = dist.metadata - md.source_url = info['url'] - # TODO SHA256 digest - if 'digest' in info and info['digest']: - dist.digest = ('md5', info['digest']) - md.dependencies = info.get('requirements', {}) - dist.exports = info.get('exports', {}) - result[dist.version] = dist - result['urls'].setdefault(dist.version, set()).add(info['url']) - return result - -class DistPathLocator(Locator): - """ - This locator finds installed distributions in a path. It can be useful for - adding to an :class:`AggregatingLocator`. - """ - def __init__(self, distpath, **kwargs): - """ - Initialise an instance. - - :param distpath: A :class:`DistributionPath` instance to search. - """ - super(DistPathLocator, self).__init__(**kwargs) - assert isinstance(distpath, DistributionPath) - self.distpath = distpath - - def _get_project(self, name): - dist = self.distpath.get_distribution(name) - if dist is None: - result = {'urls': {}, 'digests': {}} - else: - result = { - dist.version: dist, - 'urls': {dist.version: set([dist.source_url])}, - 'digests': {dist.version: set([None])} - } - return result - - -class AggregatingLocator(Locator): - """ - This class allows you to chain and/or merge a list of locators. - """ - def __init__(self, *locators, **kwargs): - """ - Initialise an instance. - - :param locators: The list of locators to search. - :param kwargs: Passed to the superclass constructor, - except for: - * merge - if False (the default), the first successful - search from any of the locators is returned. If True, - the results from all locators are merged (this can be - slow). - """ - self.merge = kwargs.pop('merge', False) - self.locators = locators - super(AggregatingLocator, self).__init__(**kwargs) - - def clear_cache(self): - super(AggregatingLocator, self).clear_cache() - for locator in self.locators: - locator.clear_cache() - - def _set_scheme(self, value): - self._scheme = value - for locator in self.locators: - locator.scheme = value - - scheme = property(Locator.scheme.fget, _set_scheme) - - def _get_project(self, name): - result = {} - for locator in self.locators: - d = locator.get_project(name) - if d: - if self.merge: - files = result.get('urls', {}) - digests = result.get('digests', {}) - # next line could overwrite result['urls'], result['digests'] - result.update(d) - df = result.get('urls') - if files and df: - for k, v in files.items(): - if k in df: - df[k] |= v - else: - df[k] = v - dd = result.get('digests') - if digests and dd: - dd.update(digests) - else: - # See issue #18. If any dists are found and we're looking - # for specific constraints, we only return something if - # a match is found. For example, if a DirectoryLocator - # returns just foo (1.0) while we're looking for - # foo (>= 2.0), we'll pretend there was nothing there so - # that subsequent locators can be queried. Otherwise we - # would just return foo (1.0) which would then lead to a - # failure to find foo (>= 2.0), because other locators - # weren't searched. Note that this only matters when - # merge=False. - if self.matcher is None: - found = True - else: - found = False - for k in d: - if self.matcher.match(k): - found = True - break - if found: - result = d - break - return result - - def get_distribution_names(self): - """ - Return all the distribution names known to this locator. - """ - result = set() - for locator in self.locators: - try: - result |= locator.get_distribution_names() - except NotImplementedError: - pass - return result - - -# We use a legacy scheme simply because most of the dists on PyPI use legacy -# versions which don't conform to PEP 426 / PEP 440. -default_locator = AggregatingLocator( - JSONLocator(), - SimpleScrapingLocator('https://pypi.python.org/simple/', - timeout=3.0), - scheme='legacy') - -locate = default_locator.locate - -NAME_VERSION_RE = re.compile(r'(?P<name>[\w-]+)\s*' - r'\(\s*(==\s*)?(?P<ver>[^)]+)\)$') - -class DependencyFinder(object): - """ - Locate dependencies for distributions. - """ - - def __init__(self, locator=None): - """ - Initialise an instance, using the specified locator - to locate distributions. - """ - self.locator = locator or default_locator - self.scheme = get_scheme(self.locator.scheme) - - def add_distribution(self, dist): - """ - Add a distribution to the finder. This will update internal information - about who provides what. - :param dist: The distribution to add. - """ - logger.debug('adding distribution %s', dist) - name = dist.key - self.dists_by_name[name] = dist - self.dists[(name, dist.version)] = dist - for p in dist.provides: - name, version = parse_name_and_version(p) - logger.debug('Add to provided: %s, %s, %s', name, version, dist) - self.provided.setdefault(name, set()).add((version, dist)) - - def remove_distribution(self, dist): - """ - Remove a distribution from the finder. This will update internal - information about who provides what. - :param dist: The distribution to remove. - """ - logger.debug('removing distribution %s', dist) - name = dist.key - del self.dists_by_name[name] - del self.dists[(name, dist.version)] - for p in dist.provides: - name, version = parse_name_and_version(p) - logger.debug('Remove from provided: %s, %s, %s', name, version, dist) - s = self.provided[name] - s.remove((version, dist)) - if not s: - del self.provided[name] - - def get_matcher(self, reqt): - """ - Get a version matcher for a requirement. - :param reqt: The requirement - :type reqt: str - :return: A version matcher (an instance of - :class:`distlib.version.Matcher`). - """ - try: - matcher = self.scheme.matcher(reqt) - except UnsupportedVersionError: # pragma: no cover - # XXX compat-mode if cannot read the version - name = reqt.split()[0] - matcher = self.scheme.matcher(name) - return matcher - - def find_providers(self, reqt): - """ - Find the distributions which can fulfill a requirement. - - :param reqt: The requirement. - :type reqt: str - :return: A set of distribution which can fulfill the requirement. - """ - matcher = self.get_matcher(reqt) - name = matcher.key # case-insensitive - result = set() - provided = self.provided - if name in provided: - for version, provider in provided[name]: - try: - match = matcher.match(version) - except UnsupportedVersionError: - match = False - - if match: - result.add(provider) - break - return result - - def try_to_replace(self, provider, other, problems): - """ - Attempt to replace one provider with another. This is typically used - when resolving dependencies from multiple sources, e.g. A requires - (B >= 1.0) while C requires (B >= 1.1). - - For successful replacement, ``provider`` must meet all the requirements - which ``other`` fulfills. - - :param provider: The provider we are trying to replace with. - :param other: The provider we're trying to replace. - :param problems: If False is returned, this will contain what - problems prevented replacement. This is currently - a tuple of the literal string 'cantreplace', - ``provider``, ``other`` and the set of requirements - that ``provider`` couldn't fulfill. - :return: True if we can replace ``other`` with ``provider``, else - False. - """ - rlist = self.reqts[other] - unmatched = set() - for s in rlist: - matcher = self.get_matcher(s) - if not matcher.match(provider.version): - unmatched.add(s) - if unmatched: - # can't replace other with provider - problems.add(('cantreplace', provider, other, - frozenset(unmatched))) - result = False - else: - # can replace other with provider - self.remove_distribution(other) - del self.reqts[other] - for s in rlist: - self.reqts.setdefault(provider, set()).add(s) - self.add_distribution(provider) - result = True - return result - - def find(self, requirement, meta_extras=None, prereleases=False): - """ - Find a distribution and all distributions it depends on. - - :param requirement: The requirement specifying the distribution to - find, or a Distribution instance. - :param meta_extras: A list of meta extras such as :test:, :build: and - so on. - :param prereleases: If ``True``, allow pre-release versions to be - returned - otherwise, don't return prereleases - unless they're all that's available. - - Return a set of :class:`Distribution` instances and a set of - problems. - - The distributions returned should be such that they have the - :attr:`required` attribute set to ``True`` if they were - from the ``requirement`` passed to ``find()``, and they have the - :attr:`build_time_dependency` attribute set to ``True`` unless they - are post-installation dependencies of the ``requirement``. - - The problems should be a tuple consisting of the string - ``'unsatisfied'`` and the requirement which couldn't be satisfied - by any distribution known to the locator. - """ - - self.provided = {} - self.dists = {} - self.dists_by_name = {} - self.reqts = {} - - meta_extras = set(meta_extras or []) - if ':*:' in meta_extras: - meta_extras.remove(':*:') - # :meta: and :run: are implicitly included - meta_extras |= set([':test:', ':build:', ':dev:']) - - if isinstance(requirement, Distribution): - dist = odist = requirement - logger.debug('passed %s as requirement', odist) - else: - dist = odist = self.locator.locate(requirement, - prereleases=prereleases) - if dist is None: - raise DistlibException('Unable to locate %r' % requirement) - logger.debug('located %s', odist) - dist.requested = True - problems = set() - todo = set([dist]) - install_dists = set([odist]) - while todo: - dist = todo.pop() - name = dist.key # case-insensitive - if name not in self.dists_by_name: - self.add_distribution(dist) - else: - #import pdb; pdb.set_trace() - other = self.dists_by_name[name] - if other != dist: - self.try_to_replace(dist, other, problems) - - ireqts = dist.run_requires | dist.meta_requires - sreqts = dist.build_requires - ereqts = set() - if meta_extras and dist in install_dists: - for key in ('test', 'build', 'dev'): - e = ':%s:' % key - if e in meta_extras: - ereqts |= getattr(dist, '%s_requires' % key) - all_reqts = ireqts | sreqts | ereqts - for r in all_reqts: - providers = self.find_providers(r) - if not providers: - logger.debug('No providers found for %r', r) - provider = self.locator.locate(r, prereleases=prereleases) - # If no provider is found and we didn't consider - # prereleases, consider them now. - if provider is None and not prereleases: - provider = self.locator.locate(r, prereleases=True) - if provider is None: - logger.debug('Cannot satisfy %r', r) - problems.add(('unsatisfied', r)) - else: - n, v = provider.key, provider.version - if (n, v) not in self.dists: - todo.add(provider) - providers.add(provider) - if r in ireqts and dist in install_dists: - install_dists.add(provider) - logger.debug('Adding %s to install_dists', - provider.name_and_version) - for p in providers: - name = p.key - if name not in self.dists_by_name: - self.reqts.setdefault(p, set()).add(r) - else: - other = self.dists_by_name[name] - if other != p: - # see if other can be replaced by p - self.try_to_replace(p, other, problems) - - dists = set(self.dists.values()) - for dist in dists: - dist.build_time_dependency = dist not in install_dists - if dist.build_time_dependency: - logger.debug('%s is a build-time dependency only.', - dist.name_and_version) - logger.debug('find done for %s', odist) - return dists, problems diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/manifest.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/manifest.py deleted file mode 100644 index ca0fe44..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/manifest.py +++ /dev/null @@ -1,393 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2013 Python Software Foundation. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -""" -Class representing the list of files in a distribution. - -Equivalent to distutils.filelist, but fixes some problems. -""" -import fnmatch -import logging -import os -import re -import sys - -from . import DistlibException -from .compat import fsdecode -from .util import convert_path - - -__all__ = ['Manifest'] - -logger = logging.getLogger(__name__) - -# a \ followed by some spaces + EOL -_COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M) -_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S) - -# -# Due to the different results returned by fnmatch.translate, we need -# to do slightly different processing for Python 2.7 and 3.2 ... this needed -# to be brought in for Python 3.6 onwards. -# -_PYTHON_VERSION = sys.version_info[:2] - -class Manifest(object): - """A list of files built by on exploring the filesystem and filtered by - applying various patterns to what we find there. - """ - - def __init__(self, base=None): - """ - Initialise an instance. - - :param base: The base directory to explore under. - """ - self.base = os.path.abspath(os.path.normpath(base or os.getcwd())) - self.prefix = self.base + os.sep - self.allfiles = None - self.files = set() - - # - # Public API - # - - def findall(self): - """Find all files under the base and set ``allfiles`` to the absolute - pathnames of files found. - """ - from stat import S_ISREG, S_ISDIR, S_ISLNK - - self.allfiles = allfiles = [] - root = self.base - stack = [root] - pop = stack.pop - push = stack.append - - while stack: - root = pop() - names = os.listdir(root) - - for name in names: - fullname = os.path.join(root, name) - - # Avoid excess stat calls -- just one will do, thank you! - stat = os.stat(fullname) - mode = stat.st_mode - if S_ISREG(mode): - allfiles.append(fsdecode(fullname)) - elif S_ISDIR(mode) and not S_ISLNK(mode): - push(fullname) - - def add(self, item): - """ - Add a file to the manifest. - - :param item: The pathname to add. This can be relative to the base. - """ - if not item.startswith(self.prefix): - item = os.path.join(self.base, item) - self.files.add(os.path.normpath(item)) - - def add_many(self, items): - """ - Add a list of files to the manifest. - - :param items: The pathnames to add. These can be relative to the base. - """ - for item in items: - self.add(item) - - def sorted(self, wantdirs=False): - """ - Return sorted files in directory order - """ - - def add_dir(dirs, d): - dirs.add(d) - logger.debug('add_dir added %s', d) - if d != self.base: - parent, _ = os.path.split(d) - assert parent not in ('', '/') - add_dir(dirs, parent) - - result = set(self.files) # make a copy! - if wantdirs: - dirs = set() - for f in result: - add_dir(dirs, os.path.dirname(f)) - result |= dirs - return [os.path.join(*path_tuple) for path_tuple in - sorted(os.path.split(path) for path in result)] - - def clear(self): - """Clear all collected files.""" - self.files = set() - self.allfiles = [] - - def process_directive(self, directive): - """ - Process a directive which either adds some files from ``allfiles`` to - ``files``, or removes some files from ``files``. - - :param directive: The directive to process. This should be in a format - compatible with distutils ``MANIFEST.in`` files: - - http://docs.python.org/distutils/sourcedist.html#commands - """ - # Parse the line: split it up, make sure the right number of words - # is there, and return the relevant words. 'action' is always - # defined: it's the first word of the line. Which of the other - # three are defined depends on the action; it'll be either - # patterns, (dir and patterns), or (dirpattern). - action, patterns, thedir, dirpattern = self._parse_directive(directive) - - # OK, now we know that the action is valid and we have the - # right number of words on the line for that action -- so we - # can proceed with minimal error-checking. - if action == 'include': - for pattern in patterns: - if not self._include_pattern(pattern, anchor=True): - logger.warning('no files found matching %r', pattern) - - elif action == 'exclude': - for pattern in patterns: - found = self._exclude_pattern(pattern, anchor=True) - #if not found: - # logger.warning('no previously-included files ' - # 'found matching %r', pattern) - - elif action == 'global-include': - for pattern in patterns: - if not self._include_pattern(pattern, anchor=False): - logger.warning('no files found matching %r ' - 'anywhere in distribution', pattern) - - elif action == 'global-exclude': - for pattern in patterns: - found = self._exclude_pattern(pattern, anchor=False) - #if not found: - # logger.warning('no previously-included files ' - # 'matching %r found anywhere in ' - # 'distribution', pattern) - - elif action == 'recursive-include': - for pattern in patterns: - if not self._include_pattern(pattern, prefix=thedir): - logger.warning('no files found matching %r ' - 'under directory %r', pattern, thedir) - - elif action == 'recursive-exclude': - for pattern in patterns: - found = self._exclude_pattern(pattern, prefix=thedir) - #if not found: - # logger.warning('no previously-included files ' - # 'matching %r found under directory %r', - # pattern, thedir) - - elif action == 'graft': - if not self._include_pattern(None, prefix=dirpattern): - logger.warning('no directories found matching %r', - dirpattern) - - elif action == 'prune': - if not self._exclude_pattern(None, prefix=dirpattern): - logger.warning('no previously-included directories found ' - 'matching %r', dirpattern) - else: # pragma: no cover - # This should never happen, as it should be caught in - # _parse_template_line - raise DistlibException( - 'invalid action %r' % action) - - # - # Private API - # - - def _parse_directive(self, directive): - """ - Validate a directive. - :param directive: The directive to validate. - :return: A tuple of action, patterns, thedir, dir_patterns - """ - words = directive.split() - if len(words) == 1 and words[0] not in ('include', 'exclude', - 'global-include', - 'global-exclude', - 'recursive-include', - 'recursive-exclude', - 'graft', 'prune'): - # no action given, let's use the default 'include' - words.insert(0, 'include') - - action = words[0] - patterns = thedir = dir_pattern = None - - if action in ('include', 'exclude', - 'global-include', 'global-exclude'): - if len(words) < 2: - raise DistlibException( - '%r expects <pattern1> <pattern2> ...' % action) - - patterns = [convert_path(word) for word in words[1:]] - - elif action in ('recursive-include', 'recursive-exclude'): - if len(words) < 3: - raise DistlibException( - '%r expects <dir> <pattern1> <pattern2> ...' % action) - - thedir = convert_path(words[1]) - patterns = [convert_path(word) for word in words[2:]] - - elif action in ('graft', 'prune'): - if len(words) != 2: - raise DistlibException( - '%r expects a single <dir_pattern>' % action) - - dir_pattern = convert_path(words[1]) - - else: - raise DistlibException('unknown action %r' % action) - - return action, patterns, thedir, dir_pattern - - def _include_pattern(self, pattern, anchor=True, prefix=None, - is_regex=False): - """Select strings (presumably filenames) from 'self.files' that - match 'pattern', a Unix-style wildcard (glob) pattern. - - Patterns are not quite the same as implemented by the 'fnmatch' - module: '*' and '?' match non-special characters, where "special" - is platform-dependent: slash on Unix; colon, slash, and backslash on - DOS/Windows; and colon on Mac OS. - - If 'anchor' is true (the default), then the pattern match is more - stringent: "*.py" will match "foo.py" but not "foo/bar.py". If - 'anchor' is false, both of these will match. - - If 'prefix' is supplied, then only filenames starting with 'prefix' - (itself a pattern) and ending with 'pattern', with anything in between - them, will match. 'anchor' is ignored in this case. - - If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and - 'pattern' is assumed to be either a string containing a regex or a - regex object -- no translation is done, the regex is just compiled - and used as-is. - - Selected strings will be added to self.files. - - Return True if files are found. - """ - # XXX docstring lying about what the special chars are? - found = False - pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) - - # delayed loading of allfiles list - if self.allfiles is None: - self.findall() - - for name in self.allfiles: - if pattern_re.search(name): - self.files.add(name) - found = True - return found - - def _exclude_pattern(self, pattern, anchor=True, prefix=None, - is_regex=False): - """Remove strings (presumably filenames) from 'files' that match - 'pattern'. - - Other parameters are the same as for 'include_pattern()', above. - The list 'self.files' is modified in place. Return True if files are - found. - - This API is public to allow e.g. exclusion of SCM subdirs, e.g. when - packaging source distributions - """ - found = False - pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) - for f in list(self.files): - if pattern_re.search(f): - self.files.remove(f) - found = True - return found - - def _translate_pattern(self, pattern, anchor=True, prefix=None, - is_regex=False): - """Translate a shell-like wildcard pattern to a compiled regular - expression. - - Return the compiled regex. If 'is_regex' true, - then 'pattern' is directly compiled to a regex (if it's a string) - or just returned as-is (assumes it's a regex object). - """ - if is_regex: - if isinstance(pattern, str): - return re.compile(pattern) - else: - return pattern - - if _PYTHON_VERSION > (3, 2): - # ditch start and end characters - start, _, end = self._glob_to_re('_').partition('_') - - if pattern: - pattern_re = self._glob_to_re(pattern) - if _PYTHON_VERSION > (3, 2): - assert pattern_re.startswith(start) and pattern_re.endswith(end) - else: - pattern_re = '' - - base = re.escape(os.path.join(self.base, '')) - if prefix is not None: - # ditch end of pattern character - if _PYTHON_VERSION <= (3, 2): - empty_pattern = self._glob_to_re('') - prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)] - else: - prefix_re = self._glob_to_re(prefix) - assert prefix_re.startswith(start) and prefix_re.endswith(end) - prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] - sep = os.sep - if os.sep == '\\': - sep = r'\\' - if _PYTHON_VERSION <= (3, 2): - pattern_re = '^' + base + sep.join((prefix_re, - '.*' + pattern_re)) - else: - pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] - pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep, - pattern_re, end) - else: # no prefix -- respect anchor flag - if anchor: - if _PYTHON_VERSION <= (3, 2): - pattern_re = '^' + base + pattern_re - else: - pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):]) - - return re.compile(pattern_re) - - def _glob_to_re(self, pattern): - """Translate a shell-like glob pattern to a regular expression. - - Return a string containing the regex. Differs from - 'fnmatch.translate()' in that '*' does not match "special characters" - (which are platform-specific). - """ - pattern_re = fnmatch.translate(pattern) - - # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which - # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, - # and by extension they shouldn't match such "special characters" under - # any OS. So change all non-escaped dots in the RE to match any - # character except the special characters (currently: just os.sep). - sep = os.sep - if os.sep == '\\': - # we're using a regex to manipulate a regex, so we need - # to escape the backslash twice - sep = r'\\\\' - escaped = r'\1[^%s]' % sep - pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re) - return pattern_re diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/markers.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/markers.py deleted file mode 100644 index ee1f3e2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/markers.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2017 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -""" -Parser for the environment markers micro-language defined in PEP 508. -""" - -# Note: In PEP 345, the micro-language was Python compatible, so the ast -# module could be used to parse it. However, PEP 508 introduced operators such -# as ~= and === which aren't in Python, necessitating a different approach. - -import os -import sys -import platform -import re - -from .compat import python_implementation, urlparse, string_types -from .util import in_venv, parse_marker - -__all__ = ['interpret'] - -def _is_literal(o): - if not isinstance(o, string_types) or not o: - return False - return o[0] in '\'"' - -class Evaluator(object): - """ - This class is used to evaluate marker expessions. - """ - - operations = { - '==': lambda x, y: x == y, - '===': lambda x, y: x == y, - '~=': lambda x, y: x == y or x > y, - '!=': lambda x, y: x != y, - '<': lambda x, y: x < y, - '<=': lambda x, y: x == y or x < y, - '>': lambda x, y: x > y, - '>=': lambda x, y: x == y or x > y, - 'and': lambda x, y: x and y, - 'or': lambda x, y: x or y, - 'in': lambda x, y: x in y, - 'not in': lambda x, y: x not in y, - } - - def evaluate(self, expr, context): - """ - Evaluate a marker expression returned by the :func:`parse_requirement` - function in the specified context. - """ - if isinstance(expr, string_types): - if expr[0] in '\'"': - result = expr[1:-1] - else: - if expr not in context: - raise SyntaxError('unknown variable: %s' % expr) - result = context[expr] - else: - assert isinstance(expr, dict) - op = expr['op'] - if op not in self.operations: - raise NotImplementedError('op not implemented: %s' % op) - elhs = expr['lhs'] - erhs = expr['rhs'] - if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): - raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs)) - - lhs = self.evaluate(elhs, context) - rhs = self.evaluate(erhs, context) - result = self.operations[op](lhs, rhs) - return result - -def default_context(): - def format_full_version(info): - version = '%s.%s.%s' % (info.major, info.minor, info.micro) - kind = info.releaselevel - if kind != 'final': - version += kind[0] + str(info.serial) - return version - - if hasattr(sys, 'implementation'): - implementation_version = format_full_version(sys.implementation.version) - implementation_name = sys.implementation.name - else: - implementation_version = '0' - implementation_name = '' - - result = { - 'implementation_name': implementation_name, - 'implementation_version': implementation_version, - 'os_name': os.name, - 'platform_machine': platform.machine(), - 'platform_python_implementation': platform.python_implementation(), - 'platform_release': platform.release(), - 'platform_system': platform.system(), - 'platform_version': platform.version(), - 'platform_in_venv': str(in_venv()), - 'python_full_version': platform.python_version(), - 'python_version': platform.python_version()[:3], - 'sys_platform': sys.platform, - } - return result - -DEFAULT_CONTEXT = default_context() -del default_context - -evaluator = Evaluator() - -def interpret(marker, execution_context=None): - """ - Interpret a marker and return a result depending on environment. - - :param marker: The marker to interpret. - :type marker: str - :param execution_context: The context used for name lookup. - :type execution_context: mapping - """ - try: - expr, rest = parse_marker(marker) - except Exception as e: - raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e)) - if rest and rest[0] != '#': - raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest)) - context = dict(DEFAULT_CONTEXT) - if execution_context: - context.update(execution_context) - return evaluator.evaluate(expr, context) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/metadata.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/metadata.py deleted file mode 100644 index 77eed7f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/metadata.py +++ /dev/null @@ -1,1094 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012 The Python Software Foundation. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -"""Implementation of the Metadata for Python packages PEPs. - -Supports all metadata formats (1.0, 1.1, 1.2, and 2.0 experimental). -""" -from __future__ import unicode_literals - -import codecs -from email import message_from_file -import json -import logging -import re - - -from . import DistlibException, __version__ -from .compat import StringIO, string_types, text_type -from .markers import interpret -from .util import extract_by_key, get_extras -from .version import get_scheme, PEP440_VERSION_RE - -logger = logging.getLogger(__name__) - - -class MetadataMissingError(DistlibException): - """A required metadata is missing""" - - -class MetadataConflictError(DistlibException): - """Attempt to read or write metadata fields that are conflictual.""" - - -class MetadataUnrecognizedVersionError(DistlibException): - """Unknown metadata version number.""" - - -class MetadataInvalidError(DistlibException): - """A metadata value is invalid""" - -# public API of this module -__all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION'] - -# Encoding used for the PKG-INFO files -PKG_INFO_ENCODING = 'utf-8' - -# preferred version. Hopefully will be changed -# to 1.2 once PEP 345 is supported everywhere -PKG_INFO_PREFERRED_VERSION = '1.1' - -_LINE_PREFIX_1_2 = re.compile('\n \\|') -_LINE_PREFIX_PRE_1_2 = re.compile('\n ') -_241_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', - 'Summary', 'Description', - 'Keywords', 'Home-page', 'Author', 'Author-email', - 'License') - -_314_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', - 'Supported-Platform', 'Summary', 'Description', - 'Keywords', 'Home-page', 'Author', 'Author-email', - 'License', 'Classifier', 'Download-URL', 'Obsoletes', - 'Provides', 'Requires') - -_314_MARKERS = ('Obsoletes', 'Provides', 'Requires', 'Classifier', - 'Download-URL') - -_345_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', - 'Supported-Platform', 'Summary', 'Description', - 'Keywords', 'Home-page', 'Author', 'Author-email', - 'Maintainer', 'Maintainer-email', 'License', - 'Classifier', 'Download-URL', 'Obsoletes-Dist', - 'Project-URL', 'Provides-Dist', 'Requires-Dist', - 'Requires-Python', 'Requires-External') - -_345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python', - 'Obsoletes-Dist', 'Requires-External', 'Maintainer', - 'Maintainer-email', 'Project-URL') - -_426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', - 'Supported-Platform', 'Summary', 'Description', - 'Keywords', 'Home-page', 'Author', 'Author-email', - 'Maintainer', 'Maintainer-email', 'License', - 'Classifier', 'Download-URL', 'Obsoletes-Dist', - 'Project-URL', 'Provides-Dist', 'Requires-Dist', - 'Requires-Python', 'Requires-External', 'Private-Version', - 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension', - 'Provides-Extra') - -_426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By', - 'Setup-Requires-Dist', 'Extension') - -# See issue #106: Sometimes 'Requires' occurs wrongly in the metadata. Include -# it in the tuple literal below to allow it (for now) -_566_FIELDS = _426_FIELDS + ('Description-Content-Type', 'Requires') - -_566_MARKERS = ('Description-Content-Type',) - -_ALL_FIELDS = set() -_ALL_FIELDS.update(_241_FIELDS) -_ALL_FIELDS.update(_314_FIELDS) -_ALL_FIELDS.update(_345_FIELDS) -_ALL_FIELDS.update(_426_FIELDS) -_ALL_FIELDS.update(_566_FIELDS) - -EXTRA_RE = re.compile(r'''extra\s*==\s*("([^"]+)"|'([^']+)')''') - - -def _version2fieldlist(version): - if version == '1.0': - return _241_FIELDS - elif version == '1.1': - return _314_FIELDS - elif version == '1.2': - return _345_FIELDS - elif version in ('1.3', '2.1'): - return _345_FIELDS + _566_FIELDS - elif version == '2.0': - return _426_FIELDS - raise MetadataUnrecognizedVersionError(version) - - -def _best_version(fields): - """Detect the best version depending on the fields used.""" - def _has_marker(keys, markers): - for marker in markers: - if marker in keys: - return True - return False - - keys = [] - for key, value in fields.items(): - if value in ([], 'UNKNOWN', None): - continue - keys.append(key) - - possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.0', '2.1'] - - # first let's try to see if a field is not part of one of the version - for key in keys: - if key not in _241_FIELDS and '1.0' in possible_versions: - possible_versions.remove('1.0') - logger.debug('Removed 1.0 due to %s', key) - if key not in _314_FIELDS and '1.1' in possible_versions: - possible_versions.remove('1.1') - logger.debug('Removed 1.1 due to %s', key) - if key not in _345_FIELDS and '1.2' in possible_versions: - possible_versions.remove('1.2') - logger.debug('Removed 1.2 due to %s', key) - if key not in _566_FIELDS and '1.3' in possible_versions: - possible_versions.remove('1.3') - logger.debug('Removed 1.3 due to %s', key) - if key not in _566_FIELDS and '2.1' in possible_versions: - if key != 'Description': # In 2.1, description allowed after headers - possible_versions.remove('2.1') - logger.debug('Removed 2.1 due to %s', key) - if key not in _426_FIELDS and '2.0' in possible_versions: - possible_versions.remove('2.0') - logger.debug('Removed 2.0 due to %s', key) - - # possible_version contains qualified versions - if len(possible_versions) == 1: - return possible_versions[0] # found ! - elif len(possible_versions) == 0: - logger.debug('Out of options - unknown metadata set: %s', fields) - raise MetadataConflictError('Unknown metadata set') - - # let's see if one unique marker is found - is_1_1 = '1.1' in possible_versions and _has_marker(keys, _314_MARKERS) - is_1_2 = '1.2' in possible_versions and _has_marker(keys, _345_MARKERS) - is_2_1 = '2.1' in possible_versions and _has_marker(keys, _566_MARKERS) - is_2_0 = '2.0' in possible_versions and _has_marker(keys, _426_MARKERS) - if int(is_1_1) + int(is_1_2) + int(is_2_1) + int(is_2_0) > 1: - raise MetadataConflictError('You used incompatible 1.1/1.2/2.0/2.1 fields') - - # we have the choice, 1.0, or 1.2, or 2.0 - # - 1.0 has a broken Summary field but works with all tools - # - 1.1 is to avoid - # - 1.2 fixes Summary but has little adoption - # - 2.0 adds more features and is very new - if not is_1_1 and not is_1_2 and not is_2_1 and not is_2_0: - # we couldn't find any specific marker - if PKG_INFO_PREFERRED_VERSION in possible_versions: - return PKG_INFO_PREFERRED_VERSION - if is_1_1: - return '1.1' - if is_1_2: - return '1.2' - if is_2_1: - return '2.1' - - return '2.0' - -_ATTR2FIELD = { - 'metadata_version': 'Metadata-Version', - 'name': 'Name', - 'version': 'Version', - 'platform': 'Platform', - 'supported_platform': 'Supported-Platform', - 'summary': 'Summary', - 'description': 'Description', - 'keywords': 'Keywords', - 'home_page': 'Home-page', - 'author': 'Author', - 'author_email': 'Author-email', - 'maintainer': 'Maintainer', - 'maintainer_email': 'Maintainer-email', - 'license': 'License', - 'classifier': 'Classifier', - 'download_url': 'Download-URL', - 'obsoletes_dist': 'Obsoletes-Dist', - 'provides_dist': 'Provides-Dist', - 'requires_dist': 'Requires-Dist', - 'setup_requires_dist': 'Setup-Requires-Dist', - 'requires_python': 'Requires-Python', - 'requires_external': 'Requires-External', - 'requires': 'Requires', - 'provides': 'Provides', - 'obsoletes': 'Obsoletes', - 'project_url': 'Project-URL', - 'private_version': 'Private-Version', - 'obsoleted_by': 'Obsoleted-By', - 'extension': 'Extension', - 'provides_extra': 'Provides-Extra', -} - -_PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') -_VERSIONS_FIELDS = ('Requires-Python',) -_VERSION_FIELDS = ('Version',) -_LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes', - 'Requires', 'Provides', 'Obsoletes-Dist', - 'Provides-Dist', 'Requires-Dist', 'Requires-External', - 'Project-URL', 'Supported-Platform', 'Setup-Requires-Dist', - 'Provides-Extra', 'Extension') -_LISTTUPLEFIELDS = ('Project-URL',) - -_ELEMENTSFIELD = ('Keywords',) - -_UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') - -_MISSING = object() - -_FILESAFE = re.compile('[^A-Za-z0-9.]+') - - -def _get_name_and_version(name, version, for_filename=False): - """Return the distribution name with version. - - If for_filename is true, return a filename-escaped form.""" - if for_filename: - # For both name and version any runs of non-alphanumeric or '.' - # characters are replaced with a single '-'. Additionally any - # spaces in the version string become '.' - name = _FILESAFE.sub('-', name) - version = _FILESAFE.sub('-', version.replace(' ', '.')) - return '%s-%s' % (name, version) - - -class LegacyMetadata(object): - """The legacy metadata of a release. - - Supports versions 1.0, 1.1 and 1.2 (auto-detected). You can - instantiate the class with one of these arguments (or none): - - *path*, the path to a metadata file - - *fileobj* give a file-like object with metadata as content - - *mapping* is a dict-like object - - *scheme* is a version scheme name - """ - # TODO document the mapping API and UNKNOWN default key - - def __init__(self, path=None, fileobj=None, mapping=None, - scheme='default'): - if [path, fileobj, mapping].count(None) < 2: - raise TypeError('path, fileobj and mapping are exclusive') - self._fields = {} - self.requires_files = [] - self._dependencies = None - self.scheme = scheme - if path is not None: - self.read(path) - elif fileobj is not None: - self.read_file(fileobj) - elif mapping is not None: - self.update(mapping) - self.set_metadata_version() - - def set_metadata_version(self): - self._fields['Metadata-Version'] = _best_version(self._fields) - - def _write_field(self, fileobj, name, value): - fileobj.write('%s: %s\n' % (name, value)) - - def __getitem__(self, name): - return self.get(name) - - def __setitem__(self, name, value): - return self.set(name, value) - - def __delitem__(self, name): - field_name = self._convert_name(name) - try: - del self._fields[field_name] - except KeyError: - raise KeyError(name) - - def __contains__(self, name): - return (name in self._fields or - self._convert_name(name) in self._fields) - - def _convert_name(self, name): - if name in _ALL_FIELDS: - return name - name = name.replace('-', '_').lower() - return _ATTR2FIELD.get(name, name) - - def _default_value(self, name): - if name in _LISTFIELDS or name in _ELEMENTSFIELD: - return [] - return 'UNKNOWN' - - def _remove_line_prefix(self, value): - if self.metadata_version in ('1.0', '1.1'): - return _LINE_PREFIX_PRE_1_2.sub('\n', value) - else: - return _LINE_PREFIX_1_2.sub('\n', value) - - def __getattr__(self, name): - if name in _ATTR2FIELD: - return self[name] - raise AttributeError(name) - - # - # Public API - # - -# dependencies = property(_get_dependencies, _set_dependencies) - - def get_fullname(self, filesafe=False): - """Return the distribution name with version. - - If filesafe is true, return a filename-escaped form.""" - return _get_name_and_version(self['Name'], self['Version'], filesafe) - - def is_field(self, name): - """return True if name is a valid metadata key""" - name = self._convert_name(name) - return name in _ALL_FIELDS - - def is_multi_field(self, name): - name = self._convert_name(name) - return name in _LISTFIELDS - - def read(self, filepath): - """Read the metadata values from a file path.""" - fp = codecs.open(filepath, 'r', encoding='utf-8') - try: - self.read_file(fp) - finally: - fp.close() - - def read_file(self, fileob): - """Read the metadata values from a file object.""" - msg = message_from_file(fileob) - self._fields['Metadata-Version'] = msg['metadata-version'] - - # When reading, get all the fields we can - for field in _ALL_FIELDS: - if field not in msg: - continue - if field in _LISTFIELDS: - # we can have multiple lines - values = msg.get_all(field) - if field in _LISTTUPLEFIELDS and values is not None: - values = [tuple(value.split(',')) for value in values] - self.set(field, values) - else: - # single line - value = msg[field] - if value is not None and value != 'UNKNOWN': - self.set(field, value) - # logger.debug('Attempting to set metadata for %s', self) - # self.set_metadata_version() - - def write(self, filepath, skip_unknown=False): - """Write the metadata fields to filepath.""" - fp = codecs.open(filepath, 'w', encoding='utf-8') - try: - self.write_file(fp, skip_unknown) - finally: - fp.close() - - def write_file(self, fileobject, skip_unknown=False): - """Write the PKG-INFO format data to a file object.""" - self.set_metadata_version() - - for field in _version2fieldlist(self['Metadata-Version']): - values = self.get(field) - if skip_unknown and values in ('UNKNOWN', [], ['UNKNOWN']): - continue - if field in _ELEMENTSFIELD: - self._write_field(fileobject, field, ','.join(values)) - continue - if field not in _LISTFIELDS: - if field == 'Description': - if self.metadata_version in ('1.0', '1.1'): - values = values.replace('\n', '\n ') - else: - values = values.replace('\n', '\n |') - values = [values] - - if field in _LISTTUPLEFIELDS: - values = [','.join(value) for value in values] - - for value in values: - self._write_field(fileobject, field, value) - - def update(self, other=None, **kwargs): - """Set metadata values from the given iterable `other` and kwargs. - - Behavior is like `dict.update`: If `other` has a ``keys`` method, - they are looped over and ``self[key]`` is assigned ``other[key]``. - Else, ``other`` is an iterable of ``(key, value)`` iterables. - - Keys that don't match a metadata field or that have an empty value are - dropped. - """ - def _set(key, value): - if key in _ATTR2FIELD and value: - self.set(self._convert_name(key), value) - - if not other: - # other is None or empty container - pass - elif hasattr(other, 'keys'): - for k in other.keys(): - _set(k, other[k]) - else: - for k, v in other: - _set(k, v) - - if kwargs: - for k, v in kwargs.items(): - _set(k, v) - - def set(self, name, value): - """Control then set a metadata field.""" - name = self._convert_name(name) - - if ((name in _ELEMENTSFIELD or name == 'Platform') and - not isinstance(value, (list, tuple))): - if isinstance(value, string_types): - value = [v.strip() for v in value.split(',')] - else: - value = [] - elif (name in _LISTFIELDS and - not isinstance(value, (list, tuple))): - if isinstance(value, string_types): - value = [value] - else: - value = [] - - if logger.isEnabledFor(logging.WARNING): - project_name = self['Name'] - - scheme = get_scheme(self.scheme) - if name in _PREDICATE_FIELDS and value is not None: - for v in value: - # check that the values are valid - if not scheme.is_valid_matcher(v.split(';')[0]): - logger.warning( - "'%s': '%s' is not valid (field '%s')", - project_name, v, name) - # FIXME this rejects UNKNOWN, is that right? - elif name in _VERSIONS_FIELDS and value is not None: - if not scheme.is_valid_constraint_list(value): - logger.warning("'%s': '%s' is not a valid version (field '%s')", - project_name, value, name) - elif name in _VERSION_FIELDS and value is not None: - if not scheme.is_valid_version(value): - logger.warning("'%s': '%s' is not a valid version (field '%s')", - project_name, value, name) - - if name in _UNICODEFIELDS: - if name == 'Description': - value = self._remove_line_prefix(value) - - self._fields[name] = value - - def get(self, name, default=_MISSING): - """Get a metadata field.""" - name = self._convert_name(name) - if name not in self._fields: - if default is _MISSING: - default = self._default_value(name) - return default - if name in _UNICODEFIELDS: - value = self._fields[name] - return value - elif name in _LISTFIELDS: - value = self._fields[name] - if value is None: - return [] - res = [] - for val in value: - if name not in _LISTTUPLEFIELDS: - res.append(val) - else: - # That's for Project-URL - res.append((val[0], val[1])) - return res - - elif name in _ELEMENTSFIELD: - value = self._fields[name] - if isinstance(value, string_types): - return value.split(',') - return self._fields[name] - - def check(self, strict=False): - """Check if the metadata is compliant. If strict is True then raise if - no Name or Version are provided""" - self.set_metadata_version() - - # XXX should check the versions (if the file was loaded) - missing, warnings = [], [] - - for attr in ('Name', 'Version'): # required by PEP 345 - if attr not in self: - missing.append(attr) - - if strict and missing != []: - msg = 'missing required metadata: %s' % ', '.join(missing) - raise MetadataMissingError(msg) - - for attr in ('Home-page', 'Author'): - if attr not in self: - missing.append(attr) - - # checking metadata 1.2 (XXX needs to check 1.1, 1.0) - if self['Metadata-Version'] != '1.2': - return missing, warnings - - scheme = get_scheme(self.scheme) - - def are_valid_constraints(value): - for v in value: - if not scheme.is_valid_matcher(v.split(';')[0]): - return False - return True - - for fields, controller in ((_PREDICATE_FIELDS, are_valid_constraints), - (_VERSIONS_FIELDS, - scheme.is_valid_constraint_list), - (_VERSION_FIELDS, - scheme.is_valid_version)): - for field in fields: - value = self.get(field, None) - if value is not None and not controller(value): - warnings.append("Wrong value for '%s': %s" % (field, value)) - - return missing, warnings - - def todict(self, skip_missing=False): - """Return fields as a dict. - - Field names will be converted to use the underscore-lowercase style - instead of hyphen-mixed case (i.e. home_page instead of Home-page). - """ - self.set_metadata_version() - - mapping_1_0 = ( - ('metadata_version', 'Metadata-Version'), - ('name', 'Name'), - ('version', 'Version'), - ('summary', 'Summary'), - ('home_page', 'Home-page'), - ('author', 'Author'), - ('author_email', 'Author-email'), - ('license', 'License'), - ('description', 'Description'), - ('keywords', 'Keywords'), - ('platform', 'Platform'), - ('classifiers', 'Classifier'), - ('download_url', 'Download-URL'), - ) - - data = {} - for key, field_name in mapping_1_0: - if not skip_missing or field_name in self._fields: - data[key] = self[field_name] - - if self['Metadata-Version'] == '1.2': - mapping_1_2 = ( - ('requires_dist', 'Requires-Dist'), - ('requires_python', 'Requires-Python'), - ('requires_external', 'Requires-External'), - ('provides_dist', 'Provides-Dist'), - ('obsoletes_dist', 'Obsoletes-Dist'), - ('project_url', 'Project-URL'), - ('maintainer', 'Maintainer'), - ('maintainer_email', 'Maintainer-email'), - ) - for key, field_name in mapping_1_2: - if not skip_missing or field_name in self._fields: - if key != 'project_url': - data[key] = self[field_name] - else: - data[key] = [','.join(u) for u in self[field_name]] - - elif self['Metadata-Version'] == '1.1': - mapping_1_1 = ( - ('provides', 'Provides'), - ('requires', 'Requires'), - ('obsoletes', 'Obsoletes'), - ) - for key, field_name in mapping_1_1: - if not skip_missing or field_name in self._fields: - data[key] = self[field_name] - - return data - - def add_requirements(self, requirements): - if self['Metadata-Version'] == '1.1': - # we can't have 1.1 metadata *and* Setuptools requires - for field in ('Obsoletes', 'Requires', 'Provides'): - if field in self: - del self[field] - self['Requires-Dist'] += requirements - - # Mapping API - # TODO could add iter* variants - - def keys(self): - return list(_version2fieldlist(self['Metadata-Version'])) - - def __iter__(self): - for key in self.keys(): - yield key - - def values(self): - return [self[key] for key in self.keys()] - - def items(self): - return [(key, self[key]) for key in self.keys()] - - def __repr__(self): - return '<%s %s %s>' % (self.__class__.__name__, self.name, - self.version) - - -METADATA_FILENAME = 'pydist.json' -WHEEL_METADATA_FILENAME = 'metadata.json' -LEGACY_METADATA_FILENAME = 'METADATA' - - -class Metadata(object): - """ - The metadata of a release. This implementation uses 2.0 (JSON) - metadata where possible. If not possible, it wraps a LegacyMetadata - instance which handles the key-value metadata format. - """ - - METADATA_VERSION_MATCHER = re.compile(r'^\d+(\.\d+)*$') - - NAME_MATCHER = re.compile('^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$', re.I) - - VERSION_MATCHER = PEP440_VERSION_RE - - SUMMARY_MATCHER = re.compile('.{1,2047}') - - METADATA_VERSION = '2.0' - - GENERATOR = 'distlib (%s)' % __version__ - - MANDATORY_KEYS = { - 'name': (), - 'version': (), - 'summary': ('legacy',), - } - - INDEX_KEYS = ('name version license summary description author ' - 'author_email keywords platform home_page classifiers ' - 'download_url') - - DEPENDENCY_KEYS = ('extras run_requires test_requires build_requires ' - 'dev_requires provides meta_requires obsoleted_by ' - 'supports_environments') - - SYNTAX_VALIDATORS = { - 'metadata_version': (METADATA_VERSION_MATCHER, ()), - 'name': (NAME_MATCHER, ('legacy',)), - 'version': (VERSION_MATCHER, ('legacy',)), - 'summary': (SUMMARY_MATCHER, ('legacy',)), - } - - __slots__ = ('_legacy', '_data', 'scheme') - - def __init__(self, path=None, fileobj=None, mapping=None, - scheme='default'): - if [path, fileobj, mapping].count(None) < 2: - raise TypeError('path, fileobj and mapping are exclusive') - self._legacy = None - self._data = None - self.scheme = scheme - #import pdb; pdb.set_trace() - if mapping is not None: - try: - self._validate_mapping(mapping, scheme) - self._data = mapping - except MetadataUnrecognizedVersionError: - self._legacy = LegacyMetadata(mapping=mapping, scheme=scheme) - self.validate() - else: - data = None - if path: - with open(path, 'rb') as f: - data = f.read() - elif fileobj: - data = fileobj.read() - if data is None: - # Initialised with no args - to be added - self._data = { - 'metadata_version': self.METADATA_VERSION, - 'generator': self.GENERATOR, - } - else: - if not isinstance(data, text_type): - data = data.decode('utf-8') - try: - self._data = json.loads(data) - self._validate_mapping(self._data, scheme) - except ValueError: - # Note: MetadataUnrecognizedVersionError does not - # inherit from ValueError (it's a DistlibException, - # which should not inherit from ValueError). - # The ValueError comes from the json.load - if that - # succeeds and we get a validation error, we want - # that to propagate - self._legacy = LegacyMetadata(fileobj=StringIO(data), - scheme=scheme) - self.validate() - - common_keys = set(('name', 'version', 'license', 'keywords', 'summary')) - - none_list = (None, list) - none_dict = (None, dict) - - mapped_keys = { - 'run_requires': ('Requires-Dist', list), - 'build_requires': ('Setup-Requires-Dist', list), - 'dev_requires': none_list, - 'test_requires': none_list, - 'meta_requires': none_list, - 'extras': ('Provides-Extra', list), - 'modules': none_list, - 'namespaces': none_list, - 'exports': none_dict, - 'commands': none_dict, - 'classifiers': ('Classifier', list), - 'source_url': ('Download-URL', None), - 'metadata_version': ('Metadata-Version', None), - } - - del none_list, none_dict - - def __getattribute__(self, key): - common = object.__getattribute__(self, 'common_keys') - mapped = object.__getattribute__(self, 'mapped_keys') - if key in mapped: - lk, maker = mapped[key] - if self._legacy: - if lk is None: - result = None if maker is None else maker() - else: - result = self._legacy.get(lk) - else: - value = None if maker is None else maker() - if key not in ('commands', 'exports', 'modules', 'namespaces', - 'classifiers'): - result = self._data.get(key, value) - else: - # special cases for PEP 459 - sentinel = object() - result = sentinel - d = self._data.get('extensions') - if d: - if key == 'commands': - result = d.get('python.commands', value) - elif key == 'classifiers': - d = d.get('python.details') - if d: - result = d.get(key, value) - else: - d = d.get('python.exports') - if not d: - d = self._data.get('python.exports') - if d: - result = d.get(key, value) - if result is sentinel: - result = value - elif key not in common: - result = object.__getattribute__(self, key) - elif self._legacy: - result = self._legacy.get(key) - else: - result = self._data.get(key) - return result - - def _validate_value(self, key, value, scheme=None): - if key in self.SYNTAX_VALIDATORS: - pattern, exclusions = self.SYNTAX_VALIDATORS[key] - if (scheme or self.scheme) not in exclusions: - m = pattern.match(value) - if not m: - raise MetadataInvalidError("'%s' is an invalid value for " - "the '%s' property" % (value, - key)) - - def __setattr__(self, key, value): - self._validate_value(key, value) - common = object.__getattribute__(self, 'common_keys') - mapped = object.__getattribute__(self, 'mapped_keys') - if key in mapped: - lk, _ = mapped[key] - if self._legacy: - if lk is None: - raise NotImplementedError - self._legacy[lk] = value - elif key not in ('commands', 'exports', 'modules', 'namespaces', - 'classifiers'): - self._data[key] = value - else: - # special cases for PEP 459 - d = self._data.setdefault('extensions', {}) - if key == 'commands': - d['python.commands'] = value - elif key == 'classifiers': - d = d.setdefault('python.details', {}) - d[key] = value - else: - d = d.setdefault('python.exports', {}) - d[key] = value - elif key not in common: - object.__setattr__(self, key, value) - else: - if key == 'keywords': - if isinstance(value, string_types): - value = value.strip() - if value: - value = value.split() - else: - value = [] - if self._legacy: - self._legacy[key] = value - else: - self._data[key] = value - - @property - def name_and_version(self): - return _get_name_and_version(self.name, self.version, True) - - @property - def provides(self): - if self._legacy: - result = self._legacy['Provides-Dist'] - else: - result = self._data.setdefault('provides', []) - s = '%s (%s)' % (self.name, self.version) - if s not in result: - result.append(s) - return result - - @provides.setter - def provides(self, value): - if self._legacy: - self._legacy['Provides-Dist'] = value - else: - self._data['provides'] = value - - def get_requirements(self, reqts, extras=None, env=None): - """ - Base method to get dependencies, given a set of extras - to satisfy and an optional environment context. - :param reqts: A list of sometimes-wanted dependencies, - perhaps dependent on extras and environment. - :param extras: A list of optional components being requested. - :param env: An optional environment for marker evaluation. - """ - if self._legacy: - result = reqts - else: - result = [] - extras = get_extras(extras or [], self.extras) - for d in reqts: - if 'extra' not in d and 'environment' not in d: - # unconditional - include = True - else: - if 'extra' not in d: - # Not extra-dependent - only environment-dependent - include = True - else: - include = d.get('extra') in extras - if include: - # Not excluded because of extras, check environment - marker = d.get('environment') - if marker: - include = interpret(marker, env) - if include: - result.extend(d['requires']) - for key in ('build', 'dev', 'test'): - e = ':%s:' % key - if e in extras: - extras.remove(e) - # A recursive call, but it should terminate since 'test' - # has been removed from the extras - reqts = self._data.get('%s_requires' % key, []) - result.extend(self.get_requirements(reqts, extras=extras, - env=env)) - return result - - @property - def dictionary(self): - if self._legacy: - return self._from_legacy() - return self._data - - @property - def dependencies(self): - if self._legacy: - raise NotImplementedError - else: - return extract_by_key(self._data, self.DEPENDENCY_KEYS) - - @dependencies.setter - def dependencies(self, value): - if self._legacy: - raise NotImplementedError - else: - self._data.update(value) - - def _validate_mapping(self, mapping, scheme): - if mapping.get('metadata_version') != self.METADATA_VERSION: - raise MetadataUnrecognizedVersionError() - missing = [] - for key, exclusions in self.MANDATORY_KEYS.items(): - if key not in mapping: - if scheme not in exclusions: - missing.append(key) - if missing: - msg = 'Missing metadata items: %s' % ', '.join(missing) - raise MetadataMissingError(msg) - for k, v in mapping.items(): - self._validate_value(k, v, scheme) - - def validate(self): - if self._legacy: - missing, warnings = self._legacy.check(True) - if missing or warnings: - logger.warning('Metadata: missing: %s, warnings: %s', - missing, warnings) - else: - self._validate_mapping(self._data, self.scheme) - - def todict(self): - if self._legacy: - return self._legacy.todict(True) - else: - result = extract_by_key(self._data, self.INDEX_KEYS) - return result - - def _from_legacy(self): - assert self._legacy and not self._data - result = { - 'metadata_version': self.METADATA_VERSION, - 'generator': self.GENERATOR, - } - lmd = self._legacy.todict(True) # skip missing ones - for k in ('name', 'version', 'license', 'summary', 'description', - 'classifier'): - if k in lmd: - if k == 'classifier': - nk = 'classifiers' - else: - nk = k - result[nk] = lmd[k] - kw = lmd.get('Keywords', []) - if kw == ['']: - kw = [] - result['keywords'] = kw - keys = (('requires_dist', 'run_requires'), - ('setup_requires_dist', 'build_requires')) - for ok, nk in keys: - if ok in lmd and lmd[ok]: - result[nk] = [{'requires': lmd[ok]}] - result['provides'] = self.provides - author = {} - maintainer = {} - return result - - LEGACY_MAPPING = { - 'name': 'Name', - 'version': 'Version', - 'license': 'License', - 'summary': 'Summary', - 'description': 'Description', - 'classifiers': 'Classifier', - } - - def _to_legacy(self): - def process_entries(entries): - reqts = set() - for e in entries: - extra = e.get('extra') - env = e.get('environment') - rlist = e['requires'] - for r in rlist: - if not env and not extra: - reqts.add(r) - else: - marker = '' - if extra: - marker = 'extra == "%s"' % extra - if env: - if marker: - marker = '(%s) and %s' % (env, marker) - else: - marker = env - reqts.add(';'.join((r, marker))) - return reqts - - assert self._data and not self._legacy - result = LegacyMetadata() - nmd = self._data - for nk, ok in self.LEGACY_MAPPING.items(): - if nk in nmd: - result[ok] = nmd[nk] - r1 = process_entries(self.run_requires + self.meta_requires) - r2 = process_entries(self.build_requires + self.dev_requires) - if self.extras: - result['Provides-Extra'] = sorted(self.extras) - result['Requires-Dist'] = sorted(r1) - result['Setup-Requires-Dist'] = sorted(r2) - # TODO: other fields such as contacts - return result - - def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): - if [path, fileobj].count(None) != 1: - raise ValueError('Exactly one of path and fileobj is needed') - self.validate() - if legacy: - if self._legacy: - legacy_md = self._legacy - else: - legacy_md = self._to_legacy() - if path: - legacy_md.write(path, skip_unknown=skip_unknown) - else: - legacy_md.write_file(fileobj, skip_unknown=skip_unknown) - else: - if self._legacy: - d = self._from_legacy() - else: - d = self._data - if fileobj: - json.dump(d, fileobj, ensure_ascii=True, indent=2, - sort_keys=True) - else: - with codecs.open(path, 'w', 'utf-8') as f: - json.dump(d, f, ensure_ascii=True, indent=2, - sort_keys=True) - - def add_requirements(self, requirements): - if self._legacy: - self._legacy.add_requirements(requirements) - else: - run_requires = self._data.setdefault('run_requires', []) - always = None - for entry in run_requires: - if 'environment' not in entry and 'extra' not in entry: - always = entry - break - if always is None: - always = { 'requires': requirements } - run_requires.insert(0, always) - else: - rset = set(always['requires']) | set(requirements) - always['requires'] = sorted(rset) - - def __repr__(self): - name = self.name or '(no name)' - version = self.version or 'no version' - return '<%s %s %s (%s)>' % (self.__class__.__name__, - self.metadata_version, name, version) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/resources.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/resources.py deleted file mode 100644 index 1884016..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/resources.py +++ /dev/null @@ -1,355 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2017 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -from __future__ import unicode_literals - -import bisect -import io -import logging -import os -import pkgutil -import shutil -import sys -import types -import zipimport - -from . import DistlibException -from .util import cached_property, get_cache_base, path_to_cache_dir, Cache - -logger = logging.getLogger(__name__) - - -cache = None # created when needed - - -class ResourceCache(Cache): - def __init__(self, base=None): - if base is None: - # Use native string to avoid issues on 2.x: see Python #20140. - base = os.path.join(get_cache_base(), str('resource-cache')) - super(ResourceCache, self).__init__(base) - - def is_stale(self, resource, path): - """ - Is the cache stale for the given resource? - - :param resource: The :class:`Resource` being cached. - :param path: The path of the resource in the cache. - :return: True if the cache is stale. - """ - # Cache invalidation is a hard problem :-) - return True - - def get(self, resource): - """ - Get a resource into the cache, - - :param resource: A :class:`Resource` instance. - :return: The pathname of the resource in the cache. - """ - prefix, path = resource.finder.get_cache_info(resource) - if prefix is None: - result = path - else: - result = os.path.join(self.base, self.prefix_to_dir(prefix), path) - dirname = os.path.dirname(result) - if not os.path.isdir(dirname): - os.makedirs(dirname) - if not os.path.exists(result): - stale = True - else: - stale = self.is_stale(resource, path) - if stale: - # write the bytes of the resource to the cache location - with open(result, 'wb') as f: - f.write(resource.bytes) - return result - - -class ResourceBase(object): - def __init__(self, finder, name): - self.finder = finder - self.name = name - - -class Resource(ResourceBase): - """ - A class representing an in-package resource, such as a data file. This is - not normally instantiated by user code, but rather by a - :class:`ResourceFinder` which manages the resource. - """ - is_container = False # Backwards compatibility - - def as_stream(self): - """ - Get the resource as a stream. - - This is not a property to make it obvious that it returns a new stream - each time. - """ - return self.finder.get_stream(self) - - @cached_property - def file_path(self): - global cache - if cache is None: - cache = ResourceCache() - return cache.get(self) - - @cached_property - def bytes(self): - return self.finder.get_bytes(self) - - @cached_property - def size(self): - return self.finder.get_size(self) - - -class ResourceContainer(ResourceBase): - is_container = True # Backwards compatibility - - @cached_property - def resources(self): - return self.finder.get_resources(self) - - -class ResourceFinder(object): - """ - Resource finder for file system resources. - """ - - if sys.platform.startswith('java'): - skipped_extensions = ('.pyc', '.pyo', '.class') - else: - skipped_extensions = ('.pyc', '.pyo') - - def __init__(self, module): - self.module = module - self.loader = getattr(module, '__loader__', None) - self.base = os.path.dirname(getattr(module, '__file__', '')) - - def _adjust_path(self, path): - return os.path.realpath(path) - - def _make_path(self, resource_name): - # Issue #50: need to preserve type of path on Python 2.x - # like os.path._get_sep - if isinstance(resource_name, bytes): # should only happen on 2.x - sep = b'/' - else: - sep = '/' - parts = resource_name.split(sep) - parts.insert(0, self.base) - result = os.path.join(*parts) - return self._adjust_path(result) - - def _find(self, path): - return os.path.exists(path) - - def get_cache_info(self, resource): - return None, resource.path - - def find(self, resource_name): - path = self._make_path(resource_name) - if not self._find(path): - result = None - else: - if self._is_directory(path): - result = ResourceContainer(self, resource_name) - else: - result = Resource(self, resource_name) - result.path = path - return result - - def get_stream(self, resource): - return open(resource.path, 'rb') - - def get_bytes(self, resource): - with open(resource.path, 'rb') as f: - return f.read() - - def get_size(self, resource): - return os.path.getsize(resource.path) - - def get_resources(self, resource): - def allowed(f): - return (f != '__pycache__' and not - f.endswith(self.skipped_extensions)) - return set([f for f in os.listdir(resource.path) if allowed(f)]) - - def is_container(self, resource): - return self._is_directory(resource.path) - - _is_directory = staticmethod(os.path.isdir) - - def iterator(self, resource_name): - resource = self.find(resource_name) - if resource is not None: - todo = [resource] - while todo: - resource = todo.pop(0) - yield resource - if resource.is_container: - rname = resource.name - for name in resource.resources: - if not rname: - new_name = name - else: - new_name = '/'.join([rname, name]) - child = self.find(new_name) - if child.is_container: - todo.append(child) - else: - yield child - - -class ZipResourceFinder(ResourceFinder): - """ - Resource finder for resources in .zip files. - """ - def __init__(self, module): - super(ZipResourceFinder, self).__init__(module) - archive = self.loader.archive - self.prefix_len = 1 + len(archive) - # PyPy doesn't have a _files attr on zipimporter, and you can't set one - if hasattr(self.loader, '_files'): - self._files = self.loader._files - else: - self._files = zipimport._zip_directory_cache[archive] - self.index = sorted(self._files) - - def _adjust_path(self, path): - return path - - def _find(self, path): - path = path[self.prefix_len:] - if path in self._files: - result = True - else: - if path and path[-1] != os.sep: - path = path + os.sep - i = bisect.bisect(self.index, path) - try: - result = self.index[i].startswith(path) - except IndexError: - result = False - if not result: - logger.debug('_find failed: %r %r', path, self.loader.prefix) - else: - logger.debug('_find worked: %r %r', path, self.loader.prefix) - return result - - def get_cache_info(self, resource): - prefix = self.loader.archive - path = resource.path[1 + len(prefix):] - return prefix, path - - def get_bytes(self, resource): - return self.loader.get_data(resource.path) - - def get_stream(self, resource): - return io.BytesIO(self.get_bytes(resource)) - - def get_size(self, resource): - path = resource.path[self.prefix_len:] - return self._files[path][3] - - def get_resources(self, resource): - path = resource.path[self.prefix_len:] - if path and path[-1] != os.sep: - path += os.sep - plen = len(path) - result = set() - i = bisect.bisect(self.index, path) - while i < len(self.index): - if not self.index[i].startswith(path): - break - s = self.index[i][plen:] - result.add(s.split(os.sep, 1)[0]) # only immediate children - i += 1 - return result - - def _is_directory(self, path): - path = path[self.prefix_len:] - if path and path[-1] != os.sep: - path += os.sep - i = bisect.bisect(self.index, path) - try: - result = self.index[i].startswith(path) - except IndexError: - result = False - return result - -_finder_registry = { - type(None): ResourceFinder, - zipimport.zipimporter: ZipResourceFinder -} - -try: - # In Python 3.6, _frozen_importlib -> _frozen_importlib_external - try: - import _frozen_importlib_external as _fi - except ImportError: - import _frozen_importlib as _fi - _finder_registry[_fi.SourceFileLoader] = ResourceFinder - _finder_registry[_fi.FileFinder] = ResourceFinder - del _fi -except (ImportError, AttributeError): - pass - - -def register_finder(loader, finder_maker): - _finder_registry[type(loader)] = finder_maker - -_finder_cache = {} - - -def finder(package): - """ - Return a resource finder for a package. - :param package: The name of the package. - :return: A :class:`ResourceFinder` instance for the package. - """ - if package in _finder_cache: - result = _finder_cache[package] - else: - if package not in sys.modules: - __import__(package) - module = sys.modules[package] - path = getattr(module, '__path__', None) - if path is None: - raise DistlibException('You cannot get a finder for a module, ' - 'only for a package') - loader = getattr(module, '__loader__', None) - finder_maker = _finder_registry.get(type(loader)) - if finder_maker is None: - raise DistlibException('Unable to locate finder for %r' % package) - result = finder_maker(module) - _finder_cache[package] = result - return result - - -_dummy_module = types.ModuleType(str('__dummy__')) - - -def finder_for_path(path): - """ - Return a resource finder for a path, which should represent a container. - - :param path: The path. - :return: A :class:`ResourceFinder` instance for the path. - """ - result = None - # calls any path hooks, gets importer into cache - pkgutil.get_importer(path) - loader = sys.path_importer_cache.get(path) - finder = _finder_registry.get(type(loader)) - if finder: - module = _dummy_module - module.__file__ = os.path.join(path, '') - module.__loader__ = loader - result = finder(module) - return result diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/scripts.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/scripts.py deleted file mode 100644 index 8e22cb9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/scripts.py +++ /dev/null @@ -1,417 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2015 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -from io import BytesIO -import logging -import os -import re -import struct -import sys - -from .compat import sysconfig, detect_encoding, ZipFile -from .resources import finder -from .util import (FileOperator, get_export_entry, convert_path, - get_executable, in_venv) - -logger = logging.getLogger(__name__) - -_DEFAULT_MANIFEST = ''' -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> - <assemblyIdentity version="1.0.0.0" - processorArchitecture="X86" - name="%s" - type="win32"/> - - <!-- Identify the application security requirements. --> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="asInvoker" uiAccess="false"/> - </requestedPrivileges> - </security> - </trustInfo> -</assembly>'''.strip() - -# check if Python is called on the first line with this expression -FIRST_LINE_RE = re.compile(b'^#!.*pythonw?[0-9.]*([ \t].*)?$') -SCRIPT_TEMPLATE = r'''# -*- coding: utf-8 -*- -if __name__ == '__main__': - import sys, re - - def _resolve(module, func): - __import__(module) - mod = sys.modules[module] - parts = func.split('.') - result = getattr(mod, parts.pop(0)) - for p in parts: - result = getattr(result, p) - return result - - try: - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - - func = _resolve('%(module)s', '%(func)s') - rc = func() # None interpreted as 0 - except Exception as e: # only supporting Python >= 2.6 - sys.stderr.write('%%s\n' %% e) - rc = 1 - sys.exit(rc) -''' - - -def _enquote_executable(executable): - if ' ' in executable: - # make sure we quote only the executable in case of env - # for example /usr/bin/env "/dir with spaces/bin/jython" - # instead of "/usr/bin/env /dir with spaces/bin/jython" - # otherwise whole - if executable.startswith('/usr/bin/env '): - env, _executable = executable.split(' ', 1) - if ' ' in _executable and not _executable.startswith('"'): - executable = '%s "%s"' % (env, _executable) - else: - if not executable.startswith('"'): - executable = '"%s"' % executable - return executable - - -class ScriptMaker(object): - """ - A class to copy or create scripts from source scripts or callable - specifications. - """ - script_template = SCRIPT_TEMPLATE - - executable = None # for shebangs - - def __init__(self, source_dir, target_dir, add_launchers=True, - dry_run=False, fileop=None): - self.source_dir = source_dir - self.target_dir = target_dir - self.add_launchers = add_launchers - self.force = False - self.clobber = False - # It only makes sense to set mode bits on POSIX. - self.set_mode = (os.name == 'posix') or (os.name == 'java' and - os._name == 'posix') - self.variants = set(('', 'X.Y')) - self._fileop = fileop or FileOperator(dry_run) - - self._is_nt = os.name == 'nt' or ( - os.name == 'java' and os._name == 'nt') - - def _get_alternate_executable(self, executable, options): - if options.get('gui', False) and self._is_nt: # pragma: no cover - dn, fn = os.path.split(executable) - fn = fn.replace('python', 'pythonw') - executable = os.path.join(dn, fn) - return executable - - if sys.platform.startswith('java'): # pragma: no cover - def _is_shell(self, executable): - """ - Determine if the specified executable is a script - (contains a #! line) - """ - try: - with open(executable) as fp: - return fp.read(2) == '#!' - except (OSError, IOError): - logger.warning('Failed to open %s', executable) - return False - - def _fix_jython_executable(self, executable): - if self._is_shell(executable): - # Workaround for Jython is not needed on Linux systems. - import java - - if java.lang.System.getProperty('os.name') == 'Linux': - return executable - elif executable.lower().endswith('jython.exe'): - # Use wrapper exe for Jython on Windows - return executable - return '/usr/bin/env %s' % executable - - def _build_shebang(self, executable, post_interp): - """ - Build a shebang line. In the simple case (on Windows, or a shebang line - which is not too long or contains spaces) use a simple formulation for - the shebang. Otherwise, use /bin/sh as the executable, with a contrived - shebang which allows the script to run either under Python or sh, using - suitable quoting. Thanks to Harald Nordgren for his input. - - See also: http://www.in-ulm.de/~mascheck/various/shebang/#length - https://hg.mozilla.org/mozilla-central/file/tip/mach - """ - if os.name != 'posix': - simple_shebang = True - else: - # Add 3 for '#!' prefix and newline suffix. - shebang_length = len(executable) + len(post_interp) + 3 - if sys.platform == 'darwin': - max_shebang_length = 512 - else: - max_shebang_length = 127 - simple_shebang = ((b' ' not in executable) and - (shebang_length <= max_shebang_length)) - - if simple_shebang: - result = b'#!' + executable + post_interp + b'\n' - else: - result = b'#!/bin/sh\n' - result += b"'''exec' " + executable + post_interp + b' "$0" "$@"\n' - result += b"' '''" - return result - - def _get_shebang(self, encoding, post_interp=b'', options=None): - enquote = True - if self.executable: - executable = self.executable - enquote = False # assume this will be taken care of - elif not sysconfig.is_python_build(): - executable = get_executable() - elif in_venv(): # pragma: no cover - executable = os.path.join(sysconfig.get_path('scripts'), - 'python%s' % sysconfig.get_config_var('EXE')) - else: # pragma: no cover - executable = os.path.join( - sysconfig.get_config_var('BINDIR'), - 'python%s%s' % (sysconfig.get_config_var('VERSION'), - sysconfig.get_config_var('EXE'))) - if options: - executable = self._get_alternate_executable(executable, options) - - if sys.platform.startswith('java'): # pragma: no cover - executable = self._fix_jython_executable(executable) - # Normalise case for Windows - executable = os.path.normcase(executable) - # If the user didn't specify an executable, it may be necessary to - # cater for executable paths with spaces (not uncommon on Windows) - if enquote: - executable = _enquote_executable(executable) - # Issue #51: don't use fsencode, since we later try to - # check that the shebang is decodable using utf-8. - executable = executable.encode('utf-8') - # in case of IronPython, play safe and enable frames support - if (sys.platform == 'cli' and '-X:Frames' not in post_interp - and '-X:FullFrames' not in post_interp): # pragma: no cover - post_interp += b' -X:Frames' - shebang = self._build_shebang(executable, post_interp) - # Python parser starts to read a script using UTF-8 until - # it gets a #coding:xxx cookie. The shebang has to be the - # first line of a file, the #coding:xxx cookie cannot be - # written before. So the shebang has to be decodable from - # UTF-8. - try: - shebang.decode('utf-8') - except UnicodeDecodeError: # pragma: no cover - raise ValueError( - 'The shebang (%r) is not decodable from utf-8' % shebang) - # If the script is encoded to a custom encoding (use a - # #coding:xxx cookie), the shebang has to be decodable from - # the script encoding too. - if encoding != 'utf-8': - try: - shebang.decode(encoding) - except UnicodeDecodeError: # pragma: no cover - raise ValueError( - 'The shebang (%r) is not decodable ' - 'from the script encoding (%r)' % (shebang, encoding)) - return shebang - - def _get_script_text(self, entry): - return self.script_template % dict(module=entry.prefix, - func=entry.suffix) - - manifest = _DEFAULT_MANIFEST - - def get_manifest(self, exename): - base = os.path.basename(exename) - return self.manifest % base - - def _write_script(self, names, shebang, script_bytes, filenames, ext): - use_launcher = self.add_launchers and self._is_nt - linesep = os.linesep.encode('utf-8') - if not shebang.endswith(linesep): - shebang += linesep - if not use_launcher: - script_bytes = shebang + script_bytes - else: # pragma: no cover - if ext == 'py': - launcher = self._get_launcher('t') - else: - launcher = self._get_launcher('w') - stream = BytesIO() - with ZipFile(stream, 'w') as zf: - zf.writestr('__main__.py', script_bytes) - zip_data = stream.getvalue() - script_bytes = launcher + shebang + zip_data - for name in names: - outname = os.path.join(self.target_dir, name) - if use_launcher: # pragma: no cover - n, e = os.path.splitext(outname) - if e.startswith('.py'): - outname = n - outname = '%s.exe' % outname - try: - self._fileop.write_binary_file(outname, script_bytes) - except Exception: - # Failed writing an executable - it might be in use. - logger.warning('Failed to write executable - trying to ' - 'use .deleteme logic') - dfname = '%s.deleteme' % outname - if os.path.exists(dfname): - os.remove(dfname) # Not allowed to fail here - os.rename(outname, dfname) # nor here - self._fileop.write_binary_file(outname, script_bytes) - logger.debug('Able to replace executable using ' - '.deleteme logic') - try: - os.remove(dfname) - except Exception: - pass # still in use - ignore error - else: - if self._is_nt and not outname.endswith('.' + ext): # pragma: no cover - outname = '%s.%s' % (outname, ext) - if os.path.exists(outname) and not self.clobber: - logger.warning('Skipping existing file %s', outname) - continue - self._fileop.write_binary_file(outname, script_bytes) - if self.set_mode: - self._fileop.set_executable_mode([outname]) - filenames.append(outname) - - def _make_script(self, entry, filenames, options=None): - post_interp = b'' - if options: - args = options.get('interpreter_args', []) - if args: - args = ' %s' % ' '.join(args) - post_interp = args.encode('utf-8') - shebang = self._get_shebang('utf-8', post_interp, options=options) - script = self._get_script_text(entry).encode('utf-8') - name = entry.name - scriptnames = set() - if '' in self.variants: - scriptnames.add(name) - if 'X' in self.variants: - scriptnames.add('%s%s' % (name, sys.version[0])) - if 'X.Y' in self.variants: - scriptnames.add('%s-%s' % (name, sys.version[:3])) - if options and options.get('gui', False): - ext = 'pyw' - else: - ext = 'py' - self._write_script(scriptnames, shebang, script, filenames, ext) - - def _copy_script(self, script, filenames): - adjust = False - script = os.path.join(self.source_dir, convert_path(script)) - outname = os.path.join(self.target_dir, os.path.basename(script)) - if not self.force and not self._fileop.newer(script, outname): - logger.debug('not copying %s (up-to-date)', script) - return - - # Always open the file, but ignore failures in dry-run mode -- - # that way, we'll get accurate feedback if we can read the - # script. - try: - f = open(script, 'rb') - except IOError: # pragma: no cover - if not self.dry_run: - raise - f = None - else: - first_line = f.readline() - if not first_line: # pragma: no cover - logger.warning('%s: %s is an empty file (skipping)', - self.get_command_name(), script) - return - - match = FIRST_LINE_RE.match(first_line.replace(b'\r\n', b'\n')) - if match: - adjust = True - post_interp = match.group(1) or b'' - - if not adjust: - if f: - f.close() - self._fileop.copy_file(script, outname) - if self.set_mode: - self._fileop.set_executable_mode([outname]) - filenames.append(outname) - else: - logger.info('copying and adjusting %s -> %s', script, - self.target_dir) - if not self._fileop.dry_run: - encoding, lines = detect_encoding(f.readline) - f.seek(0) - shebang = self._get_shebang(encoding, post_interp) - if b'pythonw' in first_line: # pragma: no cover - ext = 'pyw' - else: - ext = 'py' - n = os.path.basename(outname) - self._write_script([n], shebang, f.read(), filenames, ext) - if f: - f.close() - - @property - def dry_run(self): - return self._fileop.dry_run - - @dry_run.setter - def dry_run(self, value): - self._fileop.dry_run = value - - if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): # pragma: no cover - # Executable launcher support. - # Launchers are from https://bitbucket.org/vinay.sajip/simple_launcher/ - - def _get_launcher(self, kind): - if struct.calcsize('P') == 8: # 64-bit - bits = '64' - else: - bits = '32' - name = '%s%s.exe' % (kind, bits) - # Issue 31: don't hardcode an absolute package name, but - # determine it relative to the current package - distlib_package = __name__.rsplit('.', 1)[0] - result = finder(distlib_package).find(name).bytes - return result - - # Public API follows - - def make(self, specification, options=None): - """ - Make a script. - - :param specification: The specification, which is either a valid export - entry specification (to make a script from a - callable) or a filename (to make a script by - copying from a source location). - :param options: A dictionary of options controlling script generation. - :return: A list of all absolute pathnames written to. - """ - filenames = [] - entry = get_export_entry(specification) - if entry is None: - self._copy_script(specification, filenames) - else: - self._make_script(entry, filenames, options=options) - return filenames - - def make_multiple(self, specifications, options=None): - """ - Take a list of specifications and make scripts from them, - :param specifications: A list of specifications. - :return: A list of all absolute pathnames written to, - """ - filenames = [] - for specification in specifications: - filenames.extend(self.make(specification, options)) - return filenames diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/t32.exe b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/t32.exe deleted file mode 100644 index a09d926872d84ae22a617dfe9ebb560d420b37de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92672 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 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/t64.exe b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/t64.exe deleted file mode 100644 index 9da9b40de922fb203df6b9a1d0ad4139af536850..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102400 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�vlnW`{LoXpTySn$@;x8yoz96jn?+Kk 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�?dYNUd4WaURX_A__M4W}D0!0n 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 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/util.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/util.py deleted file mode 100644 index 9d4bfd3..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/util.py +++ /dev/null @@ -1,1756 +0,0 @@ -# -# Copyright (C) 2012-2017 The Python Software Foundation. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -import codecs -from collections import deque -import contextlib -import csv -from glob import iglob as std_iglob -import io -import json -import logging -import os -import py_compile -import re -import socket -try: - import ssl -except ImportError: # pragma: no cover - ssl = None -import subprocess -import sys -import tarfile -import tempfile -import textwrap - -try: - import threading -except ImportError: # pragma: no cover - import dummy_threading as threading -import time - -from . import DistlibException -from .compat import (string_types, text_type, shutil, raw_input, StringIO, - cache_from_source, urlopen, urljoin, httplib, xmlrpclib, - splittype, HTTPHandler, BaseConfigurator, valid_ident, - Container, configparser, URLError, ZipFile, fsdecode, - unquote, urlparse) - -logger = logging.getLogger(__name__) - -# -# Requirement parsing code as per PEP 508 -# - -IDENTIFIER = re.compile(r'^([\w\.-]+)\s*') -VERSION_IDENTIFIER = re.compile(r'^([\w\.*+-]+)\s*') -COMPARE_OP = re.compile(r'^(<=?|>=?|={2,3}|[~!]=)\s*') -MARKER_OP = re.compile(r'^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*') -OR = re.compile(r'^or\b\s*') -AND = re.compile(r'^and\b\s*') -NON_SPACE = re.compile(r'(\S+)\s*') -STRING_CHUNK = re.compile(r'([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)') - - -def parse_marker(marker_string): - """ - Parse a marker string and return a dictionary containing a marker expression. - - The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in - the expression grammar, or strings. A string contained in quotes is to be - interpreted as a literal string, and a string not contained in quotes is a - variable (such as os_name). - """ - def marker_var(remaining): - # either identifier, or literal string - m = IDENTIFIER.match(remaining) - if m: - result = m.groups()[0] - remaining = remaining[m.end():] - elif not remaining: - raise SyntaxError('unexpected end of input') - else: - q = remaining[0] - if q not in '\'"': - raise SyntaxError('invalid expression: %s' % remaining) - oq = '\'"'.replace(q, '') - remaining = remaining[1:] - parts = [q] - while remaining: - # either a string chunk, or oq, or q to terminate - if remaining[0] == q: - break - elif remaining[0] == oq: - parts.append(oq) - remaining = remaining[1:] - else: - m = STRING_CHUNK.match(remaining) - if not m: - raise SyntaxError('error in string literal: %s' % remaining) - parts.append(m.groups()[0]) - remaining = remaining[m.end():] - else: - s = ''.join(parts) - raise SyntaxError('unterminated string: %s' % s) - parts.append(q) - result = ''.join(parts) - remaining = remaining[1:].lstrip() # skip past closing quote - return result, remaining - - def marker_expr(remaining): - if remaining and remaining[0] == '(': - result, remaining = marker(remaining[1:].lstrip()) - if remaining[0] != ')': - raise SyntaxError('unterminated parenthesis: %s' % remaining) - remaining = remaining[1:].lstrip() - else: - lhs, remaining = marker_var(remaining) - while remaining: - m = MARKER_OP.match(remaining) - if not m: - break - op = m.groups()[0] - remaining = remaining[m.end():] - rhs, remaining = marker_var(remaining) - lhs = {'op': op, 'lhs': lhs, 'rhs': rhs} - result = lhs - return result, remaining - - def marker_and(remaining): - lhs, remaining = marker_expr(remaining) - while remaining: - m = AND.match(remaining) - if not m: - break - remaining = remaining[m.end():] - rhs, remaining = marker_expr(remaining) - lhs = {'op': 'and', 'lhs': lhs, 'rhs': rhs} - return lhs, remaining - - def marker(remaining): - lhs, remaining = marker_and(remaining) - while remaining: - m = OR.match(remaining) - if not m: - break - remaining = remaining[m.end():] - rhs, remaining = marker_and(remaining) - lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs} - return lhs, remaining - - return marker(marker_string) - - -def parse_requirement(req): - """ - Parse a requirement passed in as a string. Return a Container - whose attributes contain the various parts of the requirement. - """ - remaining = req.strip() - if not remaining or remaining.startswith('#'): - return None - m = IDENTIFIER.match(remaining) - if not m: - raise SyntaxError('name expected: %s' % remaining) - distname = m.groups()[0] - remaining = remaining[m.end():] - extras = mark_expr = versions = uri = None - if remaining and remaining[0] == '[': - i = remaining.find(']', 1) - if i < 0: - raise SyntaxError('unterminated extra: %s' % remaining) - s = remaining[1:i] - remaining = remaining[i + 1:].lstrip() - extras = [] - while s: - m = IDENTIFIER.match(s) - if not m: - raise SyntaxError('malformed extra: %s' % s) - extras.append(m.groups()[0]) - s = s[m.end():] - if not s: - break - if s[0] != ',': - raise SyntaxError('comma expected in extras: %s' % s) - s = s[1:].lstrip() - if not extras: - extras = None - if remaining: - if remaining[0] == '@': - # it's a URI - remaining = remaining[1:].lstrip() - m = NON_SPACE.match(remaining) - if not m: - raise SyntaxError('invalid URI: %s' % remaining) - uri = m.groups()[0] - t = urlparse(uri) - # there are issues with Python and URL parsing, so this test - # is a bit crude. See bpo-20271, bpo-23505. Python doesn't - # always parse invalid URLs correctly - it should raise - # exceptions for malformed URLs - if not (t.scheme and t.netloc): - raise SyntaxError('Invalid URL: %s' % uri) - remaining = remaining[m.end():].lstrip() - else: - - def get_versions(ver_remaining): - """ - Return a list of operator, version tuples if any are - specified, else None. - """ - m = COMPARE_OP.match(ver_remaining) - versions = None - if m: - versions = [] - while True: - op = m.groups()[0] - ver_remaining = ver_remaining[m.end():] - m = VERSION_IDENTIFIER.match(ver_remaining) - if not m: - raise SyntaxError('invalid version: %s' % ver_remaining) - v = m.groups()[0] - versions.append((op, v)) - ver_remaining = ver_remaining[m.end():] - if not ver_remaining or ver_remaining[0] != ',': - break - ver_remaining = ver_remaining[1:].lstrip() - m = COMPARE_OP.match(ver_remaining) - if not m: - raise SyntaxError('invalid constraint: %s' % ver_remaining) - if not versions: - versions = None - return versions, ver_remaining - - if remaining[0] != '(': - versions, remaining = get_versions(remaining) - else: - i = remaining.find(')', 1) - if i < 0: - raise SyntaxError('unterminated parenthesis: %s' % remaining) - s = remaining[1:i] - remaining = remaining[i + 1:].lstrip() - # As a special diversion from PEP 508, allow a version number - # a.b.c in parentheses as a synonym for ~= a.b.c (because this - # is allowed in earlier PEPs) - if COMPARE_OP.match(s): - versions, _ = get_versions(s) - else: - m = VERSION_IDENTIFIER.match(s) - if not m: - raise SyntaxError('invalid constraint: %s' % s) - v = m.groups()[0] - s = s[m.end():].lstrip() - if s: - raise SyntaxError('invalid constraint: %s' % s) - versions = [('~=', v)] - - if remaining: - if remaining[0] != ';': - raise SyntaxError('invalid requirement: %s' % remaining) - remaining = remaining[1:].lstrip() - - mark_expr, remaining = parse_marker(remaining) - - if remaining and remaining[0] != '#': - raise SyntaxError('unexpected trailing data: %s' % remaining) - - if not versions: - rs = distname - else: - rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions])) - return Container(name=distname, extras=extras, constraints=versions, - marker=mark_expr, url=uri, requirement=rs) - - -def get_resources_dests(resources_root, rules): - """Find destinations for resources files""" - - def get_rel_path(root, path): - # normalizes and returns a lstripped-/-separated path - root = root.replace(os.path.sep, '/') - path = path.replace(os.path.sep, '/') - assert path.startswith(root) - return path[len(root):].lstrip('/') - - destinations = {} - for base, suffix, dest in rules: - prefix = os.path.join(resources_root, base) - for abs_base in iglob(prefix): - abs_glob = os.path.join(abs_base, suffix) - for abs_path in iglob(abs_glob): - resource_file = get_rel_path(resources_root, abs_path) - if dest is None: # remove the entry if it was here - destinations.pop(resource_file, None) - else: - rel_path = get_rel_path(abs_base, abs_path) - rel_dest = dest.replace(os.path.sep, '/').rstrip('/') - destinations[resource_file] = rel_dest + '/' + rel_path - return destinations - - -def in_venv(): - if hasattr(sys, 'real_prefix'): - # virtualenv venvs - result = True - else: - # PEP 405 venvs - result = sys.prefix != getattr(sys, 'base_prefix', sys.prefix) - return result - - -def get_executable(): -# The __PYVENV_LAUNCHER__ dance is apparently no longer needed, as -# changes to the stub launcher mean that sys.executable always points -# to the stub on OS X -# if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' -# in os.environ): -# result = os.environ['__PYVENV_LAUNCHER__'] -# else: -# result = sys.executable -# return result - result = os.path.normcase(sys.executable) - if not isinstance(result, text_type): - result = fsdecode(result) - return result - - -def proceed(prompt, allowed_chars, error_prompt=None, default=None): - p = prompt - while True: - s = raw_input(p) - p = prompt - if not s and default: - s = default - if s: - c = s[0].lower() - if c in allowed_chars: - break - if error_prompt: - p = '%c: %s\n%s' % (c, error_prompt, prompt) - return c - - -def extract_by_key(d, keys): - if isinstance(keys, string_types): - keys = keys.split() - result = {} - for key in keys: - if key in d: - result[key] = d[key] - return result - -def read_exports(stream): - if sys.version_info[0] >= 3: - # needs to be a text stream - stream = codecs.getreader('utf-8')(stream) - # Try to load as JSON, falling back on legacy format - data = stream.read() - stream = StringIO(data) - try: - jdata = json.load(stream) - result = jdata['extensions']['python.exports']['exports'] - for group, entries in result.items(): - for k, v in entries.items(): - s = '%s = %s' % (k, v) - entry = get_export_entry(s) - assert entry is not None - entries[k] = entry - return result - except Exception: - stream.seek(0, 0) - - def read_stream(cp, stream): - if hasattr(cp, 'read_file'): - cp.read_file(stream) - else: - cp.readfp(stream) - - cp = configparser.ConfigParser() - try: - read_stream(cp, stream) - except configparser.MissingSectionHeaderError: - stream.close() - data = textwrap.dedent(data) - stream = StringIO(data) - read_stream(cp, stream) - - result = {} - for key in cp.sections(): - result[key] = entries = {} - for name, value in cp.items(key): - s = '%s = %s' % (name, value) - entry = get_export_entry(s) - assert entry is not None - #entry.dist = self - entries[name] = entry - return result - - -def write_exports(exports, stream): - if sys.version_info[0] >= 3: - # needs to be a text stream - stream = codecs.getwriter('utf-8')(stream) - cp = configparser.ConfigParser() - for k, v in exports.items(): - # TODO check k, v for valid values - cp.add_section(k) - for entry in v.values(): - if entry.suffix is None: - s = entry.prefix - else: - s = '%s:%s' % (entry.prefix, entry.suffix) - if entry.flags: - s = '%s [%s]' % (s, ', '.join(entry.flags)) - cp.set(k, entry.name, s) - cp.write(stream) - - -@contextlib.contextmanager -def tempdir(): - td = tempfile.mkdtemp() - try: - yield td - finally: - shutil.rmtree(td) - -@contextlib.contextmanager -def chdir(d): - cwd = os.getcwd() - try: - os.chdir(d) - yield - finally: - os.chdir(cwd) - - -@contextlib.contextmanager -def socket_timeout(seconds=15): - cto = socket.getdefaulttimeout() - try: - socket.setdefaulttimeout(seconds) - yield - finally: - socket.setdefaulttimeout(cto) - - -class cached_property(object): - def __init__(self, func): - self.func = func - #for attr in ('__name__', '__module__', '__doc__'): - # setattr(self, attr, getattr(func, attr, None)) - - def __get__(self, obj, cls=None): - if obj is None: - return self - value = self.func(obj) - object.__setattr__(obj, self.func.__name__, value) - #obj.__dict__[self.func.__name__] = value = self.func(obj) - return value - -def convert_path(pathname): - """Return 'pathname' as a name that will work on the native filesystem. - - The path is split on '/' and put back together again using the current - directory separator. Needed because filenames in the setup script are - always supplied in Unix style, and have to be converted to the local - convention before we can actually use them in the filesystem. Raises - ValueError on non-Unix-ish systems if 'pathname' either starts or - ends with a slash. - """ - if os.sep == '/': - return pathname - if not pathname: - return pathname - if pathname[0] == '/': - raise ValueError("path '%s' cannot be absolute" % pathname) - if pathname[-1] == '/': - raise ValueError("path '%s' cannot end with '/'" % pathname) - - paths = pathname.split('/') - while os.curdir in paths: - paths.remove(os.curdir) - if not paths: - return os.curdir - return os.path.join(*paths) - - -class FileOperator(object): - def __init__(self, dry_run=False): - self.dry_run = dry_run - self.ensured = set() - self._init_record() - - def _init_record(self): - self.record = False - self.files_written = set() - self.dirs_created = set() - - def record_as_written(self, path): - if self.record: - self.files_written.add(path) - - def newer(self, source, target): - """Tell if the target is newer than the source. - - Returns true if 'source' exists and is more recently modified than - 'target', or if 'source' exists and 'target' doesn't. - - Returns false if both exist and 'target' is the same age or younger - than 'source'. Raise PackagingFileError if 'source' does not exist. - - Note that this test is not very accurate: files created in the same - second will have the same "age". - """ - if not os.path.exists(source): - raise DistlibException("file '%r' does not exist" % - os.path.abspath(source)) - if not os.path.exists(target): - return True - - return os.stat(source).st_mtime > os.stat(target).st_mtime - - def copy_file(self, infile, outfile, check=True): - """Copy a file respecting dry-run and force flags. - """ - self.ensure_dir(os.path.dirname(outfile)) - logger.info('Copying %s to %s', infile, outfile) - if not self.dry_run: - msg = None - if check: - if os.path.islink(outfile): - msg = '%s is a symlink' % outfile - elif os.path.exists(outfile) and not os.path.isfile(outfile): - msg = '%s is a non-regular file' % outfile - if msg: - raise ValueError(msg + ' which would be overwritten') - shutil.copyfile(infile, outfile) - self.record_as_written(outfile) - - def copy_stream(self, instream, outfile, encoding=None): - assert not os.path.isdir(outfile) - self.ensure_dir(os.path.dirname(outfile)) - logger.info('Copying stream %s to %s', instream, outfile) - if not self.dry_run: - if encoding is None: - outstream = open(outfile, 'wb') - else: - outstream = codecs.open(outfile, 'w', encoding=encoding) - try: - shutil.copyfileobj(instream, outstream) - finally: - outstream.close() - self.record_as_written(outfile) - - def write_binary_file(self, path, data): - self.ensure_dir(os.path.dirname(path)) - if not self.dry_run: - if os.path.exists(path): - os.remove(path) - with open(path, 'wb') as f: - f.write(data) - self.record_as_written(path) - - def write_text_file(self, path, data, encoding): - self.write_binary_file(path, data.encode(encoding)) - - def set_mode(self, bits, mask, files): - if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'): - # Set the executable bits (owner, group, and world) on - # all the files specified. - for f in files: - if self.dry_run: - logger.info("changing mode of %s", f) - else: - mode = (os.stat(f).st_mode | bits) & mask - logger.info("changing mode of %s to %o", f, mode) - os.chmod(f, mode) - - set_executable_mode = lambda s, f: s.set_mode(0o555, 0o7777, f) - - def ensure_dir(self, path): - path = os.path.abspath(path) - if path not in self.ensured and not os.path.exists(path): - self.ensured.add(path) - d, f = os.path.split(path) - self.ensure_dir(d) - logger.info('Creating %s' % path) - if not self.dry_run: - os.mkdir(path) - if self.record: - self.dirs_created.add(path) - - def byte_compile(self, path, optimize=False, force=False, prefix=None, hashed_invalidation=False): - dpath = cache_from_source(path, not optimize) - logger.info('Byte-compiling %s to %s', path, dpath) - if not self.dry_run: - if force or self.newer(path, dpath): - if not prefix: - diagpath = None - else: - assert path.startswith(prefix) - diagpath = path[len(prefix):] - compile_kwargs = {} - if hashed_invalidation and hasattr(py_compile, 'PycInvalidationMode'): - compile_kwargs['invalidation_mode'] = py_compile.PycInvalidationMode.CHECKED_HASH - py_compile.compile(path, dpath, diagpath, True, **compile_kwargs) # raise error - self.record_as_written(dpath) - return dpath - - def ensure_removed(self, path): - if os.path.exists(path): - if os.path.isdir(path) and not os.path.islink(path): - logger.debug('Removing directory tree at %s', path) - if not self.dry_run: - shutil.rmtree(path) - if self.record: - if path in self.dirs_created: - self.dirs_created.remove(path) - else: - if os.path.islink(path): - s = 'link' - else: - s = 'file' - logger.debug('Removing %s %s', s, path) - if not self.dry_run: - os.remove(path) - if self.record: - if path in self.files_written: - self.files_written.remove(path) - - def is_writable(self, path): - result = False - while not result: - if os.path.exists(path): - result = os.access(path, os.W_OK) - break - parent = os.path.dirname(path) - if parent == path: - break - path = parent - return result - - def commit(self): - """ - Commit recorded changes, turn off recording, return - changes. - """ - assert self.record - result = self.files_written, self.dirs_created - self._init_record() - return result - - def rollback(self): - if not self.dry_run: - for f in list(self.files_written): - if os.path.exists(f): - os.remove(f) - # dirs should all be empty now, except perhaps for - # __pycache__ subdirs - # reverse so that subdirs appear before their parents - dirs = sorted(self.dirs_created, reverse=True) - for d in dirs: - flist = os.listdir(d) - if flist: - assert flist == ['__pycache__'] - sd = os.path.join(d, flist[0]) - os.rmdir(sd) - os.rmdir(d) # should fail if non-empty - self._init_record() - -def resolve(module_name, dotted_path): - if module_name in sys.modules: - mod = sys.modules[module_name] - else: - mod = __import__(module_name) - if dotted_path is None: - result = mod - else: - parts = dotted_path.split('.') - result = getattr(mod, parts.pop(0)) - for p in parts: - result = getattr(result, p) - return result - - -class ExportEntry(object): - def __init__(self, name, prefix, suffix, flags): - self.name = name - self.prefix = prefix - self.suffix = suffix - self.flags = flags - - @cached_property - def value(self): - return resolve(self.prefix, self.suffix) - - def __repr__(self): # pragma: no cover - return '<ExportEntry %s = %s:%s %s>' % (self.name, self.prefix, - self.suffix, self.flags) - - def __eq__(self, other): - if not isinstance(other, ExportEntry): - result = False - else: - result = (self.name == other.name and - self.prefix == other.prefix and - self.suffix == other.suffix and - self.flags == other.flags) - return result - - __hash__ = object.__hash__ - - -ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+) - \s*=\s*(?P<callable>(\w+)([:\.]\w+)*) - \s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? - ''', re.VERBOSE) - -def get_export_entry(specification): - m = ENTRY_RE.search(specification) - if not m: - result = None - if '[' in specification or ']' in specification: - raise DistlibException("Invalid specification " - "'%s'" % specification) - else: - d = m.groupdict() - name = d['name'] - path = d['callable'] - colons = path.count(':') - if colons == 0: - prefix, suffix = path, None - else: - if colons != 1: - raise DistlibException("Invalid specification " - "'%s'" % specification) - prefix, suffix = path.split(':') - flags = d['flags'] - if flags is None: - if '[' in specification or ']' in specification: - raise DistlibException("Invalid specification " - "'%s'" % specification) - flags = [] - else: - flags = [f.strip() for f in flags.split(',')] - result = ExportEntry(name, prefix, suffix, flags) - return result - - -def get_cache_base(suffix=None): - """ - Return the default base location for distlib caches. If the directory does - not exist, it is created. Use the suffix provided for the base directory, - and default to '.distlib' if it isn't provided. - - On Windows, if LOCALAPPDATA is defined in the environment, then it is - assumed to be a directory, and will be the parent directory of the result. - On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home - directory - using os.expanduser('~') - will be the parent directory of - the result. - - The result is just the directory '.distlib' in the parent directory as - determined above, or with the name specified with ``suffix``. - """ - if suffix is None: - suffix = '.distlib' - if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: - result = os.path.expandvars('$localappdata') - else: - # Assume posix, or old Windows - result = os.path.expanduser('~') - # we use 'isdir' instead of 'exists', because we want to - # fail if there's a file with that name - if os.path.isdir(result): - usable = os.access(result, os.W_OK) - if not usable: - logger.warning('Directory exists but is not writable: %s', result) - else: - try: - os.makedirs(result) - usable = True - except OSError: - logger.warning('Unable to create %s', result, exc_info=True) - usable = False - if not usable: - result = tempfile.mkdtemp() - logger.warning('Default location unusable, using %s', result) - return os.path.join(result, suffix) - - -def path_to_cache_dir(path): - """ - Convert an absolute path to a directory name for use in a cache. - - The algorithm used is: - - #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. - #. Any occurrence of ``os.sep`` is replaced with ``'--'``. - #. ``'.cache'`` is appended. - """ - d, p = os.path.splitdrive(os.path.abspath(path)) - if d: - d = d.replace(':', '---') - p = p.replace(os.sep, '--') - return d + p + '.cache' - - -def ensure_slash(s): - if not s.endswith('/'): - return s + '/' - return s - - -def parse_credentials(netloc): - username = password = None - if '@' in netloc: - prefix, netloc = netloc.split('@', 1) - if ':' not in prefix: - username = prefix - else: - username, password = prefix.split(':', 1) - return username, password, netloc - - -def get_process_umask(): - result = os.umask(0o22) - os.umask(result) - return result - -def is_string_sequence(seq): - result = True - i = None - for i, s in enumerate(seq): - if not isinstance(s, string_types): - result = False - break - assert i is not None - return result - -PROJECT_NAME_AND_VERSION = re.compile('([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-' - '([a-z0-9_.+-]+)', re.I) -PYTHON_VERSION = re.compile(r'-py(\d\.?\d?)') - - -def split_filename(filename, project_name=None): - """ - Extract name, version, python version from a filename (no extension) - - Return name, version, pyver or None - """ - result = None - pyver = None - filename = unquote(filename).replace(' ', '-') - m = PYTHON_VERSION.search(filename) - if m: - pyver = m.group(1) - filename = filename[:m.start()] - if project_name and len(filename) > len(project_name) + 1: - m = re.match(re.escape(project_name) + r'\b', filename) - if m: - n = m.end() - result = filename[:n], filename[n + 1:], pyver - if result is None: - m = PROJECT_NAME_AND_VERSION.match(filename) - if m: - result = m.group(1), m.group(3), pyver - return result - -# Allow spaces in name because of legacy dists like "Twisted Core" -NAME_VERSION_RE = re.compile(r'(?P<name>[\w .-]+)\s*' - r'\(\s*(?P<ver>[^\s)]+)\)$') - -def parse_name_and_version(p): - """ - A utility method used to get name and version from a string. - - From e.g. a Provides-Dist value. - - :param p: A value in a form 'foo (1.0)' - :return: The name and version as a tuple. - """ - m = NAME_VERSION_RE.match(p) - if not m: - raise DistlibException('Ill-formed name/version string: \'%s\'' % p) - d = m.groupdict() - return d['name'].strip().lower(), d['ver'] - -def get_extras(requested, available): - result = set() - requested = set(requested or []) - available = set(available or []) - if '*' in requested: - requested.remove('*') - result |= available - for r in requested: - if r == '-': - result.add(r) - elif r.startswith('-'): - unwanted = r[1:] - if unwanted not in available: - logger.warning('undeclared extra: %s' % unwanted) - if unwanted in result: - result.remove(unwanted) - else: - if r not in available: - logger.warning('undeclared extra: %s' % r) - result.add(r) - return result -# -# Extended metadata functionality -# - -def _get_external_data(url): - result = {} - try: - # urlopen might fail if it runs into redirections, - # because of Python issue #13696. Fixed in locators - # using a custom redirect handler. - resp = urlopen(url) - headers = resp.info() - ct = headers.get('Content-Type') - if not ct.startswith('application/json'): - logger.debug('Unexpected response for JSON request: %s', ct) - else: - reader = codecs.getreader('utf-8')(resp) - #data = reader.read().decode('utf-8') - #result = json.loads(data) - result = json.load(reader) - except Exception as e: - logger.exception('Failed to get external data for %s: %s', url, e) - return result - -_external_data_base_url = 'https://www.red-dove.com/pypi/projects/' - -def get_project_data(name): - url = '%s/%s/project.json' % (name[0].upper(), name) - url = urljoin(_external_data_base_url, url) - result = _get_external_data(url) - return result - -def get_package_data(name, version): - url = '%s/%s/package-%s.json' % (name[0].upper(), name, version) - url = urljoin(_external_data_base_url, url) - return _get_external_data(url) - - -class Cache(object): - """ - A class implementing a cache for resources that need to live in the file system - e.g. shared libraries. This class was moved from resources to here because it - could be used by other modules, e.g. the wheel module. - """ - - def __init__(self, base): - """ - Initialise an instance. - - :param base: The base directory where the cache should be located. - """ - # we use 'isdir' instead of 'exists', because we want to - # fail if there's a file with that name - if not os.path.isdir(base): # pragma: no cover - os.makedirs(base) - if (os.stat(base).st_mode & 0o77) != 0: - logger.warning('Directory \'%s\' is not private', base) - self.base = os.path.abspath(os.path.normpath(base)) - - def prefix_to_dir(self, prefix): - """ - Converts a resource prefix to a directory name in the cache. - """ - return path_to_cache_dir(prefix) - - def clear(self): - """ - Clear the cache. - """ - not_removed = [] - for fn in os.listdir(self.base): - fn = os.path.join(self.base, fn) - try: - if os.path.islink(fn) or os.path.isfile(fn): - os.remove(fn) - elif os.path.isdir(fn): - shutil.rmtree(fn) - except Exception: - not_removed.append(fn) - return not_removed - - -class EventMixin(object): - """ - A very simple publish/subscribe system. - """ - def __init__(self): - self._subscribers = {} - - def add(self, event, subscriber, append=True): - """ - Add a subscriber for an event. - - :param event: The name of an event. - :param subscriber: The subscriber to be added (and called when the - event is published). - :param append: Whether to append or prepend the subscriber to an - existing subscriber list for the event. - """ - subs = self._subscribers - if event not in subs: - subs[event] = deque([subscriber]) - else: - sq = subs[event] - if append: - sq.append(subscriber) - else: - sq.appendleft(subscriber) - - def remove(self, event, subscriber): - """ - Remove a subscriber for an event. - - :param event: The name of an event. - :param subscriber: The subscriber to be removed. - """ - subs = self._subscribers - if event not in subs: - raise ValueError('No subscribers: %r' % event) - subs[event].remove(subscriber) - - def get_subscribers(self, event): - """ - Return an iterator for the subscribers for an event. - :param event: The event to return subscribers for. - """ - return iter(self._subscribers.get(event, ())) - - def publish(self, event, *args, **kwargs): - """ - Publish a event and return a list of values returned by its - subscribers. - - :param event: The event to publish. - :param args: The positional arguments to pass to the event's - subscribers. - :param kwargs: The keyword arguments to pass to the event's - subscribers. - """ - result = [] - for subscriber in self.get_subscribers(event): - try: - value = subscriber(event, *args, **kwargs) - except Exception: - logger.exception('Exception during event publication') - value = None - result.append(value) - logger.debug('publish %s: args = %s, kwargs = %s, result = %s', - event, args, kwargs, result) - return result - -# -# Simple sequencing -# -class Sequencer(object): - def __init__(self): - self._preds = {} - self._succs = {} - self._nodes = set() # nodes with no preds/succs - - def add_node(self, node): - self._nodes.add(node) - - def remove_node(self, node, edges=False): - if node in self._nodes: - self._nodes.remove(node) - if edges: - for p in set(self._preds.get(node, ())): - self.remove(p, node) - for s in set(self._succs.get(node, ())): - self.remove(node, s) - # Remove empties - for k, v in list(self._preds.items()): - if not v: - del self._preds[k] - for k, v in list(self._succs.items()): - if not v: - del self._succs[k] - - def add(self, pred, succ): - assert pred != succ - self._preds.setdefault(succ, set()).add(pred) - self._succs.setdefault(pred, set()).add(succ) - - def remove(self, pred, succ): - assert pred != succ - try: - preds = self._preds[succ] - succs = self._succs[pred] - except KeyError: # pragma: no cover - raise ValueError('%r not a successor of anything' % succ) - try: - preds.remove(pred) - succs.remove(succ) - except KeyError: # pragma: no cover - raise ValueError('%r not a successor of %r' % (succ, pred)) - - def is_step(self, step): - return (step in self._preds or step in self._succs or - step in self._nodes) - - def get_steps(self, final): - if not self.is_step(final): - raise ValueError('Unknown: %r' % final) - result = [] - todo = [] - seen = set() - todo.append(final) - while todo: - step = todo.pop(0) - if step in seen: - # if a step was already seen, - # move it to the end (so it will appear earlier - # when reversed on return) ... but not for the - # final step, as that would be confusing for - # users - if step != final: - result.remove(step) - result.append(step) - else: - seen.add(step) - result.append(step) - preds = self._preds.get(step, ()) - todo.extend(preds) - return reversed(result) - - @property - def strong_connections(self): - #http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm - index_counter = [0] - stack = [] - lowlinks = {} - index = {} - result = [] - - graph = self._succs - - def strongconnect(node): - # set the depth index for this node to the smallest unused index - index[node] = index_counter[0] - lowlinks[node] = index_counter[0] - index_counter[0] += 1 - stack.append(node) - - # Consider successors - try: - successors = graph[node] - except Exception: - successors = [] - for successor in successors: - if successor not in lowlinks: - # Successor has not yet been visited - strongconnect(successor) - lowlinks[node] = min(lowlinks[node],lowlinks[successor]) - elif successor in stack: - # the successor is in the stack and hence in the current - # strongly connected component (SCC) - lowlinks[node] = min(lowlinks[node],index[successor]) - - # If `node` is a root node, pop the stack and generate an SCC - if lowlinks[node] == index[node]: - connected_component = [] - - while True: - successor = stack.pop() - connected_component.append(successor) - if successor == node: break - component = tuple(connected_component) - # storing the result - result.append(component) - - for node in graph: - if node not in lowlinks: - strongconnect(node) - - return result - - @property - def dot(self): - result = ['digraph G {'] - for succ in self._preds: - preds = self._preds[succ] - for pred in preds: - result.append(' %s -> %s;' % (pred, succ)) - for node in self._nodes: - result.append(' %s;' % node) - result.append('}') - return '\n'.join(result) - -# -# Unarchiving functionality for zip, tar, tgz, tbz, whl -# - -ARCHIVE_EXTENSIONS = ('.tar.gz', '.tar.bz2', '.tar', '.zip', - '.tgz', '.tbz', '.whl') - -def unarchive(archive_filename, dest_dir, format=None, check=True): - - def check_path(path): - if not isinstance(path, text_type): - path = path.decode('utf-8') - p = os.path.abspath(os.path.join(dest_dir, path)) - if not p.startswith(dest_dir) or p[plen] != os.sep: - raise ValueError('path outside destination: %r' % p) - - dest_dir = os.path.abspath(dest_dir) - plen = len(dest_dir) - archive = None - if format is None: - if archive_filename.endswith(('.zip', '.whl')): - format = 'zip' - elif archive_filename.endswith(('.tar.gz', '.tgz')): - format = 'tgz' - mode = 'r:gz' - elif archive_filename.endswith(('.tar.bz2', '.tbz')): - format = 'tbz' - mode = 'r:bz2' - elif archive_filename.endswith('.tar'): - format = 'tar' - mode = 'r' - else: # pragma: no cover - raise ValueError('Unknown format for %r' % archive_filename) - try: - if format == 'zip': - archive = ZipFile(archive_filename, 'r') - if check: - names = archive.namelist() - for name in names: - check_path(name) - else: - archive = tarfile.open(archive_filename, mode) - if check: - names = archive.getnames() - for name in names: - check_path(name) - if format != 'zip' and sys.version_info[0] < 3: - # See Python issue 17153. If the dest path contains Unicode, - # tarfile extraction fails on Python 2.x if a member path name - # contains non-ASCII characters - it leads to an implicit - # bytes -> unicode conversion using ASCII to decode. - for tarinfo in archive.getmembers(): - if not isinstance(tarinfo.name, text_type): - tarinfo.name = tarinfo.name.decode('utf-8') - archive.extractall(dest_dir) - - finally: - if archive: - archive.close() - - -def zip_dir(directory): - """zip a directory tree into a BytesIO object""" - result = io.BytesIO() - dlen = len(directory) - with ZipFile(result, "w") as zf: - for root, dirs, files in os.walk(directory): - for name in files: - full = os.path.join(root, name) - rel = root[dlen:] - dest = os.path.join(rel, name) - zf.write(full, dest) - return result - -# -# Simple progress bar -# - -UNITS = ('', 'K', 'M', 'G','T','P') - - -class Progress(object): - unknown = 'UNKNOWN' - - def __init__(self, minval=0, maxval=100): - assert maxval is None or maxval >= minval - self.min = self.cur = minval - self.max = maxval - self.started = None - self.elapsed = 0 - self.done = False - - def update(self, curval): - assert self.min <= curval - assert self.max is None or curval <= self.max - self.cur = curval - now = time.time() - if self.started is None: - self.started = now - else: - self.elapsed = now - self.started - - def increment(self, incr): - assert incr >= 0 - self.update(self.cur + incr) - - def start(self): - self.update(self.min) - return self - - def stop(self): - if self.max is not None: - self.update(self.max) - self.done = True - - @property - def maximum(self): - return self.unknown if self.max is None else self.max - - @property - def percentage(self): - if self.done: - result = '100 %' - elif self.max is None: - result = ' ?? %' - else: - v = 100.0 * (self.cur - self.min) / (self.max - self.min) - result = '%3d %%' % v - return result - - def format_duration(self, duration): - if (duration <= 0) and self.max is None or self.cur == self.min: - result = '??:??:??' - #elif duration < 1: - # result = '--:--:--' - else: - result = time.strftime('%H:%M:%S', time.gmtime(duration)) - return result - - @property - def ETA(self): - if self.done: - prefix = 'Done' - t = self.elapsed - #import pdb; pdb.set_trace() - else: - prefix = 'ETA ' - if self.max is None: - t = -1 - elif self.elapsed == 0 or (self.cur == self.min): - t = 0 - else: - #import pdb; pdb.set_trace() - t = float(self.max - self.min) - t /= self.cur - self.min - t = (t - 1) * self.elapsed - return '%s: %s' % (prefix, self.format_duration(t)) - - @property - def speed(self): - if self.elapsed == 0: - result = 0.0 - else: - result = (self.cur - self.min) / self.elapsed - for unit in UNITS: - if result < 1000: - break - result /= 1000.0 - return '%d %sB/s' % (result, unit) - -# -# Glob functionality -# - -RICH_GLOB = re.compile(r'\{([^}]*)\}') -_CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') -_CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') - - -def iglob(path_glob): - """Extended globbing function that supports ** and {opt1,opt2,opt3}.""" - if _CHECK_RECURSIVE_GLOB.search(path_glob): - msg = """invalid glob %r: recursive glob "**" must be used alone""" - raise ValueError(msg % path_glob) - if _CHECK_MISMATCH_SET.search(path_glob): - msg = """invalid glob %r: mismatching set marker '{' or '}'""" - raise ValueError(msg % path_glob) - return _iglob(path_glob) - - -def _iglob(path_glob): - rich_path_glob = RICH_GLOB.split(path_glob, 1) - if len(rich_path_glob) > 1: - assert len(rich_path_glob) == 3, rich_path_glob - prefix, set, suffix = rich_path_glob - for item in set.split(','): - for path in _iglob(''.join((prefix, item, suffix))): - yield path - else: - if '**' not in path_glob: - for item in std_iglob(path_glob): - yield item - else: - prefix, radical = path_glob.split('**', 1) - if prefix == '': - prefix = '.' - if radical == '': - radical = '*' - else: - # we support both - radical = radical.lstrip('/') - radical = radical.lstrip('\\') - for path, dir, files in os.walk(prefix): - path = os.path.normpath(path) - for fn in _iglob(os.path.join(path, radical)): - yield fn - -if ssl: - from .compat import (HTTPSHandler as BaseHTTPSHandler, match_hostname, - CertificateError) - - -# -# HTTPSConnection which verifies certificates/matches domains -# - - class HTTPSConnection(httplib.HTTPSConnection): - ca_certs = None # set this to the path to the certs file (.pem) - check_domain = True # only used if ca_certs is not None - - # noinspection PyPropertyAccess - def connect(self): - sock = socket.create_connection((self.host, self.port), self.timeout) - if getattr(self, '_tunnel_host', False): - self.sock = sock - self._tunnel() - - if not hasattr(ssl, 'SSLContext'): - # For 2.x - if self.ca_certs: - cert_reqs = ssl.CERT_REQUIRED - else: - cert_reqs = ssl.CERT_NONE - self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, - cert_reqs=cert_reqs, - ssl_version=ssl.PROTOCOL_SSLv23, - ca_certs=self.ca_certs) - else: # pragma: no cover - context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - context.options |= ssl.OP_NO_SSLv2 - if self.cert_file: - context.load_cert_chain(self.cert_file, self.key_file) - kwargs = {} - if self.ca_certs: - context.verify_mode = ssl.CERT_REQUIRED - context.load_verify_locations(cafile=self.ca_certs) - if getattr(ssl, 'HAS_SNI', False): - kwargs['server_hostname'] = self.host - self.sock = context.wrap_socket(sock, **kwargs) - if self.ca_certs and self.check_domain: - try: - match_hostname(self.sock.getpeercert(), self.host) - logger.debug('Host verified: %s', self.host) - except CertificateError: # pragma: no cover - self.sock.shutdown(socket.SHUT_RDWR) - self.sock.close() - raise - - class HTTPSHandler(BaseHTTPSHandler): - def __init__(self, ca_certs, check_domain=True): - BaseHTTPSHandler.__init__(self) - self.ca_certs = ca_certs - self.check_domain = check_domain - - def _conn_maker(self, *args, **kwargs): - """ - This is called to create a connection instance. Normally you'd - pass a connection class to do_open, but it doesn't actually check for - a class, and just expects a callable. As long as we behave just as a - constructor would have, we should be OK. If it ever changes so that - we *must* pass a class, we'll create an UnsafeHTTPSConnection class - which just sets check_domain to False in the class definition, and - choose which one to pass to do_open. - """ - result = HTTPSConnection(*args, **kwargs) - if self.ca_certs: - result.ca_certs = self.ca_certs - result.check_domain = self.check_domain - return result - - def https_open(self, req): - try: - return self.do_open(self._conn_maker, req) - except URLError as e: - if 'certificate verify failed' in str(e.reason): - raise CertificateError('Unable to verify server certificate ' - 'for %s' % req.host) - else: - raise - - # - # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The- - # Middle proxy using HTTP listens on port 443, or an index mistakenly serves - # HTML containing a http://xyz link when it should be https://xyz), - # you can use the following handler class, which does not allow HTTP traffic. - # - # It works by inheriting from HTTPHandler - so build_opener won't add a - # handler for HTTP itself. - # - class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler): - def http_open(self, req): - raise URLError('Unexpected HTTP request on what should be a secure ' - 'connection: %s' % req) - -# -# XML-RPC with timeouts -# - -_ver_info = sys.version_info[:2] - -if _ver_info == (2, 6): - class HTTP(httplib.HTTP): - def __init__(self, host='', port=None, **kwargs): - if port == 0: # 0 means use port 0, not the default port - port = None - self._setup(self._connection_class(host, port, **kwargs)) - - - if ssl: - class HTTPS(httplib.HTTPS): - def __init__(self, host='', port=None, **kwargs): - if port == 0: # 0 means use port 0, not the default port - port = None - self._setup(self._connection_class(host, port, **kwargs)) - - -class Transport(xmlrpclib.Transport): - def __init__(self, timeout, use_datetime=0): - self.timeout = timeout - xmlrpclib.Transport.__init__(self, use_datetime) - - def make_connection(self, host): - h, eh, x509 = self.get_host_info(host) - if _ver_info == (2, 6): - result = HTTP(h, timeout=self.timeout) - else: - if not self._connection or host != self._connection[0]: - self._extra_headers = eh - self._connection = host, httplib.HTTPConnection(h) - result = self._connection[1] - return result - -if ssl: - class SafeTransport(xmlrpclib.SafeTransport): - def __init__(self, timeout, use_datetime=0): - self.timeout = timeout - xmlrpclib.SafeTransport.__init__(self, use_datetime) - - def make_connection(self, host): - h, eh, kwargs = self.get_host_info(host) - if not kwargs: - kwargs = {} - kwargs['timeout'] = self.timeout - if _ver_info == (2, 6): - result = HTTPS(host, None, **kwargs) - else: - if not self._connection or host != self._connection[0]: - self._extra_headers = eh - self._connection = host, httplib.HTTPSConnection(h, None, - **kwargs) - result = self._connection[1] - return result - - -class ServerProxy(xmlrpclib.ServerProxy): - def __init__(self, uri, **kwargs): - self.timeout = timeout = kwargs.pop('timeout', None) - # The above classes only come into play if a timeout - # is specified - if timeout is not None: - scheme, _ = splittype(uri) - use_datetime = kwargs.get('use_datetime', 0) - if scheme == 'https': - tcls = SafeTransport - else: - tcls = Transport - kwargs['transport'] = t = tcls(timeout, use_datetime=use_datetime) - self.transport = t - xmlrpclib.ServerProxy.__init__(self, uri, **kwargs) - -# -# CSV functionality. This is provided because on 2.x, the csv module can't -# handle Unicode. However, we need to deal with Unicode in e.g. RECORD files. -# - -def _csv_open(fn, mode, **kwargs): - if sys.version_info[0] < 3: - mode += 'b' - else: - kwargs['newline'] = '' - # Python 3 determines encoding from locale. Force 'utf-8' - # file encoding to match other forced utf-8 encoding - kwargs['encoding'] = 'utf-8' - return open(fn, mode, **kwargs) - - -class CSVBase(object): - defaults = { - 'delimiter': str(','), # The strs are used because we need native - 'quotechar': str('"'), # str in the csv API (2.x won't take - 'lineterminator': str('\n') # Unicode) - } - - def __enter__(self): - return self - - def __exit__(self, *exc_info): - self.stream.close() - - -class CSVReader(CSVBase): - def __init__(self, **kwargs): - if 'stream' in kwargs: - stream = kwargs['stream'] - if sys.version_info[0] >= 3: - # needs to be a text stream - stream = codecs.getreader('utf-8')(stream) - self.stream = stream - else: - self.stream = _csv_open(kwargs['path'], 'r') - self.reader = csv.reader(self.stream, **self.defaults) - - def __iter__(self): - return self - - def next(self): - result = next(self.reader) - if sys.version_info[0] < 3: - for i, item in enumerate(result): - if not isinstance(item, text_type): - result[i] = item.decode('utf-8') - return result - - __next__ = next - -class CSVWriter(CSVBase): - def __init__(self, fn, **kwargs): - self.stream = _csv_open(fn, 'w') - self.writer = csv.writer(self.stream, **self.defaults) - - def writerow(self, row): - if sys.version_info[0] < 3: - r = [] - for item in row: - if isinstance(item, text_type): - item = item.encode('utf-8') - r.append(item) - row = r - self.writer.writerow(row) - -# -# Configurator functionality -# - -class Configurator(BaseConfigurator): - - value_converters = dict(BaseConfigurator.value_converters) - value_converters['inc'] = 'inc_convert' - - def __init__(self, config, base=None): - super(Configurator, self).__init__(config) - self.base = base or os.getcwd() - - def configure_custom(self, config): - def convert(o): - if isinstance(o, (list, tuple)): - result = type(o)([convert(i) for i in o]) - elif isinstance(o, dict): - if '()' in o: - result = self.configure_custom(o) - else: - result = {} - for k in o: - result[k] = convert(o[k]) - else: - result = self.convert(o) - return result - - c = config.pop('()') - if not callable(c): - c = self.resolve(c) - props = config.pop('.', None) - # Check for valid identifiers - args = config.pop('[]', ()) - if args: - args = tuple([convert(o) for o in args]) - items = [(k, convert(config[k])) for k in config if valid_ident(k)] - kwargs = dict(items) - result = c(*args, **kwargs) - if props: - for n, v in props.items(): - setattr(result, n, convert(v)) - return result - - def __getitem__(self, key): - result = self.config[key] - if isinstance(result, dict) and '()' in result: - self.config[key] = result = self.configure_custom(result) - return result - - def inc_convert(self, value): - """Default converter for the inc:// protocol.""" - if not os.path.isabs(value): - value = os.path.join(self.base, value) - with codecs.open(value, 'r', encoding='utf-8') as f: - result = json.load(f) - return result - - -class SubprocessMixin(object): - """ - Mixin for running subprocesses and capturing their output - """ - def __init__(self, verbose=False, progress=None): - self.verbose = verbose - self.progress = progress - - def reader(self, stream, context): - """ - Read lines from a subprocess' output stream and either pass to a progress - callable (if specified) or write progress information to sys.stderr. - """ - progress = self.progress - verbose = self.verbose - while True: - s = stream.readline() - if not s: - break - if progress is not None: - progress(s, context) - else: - if not verbose: - sys.stderr.write('.') - else: - sys.stderr.write(s.decode('utf-8')) - sys.stderr.flush() - stream.close() - - def run_command(self, cmd, **kwargs): - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, **kwargs) - t1 = threading.Thread(target=self.reader, args=(p.stdout, 'stdout')) - t1.start() - t2 = threading.Thread(target=self.reader, args=(p.stderr, 'stderr')) - t2.start() - p.wait() - t1.join() - t2.join() - if self.progress is not None: - self.progress('done.', 'main') - elif self.verbose: - sys.stderr.write('done.\n') - return p - - -def normalize_name(name): - """Normalize a python package name a la PEP 503""" - # https://www.python.org/dev/peps/pep-0503/#normalized-names - return re.sub('[-_.]+', '-', name).lower() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/version.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/version.py deleted file mode 100644 index 3eebe18..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/version.py +++ /dev/null @@ -1,736 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2017 The Python Software Foundation. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -""" -Implementation of a flexible versioning scheme providing support for PEP-440, -setuptools-compatible and semantic versioning. -""" - -import logging -import re - -from .compat import string_types -from .util import parse_requirement - -__all__ = ['NormalizedVersion', 'NormalizedMatcher', - 'LegacyVersion', 'LegacyMatcher', - 'SemanticVersion', 'SemanticMatcher', - 'UnsupportedVersionError', 'get_scheme'] - -logger = logging.getLogger(__name__) - - -class UnsupportedVersionError(ValueError): - """This is an unsupported version.""" - pass - - -class Version(object): - def __init__(self, s): - self._string = s = s.strip() - self._parts = parts = self.parse(s) - assert isinstance(parts, tuple) - assert len(parts) > 0 - - def parse(self, s): - raise NotImplementedError('please implement in a subclass') - - def _check_compatible(self, other): - if type(self) != type(other): - raise TypeError('cannot compare %r and %r' % (self, other)) - - def __eq__(self, other): - self._check_compatible(other) - return self._parts == other._parts - - def __ne__(self, other): - return not self.__eq__(other) - - def __lt__(self, other): - self._check_compatible(other) - return self._parts < other._parts - - def __gt__(self, other): - return not (self.__lt__(other) or self.__eq__(other)) - - def __le__(self, other): - return self.__lt__(other) or self.__eq__(other) - - def __ge__(self, other): - return self.__gt__(other) or self.__eq__(other) - - # See http://docs.python.org/reference/datamodel#object.__hash__ - def __hash__(self): - return hash(self._parts) - - def __repr__(self): - return "%s('%s')" % (self.__class__.__name__, self._string) - - def __str__(self): - return self._string - - @property - def is_prerelease(self): - raise NotImplementedError('Please implement in subclasses.') - - -class Matcher(object): - version_class = None - - # value is either a callable or the name of a method - _operators = { - '<': lambda v, c, p: v < c, - '>': lambda v, c, p: v > c, - '<=': lambda v, c, p: v == c or v < c, - '>=': lambda v, c, p: v == c or v > c, - '==': lambda v, c, p: v == c, - '===': lambda v, c, p: v == c, - # by default, compatible => >=. - '~=': lambda v, c, p: v == c or v > c, - '!=': lambda v, c, p: v != c, - } - - # this is a method only to support alternative implementations - # via overriding - def parse_requirement(self, s): - return parse_requirement(s) - - def __init__(self, s): - if self.version_class is None: - raise ValueError('Please specify a version class') - self._string = s = s.strip() - r = self.parse_requirement(s) - if not r: - raise ValueError('Not valid: %r' % s) - self.name = r.name - self.key = self.name.lower() # for case-insensitive comparisons - clist = [] - if r.constraints: - # import pdb; pdb.set_trace() - for op, s in r.constraints: - if s.endswith('.*'): - if op not in ('==', '!='): - raise ValueError('\'.*\' not allowed for ' - '%r constraints' % op) - # Could be a partial version (e.g. for '2.*') which - # won't parse as a version, so keep it as a string - vn, prefix = s[:-2], True - # Just to check that vn is a valid version - self.version_class(vn) - else: - # Should parse as a version, so we can create an - # instance for the comparison - vn, prefix = self.version_class(s), False - clist.append((op, vn, prefix)) - self._parts = tuple(clist) - - def match(self, version): - """ - Check if the provided version matches the constraints. - - :param version: The version to match against this instance. - :type version: String or :class:`Version` instance. - """ - if isinstance(version, string_types): - version = self.version_class(version) - for operator, constraint, prefix in self._parts: - f = self._operators.get(operator) - if isinstance(f, string_types): - f = getattr(self, f) - if not f: - msg = ('%r not implemented ' - 'for %s' % (operator, self.__class__.__name__)) - raise NotImplementedError(msg) - if not f(version, constraint, prefix): - return False - return True - - @property - def exact_version(self): - result = None - if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='): - result = self._parts[0][1] - return result - - def _check_compatible(self, other): - if type(self) != type(other) or self.name != other.name: - raise TypeError('cannot compare %s and %s' % (self, other)) - - def __eq__(self, other): - self._check_compatible(other) - return self.key == other.key and self._parts == other._parts - - def __ne__(self, other): - return not self.__eq__(other) - - # See http://docs.python.org/reference/datamodel#object.__hash__ - def __hash__(self): - return hash(self.key) + hash(self._parts) - - def __repr__(self): - return "%s(%r)" % (self.__class__.__name__, self._string) - - def __str__(self): - return self._string - - -PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?' - r'(\.(post)(\d+))?(\.(dev)(\d+))?' - r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$') - - -def _pep_440_key(s): - s = s.strip() - m = PEP440_VERSION_RE.match(s) - if not m: - raise UnsupportedVersionError('Not a valid version: %s' % s) - groups = m.groups() - nums = tuple(int(v) for v in groups[1].split('.')) - while len(nums) > 1 and nums[-1] == 0: - nums = nums[:-1] - - if not groups[0]: - epoch = 0 - else: - epoch = int(groups[0]) - pre = groups[4:6] - post = groups[7:9] - dev = groups[10:12] - local = groups[13] - if pre == (None, None): - pre = () - else: - pre = pre[0], int(pre[1]) - if post == (None, None): - post = () - else: - post = post[0], int(post[1]) - if dev == (None, None): - dev = () - else: - dev = dev[0], int(dev[1]) - if local is None: - local = () - else: - parts = [] - for part in local.split('.'): - # to ensure that numeric compares as > lexicographic, avoid - # comparing them directly, but encode a tuple which ensures - # correct sorting - if part.isdigit(): - part = (1, int(part)) - else: - part = (0, part) - parts.append(part) - local = tuple(parts) - if not pre: - # either before pre-release, or final release and after - if not post and dev: - # before pre-release - pre = ('a', -1) # to sort before a0 - else: - pre = ('z',) # to sort after all pre-releases - # now look at the state of post and dev. - if not post: - post = ('_',) # sort before 'a' - if not dev: - dev = ('final',) - - #print('%s -> %s' % (s, m.groups())) - return epoch, nums, pre, post, dev, local - - -_normalized_key = _pep_440_key - - -class NormalizedVersion(Version): - """A rational version. - - Good: - 1.2 # equivalent to "1.2.0" - 1.2.0 - 1.2a1 - 1.2.3a2 - 1.2.3b1 - 1.2.3c1 - 1.2.3.4 - TODO: fill this out - - Bad: - 1 # minimum two numbers - 1.2a # release level must have a release serial - 1.2.3b - """ - def parse(self, s): - result = _normalized_key(s) - # _normalized_key loses trailing zeroes in the release - # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0 - # However, PEP 440 prefix matching needs it: for example, - # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0). - m = PEP440_VERSION_RE.match(s) # must succeed - groups = m.groups() - self._release_clause = tuple(int(v) for v in groups[1].split('.')) - return result - - PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev']) - - @property - def is_prerelease(self): - return any(t[0] in self.PREREL_TAGS for t in self._parts if t) - - -def _match_prefix(x, y): - x = str(x) - y = str(y) - if x == y: - return True - if not x.startswith(y): - return False - n = len(y) - return x[n] == '.' - - -class NormalizedMatcher(Matcher): - version_class = NormalizedVersion - - # value is either a callable or the name of a method - _operators = { - '~=': '_match_compatible', - '<': '_match_lt', - '>': '_match_gt', - '<=': '_match_le', - '>=': '_match_ge', - '==': '_match_eq', - '===': '_match_arbitrary', - '!=': '_match_ne', - } - - def _adjust_local(self, version, constraint, prefix): - if prefix: - strip_local = '+' not in constraint and version._parts[-1] - else: - # both constraint and version are - # NormalizedVersion instances. - # If constraint does not have a local component, - # ensure the version doesn't, either. - strip_local = not constraint._parts[-1] and version._parts[-1] - if strip_local: - s = version._string.split('+', 1)[0] - version = self.version_class(s) - return version, constraint - - def _match_lt(self, version, constraint, prefix): - version, constraint = self._adjust_local(version, constraint, prefix) - if version >= constraint: - return False - release_clause = constraint._release_clause - pfx = '.'.join([str(i) for i in release_clause]) - return not _match_prefix(version, pfx) - - def _match_gt(self, version, constraint, prefix): - version, constraint = self._adjust_local(version, constraint, prefix) - if version <= constraint: - return False - release_clause = constraint._release_clause - pfx = '.'.join([str(i) for i in release_clause]) - return not _match_prefix(version, pfx) - - def _match_le(self, version, constraint, prefix): - version, constraint = self._adjust_local(version, constraint, prefix) - return version <= constraint - - def _match_ge(self, version, constraint, prefix): - version, constraint = self._adjust_local(version, constraint, prefix) - return version >= constraint - - def _match_eq(self, version, constraint, prefix): - version, constraint = self._adjust_local(version, constraint, prefix) - if not prefix: - result = (version == constraint) - else: - result = _match_prefix(version, constraint) - return result - - def _match_arbitrary(self, version, constraint, prefix): - return str(version) == str(constraint) - - def _match_ne(self, version, constraint, prefix): - version, constraint = self._adjust_local(version, constraint, prefix) - if not prefix: - result = (version != constraint) - else: - result = not _match_prefix(version, constraint) - return result - - def _match_compatible(self, version, constraint, prefix): - version, constraint = self._adjust_local(version, constraint, prefix) - if version == constraint: - return True - if version < constraint: - return False -# if not prefix: -# return True - release_clause = constraint._release_clause - if len(release_clause) > 1: - release_clause = release_clause[:-1] - pfx = '.'.join([str(i) for i in release_clause]) - return _match_prefix(version, pfx) - -_REPLACEMENTS = ( - (re.compile('[.+-]$'), ''), # remove trailing puncts - (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start - (re.compile('^[.-]'), ''), # remove leading puncts - (re.compile(r'^\((.*)\)$'), r'\1'), # remove parentheses - (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion) - (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion) - (re.compile('[.]{2,}'), '.'), # multiple runs of '.' - (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha - (re.compile(r'\b(pre-alpha|prealpha)\b'), - 'pre.alpha'), # standardise - (re.compile(r'\(beta\)$'), 'beta'), # remove parentheses -) - -_SUFFIX_REPLACEMENTS = ( - (re.compile('^[:~._+-]+'), ''), # remove leading puncts - (re.compile('[,*")([\\]]'), ''), # remove unwanted chars - (re.compile('[~:+_ -]'), '.'), # replace illegal chars - (re.compile('[.]{2,}'), '.'), # multiple runs of '.' - (re.compile(r'\.$'), ''), # trailing '.' -) - -_NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)') - - -def _suggest_semantic_version(s): - """ - Try to suggest a semantic form for a version for which - _suggest_normalized_version couldn't come up with anything. - """ - result = s.strip().lower() - for pat, repl in _REPLACEMENTS: - result = pat.sub(repl, result) - if not result: - result = '0.0.0' - - # Now look for numeric prefix, and separate it out from - # the rest. - #import pdb; pdb.set_trace() - m = _NUMERIC_PREFIX.match(result) - if not m: - prefix = '0.0.0' - suffix = result - else: - prefix = m.groups()[0].split('.') - prefix = [int(i) for i in prefix] - while len(prefix) < 3: - prefix.append(0) - if len(prefix) == 3: - suffix = result[m.end():] - else: - suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():] - prefix = prefix[:3] - prefix = '.'.join([str(i) for i in prefix]) - suffix = suffix.strip() - if suffix: - #import pdb; pdb.set_trace() - # massage the suffix. - for pat, repl in _SUFFIX_REPLACEMENTS: - suffix = pat.sub(repl, suffix) - - if not suffix: - result = prefix - else: - sep = '-' if 'dev' in suffix else '+' - result = prefix + sep + suffix - if not is_semver(result): - result = None - return result - - -def _suggest_normalized_version(s): - """Suggest a normalized version close to the given version string. - - If you have a version string that isn't rational (i.e. NormalizedVersion - doesn't like it) then you might be able to get an equivalent (or close) - rational version from this function. - - This does a number of simple normalizations to the given string, based - on observation of versions currently in use on PyPI. Given a dump of - those version during PyCon 2009, 4287 of them: - - 2312 (53.93%) match NormalizedVersion without change - with the automatic suggestion - - 3474 (81.04%) match when using this suggestion method - - @param s {str} An irrational version string. - @returns A rational version string, or None, if couldn't determine one. - """ - try: - _normalized_key(s) - return s # already rational - except UnsupportedVersionError: - pass - - rs = s.lower() - - # part of this could use maketrans - for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'), - ('beta', 'b'), ('rc', 'c'), ('-final', ''), - ('-pre', 'c'), - ('-release', ''), ('.release', ''), ('-stable', ''), - ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''), - ('final', '')): - rs = rs.replace(orig, repl) - - # if something ends with dev or pre, we add a 0 - rs = re.sub(r"pre$", r"pre0", rs) - rs = re.sub(r"dev$", r"dev0", rs) - - # if we have something like "b-2" or "a.2" at the end of the - # version, that is probably beta, alpha, etc - # let's remove the dash or dot - rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs) - - # 1.0-dev-r371 -> 1.0.dev371 - # 0.1-dev-r79 -> 0.1.dev79 - rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs) - - # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1 - rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs) - - # Clean: v0.3, v1.0 - if rs.startswith('v'): - rs = rs[1:] - - # Clean leading '0's on numbers. - #TODO: unintended side-effect on, e.g., "2003.05.09" - # PyPI stats: 77 (~2%) better - rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs) - - # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers - # zero. - # PyPI stats: 245 (7.56%) better - rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs) - - # the 'dev-rNNN' tag is a dev tag - rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs) - - # clean the - when used as a pre delimiter - rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs) - - # a terminal "dev" or "devel" can be changed into ".dev0" - rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs) - - # a terminal "dev" can be changed into ".dev0" - rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs) - - # a terminal "final" or "stable" can be removed - rs = re.sub(r"(final|stable)$", "", rs) - - # The 'r' and the '-' tags are post release tags - # 0.4a1.r10 -> 0.4a1.post10 - # 0.9.33-17222 -> 0.9.33.post17222 - # 0.9.33-r17222 -> 0.9.33.post17222 - rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs) - - # Clean 'r' instead of 'dev' usage: - # 0.9.33+r17222 -> 0.9.33.dev17222 - # 1.0dev123 -> 1.0.dev123 - # 1.0.git123 -> 1.0.dev123 - # 1.0.bzr123 -> 1.0.dev123 - # 0.1a0dev.123 -> 0.1a0.dev123 - # PyPI stats: ~150 (~4%) better - rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs) - - # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage: - # 0.2.pre1 -> 0.2c1 - # 0.2-c1 -> 0.2c1 - # 1.0preview123 -> 1.0c123 - # PyPI stats: ~21 (0.62%) better - rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs) - - # Tcl/Tk uses "px" for their post release markers - rs = re.sub(r"p(\d+)$", r".post\1", rs) - - try: - _normalized_key(rs) - except UnsupportedVersionError: - rs = None - return rs - -# -# Legacy version processing (distribute-compatible) -# - -_VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I) -_VERSION_REPLACE = { - 'pre': 'c', - 'preview': 'c', - '-': 'final-', - 'rc': 'c', - 'dev': '@', - '': None, - '.': None, -} - - -def _legacy_key(s): - def get_parts(s): - result = [] - for p in _VERSION_PART.split(s.lower()): - p = _VERSION_REPLACE.get(p, p) - if p: - if '0' <= p[:1] <= '9': - p = p.zfill(8) - else: - p = '*' + p - result.append(p) - result.append('*final') - return result - - result = [] - for p in get_parts(s): - if p.startswith('*'): - if p < '*final': - while result and result[-1] == '*final-': - result.pop() - while result and result[-1] == '00000000': - result.pop() - result.append(p) - return tuple(result) - - -class LegacyVersion(Version): - def parse(self, s): - return _legacy_key(s) - - @property - def is_prerelease(self): - result = False - for x in self._parts: - if (isinstance(x, string_types) and x.startswith('*') and - x < '*final'): - result = True - break - return result - - -class LegacyMatcher(Matcher): - version_class = LegacyVersion - - _operators = dict(Matcher._operators) - _operators['~='] = '_match_compatible' - - numeric_re = re.compile(r'^(\d+(\.\d+)*)') - - def _match_compatible(self, version, constraint, prefix): - if version < constraint: - return False - m = self.numeric_re.match(str(constraint)) - if not m: - logger.warning('Cannot compute compatible match for version %s ' - ' and constraint %s', version, constraint) - return True - s = m.groups()[0] - if '.' in s: - s = s.rsplit('.', 1)[0] - return _match_prefix(version, s) - -# -# Semantic versioning -# - -_SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)' - r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?' - r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I) - - -def is_semver(s): - return _SEMVER_RE.match(s) - - -def _semantic_key(s): - def make_tuple(s, absent): - if s is None: - result = (absent,) - else: - parts = s[1:].split('.') - # We can't compare ints and strings on Python 3, so fudge it - # by zero-filling numeric values so simulate a numeric comparison - result = tuple([p.zfill(8) if p.isdigit() else p for p in parts]) - return result - - m = is_semver(s) - if not m: - raise UnsupportedVersionError(s) - groups = m.groups() - major, minor, patch = [int(i) for i in groups[:3]] - # choose the '|' and '*' so that versions sort correctly - pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*') - return (major, minor, patch), pre, build - - -class SemanticVersion(Version): - def parse(self, s): - return _semantic_key(s) - - @property - def is_prerelease(self): - return self._parts[1][0] != '|' - - -class SemanticMatcher(Matcher): - version_class = SemanticVersion - - -class VersionScheme(object): - def __init__(self, key, matcher, suggester=None): - self.key = key - self.matcher = matcher - self.suggester = suggester - - def is_valid_version(self, s): - try: - self.matcher.version_class(s) - result = True - except UnsupportedVersionError: - result = False - return result - - def is_valid_matcher(self, s): - try: - self.matcher(s) - result = True - except UnsupportedVersionError: - result = False - return result - - def is_valid_constraint_list(self, s): - """ - Used for processing some metadata fields - """ - return self.is_valid_matcher('dummy_name (%s)' % s) - - def suggest(self, s): - if self.suggester is None: - result = None - else: - result = self.suggester(s) - return result - -_SCHEMES = { - 'normalized': VersionScheme(_normalized_key, NormalizedMatcher, - _suggest_normalized_version), - 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s), - 'semantic': VersionScheme(_semantic_key, SemanticMatcher, - _suggest_semantic_version), -} - -_SCHEMES['default'] = _SCHEMES['normalized'] - - -def get_scheme(name): - if name not in _SCHEMES: - raise ValueError('unknown scheme name: %r' % name) - return _SCHEMES[name] diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/w32.exe b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/w32.exe deleted file mode 100644 index 732215a9d34ccb7b417d637a7646d9b843ecafa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89088 zcmeFae|S?>wm*FGqitH!CO`{C3REl(SahnPNDYM`O{q#T7)Xdvz$<hz5gjb&0FD$| zPs=nt#$jgk-tk`NUb*PJIy$3wMg@OiORy=5PEkZ0P^;6cyPm2=Y8#~Xyq~pC(iU~@ z_dd`2ywCg3TS)e=wSTX@_S$Q$y;FJf9>F9Cf*Bu86NCeB>CeT#|L3nblC!40kR?2m z{>H@z3`^g*ct!B1Tk<#8{Ol(+x7?n8>n(TO@iQ_1pEl;#NO$D_^p5<p8@>6r|7^p? zD>5@P3KB)%InlPUc<U{5lb_$uJ2!U@!dIxT&CTYnHuoCtzCL#`-1%8w%`JjkymkHD zpYr&>Cg9H}+(GW%^wV2|ROUbGfyXTfOART)i?<!WISJD#7!6|#8G`TvV*Xu^z32+K zc6>T0?9%;4K}Zn{6fx`yPa}*$9C+R!7zI~72c&$InY+UdMGBkF3c`HyxD3K09`bzW z?_q;rO&5ec#{?noJ4vI19bbHBt~vx^h2FH$V8i|^#EsiUg#JboP3@w-(&Uf&%NK<8 zSJZ5{MZ852W)~s>WeT(LIf&1wKNqULLI)GN_(-E-D)X~ZK=1;t<%*guHMhdg`-(mb zHzDv1KBN9zR9?--O+N$ReOXAr81V9z!X5SJ5`=3<1^<8V|AP@&sr2}Qvp;hQT24iW zOHg|EiZd1ojV;oo#(r^ba2`^8T22{~_UQ@YMZp7O1R*2@?SerFE~TuJB_wDaYC0h8 zfONF1t%{=H`W`bdYp+>YBsg9Ty9ec3iy+O3xa}TIvPK#Q&udyx1MvwG0(#iaGC|N| zJ#3?<Y4YLRkU`54s9BYRjyISA>){9$tW;Y34lPnX=&>D4X~|k7c$TwEfOzs@Yh#Nz z`FV;`(w!E`sKg@`2E}bDY>ku^4XS@tV(WO*<eu67;0Clk;vRHp!Qf<+5w0B!*Y>g? zYH=KK#%%Yu1~&m>IlB^#2^syGG|2AB1(}4aOcaC%!)}%`I7AIC2(Ro3yW`GSttng^ z_xb=ECor!L{-PNO>_ulJ3%fm=O0X!s%)$GZ?~I94l-^KEAX0n$?4wGpr7&i4#~)OB zQD%2NrWUKtZuYT1Vnu}AeF`cSgx>Rkk@}Lg{WltgT76VeA2aic`cTnpXrt2WXmJkM z9%u<Rp-*9{$HQ)>Xm?McyDyZ28Ux7mpxy?mnmvzMMr-85vkRrJLaDRx>|I7je+cM+ zj{RJ(3Vrgke;W@#D!y%U%fQLtlPKTAzWtVuOQdXpwsy6eRjt^cZ%0D4bF7$F;f!th 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ð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 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/w64.exe b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/w64.exe deleted file mode 100644 index c41bd0a011fd760ce20ba795d9e535e0d2c39876..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99328 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 B=L-M; diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/wheel.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/wheel.py deleted file mode 100644 index b04bfae..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distlib/wheel.py +++ /dev/null @@ -1,988 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2017 Vinay Sajip. -# Licensed to the Python Software Foundation under a contributor agreement. -# See LICENSE.txt and CONTRIBUTORS.txt. -# -from __future__ import unicode_literals - -import base64 -import codecs -import datetime -import distutils.util -from email import message_from_file -import hashlib -import imp -import json -import logging -import os -import posixpath -import re -import shutil -import sys -import tempfile -import zipfile - -from . import __version__, DistlibException -from .compat import sysconfig, ZipFile, fsdecode, text_type, filter -from .database import InstalledDistribution -from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME -from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache, - cached_property, get_cache_base, read_exports, tempdir) -from .version import NormalizedVersion, UnsupportedVersionError - -logger = logging.getLogger(__name__) - -cache = None # created when needed - -if hasattr(sys, 'pypy_version_info'): # pragma: no cover - IMP_PREFIX = 'pp' -elif sys.platform.startswith('java'): # pragma: no cover - IMP_PREFIX = 'jy' -elif sys.platform == 'cli': # pragma: no cover - IMP_PREFIX = 'ip' -else: - IMP_PREFIX = 'cp' - -VER_SUFFIX = sysconfig.get_config_var('py_version_nodot') -if not VER_SUFFIX: # pragma: no cover - VER_SUFFIX = '%s%s' % sys.version_info[:2] -PYVER = 'py' + VER_SUFFIX -IMPVER = IMP_PREFIX + VER_SUFFIX - -ARCH = distutils.util.get_platform().replace('-', '_').replace('.', '_') - -ABI = sysconfig.get_config_var('SOABI') -if ABI and ABI.startswith('cpython-'): - ABI = ABI.replace('cpython-', 'cp') -else: - def _derive_abi(): - parts = ['cp', VER_SUFFIX] - if sysconfig.get_config_var('Py_DEBUG'): - parts.append('d') - if sysconfig.get_config_var('WITH_PYMALLOC'): - parts.append('m') - if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4: - parts.append('u') - return ''.join(parts) - ABI = _derive_abi() - del _derive_abi - -FILENAME_RE = re.compile(r''' -(?P<nm>[^-]+) --(?P<vn>\d+[^-]*) -(-(?P<bn>\d+[^-]*))? --(?P<py>\w+\d+(\.\w+\d+)*) --(?P<bi>\w+) --(?P<ar>\w+(\.\w+)*) -\.whl$ -''', re.IGNORECASE | re.VERBOSE) - -NAME_VERSION_RE = re.compile(r''' -(?P<nm>[^-]+) --(?P<vn>\d+[^-]*) -(-(?P<bn>\d+[^-]*))?$ -''', re.IGNORECASE | re.VERBOSE) - -SHEBANG_RE = re.compile(br'\s*#![^\r\n]*') -SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$') -SHEBANG_PYTHON = b'#!python' -SHEBANG_PYTHONW = b'#!pythonw' - -if os.sep == '/': - to_posix = lambda o: o -else: - to_posix = lambda o: o.replace(os.sep, '/') - - -class Mounter(object): - def __init__(self): - self.impure_wheels = {} - self.libs = {} - - def add(self, pathname, extensions): - self.impure_wheels[pathname] = extensions - self.libs.update(extensions) - - def remove(self, pathname): - extensions = self.impure_wheels.pop(pathname) - for k, v in extensions: - if k in self.libs: - del self.libs[k] - - def find_module(self, fullname, path=None): - if fullname in self.libs: - result = self - else: - result = None - return result - - def load_module(self, fullname): - if fullname in sys.modules: - result = sys.modules[fullname] - else: - if fullname not in self.libs: - raise ImportError('unable to find extension for %s' % fullname) - result = imp.load_dynamic(fullname, self.libs[fullname]) - result.__loader__ = self - parts = fullname.rsplit('.', 1) - if len(parts) > 1: - result.__package__ = parts[0] - return result - -_hook = Mounter() - - -class Wheel(object): - """ - Class to build and install from Wheel files (PEP 427). - """ - - wheel_version = (1, 1) - hash_kind = 'sha256' - - def __init__(self, filename=None, sign=False, verify=False): - """ - Initialise an instance using a (valid) filename. - """ - self.sign = sign - self.should_verify = verify - self.buildver = '' - self.pyver = [PYVER] - self.abi = ['none'] - self.arch = ['any'] - self.dirname = os.getcwd() - if filename is None: - self.name = 'dummy' - self.version = '0.1' - self._filename = self.filename - else: - m = NAME_VERSION_RE.match(filename) - if m: - info = m.groupdict('') - self.name = info['nm'] - # Reinstate the local version separator - self.version = info['vn'].replace('_', '-') - self.buildver = info['bn'] - self._filename = self.filename - else: - dirname, filename = os.path.split(filename) - m = FILENAME_RE.match(filename) - if not m: - raise DistlibException('Invalid name or ' - 'filename: %r' % filename) - if dirname: - self.dirname = os.path.abspath(dirname) - self._filename = filename - info = m.groupdict('') - self.name = info['nm'] - self.version = info['vn'] - self.buildver = info['bn'] - self.pyver = info['py'].split('.') - self.abi = info['bi'].split('.') - self.arch = info['ar'].split('.') - - @property - def filename(self): - """ - Build and return a filename from the various components. - """ - if self.buildver: - buildver = '-' + self.buildver - else: - buildver = '' - pyver = '.'.join(self.pyver) - abi = '.'.join(self.abi) - arch = '.'.join(self.arch) - # replace - with _ as a local version separator - version = self.version.replace('-', '_') - return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver, - pyver, abi, arch) - - @property - def exists(self): - path = os.path.join(self.dirname, self.filename) - return os.path.isfile(path) - - @property - def tags(self): - for pyver in self.pyver: - for abi in self.abi: - for arch in self.arch: - yield pyver, abi, arch - - @cached_property - def metadata(self): - pathname = os.path.join(self.dirname, self.filename) - name_ver = '%s-%s' % (self.name, self.version) - info_dir = '%s.dist-info' % name_ver - wrapper = codecs.getreader('utf-8') - with ZipFile(pathname, 'r') as zf: - wheel_metadata = self.get_wheel_metadata(zf) - wv = wheel_metadata['Wheel-Version'].split('.', 1) - file_version = tuple([int(i) for i in wv]) - if file_version < (1, 1): - fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, 'METADATA'] - else: - fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] - result = None - for fn in fns: - try: - metadata_filename = posixpath.join(info_dir, fn) - with zf.open(metadata_filename) as bf: - wf = wrapper(bf) - result = Metadata(fileobj=wf) - if result: - break - except KeyError: - pass - if not result: - raise ValueError('Invalid wheel, because metadata is ' - 'missing: looked in %s' % ', '.join(fns)) - return result - - def get_wheel_metadata(self, zf): - name_ver = '%s-%s' % (self.name, self.version) - info_dir = '%s.dist-info' % name_ver - metadata_filename = posixpath.join(info_dir, 'WHEEL') - with zf.open(metadata_filename) as bf: - wf = codecs.getreader('utf-8')(bf) - message = message_from_file(wf) - return dict(message) - - @cached_property - def info(self): - pathname = os.path.join(self.dirname, self.filename) - with ZipFile(pathname, 'r') as zf: - result = self.get_wheel_metadata(zf) - return result - - def process_shebang(self, data): - m = SHEBANG_RE.match(data) - if m: - end = m.end() - shebang, data_after_shebang = data[:end], data[end:] - # Preserve any arguments after the interpreter - if b'pythonw' in shebang.lower(): - shebang_python = SHEBANG_PYTHONW - else: - shebang_python = SHEBANG_PYTHON - m = SHEBANG_DETAIL_RE.match(shebang) - if m: - args = b' ' + m.groups()[-1] - else: - args = b'' - shebang = shebang_python + args - data = shebang + data_after_shebang - else: - cr = data.find(b'\r') - lf = data.find(b'\n') - if cr < 0 or cr > lf: - term = b'\n' - else: - if data[cr:cr + 2] == b'\r\n': - term = b'\r\n' - else: - term = b'\r' - data = SHEBANG_PYTHON + term + data - return data - - def get_hash(self, data, hash_kind=None): - if hash_kind is None: - hash_kind = self.hash_kind - try: - hasher = getattr(hashlib, hash_kind) - except AttributeError: - raise DistlibException('Unsupported hash algorithm: %r' % hash_kind) - result = hasher(data).digest() - result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii') - return hash_kind, result - - def write_record(self, records, record_path, base): - records = list(records) # make a copy for sorting - p = to_posix(os.path.relpath(record_path, base)) - records.append((p, '', '')) - records.sort() - with CSVWriter(record_path) as writer: - for row in records: - writer.writerow(row) - - def write_records(self, info, libdir, archive_paths): - records = [] - distinfo, info_dir = info - hasher = getattr(hashlib, self.hash_kind) - for ap, p in archive_paths: - with open(p, 'rb') as f: - data = f.read() - digest = '%s=%s' % self.get_hash(data) - size = os.path.getsize(p) - records.append((ap, digest, size)) - - p = os.path.join(distinfo, 'RECORD') - self.write_record(records, p, libdir) - ap = to_posix(os.path.join(info_dir, 'RECORD')) - archive_paths.append((ap, p)) - - def build_zip(self, pathname, archive_paths): - with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf: - for ap, p in archive_paths: - logger.debug('Wrote %s to %s in wheel', p, ap) - zf.write(p, ap) - - def build(self, paths, tags=None, wheel_version=None): - """ - Build a wheel from files in specified paths, and use any specified tags - when determining the name of the wheel. - """ - if tags is None: - tags = {} - - libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0] - if libkey == 'platlib': - is_pure = 'false' - default_pyver = [IMPVER] - default_abi = [ABI] - default_arch = [ARCH] - else: - is_pure = 'true' - default_pyver = [PYVER] - default_abi = ['none'] - default_arch = ['any'] - - self.pyver = tags.get('pyver', default_pyver) - self.abi = tags.get('abi', default_abi) - self.arch = tags.get('arch', default_arch) - - libdir = paths[libkey] - - name_ver = '%s-%s' % (self.name, self.version) - data_dir = '%s.data' % name_ver - info_dir = '%s.dist-info' % name_ver - - archive_paths = [] - - # First, stuff which is not in site-packages - for key in ('data', 'headers', 'scripts'): - if key not in paths: - continue - path = paths[key] - if os.path.isdir(path): - for root, dirs, files in os.walk(path): - for fn in files: - p = fsdecode(os.path.join(root, fn)) - rp = os.path.relpath(p, path) - ap = to_posix(os.path.join(data_dir, key, rp)) - archive_paths.append((ap, p)) - if key == 'scripts' and not p.endswith('.exe'): - with open(p, 'rb') as f: - data = f.read() - data = self.process_shebang(data) - with open(p, 'wb') as f: - f.write(data) - - # Now, stuff which is in site-packages, other than the - # distinfo stuff. - path = libdir - distinfo = None - for root, dirs, files in os.walk(path): - if root == path: - # At the top level only, save distinfo for later - # and skip it for now - for i, dn in enumerate(dirs): - dn = fsdecode(dn) - if dn.endswith('.dist-info'): - distinfo = os.path.join(root, dn) - del dirs[i] - break - assert distinfo, '.dist-info directory expected, not found' - - for fn in files: - # comment out next suite to leave .pyc files in - if fsdecode(fn).endswith(('.pyc', '.pyo')): - continue - p = os.path.join(root, fn) - rp = to_posix(os.path.relpath(p, path)) - archive_paths.append((rp, p)) - - # Now distinfo. Assumed to be flat, i.e. os.listdir is enough. - files = os.listdir(distinfo) - for fn in files: - if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'): - p = fsdecode(os.path.join(distinfo, fn)) - ap = to_posix(os.path.join(info_dir, fn)) - archive_paths.append((ap, p)) - - wheel_metadata = [ - 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version), - 'Generator: distlib %s' % __version__, - 'Root-Is-Purelib: %s' % is_pure, - ] - for pyver, abi, arch in self.tags: - wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch)) - p = os.path.join(distinfo, 'WHEEL') - with open(p, 'w') as f: - f.write('\n'.join(wheel_metadata)) - ap = to_posix(os.path.join(info_dir, 'WHEEL')) - archive_paths.append((ap, p)) - - # Now, at last, RECORD. - # Paths in here are archive paths - nothing else makes sense. - self.write_records((distinfo, info_dir), libdir, archive_paths) - # Now, ready to build the zip file - pathname = os.path.join(self.dirname, self.filename) - self.build_zip(pathname, archive_paths) - return pathname - - def install(self, paths, maker, **kwargs): - """ - Install a wheel to the specified paths. If kwarg ``warner`` is - specified, it should be a callable, which will be called with two - tuples indicating the wheel version of this software and the wheel - version in the file, if there is a discrepancy in the versions. - This can be used to issue any warnings to raise any exceptions. - If kwarg ``lib_only`` is True, only the purelib/platlib files are - installed, and the headers, scripts, data and dist-info metadata are - not written. If kwarg ``bytecode_hashed_invalidation`` is True, written - bytecode will try to use file-hash based invalidation (PEP-552) on - supported interpreter versions (CPython 2.7+). - - The return value is a :class:`InstalledDistribution` instance unless - ``options.lib_only`` is True, in which case the return value is ``None``. - """ - - dry_run = maker.dry_run - warner = kwargs.get('warner') - lib_only = kwargs.get('lib_only', False) - bc_hashed_invalidation = kwargs.get('bytecode_hashed_invalidation', False) - - pathname = os.path.join(self.dirname, self.filename) - name_ver = '%s-%s' % (self.name, self.version) - data_dir = '%s.data' % name_ver - info_dir = '%s.dist-info' % name_ver - - metadata_name = posixpath.join(info_dir, METADATA_FILENAME) - wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') - record_name = posixpath.join(info_dir, 'RECORD') - - wrapper = codecs.getreader('utf-8') - - with ZipFile(pathname, 'r') as zf: - with zf.open(wheel_metadata_name) as bwf: - wf = wrapper(bwf) - message = message_from_file(wf) - wv = message['Wheel-Version'].split('.', 1) - file_version = tuple([int(i) for i in wv]) - if (file_version != self.wheel_version) and warner: - warner(self.wheel_version, file_version) - - if message['Root-Is-Purelib'] == 'true': - libdir = paths['purelib'] - else: - libdir = paths['platlib'] - - records = {} - with zf.open(record_name) as bf: - with CSVReader(stream=bf) as reader: - for row in reader: - p = row[0] - records[p] = row - - data_pfx = posixpath.join(data_dir, '') - info_pfx = posixpath.join(info_dir, '') - script_pfx = posixpath.join(data_dir, 'scripts', '') - - # make a new instance rather than a copy of maker's, - # as we mutate it - fileop = FileOperator(dry_run=dry_run) - fileop.record = True # so we can rollback if needed - - bc = not sys.dont_write_bytecode # Double negatives. Lovely! - - outfiles = [] # for RECORD writing - - # for script copying/shebang processing - workdir = tempfile.mkdtemp() - # set target dir later - # we default add_launchers to False, as the - # Python Launcher should be used instead - maker.source_dir = workdir - maker.target_dir = None - try: - for zinfo in zf.infolist(): - arcname = zinfo.filename - if isinstance(arcname, text_type): - u_arcname = arcname - else: - u_arcname = arcname.decode('utf-8') - # The signature file won't be in RECORD, - # and we don't currently don't do anything with it - if u_arcname.endswith('/RECORD.jws'): - continue - row = records[u_arcname] - if row[2] and str(zinfo.file_size) != row[2]: - raise DistlibException('size mismatch for ' - '%s' % u_arcname) - if row[1]: - kind, value = row[1].split('=', 1) - with zf.open(arcname) as bf: - data = bf.read() - _, digest = self.get_hash(data, kind) - if digest != value: - raise DistlibException('digest mismatch for ' - '%s' % arcname) - - if lib_only and u_arcname.startswith((info_pfx, data_pfx)): - logger.debug('lib_only: skipping %s', u_arcname) - continue - is_script = (u_arcname.startswith(script_pfx) - and not u_arcname.endswith('.exe')) - - if u_arcname.startswith(data_pfx): - _, where, rp = u_arcname.split('/', 2) - outfile = os.path.join(paths[where], convert_path(rp)) - else: - # meant for site-packages. - if u_arcname in (wheel_metadata_name, record_name): - continue - outfile = os.path.join(libdir, convert_path(u_arcname)) - if not is_script: - with zf.open(arcname) as bf: - fileop.copy_stream(bf, outfile) - outfiles.append(outfile) - # Double check the digest of the written file - if not dry_run and row[1]: - with open(outfile, 'rb') as bf: - data = bf.read() - _, newdigest = self.get_hash(data, kind) - if newdigest != digest: - raise DistlibException('digest mismatch ' - 'on write for ' - '%s' % outfile) - if bc and outfile.endswith('.py'): - try: - pyc = fileop.byte_compile(outfile, - hashed_invalidation=bc_hashed_invalidation) - outfiles.append(pyc) - except Exception: - # Don't give up if byte-compilation fails, - # but log it and perhaps warn the user - logger.warning('Byte-compilation failed', - exc_info=True) - else: - fn = os.path.basename(convert_path(arcname)) - workname = os.path.join(workdir, fn) - with zf.open(arcname) as bf: - fileop.copy_stream(bf, workname) - - dn, fn = os.path.split(outfile) - maker.target_dir = dn - filenames = maker.make(fn) - fileop.set_executable_mode(filenames) - outfiles.extend(filenames) - - if lib_only: - logger.debug('lib_only: returning None') - dist = None - else: - # Generate scripts - - # Try to get pydist.json so we can see if there are - # any commands to generate. If this fails (e.g. because - # of a legacy wheel), log a warning but don't give up. - commands = None - file_version = self.info['Wheel-Version'] - if file_version == '1.0': - # Use legacy info - ep = posixpath.join(info_dir, 'entry_points.txt') - try: - with zf.open(ep) as bwf: - epdata = read_exports(bwf) - commands = {} - for key in ('console', 'gui'): - k = '%s_scripts' % key - if k in epdata: - commands['wrap_%s' % key] = d = {} - for v in epdata[k].values(): - s = '%s:%s' % (v.prefix, v.suffix) - if v.flags: - s += ' %s' % v.flags - d[v.name] = s - except Exception: - logger.warning('Unable to read legacy script ' - 'metadata, so cannot generate ' - 'scripts') - else: - try: - with zf.open(metadata_name) as bwf: - wf = wrapper(bwf) - commands = json.load(wf).get('extensions') - if commands: - commands = commands.get('python.commands') - except Exception: - logger.warning('Unable to read JSON metadata, so ' - 'cannot generate scripts') - if commands: - console_scripts = commands.get('wrap_console', {}) - gui_scripts = commands.get('wrap_gui', {}) - if console_scripts or gui_scripts: - script_dir = paths.get('scripts', '') - if not os.path.isdir(script_dir): - raise ValueError('Valid script path not ' - 'specified') - maker.target_dir = script_dir - for k, v in console_scripts.items(): - script = '%s = %s' % (k, v) - filenames = maker.make(script) - fileop.set_executable_mode(filenames) - - if gui_scripts: - options = {'gui': True } - for k, v in gui_scripts.items(): - script = '%s = %s' % (k, v) - filenames = maker.make(script, options) - fileop.set_executable_mode(filenames) - - p = os.path.join(libdir, info_dir) - dist = InstalledDistribution(p) - - # Write SHARED - paths = dict(paths) # don't change passed in dict - del paths['purelib'] - del paths['platlib'] - paths['lib'] = libdir - p = dist.write_shared_locations(paths, dry_run) - if p: - outfiles.append(p) - - # Write RECORD - dist.write_installed_files(outfiles, paths['prefix'], - dry_run) - return dist - except Exception: # pragma: no cover - logger.exception('installation failed.') - fileop.rollback() - raise - finally: - shutil.rmtree(workdir) - - def _get_dylib_cache(self): - global cache - if cache is None: - # Use native string to avoid issues on 2.x: see Python #20140. - base = os.path.join(get_cache_base(), str('dylib-cache'), - sys.version[:3]) - cache = Cache(base) - return cache - - def _get_extensions(self): - pathname = os.path.join(self.dirname, self.filename) - name_ver = '%s-%s' % (self.name, self.version) - info_dir = '%s.dist-info' % name_ver - arcname = posixpath.join(info_dir, 'EXTENSIONS') - wrapper = codecs.getreader('utf-8') - result = [] - with ZipFile(pathname, 'r') as zf: - try: - with zf.open(arcname) as bf: - wf = wrapper(bf) - extensions = json.load(wf) - cache = self._get_dylib_cache() - prefix = cache.prefix_to_dir(pathname) - cache_base = os.path.join(cache.base, prefix) - if not os.path.isdir(cache_base): - os.makedirs(cache_base) - for name, relpath in extensions.items(): - dest = os.path.join(cache_base, convert_path(relpath)) - if not os.path.exists(dest): - extract = True - else: - file_time = os.stat(dest).st_mtime - file_time = datetime.datetime.fromtimestamp(file_time) - info = zf.getinfo(relpath) - wheel_time = datetime.datetime(*info.date_time) - extract = wheel_time > file_time - if extract: - zf.extract(relpath, cache_base) - result.append((name, dest)) - except KeyError: - pass - return result - - def is_compatible(self): - """ - Determine if a wheel is compatible with the running system. - """ - return is_compatible(self) - - def is_mountable(self): - """ - Determine if a wheel is asserted as mountable by its metadata. - """ - return True # for now - metadata details TBD - - def mount(self, append=False): - pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) - if not self.is_compatible(): - msg = 'Wheel %s not compatible with this Python.' % pathname - raise DistlibException(msg) - if not self.is_mountable(): - msg = 'Wheel %s is marked as not mountable.' % pathname - raise DistlibException(msg) - if pathname in sys.path: - logger.debug('%s already in path', pathname) - else: - if append: - sys.path.append(pathname) - else: - sys.path.insert(0, pathname) - extensions = self._get_extensions() - if extensions: - if _hook not in sys.meta_path: - sys.meta_path.append(_hook) - _hook.add(pathname, extensions) - - def unmount(self): - pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) - if pathname not in sys.path: - logger.debug('%s not in path', pathname) - else: - sys.path.remove(pathname) - if pathname in _hook.impure_wheels: - _hook.remove(pathname) - if not _hook.impure_wheels: - if _hook in sys.meta_path: - sys.meta_path.remove(_hook) - - def verify(self): - pathname = os.path.join(self.dirname, self.filename) - name_ver = '%s-%s' % (self.name, self.version) - data_dir = '%s.data' % name_ver - info_dir = '%s.dist-info' % name_ver - - metadata_name = posixpath.join(info_dir, METADATA_FILENAME) - wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') - record_name = posixpath.join(info_dir, 'RECORD') - - wrapper = codecs.getreader('utf-8') - - with ZipFile(pathname, 'r') as zf: - with zf.open(wheel_metadata_name) as bwf: - wf = wrapper(bwf) - message = message_from_file(wf) - wv = message['Wheel-Version'].split('.', 1) - file_version = tuple([int(i) for i in wv]) - # TODO version verification - - records = {} - with zf.open(record_name) as bf: - with CSVReader(stream=bf) as reader: - for row in reader: - p = row[0] - records[p] = row - - for zinfo in zf.infolist(): - arcname = zinfo.filename - if isinstance(arcname, text_type): - u_arcname = arcname - else: - u_arcname = arcname.decode('utf-8') - if '..' in u_arcname: - raise DistlibException('invalid entry in ' - 'wheel: %r' % u_arcname) - - # The signature file won't be in RECORD, - # and we don't currently don't do anything with it - if u_arcname.endswith('/RECORD.jws'): - continue - row = records[u_arcname] - if row[2] and str(zinfo.file_size) != row[2]: - raise DistlibException('size mismatch for ' - '%s' % u_arcname) - if row[1]: - kind, value = row[1].split('=', 1) - with zf.open(arcname) as bf: - data = bf.read() - _, digest = self.get_hash(data, kind) - if digest != value: - raise DistlibException('digest mismatch for ' - '%s' % arcname) - - def update(self, modifier, dest_dir=None, **kwargs): - """ - Update the contents of a wheel in a generic way. The modifier should - be a callable which expects a dictionary argument: its keys are - archive-entry paths, and its values are absolute filesystem paths - where the contents the corresponding archive entries can be found. The - modifier is free to change the contents of the files pointed to, add - new entries and remove entries, before returning. This method will - extract the entire contents of the wheel to a temporary location, call - the modifier, and then use the passed (and possibly updated) - dictionary to write a new wheel. If ``dest_dir`` is specified, the new - wheel is written there -- otherwise, the original wheel is overwritten. - - The modifier should return True if it updated the wheel, else False. - This method returns the same value the modifier returns. - """ - - def get_version(path_map, info_dir): - version = path = None - key = '%s/%s' % (info_dir, METADATA_FILENAME) - if key not in path_map: - key = '%s/PKG-INFO' % info_dir - if key in path_map: - path = path_map[key] - version = Metadata(path=path).version - return version, path - - def update_version(version, path): - updated = None - try: - v = NormalizedVersion(version) - i = version.find('-') - if i < 0: - updated = '%s+1' % version - else: - parts = [int(s) for s in version[i + 1:].split('.')] - parts[-1] += 1 - updated = '%s+%s' % (version[:i], - '.'.join(str(i) for i in parts)) - except UnsupportedVersionError: - logger.debug('Cannot update non-compliant (PEP-440) ' - 'version %r', version) - if updated: - md = Metadata(path=path) - md.version = updated - legacy = not path.endswith(METADATA_FILENAME) - md.write(path=path, legacy=legacy) - logger.debug('Version updated from %r to %r', version, - updated) - - pathname = os.path.join(self.dirname, self.filename) - name_ver = '%s-%s' % (self.name, self.version) - info_dir = '%s.dist-info' % name_ver - record_name = posixpath.join(info_dir, 'RECORD') - with tempdir() as workdir: - with ZipFile(pathname, 'r') as zf: - path_map = {} - for zinfo in zf.infolist(): - arcname = zinfo.filename - if isinstance(arcname, text_type): - u_arcname = arcname - else: - u_arcname = arcname.decode('utf-8') - if u_arcname == record_name: - continue - if '..' in u_arcname: - raise DistlibException('invalid entry in ' - 'wheel: %r' % u_arcname) - zf.extract(zinfo, workdir) - path = os.path.join(workdir, convert_path(u_arcname)) - path_map[u_arcname] = path - - # Remember the version. - original_version, _ = get_version(path_map, info_dir) - # Files extracted. Call the modifier. - modified = modifier(path_map, **kwargs) - if modified: - # Something changed - need to build a new wheel. - current_version, path = get_version(path_map, info_dir) - if current_version and (current_version == original_version): - # Add or update local version to signify changes. - update_version(current_version, path) - # Decide where the new wheel goes. - if dest_dir is None: - fd, newpath = tempfile.mkstemp(suffix='.whl', - prefix='wheel-update-', - dir=workdir) - os.close(fd) - else: - if not os.path.isdir(dest_dir): - raise DistlibException('Not a directory: %r' % dest_dir) - newpath = os.path.join(dest_dir, self.filename) - archive_paths = list(path_map.items()) - distinfo = os.path.join(workdir, info_dir) - info = distinfo, info_dir - self.write_records(info, workdir, archive_paths) - self.build_zip(newpath, archive_paths) - if dest_dir is None: - shutil.copyfile(newpath, pathname) - return modified - -def compatible_tags(): - """ - Return (pyver, abi, arch) tuples compatible with this Python. - """ - versions = [VER_SUFFIX] - major = VER_SUFFIX[0] - for minor in range(sys.version_info[1] - 1, - 1, -1): - versions.append(''.join([major, str(minor)])) - - abis = [] - for suffix, _, _ in imp.get_suffixes(): - if suffix.startswith('.abi'): - abis.append(suffix.split('.', 2)[1]) - abis.sort() - if ABI != 'none': - abis.insert(0, ABI) - abis.append('none') - result = [] - - arches = [ARCH] - if sys.platform == 'darwin': - m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH) - if m: - name, major, minor, arch = m.groups() - minor = int(minor) - matches = [arch] - if arch in ('i386', 'ppc'): - matches.append('fat') - if arch in ('i386', 'ppc', 'x86_64'): - matches.append('fat3') - if arch in ('ppc64', 'x86_64'): - matches.append('fat64') - if arch in ('i386', 'x86_64'): - matches.append('intel') - if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): - matches.append('universal') - while minor >= 0: - for match in matches: - s = '%s_%s_%s_%s' % (name, major, minor, match) - if s != ARCH: # already there - arches.append(s) - minor -= 1 - - # Most specific - our Python version, ABI and arch - for abi in abis: - for arch in arches: - result.append((''.join((IMP_PREFIX, versions[0])), abi, arch)) - - # where no ABI / arch dependency, but IMP_PREFIX dependency - for i, version in enumerate(versions): - result.append((''.join((IMP_PREFIX, version)), 'none', 'any')) - if i == 0: - result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any')) - - # no IMP_PREFIX, ABI or arch dependency - for i, version in enumerate(versions): - result.append((''.join(('py', version)), 'none', 'any')) - if i == 0: - result.append((''.join(('py', version[0])), 'none', 'any')) - return set(result) - - -COMPATIBLE_TAGS = compatible_tags() - -del compatible_tags - - -def is_compatible(wheel, tags=None): - if not isinstance(wheel, Wheel): - wheel = Wheel(wheel) # assume it's a filename - result = False - if tags is None: - tags = COMPATIBLE_TAGS - for ver, abi, arch in tags: - if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch: - result = True - break - return result diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distro.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distro.py deleted file mode 100644 index aa4defc..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/distro.py +++ /dev/null @@ -1,1197 +0,0 @@ -# Copyright 2015,2016,2017 Nir Cohen -# -# 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. - -""" -The ``distro`` package (``distro`` stands for Linux Distribution) provides -information about the Linux distribution it runs on, such as a reliable -machine-readable distro ID, or version information. - -It is a renewed alternative implementation for Python's original -:py:func:`platform.linux_distribution` function, but it provides much more -functionality. An alternative implementation became necessary because Python -3.5 deprecated this function, and Python 3.7 is expected to remove it -altogether. Its predecessor function :py:func:`platform.dist` was already -deprecated since Python 2.6 and is also expected to be removed in Python 3.7. -Still, there are many cases in which access to OS distribution information -is needed. See `Python issue 1322 <https://bugs.python.org/issue1322>`_ for -more information. -""" - -import os -import re -import sys -import json -import shlex -import logging -import argparse -import subprocess - - -_UNIXCONFDIR = os.environ.get('UNIXCONFDIR', '/etc') -_OS_RELEASE_BASENAME = 'os-release' - -#: Translation table for normalizing the "ID" attribute defined in os-release -#: files, for use by the :func:`distro.id` method. -#: -#: * Key: Value as defined in the os-release file, translated to lower case, -#: with blanks translated to underscores. -#: -#: * Value: Normalized value. -NORMALIZED_OS_ID = {} - -#: Translation table for normalizing the "Distributor ID" attribute returned by -#: the lsb_release command, for use by the :func:`distro.id` method. -#: -#: * Key: Value as returned by the lsb_release command, translated to lower -#: case, with blanks translated to underscores. -#: -#: * Value: Normalized value. -NORMALIZED_LSB_ID = { - 'enterpriseenterprise': 'oracle', # Oracle Enterprise Linux - 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation - 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server -} - -#: Translation table for normalizing the distro ID derived from the file name -#: of distro release files, for use by the :func:`distro.id` method. -#: -#: * Key: Value as derived from the file name of a distro release file, -#: translated to lower case, with blanks translated to underscores. -#: -#: * Value: Normalized value. -NORMALIZED_DISTRO_ID = { - 'redhat': 'rhel', # RHEL 6.x, 7.x -} - -# Pattern for content of distro release file (reversed) -_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile( - r'(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)') - -# Pattern for base file name of distro release file -_DISTRO_RELEASE_BASENAME_PATTERN = re.compile( - r'(\w+)[-_](release|version)$') - -# Base file names to be ignored when searching for distro release file -_DISTRO_RELEASE_IGNORE_BASENAMES = ( - 'debian_version', - 'lsb-release', - 'oem-release', - _OS_RELEASE_BASENAME, - 'system-release' -) - - -def linux_distribution(full_distribution_name=True): - """ - Return information about the current OS distribution as a tuple - ``(id_name, version, codename)`` with items as follows: - - * ``id_name``: If *full_distribution_name* is false, the result of - :func:`distro.id`. Otherwise, the result of :func:`distro.name`. - - * ``version``: The result of :func:`distro.version`. - - * ``codename``: The result of :func:`distro.codename`. - - The interface of this function is compatible with the original - :py:func:`platform.linux_distribution` function, supporting a subset of - its parameters. - - The data it returns may not exactly be the same, because it uses more data - sources than the original function, and that may lead to different data if - the OS distribution is not consistent across multiple data sources it - provides (there are indeed such distributions ...). - - Another reason for differences is the fact that the :func:`distro.id` - method normalizes the distro ID string to a reliable machine-readable value - for a number of popular OS distributions. - """ - return _distro.linux_distribution(full_distribution_name) - - -def id(): - """ - Return the distro ID of the current distribution, as a - machine-readable string. - - For a number of OS distributions, the returned distro ID value is - *reliable*, in the sense that it is documented and that it does not change - across releases of the distribution. - - This package maintains the following reliable distro ID values: - - ============== ========================================= - Distro ID Distribution - ============== ========================================= - "ubuntu" Ubuntu - "debian" Debian - "rhel" RedHat Enterprise Linux - "centos" CentOS - "fedora" Fedora - "sles" SUSE Linux Enterprise Server - "opensuse" openSUSE - "amazon" Amazon Linux - "arch" Arch Linux - "cloudlinux" CloudLinux OS - "exherbo" Exherbo Linux - "gentoo" GenToo Linux - "ibm_powerkvm" IBM PowerKVM - "kvmibm" KVM for IBM z Systems - "linuxmint" Linux Mint - "mageia" Mageia - "mandriva" Mandriva Linux - "parallels" Parallels - "pidora" Pidora - "raspbian" Raspbian - "oracle" Oracle Linux (and Oracle Enterprise Linux) - "scientific" Scientific Linux - "slackware" Slackware - "xenserver" XenServer - "openbsd" OpenBSD - "netbsd" NetBSD - "freebsd" FreeBSD - ============== ========================================= - - If you have a need to get distros for reliable IDs added into this set, - or if you find that the :func:`distro.id` function returns a different - distro ID for one of the listed distros, please create an issue in the - `distro issue tracker`_. - - **Lookup hierarchy and transformations:** - - First, the ID is obtained from the following sources, in the specified - order. The first available and non-empty value is used: - - * the value of the "ID" attribute of the os-release file, - - * the value of the "Distributor ID" attribute returned by the lsb_release - command, - - * the first part of the file name of the distro release file, - - The so determined ID value then passes the following transformations, - before it is returned by this method: - - * it is translated to lower case, - - * blanks (which should not be there anyway) are translated to underscores, - - * a normalization of the ID is performed, based upon - `normalization tables`_. The purpose of this normalization is to ensure - that the ID is as reliable as possible, even across incompatible changes - in the OS distributions. A common reason for an incompatible change is - the addition of an os-release file, or the addition of the lsb_release - command, with ID values that differ from what was previously determined - from the distro release file name. - """ - return _distro.id() - - -def name(pretty=False): - """ - Return the name of the current OS distribution, as a human-readable - string. - - If *pretty* is false, the name is returned without version or codename. - (e.g. "CentOS Linux") - - If *pretty* is true, the version and codename are appended. - (e.g. "CentOS Linux 7.1.1503 (Core)") - - **Lookup hierarchy:** - - The name is obtained from the following sources, in the specified order. - The first available and non-empty value is used: - - * If *pretty* is false: - - - the value of the "NAME" attribute of the os-release file, - - - the value of the "Distributor ID" attribute returned by the lsb_release - command, - - - the value of the "<name>" field of the distro release file. - - * If *pretty* is true: - - - the value of the "PRETTY_NAME" attribute of the os-release file, - - - the value of the "Description" attribute returned by the lsb_release - command, - - - the value of the "<name>" field of the distro release file, appended - with the value of the pretty version ("<version_id>" and "<codename>" - fields) of the distro release file, if available. - """ - return _distro.name(pretty) - - -def version(pretty=False, best=False): - """ - Return the version of the current OS distribution, as a human-readable - string. - - If *pretty* is false, the version is returned without codename (e.g. - "7.0"). - - If *pretty* is true, the codename in parenthesis is appended, if the - codename is non-empty (e.g. "7.0 (Maipo)"). - - Some distributions provide version numbers with different precisions in - the different sources of distribution information. Examining the different - sources in a fixed priority order does not always yield the most precise - version (e.g. for Debian 8.2, or CentOS 7.1). - - The *best* parameter can be used to control the approach for the returned - version: - - If *best* is false, the first non-empty version number in priority order of - the examined sources is returned. - - If *best* is true, the most precise version number out of all examined - sources is returned. - - **Lookup hierarchy:** - - In all cases, the version number is obtained from the following sources. - If *best* is false, this order represents the priority order: - - * the value of the "VERSION_ID" attribute of the os-release file, - * the value of the "Release" attribute returned by the lsb_release - command, - * the version number parsed from the "<version_id>" field of the first line - of the distro release file, - * the version number parsed from the "PRETTY_NAME" attribute of the - os-release file, if it follows the format of the distro release files. - * the version number parsed from the "Description" attribute returned by - the lsb_release command, if it follows the format of the distro release - files. - """ - return _distro.version(pretty, best) - - -def version_parts(best=False): - """ - Return the version of the current OS distribution as a tuple - ``(major, minor, build_number)`` with items as follows: - - * ``major``: The result of :func:`distro.major_version`. - - * ``minor``: The result of :func:`distro.minor_version`. - - * ``build_number``: The result of :func:`distro.build_number`. - - For a description of the *best* parameter, see the :func:`distro.version` - method. - """ - return _distro.version_parts(best) - - -def major_version(best=False): - """ - Return the major version of the current OS distribution, as a string, - if provided. - Otherwise, the empty string is returned. The major version is the first - part of the dot-separated version string. - - For a description of the *best* parameter, see the :func:`distro.version` - method. - """ - return _distro.major_version(best) - - -def minor_version(best=False): - """ - Return the minor version of the current OS distribution, as a string, - if provided. - Otherwise, the empty string is returned. The minor version is the second - part of the dot-separated version string. - - For a description of the *best* parameter, see the :func:`distro.version` - method. - """ - return _distro.minor_version(best) - - -def build_number(best=False): - """ - Return the build number of the current OS distribution, as a string, - if provided. - Otherwise, the empty string is returned. The build number is the third part - of the dot-separated version string. - - For a description of the *best* parameter, see the :func:`distro.version` - method. - """ - return _distro.build_number(best) - - -def like(): - """ - Return a space-separated list of distro IDs of distributions that are - closely related to the current OS distribution in regards to packaging - and programming interfaces, for example distributions the current - distribution is a derivative from. - - **Lookup hierarchy:** - - This information item is only provided by the os-release file. - For details, see the description of the "ID_LIKE" attribute in the - `os-release man page - <http://www.freedesktop.org/software/systemd/man/os-release.html>`_. - """ - return _distro.like() - - -def codename(): - """ - Return the codename for the release of the current OS distribution, - as a string. - - If the distribution does not have a codename, an empty string is returned. - - Note that the returned codename is not always really a codename. For - example, openSUSE returns "x86_64". This function does not handle such - cases in any special way and just returns the string it finds, if any. - - **Lookup hierarchy:** - - * the codename within the "VERSION" attribute of the os-release file, if - provided, - - * the value of the "Codename" attribute returned by the lsb_release - command, - - * the value of the "<codename>" field of the distro release file. - """ - return _distro.codename() - - -def info(pretty=False, best=False): - """ - Return certain machine-readable information items about the current OS - distribution in a dictionary, as shown in the following example: - - .. sourcecode:: python - - { - 'id': 'rhel', - 'version': '7.0', - 'version_parts': { - 'major': '7', - 'minor': '0', - 'build_number': '' - }, - 'like': 'fedora', - 'codename': 'Maipo' - } - - The dictionary structure and keys are always the same, regardless of which - information items are available in the underlying data sources. The values - for the various keys are as follows: - - * ``id``: The result of :func:`distro.id`. - - * ``version``: The result of :func:`distro.version`. - - * ``version_parts -> major``: The result of :func:`distro.major_version`. - - * ``version_parts -> minor``: The result of :func:`distro.minor_version`. - - * ``version_parts -> build_number``: The result of - :func:`distro.build_number`. - - * ``like``: The result of :func:`distro.like`. - - * ``codename``: The result of :func:`distro.codename`. - - For a description of the *pretty* and *best* parameters, see the - :func:`distro.version` method. - """ - return _distro.info(pretty, best) - - -def os_release_info(): - """ - Return a dictionary containing key-value pairs for the information items - from the os-release file data source of the current OS distribution. - - See `os-release file`_ for details about these information items. - """ - return _distro.os_release_info() - - -def lsb_release_info(): - """ - Return a dictionary containing key-value pairs for the information items - from the lsb_release command data source of the current OS distribution. - - See `lsb_release command output`_ for details about these information - items. - """ - return _distro.lsb_release_info() - - -def distro_release_info(): - """ - Return a dictionary containing key-value pairs for the information items - from the distro release file data source of the current OS distribution. - - See `distro release file`_ for details about these information items. - """ - return _distro.distro_release_info() - - -def uname_info(): - """ - Return a dictionary containing key-value pairs for the information items - from the distro release file data source of the current OS distribution. - """ - return _distro.uname_info() - - -def os_release_attr(attribute): - """ - Return a single named information item from the os-release file data source - of the current OS distribution. - - Parameters: - - * ``attribute`` (string): Key of the information item. - - Returns: - - * (string): Value of the information item, if the item exists. - The empty string, if the item does not exist. - - See `os-release file`_ for details about these information items. - """ - return _distro.os_release_attr(attribute) - - -def lsb_release_attr(attribute): - """ - Return a single named information item from the lsb_release command output - data source of the current OS distribution. - - Parameters: - - * ``attribute`` (string): Key of the information item. - - Returns: - - * (string): Value of the information item, if the item exists. - The empty string, if the item does not exist. - - See `lsb_release command output`_ for details about these information - items. - """ - return _distro.lsb_release_attr(attribute) - - -def distro_release_attr(attribute): - """ - Return a single named information item from the distro release file - data source of the current OS distribution. - - Parameters: - - * ``attribute`` (string): Key of the information item. - - Returns: - - * (string): Value of the information item, if the item exists. - The empty string, if the item does not exist. - - See `distro release file`_ for details about these information items. - """ - return _distro.distro_release_attr(attribute) - - -def uname_attr(attribute): - """ - Return a single named information item from the distro release file - data source of the current OS distribution. - - Parameters: - - * ``attribute`` (string): Key of the information item. - - Returns: - - * (string): Value of the information item, if the item exists. - The empty string, if the item does not exist. - """ - return _distro.uname_attr(attribute) - - -class cached_property(object): - """A version of @property which caches the value. On access, it calls the - underlying function and sets the value in `__dict__` so future accesses - will not re-call the property. - """ - def __init__(self, f): - self._fname = f.__name__ - self._f = f - - def __get__(self, obj, owner): - assert obj is not None, 'call {} on an instance'.format(self._fname) - ret = obj.__dict__[self._fname] = self._f(obj) - return ret - - -class LinuxDistribution(object): - """ - Provides information about a OS distribution. - - This package creates a private module-global instance of this class with - default initialization arguments, that is used by the - `consolidated accessor functions`_ and `single source accessor functions`_. - By using default initialization arguments, that module-global instance - returns data about the current OS distribution (i.e. the distro this - package runs on). - - Normally, it is not necessary to create additional instances of this class. - However, in situations where control is needed over the exact data sources - that are used, instances of this class can be created with a specific - distro release file, or a specific os-release file, or without invoking the - lsb_release command. - """ - - def __init__(self, - include_lsb=True, - os_release_file='', - distro_release_file='', - include_uname=True): - """ - The initialization method of this class gathers information from the - available data sources, and stores that in private instance attributes. - Subsequent access to the information items uses these private instance - attributes, so that the data sources are read only once. - - Parameters: - - * ``include_lsb`` (bool): Controls whether the - `lsb_release command output`_ is included as a data source. - - If the lsb_release command is not available in the program execution - path, the data source for the lsb_release command will be empty. - - * ``os_release_file`` (string): The path name of the - `os-release file`_ that is to be used as a data source. - - An empty string (the default) will cause the default path name to - be used (see `os-release file`_ for details). - - If the specified or defaulted os-release file does not exist, the - data source for the os-release file will be empty. - - * ``distro_release_file`` (string): The path name of the - `distro release file`_ that is to be used as a data source. - - An empty string (the default) will cause a default search algorithm - to be used (see `distro release file`_ for details). - - If the specified distro release file does not exist, or if no default - distro release file can be found, the data source for the distro - release file will be empty. - - * ``include_name`` (bool): Controls whether uname command output is - included as a data source. If the uname command is not available in - the program execution path the data source for the uname command will - be empty. - - Public instance attributes: - - * ``os_release_file`` (string): The path name of the - `os-release file`_ that is actually used as a data source. The - empty string if no distro release file is used as a data source. - - * ``distro_release_file`` (string): The path name of the - `distro release file`_ that is actually used as a data source. The - empty string if no distro release file is used as a data source. - - * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. - This controls whether the lsb information will be loaded. - - * ``include_uname`` (bool): The result of the ``include_uname`` - parameter. This controls whether the uname information will - be loaded. - - Raises: - - * :py:exc:`IOError`: Some I/O issue with an os-release file or distro - release file. - - * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had - some issue (other than not being available in the program execution - path). - - * :py:exc:`UnicodeError`: A data source has unexpected characters or - uses an unexpected encoding. - """ - self.os_release_file = os_release_file or \ - os.path.join(_UNIXCONFDIR, _OS_RELEASE_BASENAME) - self.distro_release_file = distro_release_file or '' # updated later - self.include_lsb = include_lsb - self.include_uname = include_uname - - def __repr__(self): - """Return repr of all info - """ - return \ - "LinuxDistribution(" \ - "os_release_file={self.os_release_file!r}, " \ - "distro_release_file={self.distro_release_file!r}, " \ - "include_lsb={self.include_lsb!r}, " \ - "include_uname={self.include_uname!r}, " \ - "_os_release_info={self._os_release_info!r}, " \ - "_lsb_release_info={self._lsb_release_info!r}, " \ - "_distro_release_info={self._distro_release_info!r}, " \ - "_uname_info={self._uname_info!r})".format( - self=self) - - def linux_distribution(self, full_distribution_name=True): - """ - Return information about the OS distribution that is compatible - with Python's :func:`platform.linux_distribution`, supporting a subset - of its parameters. - - For details, see :func:`distro.linux_distribution`. - """ - return ( - self.name() if full_distribution_name else self.id(), - self.version(), - self.codename() - ) - - def id(self): - """Return the distro ID of the OS distribution, as a string. - - For details, see :func:`distro.id`. - """ - def normalize(distro_id, table): - distro_id = distro_id.lower().replace(' ', '_') - return table.get(distro_id, distro_id) - - distro_id = self.os_release_attr('id') - if distro_id: - return normalize(distro_id, NORMALIZED_OS_ID) - - distro_id = self.lsb_release_attr('distributor_id') - if distro_id: - return normalize(distro_id, NORMALIZED_LSB_ID) - - distro_id = self.distro_release_attr('id') - if distro_id: - return normalize(distro_id, NORMALIZED_DISTRO_ID) - - distro_id = self.uname_attr('id') - if distro_id: - return normalize(distro_id, NORMALIZED_DISTRO_ID) - - return '' - - def name(self, pretty=False): - """ - Return the name of the OS distribution, as a string. - - For details, see :func:`distro.name`. - """ - name = self.os_release_attr('name') \ - or self.lsb_release_attr('distributor_id') \ - or self.distro_release_attr('name') \ - or self.uname_attr('name') - if pretty: - name = self.os_release_attr('pretty_name') \ - or self.lsb_release_attr('description') - if not name: - name = self.distro_release_attr('name') \ - or self.uname_attr('name') - version = self.version(pretty=True) - if version: - name = name + ' ' + version - return name or '' - - def version(self, pretty=False, best=False): - """ - Return the version of the OS distribution, as a string. - - For details, see :func:`distro.version`. - """ - versions = [ - self.os_release_attr('version_id'), - self.lsb_release_attr('release'), - self.distro_release_attr('version_id'), - self._parse_distro_release_content( - self.os_release_attr('pretty_name')).get('version_id', ''), - self._parse_distro_release_content( - self.lsb_release_attr('description')).get('version_id', ''), - self.uname_attr('release') - ] - version = '' - if best: - # This algorithm uses the last version in priority order that has - # the best precision. If the versions are not in conflict, that - # does not matter; otherwise, using the last one instead of the - # first one might be considered a surprise. - for v in versions: - if v.count(".") > version.count(".") or version == '': - version = v - else: - for v in versions: - if v != '': - version = v - break - if pretty and version and self.codename(): - version = u'{0} ({1})'.format(version, self.codename()) - return version - - def version_parts(self, best=False): - """ - Return the version of the OS distribution, as a tuple of version - numbers. - - For details, see :func:`distro.version_parts`. - """ - version_str = self.version(best=best) - if version_str: - version_regex = re.compile(r'(\d+)\.?(\d+)?\.?(\d+)?') - matches = version_regex.match(version_str) - if matches: - major, minor, build_number = matches.groups() - return major, minor or '', build_number or '' - return '', '', '' - - def major_version(self, best=False): - """ - Return the major version number of the current distribution. - - For details, see :func:`distro.major_version`. - """ - return self.version_parts(best)[0] - - def minor_version(self, best=False): - """ - Return the minor version number of the current distribution. - - For details, see :func:`distro.minor_version`. - """ - return self.version_parts(best)[1] - - def build_number(self, best=False): - """ - Return the build number of the current distribution. - - For details, see :func:`distro.build_number`. - """ - return self.version_parts(best)[2] - - def like(self): - """ - Return the IDs of distributions that are like the OS distribution. - - For details, see :func:`distro.like`. - """ - return self.os_release_attr('id_like') or '' - - def codename(self): - """ - Return the codename of the OS distribution. - - For details, see :func:`distro.codename`. - """ - return self.os_release_attr('codename') \ - or self.lsb_release_attr('codename') \ - or self.distro_release_attr('codename') \ - or '' - - def info(self, pretty=False, best=False): - """ - Return certain machine-readable information about the OS - distribution. - - For details, see :func:`distro.info`. - """ - return dict( - id=self.id(), - version=self.version(pretty, best), - version_parts=dict( - major=self.major_version(best), - minor=self.minor_version(best), - build_number=self.build_number(best) - ), - like=self.like(), - codename=self.codename(), - ) - - def os_release_info(self): - """ - Return a dictionary containing key-value pairs for the information - items from the os-release file data source of the OS distribution. - - For details, see :func:`distro.os_release_info`. - """ - return self._os_release_info - - def lsb_release_info(self): - """ - Return a dictionary containing key-value pairs for the information - items from the lsb_release command data source of the OS - distribution. - - For details, see :func:`distro.lsb_release_info`. - """ - return self._lsb_release_info - - def distro_release_info(self): - """ - Return a dictionary containing key-value pairs for the information - items from the distro release file data source of the OS - distribution. - - For details, see :func:`distro.distro_release_info`. - """ - return self._distro_release_info - - def uname_info(self): - """ - Return a dictionary containing key-value pairs for the information - items from the uname command data source of the OS distribution. - - For details, see :func:`distro.uname_info`. - """ - - def os_release_attr(self, attribute): - """ - Return a single named information item from the os-release file data - source of the OS distribution. - - For details, see :func:`distro.os_release_attr`. - """ - return self._os_release_info.get(attribute, '') - - def lsb_release_attr(self, attribute): - """ - Return a single named information item from the lsb_release command - output data source of the OS distribution. - - For details, see :func:`distro.lsb_release_attr`. - """ - return self._lsb_release_info.get(attribute, '') - - def distro_release_attr(self, attribute): - """ - Return a single named information item from the distro release file - data source of the OS distribution. - - For details, see :func:`distro.distro_release_attr`. - """ - return self._distro_release_info.get(attribute, '') - - def uname_attr(self, attribute): - """ - Return a single named information item from the uname command - output data source of the OS distribution. - - For details, see :func:`distro.uname_release_attr`. - """ - return self._uname_info.get(attribute, '') - - @cached_property - def _os_release_info(self): - """ - Get the information items from the specified os-release file. - - Returns: - A dictionary containing all information items. - """ - if os.path.isfile(self.os_release_file): - with open(self.os_release_file) as release_file: - return self._parse_os_release_content(release_file) - return {} - - @staticmethod - def _parse_os_release_content(lines): - """ - Parse the lines of an os-release file. - - Parameters: - - * lines: Iterable through the lines in the os-release file. - Each line must be a unicode string or a UTF-8 encoded byte - string. - - Returns: - A dictionary containing all information items. - """ - props = {} - lexer = shlex.shlex(lines, posix=True) - lexer.whitespace_split = True - - # The shlex module defines its `wordchars` variable using literals, - # making it dependent on the encoding of the Python source file. - # In Python 2.6 and 2.7, the shlex source file is encoded in - # 'iso-8859-1', and the `wordchars` variable is defined as a byte - # string. This causes a UnicodeDecodeError to be raised when the - # parsed content is a unicode object. The following fix resolves that - # (... but it should be fixed in shlex...): - if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes): - lexer.wordchars = lexer.wordchars.decode('iso-8859-1') - - tokens = list(lexer) - for token in tokens: - # At this point, all shell-like parsing has been done (i.e. - # comments processed, quotes and backslash escape sequences - # processed, multi-line values assembled, trailing newlines - # stripped, etc.), so the tokens are now either: - # * variable assignments: var=value - # * commands or their arguments (not allowed in os-release) - if '=' in token: - k, v = token.split('=', 1) - if isinstance(v, bytes): - v = v.decode('utf-8') - props[k.lower()] = v - if k == 'VERSION': - # this handles cases in which the codename is in - # the `(CODENAME)` (rhel, centos, fedora) format - # or in the `, CODENAME` format (Ubuntu). - codename = re.search(r'(\(\D+\))|,(\s+)?\D+', v) - if codename: - codename = codename.group() - codename = codename.strip('()') - codename = codename.strip(',') - codename = codename.strip() - # codename appears within paranthese. - props['codename'] = codename - else: - props['codename'] = '' - else: - # Ignore any tokens that are not variable assignments - pass - return props - - @cached_property - def _lsb_release_info(self): - """ - Get the information items from the lsb_release command output. - - Returns: - A dictionary containing all information items. - """ - if not self.include_lsb: - return {} - with open(os.devnull, 'w') as devnull: - try: - cmd = ('lsb_release', '-a') - stdout = subprocess.check_output(cmd, stderr=devnull) - except OSError: # Command not found - return {} - content = stdout.decode(sys.getfilesystemencoding()).splitlines() - return self._parse_lsb_release_content(content) - - @staticmethod - def _parse_lsb_release_content(lines): - """ - Parse the output of the lsb_release command. - - Parameters: - - * lines: Iterable through the lines of the lsb_release output. - Each line must be a unicode string or a UTF-8 encoded byte - string. - - Returns: - A dictionary containing all information items. - """ - props = {} - for line in lines: - kv = line.strip('\n').split(':', 1) - if len(kv) != 2: - # Ignore lines without colon. - continue - k, v = kv - props.update({k.replace(' ', '_').lower(): v.strip()}) - return props - - @cached_property - def _uname_info(self): - with open(os.devnull, 'w') as devnull: - try: - cmd = ('uname', '-rs') - stdout = subprocess.check_output(cmd, stderr=devnull) - except OSError: - return {} - content = stdout.decode(sys.getfilesystemencoding()).splitlines() - return self._parse_uname_content(content) - - @staticmethod - def _parse_uname_content(lines): - props = {} - match = re.search(r'^([^\s]+)\s+([\d\.]+)', lines[0].strip()) - if match: - name, version = match.groups() - - # This is to prevent the Linux kernel version from - # appearing as the 'best' version on otherwise - # identifiable distributions. - if name == 'Linux': - return {} - props['id'] = name.lower() - props['name'] = name - props['release'] = version - return props - - @cached_property - def _distro_release_info(self): - """ - Get the information items from the specified distro release file. - - Returns: - A dictionary containing all information items. - """ - if self.distro_release_file: - # If it was specified, we use it and parse what we can, even if - # its file name or content does not match the expected pattern. - distro_info = self._parse_distro_release_file( - self.distro_release_file) - basename = os.path.basename(self.distro_release_file) - # The file name pattern for user-specified distro release files - # is somewhat more tolerant (compared to when searching for the - # file), because we want to use what was specified as best as - # possible. - match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) - if match: - distro_info['id'] = match.group(1) - return distro_info - else: - try: - basenames = os.listdir(_UNIXCONFDIR) - # We sort for repeatability in cases where there are multiple - # distro specific files; e.g. CentOS, Oracle, Enterprise all - # containing `redhat-release` on top of their own. - basenames.sort() - except OSError: - # This may occur when /etc is not readable but we can't be - # sure about the *-release files. Check common entries of - # /etc for information. If they turn out to not be there the - # error is handled in `_parse_distro_release_file()`. - basenames = ['SuSE-release', - 'arch-release', - 'base-release', - 'centos-release', - 'fedora-release', - 'gentoo-release', - 'mageia-release', - 'mandrake-release', - 'mandriva-release', - 'mandrivalinux-release', - 'manjaro-release', - 'oracle-release', - 'redhat-release', - 'sl-release', - 'slackware-version'] - for basename in basenames: - if basename in _DISTRO_RELEASE_IGNORE_BASENAMES: - continue - match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) - if match: - filepath = os.path.join(_UNIXCONFDIR, basename) - distro_info = self._parse_distro_release_file(filepath) - if 'name' in distro_info: - # The name is always present if the pattern matches - self.distro_release_file = filepath - distro_info['id'] = match.group(1) - return distro_info - return {} - - def _parse_distro_release_file(self, filepath): - """ - Parse a distro release file. - - Parameters: - - * filepath: Path name of the distro release file. - - Returns: - A dictionary containing all information items. - """ - try: - with open(filepath) as fp: - # Only parse the first line. For instance, on SLES there - # are multiple lines. We don't want them... - return self._parse_distro_release_content(fp.readline()) - except (OSError, IOError): - # Ignore not being able to read a specific, seemingly version - # related file. - # See https://github.com/nir0s/distro/issues/162 - return {} - - @staticmethod - def _parse_distro_release_content(line): - """ - Parse a line from a distro release file. - - Parameters: - * line: Line from the distro release file. Must be a unicode string - or a UTF-8 encoded byte string. - - Returns: - A dictionary containing all information items. - """ - if isinstance(line, bytes): - line = line.decode('utf-8') - matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( - line.strip()[::-1]) - distro_info = {} - if matches: - # regexp ensures non-None - distro_info['name'] = matches.group(3)[::-1] - if matches.group(2): - distro_info['version_id'] = matches.group(2)[::-1] - if matches.group(1): - distro_info['codename'] = matches.group(1)[::-1] - elif line: - distro_info['name'] = line.strip() - return distro_info - - -_distro = LinuxDistribution() - - -def main(): - logger = logging.getLogger(__name__) - logger.setLevel(logging.DEBUG) - logger.addHandler(logging.StreamHandler(sys.stdout)) - - parser = argparse.ArgumentParser(description="OS distro info tool") - parser.add_argument( - '--json', - '-j', - help="Output in machine readable format", - action="store_true") - args = parser.parse_args() - - if args.json: - logger.info(json.dumps(info(), indent=4, sort_keys=True)) - else: - logger.info('Name: %s', name(pretty=True)) - distribution_version = version(pretty=True) - logger.info('Version: %s', distribution_version) - distribution_codename = codename() - logger.info('Codename: %s', distribution_codename) - - -if __name__ == '__main__': - main() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/__init__.py deleted file mode 100644 index 0491234..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/__init__.py +++ /dev/null @@ -1,35 +0,0 @@ -""" -HTML parsing library based on the `WHATWG HTML specification -<https://whatwg.org/html>`_. The parser is designed to be compatible with -existing HTML found in the wild and implements well-defined error recovery that -is largely compatible with modern desktop web browsers. - -Example usage:: - - from pip._vendor import html5lib - with open("my_document.html", "rb") as f: - tree = html5lib.parse(f) - -For convenience, this module re-exports the following names: - -* :func:`~.html5parser.parse` -* :func:`~.html5parser.parseFragment` -* :class:`~.html5parser.HTMLParser` -* :func:`~.treebuilders.getTreeBuilder` -* :func:`~.treewalkers.getTreeWalker` -* :func:`~.serializer.serialize` -""" - -from __future__ import absolute_import, division, unicode_literals - -from .html5parser import HTMLParser, parse, parseFragment -from .treebuilders import getTreeBuilder -from .treewalkers import getTreeWalker -from .serializer import serialize - -__all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", - "getTreeWalker", "serialize"] - -# this has to be at the top level, see how setup.py parses this -#: Distribution version number. -__version__ = "1.0.1" diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_ihatexml.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_ihatexml.py deleted file mode 100644 index 4c77717..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_ihatexml.py +++ /dev/null @@ -1,288 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -import re -import warnings - -from .constants import DataLossWarning - -baseChar = """ -[#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | -[#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | -[#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | -[#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | -[#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | -[#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | -[#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | -[#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | -[#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | -[#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | -[#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | -[#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | -[#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | -[#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | -[#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | -[#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | -[#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | -[#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | -[#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | -[#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | -[#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | -[#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | -[#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | -[#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | -[#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | -[#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | -[#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | -[#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | -[#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | -[#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | -#x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | -#x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | -#x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | -[#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | -[#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | -#x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | -[#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | -[#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | -[#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | -[#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | -[#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | -#x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | -[#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | -[#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | -[#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | -[#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]""" - -ideographic = """[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]""" - -combiningCharacter = """ -[#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | -[#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | -[#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | -[#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | -#x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | -[#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | -[#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | -#x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | -[#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | -[#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | -#x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | -[#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | -[#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | -[#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | -[#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | -[#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | -#x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | -[#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | -#x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | -[#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | -[#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | -#x3099 | #x309A""" - -digit = """ -[#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | -[#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | -[#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | -[#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]""" - -extender = """ -#x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | -#[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE]""" - -letter = " | ".join([baseChar, ideographic]) - -# Without the -name = " | ".join([letter, digit, ".", "-", "_", combiningCharacter, - extender]) -nameFirst = " | ".join([letter, "_"]) - -reChar = re.compile(r"#x([\d|A-F]{4,4})") -reCharRange = re.compile(r"\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]") - - -def charStringToList(chars): - charRanges = [item.strip() for item in chars.split(" | ")] - rv = [] - for item in charRanges: - foundMatch = False - for regexp in (reChar, reCharRange): - match = regexp.match(item) - if match is not None: - rv.append([hexToInt(item) for item in match.groups()]) - if len(rv[-1]) == 1: - rv[-1] = rv[-1] * 2 - foundMatch = True - break - if not foundMatch: - assert len(item) == 1 - - rv.append([ord(item)] * 2) - rv = normaliseCharList(rv) - return rv - - -def normaliseCharList(charList): - charList = sorted(charList) - for item in charList: - assert item[1] >= item[0] - rv = [] - i = 0 - while i < len(charList): - j = 1 - rv.append(charList[i]) - while i + j < len(charList) and charList[i + j][0] <= rv[-1][1] + 1: - rv[-1][1] = charList[i + j][1] - j += 1 - i += j - return rv - -# We don't really support characters above the BMP :( -max_unicode = int("FFFF", 16) - - -def missingRanges(charList): - rv = [] - if charList[0] != 0: - rv.append([0, charList[0][0] - 1]) - for i, item in enumerate(charList[:-1]): - rv.append([item[1] + 1, charList[i + 1][0] - 1]) - if charList[-1][1] != max_unicode: - rv.append([charList[-1][1] + 1, max_unicode]) - return rv - - -def listToRegexpStr(charList): - rv = [] - for item in charList: - if item[0] == item[1]: - rv.append(escapeRegexp(chr(item[0]))) - else: - rv.append(escapeRegexp(chr(item[0])) + "-" + - escapeRegexp(chr(item[1]))) - return "[%s]" % "".join(rv) - - -def hexToInt(hex_str): - return int(hex_str, 16) - - -def escapeRegexp(string): - specialCharacters = (".", "^", "$", "*", "+", "?", "{", "}", - "[", "]", "|", "(", ")", "-") - for char in specialCharacters: - string = string.replace(char, "\\" + char) - - return string - -# output from the above -nonXmlNameBMPRegexp = re.compile('[\x00-,/:-@\\[-\\^`\\{-\xb6\xb8-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u02cf\u02d2-\u02ff\u0346-\u035f\u0362-\u0385\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482\u0487-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u0590\u05a2\u05ba\u05be\u05c0\u05c3\u05c5-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u063f\u0653-\u065f\u066a-\u066f\u06b8-\u06b9\u06bf\u06cf\u06d4\u06e9\u06ee-\u06ef\u06fa-\u0900\u0904\u093a-\u093b\u094e-\u0950\u0955-\u0957\u0964-\u0965\u0970-\u0980\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09bd\u09c5-\u09c6\u09c9-\u09ca\u09ce-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09f2-\u0a01\u0a03-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a58\u0a5d\u0a5f-\u0a65\u0a75-\u0a80\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0adf\u0ae1-\u0ae5\u0af0-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3b\u0b44-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b62-\u0b65\u0b70-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bd6\u0bd8-\u0be6\u0bf0-\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c3d\u0c45\u0c49\u0c4e-\u0c54\u0c57-\u0c5f\u0c62-\u0c65\u0c70-\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbd\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce2-\u0ce5\u0cf0-\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d3d\u0d44-\u0d45\u0d49\u0d4e-\u0d56\u0d58-\u0d5f\u0d62-\u0d65\u0d70-\u0e00\u0e2f\u0e3b-\u0e3f\u0e4f\u0e5a-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0f17\u0f1a-\u0f1f\u0f2a-\u0f34\u0f36\u0f38\u0f3a-\u0f3d\u0f48\u0f6a-\u0f70\u0f85\u0f8c-\u0f8f\u0f96\u0f98\u0fae-\u0fb0\u0fb8\u0fba-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u20cf\u20dd-\u20e0\u20e2-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3004\u3006\u3008-\u3020\u3030\u3036-\u3040\u3095-\u3098\u309b-\u309c\u309f-\u30a0\u30fb\u30ff-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa - -nonXmlNameFirstBMPRegexp = re.compile('[\x00-@\\[-\\^`\\{-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u0385\u0387\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u0640\u064b-\u0670\u06b8-\u06b9\u06bf\u06cf\u06d4\u06d6-\u06e4\u06e7-\u0904\u093a-\u093c\u093e-\u0957\u0962-\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09db\u09de\u09e2-\u09ef\u09f2-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a58\u0a5d\u0a5f-\u0a71\u0a75-\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abc\u0abe-\u0adf\u0ae1-\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3c\u0b3e-\u0b5b\u0b5e\u0b62-\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c5f\u0c62-\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cdd\u0cdf\u0ce2-\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d5f\u0d62-\u0e00\u0e2f\u0e31\u0e34-\u0e3f\u0e46-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eb1\u0eb4-\u0ebc\u0ebe-\u0ebf\u0ec5-\u0f3f\u0f48\u0f6a-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3006\u3008-\u3020\u302a-\u3040\u3095-\u30a0\u30fb-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa - -# Simpler things -nonPubidCharRegexp = re.compile("[^\x20\x0D\x0Aa-zA-Z0-9\\-'()+,./:=?;!*#@$_%]") - - -class InfosetFilter(object): - replacementRegexp = re.compile(r"U[\dA-F]{5,5}") - - def __init__(self, - dropXmlnsLocalName=False, - dropXmlnsAttrNs=False, - preventDoubleDashComments=False, - preventDashAtCommentEnd=False, - replaceFormFeedCharacters=True, - preventSingleQuotePubid=False): - - self.dropXmlnsLocalName = dropXmlnsLocalName - self.dropXmlnsAttrNs = dropXmlnsAttrNs - - self.preventDoubleDashComments = preventDoubleDashComments - self.preventDashAtCommentEnd = preventDashAtCommentEnd - - self.replaceFormFeedCharacters = replaceFormFeedCharacters - - self.preventSingleQuotePubid = preventSingleQuotePubid - - self.replaceCache = {} - - def coerceAttribute(self, name, namespace=None): - if self.dropXmlnsLocalName and name.startswith("xmlns:"): - warnings.warn("Attributes cannot begin with xmlns", DataLossWarning) - return None - elif (self.dropXmlnsAttrNs and - namespace == "http://www.w3.org/2000/xmlns/"): - warnings.warn("Attributes cannot be in the xml namespace", DataLossWarning) - return None - else: - return self.toXmlName(name) - - def coerceElement(self, name): - return self.toXmlName(name) - - def coerceComment(self, data): - if self.preventDoubleDashComments: - while "--" in data: - warnings.warn("Comments cannot contain adjacent dashes", DataLossWarning) - data = data.replace("--", "- -") - if data.endswith("-"): - warnings.warn("Comments cannot end in a dash", DataLossWarning) - data += " " - return data - - def coerceCharacters(self, data): - if self.replaceFormFeedCharacters: - for _ in range(data.count("\x0C")): - warnings.warn("Text cannot contain U+000C", DataLossWarning) - data = data.replace("\x0C", " ") - # Other non-xml characters - return data - - def coercePubid(self, data): - dataOutput = data - for char in nonPubidCharRegexp.findall(data): - warnings.warn("Coercing non-XML pubid", DataLossWarning) - replacement = self.getReplacementCharacter(char) - dataOutput = dataOutput.replace(char, replacement) - if self.preventSingleQuotePubid and dataOutput.find("'") >= 0: - warnings.warn("Pubid cannot contain single quote", DataLossWarning) - dataOutput = dataOutput.replace("'", self.getReplacementCharacter("'")) - return dataOutput - - def toXmlName(self, name): - nameFirst = name[0] - nameRest = name[1:] - m = nonXmlNameFirstBMPRegexp.match(nameFirst) - if m: - warnings.warn("Coercing non-XML name", DataLossWarning) - nameFirstOutput = self.getReplacementCharacter(nameFirst) - else: - nameFirstOutput = nameFirst - - nameRestOutput = nameRest - replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) - for char in replaceChars: - warnings.warn("Coercing non-XML name", DataLossWarning) - replacement = self.getReplacementCharacter(char) - nameRestOutput = nameRestOutput.replace(char, replacement) - return nameFirstOutput + nameRestOutput - - def getReplacementCharacter(self, char): - if char in self.replaceCache: - replacement = self.replaceCache[char] - else: - replacement = self.escapeChar(char) - return replacement - - def fromXmlName(self, name): - for item in set(self.replacementRegexp.findall(name)): - name = name.replace(item, self.unescapeChar(item)) - return name - - def escapeChar(self, char): - replacement = "U%05X" % ord(char) - self.replaceCache[char] = replacement - return replacement - - def unescapeChar(self, charcode): - return chr(int(charcode[1:], 16)) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_inputstream.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_inputstream.py deleted file mode 100644 index a65e55f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_inputstream.py +++ /dev/null @@ -1,923 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from pip._vendor.six import text_type, binary_type -from pip._vendor.six.moves import http_client, urllib - -import codecs -import re - -from pip._vendor import webencodings - -from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase -from .constants import _ReparseException -from . import _utils - -from io import StringIO - -try: - from io import BytesIO -except ImportError: - BytesIO = StringIO - -# Non-unicode versions of constants for use in the pre-parser -spaceCharactersBytes = frozenset([item.encode("ascii") for item in spaceCharacters]) -asciiLettersBytes = frozenset([item.encode("ascii") for item in asciiLetters]) -asciiUppercaseBytes = frozenset([item.encode("ascii") for item in asciiUppercase]) -spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"]) - - -invalid_unicode_no_surrogate = "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" # noqa - -if _utils.supports_lone_surrogates: - # Use one extra step of indirection and create surrogates with - # eval. Not using this indirection would introduce an illegal - # unicode literal on platforms not supporting such lone - # surrogates. - assert invalid_unicode_no_surrogate[-1] == "]" and invalid_unicode_no_surrogate.count("]") == 1 - invalid_unicode_re = re.compile(invalid_unicode_no_surrogate[:-1] + - eval('"\\uD800-\\uDFFF"') + # pylint:disable=eval-used - "]") -else: - invalid_unicode_re = re.compile(invalid_unicode_no_surrogate) - -non_bmp_invalid_codepoints = set([0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, - 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, - 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, - 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, - 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, - 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, - 0x10FFFE, 0x10FFFF]) - -ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") - -# Cache for charsUntil() -charsUntilRegEx = {} - - -class BufferedStream(object): - """Buffering for streams that do not have buffering of their own - - The buffer is implemented as a list of chunks on the assumption that - joining many strings will be slow since it is O(n**2) - """ - - def __init__(self, stream): - self.stream = stream - self.buffer = [] - self.position = [-1, 0] # chunk number, offset - - def tell(self): - pos = 0 - for chunk in self.buffer[:self.position[0]]: - pos += len(chunk) - pos += self.position[1] - return pos - - def seek(self, pos): - assert pos <= self._bufferedBytes() - offset = pos - i = 0 - while len(self.buffer[i]) < offset: - offset -= len(self.buffer[i]) - i += 1 - self.position = [i, offset] - - def read(self, bytes): - if not self.buffer: - return self._readStream(bytes) - elif (self.position[0] == len(self.buffer) and - self.position[1] == len(self.buffer[-1])): - return self._readStream(bytes) - else: - return self._readFromBuffer(bytes) - - def _bufferedBytes(self): - return sum([len(item) for item in self.buffer]) - - def _readStream(self, bytes): - data = self.stream.read(bytes) - self.buffer.append(data) - self.position[0] += 1 - self.position[1] = len(data) - return data - - def _readFromBuffer(self, bytes): - remainingBytes = bytes - rv = [] - bufferIndex = self.position[0] - bufferOffset = self.position[1] - while bufferIndex < len(self.buffer) and remainingBytes != 0: - assert remainingBytes > 0 - bufferedData = self.buffer[bufferIndex] - - if remainingBytes <= len(bufferedData) - bufferOffset: - bytesToRead = remainingBytes - self.position = [bufferIndex, bufferOffset + bytesToRead] - else: - bytesToRead = len(bufferedData) - bufferOffset - self.position = [bufferIndex, len(bufferedData)] - bufferIndex += 1 - rv.append(bufferedData[bufferOffset:bufferOffset + bytesToRead]) - remainingBytes -= bytesToRead - - bufferOffset = 0 - - if remainingBytes: - rv.append(self._readStream(remainingBytes)) - - return b"".join(rv) - - -def HTMLInputStream(source, **kwargs): - # Work around Python bug #20007: read(0) closes the connection. - # http://bugs.python.org/issue20007 - if (isinstance(source, http_client.HTTPResponse) or - # Also check for addinfourl wrapping HTTPResponse - (isinstance(source, urllib.response.addbase) and - isinstance(source.fp, http_client.HTTPResponse))): - isUnicode = False - elif hasattr(source, "read"): - isUnicode = isinstance(source.read(0), text_type) - else: - isUnicode = isinstance(source, text_type) - - if isUnicode: - encodings = [x for x in kwargs if x.endswith("_encoding")] - if encodings: - raise TypeError("Cannot set an encoding with a unicode input, set %r" % encodings) - - return HTMLUnicodeInputStream(source, **kwargs) - else: - return HTMLBinaryInputStream(source, **kwargs) - - -class HTMLUnicodeInputStream(object): - """Provides a unicode stream of characters to the HTMLTokenizer. - - This class takes care of character encoding and removing or replacing - incorrect byte-sequences and also provides column and line tracking. - - """ - - _defaultChunkSize = 10240 - - def __init__(self, source): - """Initialises the HTMLInputStream. - - HTMLInputStream(source, [encoding]) -> Normalized stream from source - for use by html5lib. - - source can be either a file-object, local filename or a string. - - The optional encoding parameter must be a string that indicates - the encoding. If specified, that encoding will be used, - regardless of any BOM or later declaration (such as in a meta - element) - - """ - - if not _utils.supports_lone_surrogates: - # Such platforms will have already checked for such - # surrogate errors, so no need to do this checking. - self.reportCharacterErrors = None - elif len("\U0010FFFF") == 1: - self.reportCharacterErrors = self.characterErrorsUCS4 - else: - self.reportCharacterErrors = self.characterErrorsUCS2 - - # List of where new lines occur - self.newLines = [0] - - self.charEncoding = (lookupEncoding("utf-8"), "certain") - self.dataStream = self.openStream(source) - - self.reset() - - def reset(self): - self.chunk = "" - self.chunkSize = 0 - self.chunkOffset = 0 - self.errors = [] - - # number of (complete) lines in previous chunks - self.prevNumLines = 0 - # number of columns in the last line of the previous chunk - self.prevNumCols = 0 - - # Deal with CR LF and surrogates split over chunk boundaries - self._bufferedCharacter = None - - def openStream(self, source): - """Produces a file object from source. - - source can be either a file object, local filename or a string. - - """ - # Already a file object - if hasattr(source, 'read'): - stream = source - else: - stream = StringIO(source) - - return stream - - def _position(self, offset): - chunk = self.chunk - nLines = chunk.count('\n', 0, offset) - positionLine = self.prevNumLines + nLines - lastLinePos = chunk.rfind('\n', 0, offset) - if lastLinePos == -1: - positionColumn = self.prevNumCols + offset - else: - positionColumn = offset - (lastLinePos + 1) - return (positionLine, positionColumn) - - def position(self): - """Returns (line, col) of the current position in the stream.""" - line, col = self._position(self.chunkOffset) - return (line + 1, col) - - def char(self): - """ Read one character from the stream or queue if available. Return - EOF when EOF is reached. - """ - # Read a new chunk from the input stream if necessary - if self.chunkOffset >= self.chunkSize: - if not self.readChunk(): - return EOF - - chunkOffset = self.chunkOffset - char = self.chunk[chunkOffset] - self.chunkOffset = chunkOffset + 1 - - return char - - def readChunk(self, chunkSize=None): - if chunkSize is None: - chunkSize = self._defaultChunkSize - - self.prevNumLines, self.prevNumCols = self._position(self.chunkSize) - - self.chunk = "" - self.chunkSize = 0 - self.chunkOffset = 0 - - data = self.dataStream.read(chunkSize) - - # Deal with CR LF and surrogates broken across chunks - if self._bufferedCharacter: - data = self._bufferedCharacter + data - self._bufferedCharacter = None - elif not data: - # We have no more data, bye-bye stream - return False - - if len(data) > 1: - lastv = ord(data[-1]) - if lastv == 0x0D or 0xD800 <= lastv <= 0xDBFF: - self._bufferedCharacter = data[-1] - data = data[:-1] - - if self.reportCharacterErrors: - self.reportCharacterErrors(data) - - # Replace invalid characters - data = data.replace("\r\n", "\n") - data = data.replace("\r", "\n") - - self.chunk = data - self.chunkSize = len(data) - - return True - - def characterErrorsUCS4(self, data): - for _ in range(len(invalid_unicode_re.findall(data))): - self.errors.append("invalid-codepoint") - - def characterErrorsUCS2(self, data): - # Someone picked the wrong compile option - # You lose - skip = False - for match in invalid_unicode_re.finditer(data): - if skip: - continue - codepoint = ord(match.group()) - pos = match.start() - # Pretty sure there should be endianness issues here - if _utils.isSurrogatePair(data[pos:pos + 2]): - # We have a surrogate pair! - char_val = _utils.surrogatePairToCodepoint(data[pos:pos + 2]) - if char_val in non_bmp_invalid_codepoints: - self.errors.append("invalid-codepoint") - skip = True - elif (codepoint >= 0xD800 and codepoint <= 0xDFFF and - pos == len(data) - 1): - self.errors.append("invalid-codepoint") - else: - skip = False - self.errors.append("invalid-codepoint") - - def charsUntil(self, characters, opposite=False): - """ Returns a string of characters from the stream up to but not - including any character in 'characters' or EOF. 'characters' must be - a container that supports the 'in' method and iteration over its - characters. - """ - - # Use a cache of regexps to find the required characters - try: - chars = charsUntilRegEx[(characters, opposite)] - except KeyError: - if __debug__: - for c in characters: - assert(ord(c) < 128) - regex = "".join(["\\x%02x" % ord(c) for c in characters]) - if not opposite: - regex = "^%s" % regex - chars = charsUntilRegEx[(characters, opposite)] = re.compile("[%s]+" % regex) - - rv = [] - - while True: - # Find the longest matching prefix - m = chars.match(self.chunk, self.chunkOffset) - if m is None: - # If nothing matched, and it wasn't because we ran out of chunk, - # then stop - if self.chunkOffset != self.chunkSize: - break - else: - end = m.end() - # If not the whole chunk matched, return everything - # up to the part that didn't match - if end != self.chunkSize: - rv.append(self.chunk[self.chunkOffset:end]) - self.chunkOffset = end - break - # If the whole remainder of the chunk matched, - # use it all and read the next chunk - rv.append(self.chunk[self.chunkOffset:]) - if not self.readChunk(): - # Reached EOF - break - - r = "".join(rv) - return r - - def unget(self, char): - # Only one character is allowed to be ungotten at once - it must - # be consumed again before any further call to unget - if char is not None: - if self.chunkOffset == 0: - # unget is called quite rarely, so it's a good idea to do - # more work here if it saves a bit of work in the frequently - # called char and charsUntil. - # So, just prepend the ungotten character onto the current - # chunk: - self.chunk = char + self.chunk - self.chunkSize += 1 - else: - self.chunkOffset -= 1 - assert self.chunk[self.chunkOffset] == char - - -class HTMLBinaryInputStream(HTMLUnicodeInputStream): - """Provides a unicode stream of characters to the HTMLTokenizer. - - This class takes care of character encoding and removing or replacing - incorrect byte-sequences and also provides column and line tracking. - - """ - - def __init__(self, source, override_encoding=None, transport_encoding=None, - same_origin_parent_encoding=None, likely_encoding=None, - default_encoding="windows-1252", useChardet=True): - """Initialises the HTMLInputStream. - - HTMLInputStream(source, [encoding]) -> Normalized stream from source - for use by html5lib. - - source can be either a file-object, local filename or a string. - - The optional encoding parameter must be a string that indicates - the encoding. If specified, that encoding will be used, - regardless of any BOM or later declaration (such as in a meta - element) - - """ - # Raw Stream - for unicode objects this will encode to utf-8 and set - # self.charEncoding as appropriate - self.rawStream = self.openStream(source) - - HTMLUnicodeInputStream.__init__(self, self.rawStream) - - # Encoding Information - # Number of bytes to use when looking for a meta element with - # encoding information - self.numBytesMeta = 1024 - # Number of bytes to use when using detecting encoding using chardet - self.numBytesChardet = 100 - # Things from args - self.override_encoding = override_encoding - self.transport_encoding = transport_encoding - self.same_origin_parent_encoding = same_origin_parent_encoding - self.likely_encoding = likely_encoding - self.default_encoding = default_encoding - - # Determine encoding - self.charEncoding = self.determineEncoding(useChardet) - assert self.charEncoding[0] is not None - - # Call superclass - self.reset() - - def reset(self): - self.dataStream = self.charEncoding[0].codec_info.streamreader(self.rawStream, 'replace') - HTMLUnicodeInputStream.reset(self) - - def openStream(self, source): - """Produces a file object from source. - - source can be either a file object, local filename or a string. - - """ - # Already a file object - if hasattr(source, 'read'): - stream = source - else: - stream = BytesIO(source) - - try: - stream.seek(stream.tell()) - except: # pylint:disable=bare-except - stream = BufferedStream(stream) - - return stream - - def determineEncoding(self, chardet=True): - # BOMs take precedence over everything - # This will also read past the BOM if present - charEncoding = self.detectBOM(), "certain" - if charEncoding[0] is not None: - return charEncoding - - # If we've been overriden, we've been overriden - charEncoding = lookupEncoding(self.override_encoding), "certain" - if charEncoding[0] is not None: - return charEncoding - - # Now check the transport layer - charEncoding = lookupEncoding(self.transport_encoding), "certain" - if charEncoding[0] is not None: - return charEncoding - - # Look for meta elements with encoding information - charEncoding = self.detectEncodingMeta(), "tentative" - if charEncoding[0] is not None: - return charEncoding - - # Parent document encoding - charEncoding = lookupEncoding(self.same_origin_parent_encoding), "tentative" - if charEncoding[0] is not None and not charEncoding[0].name.startswith("utf-16"): - return charEncoding - - # "likely" encoding - charEncoding = lookupEncoding(self.likely_encoding), "tentative" - if charEncoding[0] is not None: - return charEncoding - - # Guess with chardet, if available - if chardet: - try: - from pip._vendor.chardet.universaldetector import UniversalDetector - except ImportError: - pass - else: - buffers = [] - detector = UniversalDetector() - while not detector.done: - buffer = self.rawStream.read(self.numBytesChardet) - assert isinstance(buffer, bytes) - if not buffer: - break - buffers.append(buffer) - detector.feed(buffer) - detector.close() - encoding = lookupEncoding(detector.result['encoding']) - self.rawStream.seek(0) - if encoding is not None: - return encoding, "tentative" - - # Try the default encoding - charEncoding = lookupEncoding(self.default_encoding), "tentative" - if charEncoding[0] is not None: - return charEncoding - - # Fallback to html5lib's default if even that hasn't worked - return lookupEncoding("windows-1252"), "tentative" - - def changeEncoding(self, newEncoding): - assert self.charEncoding[1] != "certain" - newEncoding = lookupEncoding(newEncoding) - if newEncoding is None: - return - if newEncoding.name in ("utf-16be", "utf-16le"): - newEncoding = lookupEncoding("utf-8") - assert newEncoding is not None - elif newEncoding == self.charEncoding[0]: - self.charEncoding = (self.charEncoding[0], "certain") - else: - self.rawStream.seek(0) - self.charEncoding = (newEncoding, "certain") - self.reset() - raise _ReparseException("Encoding changed from %s to %s" % (self.charEncoding[0], newEncoding)) - - def detectBOM(self): - """Attempts to detect at BOM at the start of the stream. If - an encoding can be determined from the BOM return the name of the - encoding otherwise return None""" - bomDict = { - codecs.BOM_UTF8: 'utf-8', - codecs.BOM_UTF16_LE: 'utf-16le', codecs.BOM_UTF16_BE: 'utf-16be', - codecs.BOM_UTF32_LE: 'utf-32le', codecs.BOM_UTF32_BE: 'utf-32be' - } - - # Go to beginning of file and read in 4 bytes - string = self.rawStream.read(4) - assert isinstance(string, bytes) - - # Try detecting the BOM using bytes from the string - encoding = bomDict.get(string[:3]) # UTF-8 - seek = 3 - if not encoding: - # Need to detect UTF-32 before UTF-16 - encoding = bomDict.get(string) # UTF-32 - seek = 4 - if not encoding: - encoding = bomDict.get(string[:2]) # UTF-16 - seek = 2 - - # Set the read position past the BOM if one was found, otherwise - # set it to the start of the stream - if encoding: - self.rawStream.seek(seek) - return lookupEncoding(encoding) - else: - self.rawStream.seek(0) - return None - - def detectEncodingMeta(self): - """Report the encoding declared by the meta element - """ - buffer = self.rawStream.read(self.numBytesMeta) - assert isinstance(buffer, bytes) - parser = EncodingParser(buffer) - self.rawStream.seek(0) - encoding = parser.getEncoding() - - if encoding is not None and encoding.name in ("utf-16be", "utf-16le"): - encoding = lookupEncoding("utf-8") - - return encoding - - -class EncodingBytes(bytes): - """String-like object with an associated position and various extra methods - If the position is ever greater than the string length then an exception is - raised""" - def __new__(self, value): - assert isinstance(value, bytes) - return bytes.__new__(self, value.lower()) - - def __init__(self, value): - # pylint:disable=unused-argument - self._position = -1 - - def __iter__(self): - return self - - def __next__(self): - p = self._position = self._position + 1 - if p >= len(self): - raise StopIteration - elif p < 0: - raise TypeError - return self[p:p + 1] - - def next(self): - # Py2 compat - return self.__next__() - - def previous(self): - p = self._position - if p >= len(self): - raise StopIteration - elif p < 0: - raise TypeError - self._position = p = p - 1 - return self[p:p + 1] - - def setPosition(self, position): - if self._position >= len(self): - raise StopIteration - self._position = position - - def getPosition(self): - if self._position >= len(self): - raise StopIteration - if self._position >= 0: - return self._position - else: - return None - - position = property(getPosition, setPosition) - - def getCurrentByte(self): - return self[self.position:self.position + 1] - - currentByte = property(getCurrentByte) - - def skip(self, chars=spaceCharactersBytes): - """Skip past a list of characters""" - p = self.position # use property for the error-checking - while p < len(self): - c = self[p:p + 1] - if c not in chars: - self._position = p - return c - p += 1 - self._position = p - return None - - def skipUntil(self, chars): - p = self.position - while p < len(self): - c = self[p:p + 1] - if c in chars: - self._position = p - return c - p += 1 - self._position = p - return None - - def matchBytes(self, bytes): - """Look for a sequence of bytes at the start of a string. If the bytes - are found return True and advance the position to the byte after the - match. Otherwise return False and leave the position alone""" - p = self.position - data = self[p:p + len(bytes)] - rv = data.startswith(bytes) - if rv: - self.position += len(bytes) - return rv - - def jumpTo(self, bytes): - """Look for the next sequence of bytes matching a given sequence. If - a match is found advance the position to the last byte of the match""" - newPosition = self[self.position:].find(bytes) - if newPosition > -1: - # XXX: This is ugly, but I can't see a nicer way to fix this. - if self._position == -1: - self._position = 0 - self._position += (newPosition + len(bytes) - 1) - return True - else: - raise StopIteration - - -class EncodingParser(object): - """Mini parser for detecting character encoding from meta elements""" - - def __init__(self, data): - """string - the data to work on for encoding detection""" - self.data = EncodingBytes(data) - self.encoding = None - - def getEncoding(self): - methodDispatch = ( - (b"<!--", self.handleComment), - (b"<meta", self.handleMeta), - (b"</", self.handlePossibleEndTag), - (b"<!", self.handleOther), - (b"<?", self.handleOther), - (b"<", self.handlePossibleStartTag)) - for _ in self.data: - keepParsing = True - for key, method in methodDispatch: - if self.data.matchBytes(key): - try: - keepParsing = method() - break - except StopIteration: - keepParsing = False - break - if not keepParsing: - break - - return self.encoding - - def handleComment(self): - """Skip over comments""" - return self.data.jumpTo(b"-->") - - def handleMeta(self): - if self.data.currentByte not in spaceCharactersBytes: - # if we have <meta not followed by a space so just keep going - return True - # We have a valid meta element we want to search for attributes - hasPragma = False - pendingEncoding = None - while True: - # Try to find the next attribute after the current position - attr = self.getAttribute() - if attr is None: - return True - else: - if attr[0] == b"http-equiv": - hasPragma = attr[1] == b"content-type" - if hasPragma and pendingEncoding is not None: - self.encoding = pendingEncoding - return False - elif attr[0] == b"charset": - tentativeEncoding = attr[1] - codec = lookupEncoding(tentativeEncoding) - if codec is not None: - self.encoding = codec - return False - elif attr[0] == b"content": - contentParser = ContentAttrParser(EncodingBytes(attr[1])) - tentativeEncoding = contentParser.parse() - if tentativeEncoding is not None: - codec = lookupEncoding(tentativeEncoding) - if codec is not None: - if hasPragma: - self.encoding = codec - return False - else: - pendingEncoding = codec - - def handlePossibleStartTag(self): - return self.handlePossibleTag(False) - - def handlePossibleEndTag(self): - next(self.data) - return self.handlePossibleTag(True) - - def handlePossibleTag(self, endTag): - data = self.data - if data.currentByte not in asciiLettersBytes: - # If the next byte is not an ascii letter either ignore this - # fragment (possible start tag case) or treat it according to - # handleOther - if endTag: - data.previous() - self.handleOther() - return True - - c = data.skipUntil(spacesAngleBrackets) - if c == b"<": - # return to the first step in the overall "two step" algorithm - # reprocessing the < byte - data.previous() - else: - # Read all attributes - attr = self.getAttribute() - while attr is not None: - attr = self.getAttribute() - return True - - def handleOther(self): - return self.data.jumpTo(b">") - - def getAttribute(self): - """Return a name,value pair for the next attribute in the stream, - if one is found, or None""" - data = self.data - # Step 1 (skip chars) - c = data.skip(spaceCharactersBytes | frozenset([b"/"])) - assert c is None or len(c) == 1 - # Step 2 - if c in (b">", None): - return None - # Step 3 - attrName = [] - attrValue = [] - # Step 4 attribute name - while True: - if c == b"=" and attrName: - break - elif c in spaceCharactersBytes: - # Step 6! - c = data.skip() - break - elif c in (b"/", b">"): - return b"".join(attrName), b"" - elif c in asciiUppercaseBytes: - attrName.append(c.lower()) - elif c is None: - return None - else: - attrName.append(c) - # Step 5 - c = next(data) - # Step 7 - if c != b"=": - data.previous() - return b"".join(attrName), b"" - # Step 8 - next(data) - # Step 9 - c = data.skip() - # Step 10 - if c in (b"'", b'"'): - # 10.1 - quoteChar = c - while True: - # 10.2 - c = next(data) - # 10.3 - if c == quoteChar: - next(data) - return b"".join(attrName), b"".join(attrValue) - # 10.4 - elif c in asciiUppercaseBytes: - attrValue.append(c.lower()) - # 10.5 - else: - attrValue.append(c) - elif c == b">": - return b"".join(attrName), b"" - elif c in asciiUppercaseBytes: - attrValue.append(c.lower()) - elif c is None: - return None - else: - attrValue.append(c) - # Step 11 - while True: - c = next(data) - if c in spacesAngleBrackets: - return b"".join(attrName), b"".join(attrValue) - elif c in asciiUppercaseBytes: - attrValue.append(c.lower()) - elif c is None: - return None - else: - attrValue.append(c) - - -class ContentAttrParser(object): - def __init__(self, data): - assert isinstance(data, bytes) - self.data = data - - def parse(self): - try: - # Check if the attr name is charset - # otherwise return - self.data.jumpTo(b"charset") - self.data.position += 1 - self.data.skip() - if not self.data.currentByte == b"=": - # If there is no = sign keep looking for attrs - return None - self.data.position += 1 - self.data.skip() - # Look for an encoding between matching quote marks - if self.data.currentByte in (b'"', b"'"): - quoteMark = self.data.currentByte - self.data.position += 1 - oldPosition = self.data.position - if self.data.jumpTo(quoteMark): - return self.data[oldPosition:self.data.position] - else: - return None - else: - # Unquoted value - oldPosition = self.data.position - try: - self.data.skipUntil(spaceCharactersBytes) - return self.data[oldPosition:self.data.position] - except StopIteration: - # Return the whole remaining value - return self.data[oldPosition:] - except StopIteration: - return None - - -def lookupEncoding(encoding): - """Return the python codec name corresponding to an encoding or None if the - string doesn't correspond to a valid encoding.""" - if isinstance(encoding, binary_type): - try: - encoding = encoding.decode("ascii") - except UnicodeDecodeError: - return None - - if encoding is not None: - try: - return webencodings.lookup(encoding) - except AttributeError: - return None - else: - return None diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_tokenizer.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_tokenizer.py deleted file mode 100644 index 178f6e7..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_tokenizer.py +++ /dev/null @@ -1,1721 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from pip._vendor.six import unichr as chr - -from collections import deque - -from .constants import spaceCharacters -from .constants import entities -from .constants import asciiLetters, asciiUpper2Lower -from .constants import digits, hexDigits, EOF -from .constants import tokenTypes, tagTokenTypes -from .constants import replacementCharacters - -from ._inputstream import HTMLInputStream - -from ._trie import Trie - -entitiesTrie = Trie(entities) - - -class HTMLTokenizer(object): - """ This class takes care of tokenizing HTML. - - * self.currentToken - Holds the token that is currently being processed. - - * self.state - Holds a reference to the method to be invoked... XXX - - * self.stream - Points to HTMLInputStream object. - """ - - def __init__(self, stream, parser=None, **kwargs): - - self.stream = HTMLInputStream(stream, **kwargs) - self.parser = parser - - # Setup the initial tokenizer state - self.escapeFlag = False - self.lastFourChars = [] - self.state = self.dataState - self.escape = False - - # The current token being created - self.currentToken = None - super(HTMLTokenizer, self).__init__() - - def __iter__(self): - """ This is where the magic happens. - - We do our usually processing through the states and when we have a token - to return we yield the token which pauses processing until the next token - is requested. - """ - self.tokenQueue = deque([]) - # Start processing. When EOF is reached self.state will return False - # instead of True and the loop will terminate. - while self.state(): - while self.stream.errors: - yield {"type": tokenTypes["ParseError"], "data": self.stream.errors.pop(0)} - while self.tokenQueue: - yield self.tokenQueue.popleft() - - def consumeNumberEntity(self, isHex): - """This function returns either U+FFFD or the character based on the - decimal or hexadecimal representation. It also discards ";" if present. - If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. - """ - - allowed = digits - radix = 10 - if isHex: - allowed = hexDigits - radix = 16 - - charStack = [] - - # Consume all the characters that are in range while making sure we - # don't hit an EOF. - c = self.stream.char() - while c in allowed and c is not EOF: - charStack.append(c) - c = self.stream.char() - - # Convert the set of characters consumed to an int. - charAsInt = int("".join(charStack), radix) - - # Certain characters get replaced with others - if charAsInt in replacementCharacters: - char = replacementCharacters[charAsInt] - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "illegal-codepoint-for-numeric-entity", - "datavars": {"charAsInt": charAsInt}}) - elif ((0xD800 <= charAsInt <= 0xDFFF) or - (charAsInt > 0x10FFFF)): - char = "\uFFFD" - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "illegal-codepoint-for-numeric-entity", - "datavars": {"charAsInt": charAsInt}}) - else: - # Should speed up this check somehow (e.g. move the set to a constant) - if ((0x0001 <= charAsInt <= 0x0008) or - (0x000E <= charAsInt <= 0x001F) or - (0x007F <= charAsInt <= 0x009F) or - (0xFDD0 <= charAsInt <= 0xFDEF) or - charAsInt in frozenset([0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, - 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, - 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, - 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, - 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, - 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, - 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, - 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, - 0xFFFFF, 0x10FFFE, 0x10FFFF])): - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": - "illegal-codepoint-for-numeric-entity", - "datavars": {"charAsInt": charAsInt}}) - try: - # Try/except needed as UCS-2 Python builds' unichar only works - # within the BMP. - char = chr(charAsInt) - except ValueError: - v = charAsInt - 0x10000 - char = chr(0xD800 | (v >> 10)) + chr(0xDC00 | (v & 0x3FF)) - - # Discard the ; if present. Otherwise, put it back on the queue and - # invoke parseError on parser. - if c != ";": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "numeric-entity-without-semicolon"}) - self.stream.unget(c) - - return char - - def consumeEntity(self, allowedChar=None, fromAttribute=False): - # Initialise to the default output for when no entity is matched - output = "&" - - charStack = [self.stream.char()] - if (charStack[0] in spaceCharacters or charStack[0] in (EOF, "<", "&") or - (allowedChar is not None and allowedChar == charStack[0])): - self.stream.unget(charStack[0]) - - elif charStack[0] == "#": - # Read the next character to see if it's hex or decimal - hex = False - charStack.append(self.stream.char()) - if charStack[-1] in ("x", "X"): - hex = True - charStack.append(self.stream.char()) - - # charStack[-1] should be the first digit - if (hex and charStack[-1] in hexDigits) \ - or (not hex and charStack[-1] in digits): - # At least one digit found, so consume the whole number - self.stream.unget(charStack[-1]) - output = self.consumeNumberEntity(hex) - else: - # No digits found - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "expected-numeric-entity"}) - self.stream.unget(charStack.pop()) - output = "&" + "".join(charStack) - - else: - # At this point in the process might have named entity. Entities - # are stored in the global variable "entities". - # - # Consume characters and compare to these to a substring of the - # entity names in the list until the substring no longer matches. - while (charStack[-1] is not EOF): - if not entitiesTrie.has_keys_with_prefix("".join(charStack)): - break - charStack.append(self.stream.char()) - - # At this point we have a string that starts with some characters - # that may match an entity - # Try to find the longest entity the string will match to take care - # of ¬i for instance. - try: - entityName = entitiesTrie.longest_prefix("".join(charStack[:-1])) - entityLength = len(entityName) - except KeyError: - entityName = None - - if entityName is not None: - if entityName[-1] != ";": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "named-entity-without-semicolon"}) - if (entityName[-1] != ";" and fromAttribute and - (charStack[entityLength] in asciiLetters or - charStack[entityLength] in digits or - charStack[entityLength] == "=")): - self.stream.unget(charStack.pop()) - output = "&" + "".join(charStack) - else: - output = entities[entityName] - self.stream.unget(charStack.pop()) - output += "".join(charStack[entityLength:]) - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-named-entity"}) - self.stream.unget(charStack.pop()) - output = "&" + "".join(charStack) - - if fromAttribute: - self.currentToken["data"][-1][1] += output - else: - if output in spaceCharacters: - tokenType = "SpaceCharacters" - else: - tokenType = "Characters" - self.tokenQueue.append({"type": tokenTypes[tokenType], "data": output}) - - def processEntityInAttribute(self, allowedChar): - """This method replaces the need for "entityInAttributeValueState". - """ - self.consumeEntity(allowedChar=allowedChar, fromAttribute=True) - - def emitCurrentToken(self): - """This method is a generic handler for emitting the tags. It also sets - the state to "data" because that's what's needed after a token has been - emitted. - """ - token = self.currentToken - # Add token to the queue to be yielded - if (token["type"] in tagTokenTypes): - token["name"] = token["name"].translate(asciiUpper2Lower) - if token["type"] == tokenTypes["EndTag"]: - if token["data"]: - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "attributes-in-end-tag"}) - if token["selfClosing"]: - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "self-closing-flag-on-end-tag"}) - self.tokenQueue.append(token) - self.state = self.dataState - - # Below are the various tokenizer states worked out. - def dataState(self): - data = self.stream.char() - if data == "&": - self.state = self.entityDataState - elif data == "<": - self.state = self.tagOpenState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\u0000"}) - elif data is EOF: - # Tokenization ends. - return False - elif data in spaceCharacters: - # Directly after emitting a token you switch back to the "data - # state". At that point spaceCharacters are important so they are - # emitted separately. - self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": - data + self.stream.charsUntil(spaceCharacters, True)}) - # No need to update lastFourChars here, since the first space will - # have already been appended to lastFourChars and will have broken - # any <!-- or --> sequences - else: - chars = self.stream.charsUntil(("&", "<", "\u0000")) - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": - data + chars}) - return True - - def entityDataState(self): - self.consumeEntity() - self.state = self.dataState - return True - - def rcdataState(self): - data = self.stream.char() - if data == "&": - self.state = self.characterReferenceInRcdata - elif data == "<": - self.state = self.rcdataLessThanSignState - elif data == EOF: - # Tokenization ends. - return False - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - elif data in spaceCharacters: - # Directly after emitting a token you switch back to the "data - # state". At that point spaceCharacters are important so they are - # emitted separately. - self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": - data + self.stream.charsUntil(spaceCharacters, True)}) - # No need to update lastFourChars here, since the first space will - # have already been appended to lastFourChars and will have broken - # any <!-- or --> sequences - else: - chars = self.stream.charsUntil(("&", "<", "\u0000")) - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": - data + chars}) - return True - - def characterReferenceInRcdata(self): - self.consumeEntity() - self.state = self.rcdataState - return True - - def rawtextState(self): - data = self.stream.char() - if data == "<": - self.state = self.rawtextLessThanSignState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - elif data == EOF: - # Tokenization ends. - return False - else: - chars = self.stream.charsUntil(("<", "\u0000")) - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": - data + chars}) - return True - - def scriptDataState(self): - data = self.stream.char() - if data == "<": - self.state = self.scriptDataLessThanSignState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - elif data == EOF: - # Tokenization ends. - return False - else: - chars = self.stream.charsUntil(("<", "\u0000")) - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": - data + chars}) - return True - - def plaintextState(self): - data = self.stream.char() - if data == EOF: - # Tokenization ends. - return False - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": - data + self.stream.charsUntil("\u0000")}) - return True - - def tagOpenState(self): - data = self.stream.char() - if data == "!": - self.state = self.markupDeclarationOpenState - elif data == "/": - self.state = self.closeTagOpenState - elif data in asciiLetters: - self.currentToken = {"type": tokenTypes["StartTag"], - "name": data, "data": [], - "selfClosing": False, - "selfClosingAcknowledged": False} - self.state = self.tagNameState - elif data == ">": - # XXX In theory it could be something besides a tag name. But - # do we really care? - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-tag-name-but-got-right-bracket"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<>"}) - self.state = self.dataState - elif data == "?": - # XXX In theory it could be something besides a tag name. But - # do we really care? - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-tag-name-but-got-question-mark"}) - self.stream.unget(data) - self.state = self.bogusCommentState - else: - # XXX - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-tag-name"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) - self.stream.unget(data) - self.state = self.dataState - return True - - def closeTagOpenState(self): - data = self.stream.char() - if data in asciiLetters: - self.currentToken = {"type": tokenTypes["EndTag"], "name": data, - "data": [], "selfClosing": False} - self.state = self.tagNameState - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-closing-tag-but-got-right-bracket"}) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-closing-tag-but-got-eof"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) - self.state = self.dataState - else: - # XXX data can be _'_... - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-closing-tag-but-got-char", - "datavars": {"data": data}}) - self.stream.unget(data) - self.state = self.bogusCommentState - return True - - def tagNameState(self): - data = self.stream.char() - if data in spaceCharacters: - self.state = self.beforeAttributeNameState - elif data == ">": - self.emitCurrentToken() - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-tag-name"}) - self.state = self.dataState - elif data == "/": - self.state = self.selfClosingStartTagState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["name"] += "\uFFFD" - else: - self.currentToken["name"] += data - # (Don't use charsUntil here, because tag names are - # very short and it's faster to not do anything fancy) - return True - - def rcdataLessThanSignState(self): - data = self.stream.char() - if data == "/": - self.temporaryBuffer = "" - self.state = self.rcdataEndTagOpenState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) - self.stream.unget(data) - self.state = self.rcdataState - return True - - def rcdataEndTagOpenState(self): - data = self.stream.char() - if data in asciiLetters: - self.temporaryBuffer += data - self.state = self.rcdataEndTagNameState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) - self.stream.unget(data) - self.state = self.rcdataState - return True - - def rcdataEndTagNameState(self): - appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() - data = self.stream.char() - if data in spaceCharacters and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.state = self.beforeAttributeNameState - elif data == "/" and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.state = self.selfClosingStartTagState - elif data == ">" and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.emitCurrentToken() - self.state = self.dataState - elif data in asciiLetters: - self.temporaryBuffer += data - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "</" + self.temporaryBuffer}) - self.stream.unget(data) - self.state = self.rcdataState - return True - - def rawtextLessThanSignState(self): - data = self.stream.char() - if data == "/": - self.temporaryBuffer = "" - self.state = self.rawtextEndTagOpenState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) - self.stream.unget(data) - self.state = self.rawtextState - return True - - def rawtextEndTagOpenState(self): - data = self.stream.char() - if data in asciiLetters: - self.temporaryBuffer += data - self.state = self.rawtextEndTagNameState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) - self.stream.unget(data) - self.state = self.rawtextState - return True - - def rawtextEndTagNameState(self): - appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() - data = self.stream.char() - if data in spaceCharacters and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.state = self.beforeAttributeNameState - elif data == "/" and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.state = self.selfClosingStartTagState - elif data == ">" and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.emitCurrentToken() - self.state = self.dataState - elif data in asciiLetters: - self.temporaryBuffer += data - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "</" + self.temporaryBuffer}) - self.stream.unget(data) - self.state = self.rawtextState - return True - - def scriptDataLessThanSignState(self): - data = self.stream.char() - if data == "/": - self.temporaryBuffer = "" - self.state = self.scriptDataEndTagOpenState - elif data == "!": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<!"}) - self.state = self.scriptDataEscapeStartState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) - self.stream.unget(data) - self.state = self.scriptDataState - return True - - def scriptDataEndTagOpenState(self): - data = self.stream.char() - if data in asciiLetters: - self.temporaryBuffer += data - self.state = self.scriptDataEndTagNameState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) - self.stream.unget(data) - self.state = self.scriptDataState - return True - - def scriptDataEndTagNameState(self): - appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() - data = self.stream.char() - if data in spaceCharacters and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.state = self.beforeAttributeNameState - elif data == "/" and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.state = self.selfClosingStartTagState - elif data == ">" and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.emitCurrentToken() - self.state = self.dataState - elif data in asciiLetters: - self.temporaryBuffer += data - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "</" + self.temporaryBuffer}) - self.stream.unget(data) - self.state = self.scriptDataState - return True - - def scriptDataEscapeStartState(self): - data = self.stream.char() - if data == "-": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) - self.state = self.scriptDataEscapeStartDashState - else: - self.stream.unget(data) - self.state = self.scriptDataState - return True - - def scriptDataEscapeStartDashState(self): - data = self.stream.char() - if data == "-": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) - self.state = self.scriptDataEscapedDashDashState - else: - self.stream.unget(data) - self.state = self.scriptDataState - return True - - def scriptDataEscapedState(self): - data = self.stream.char() - if data == "-": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) - self.state = self.scriptDataEscapedDashState - elif data == "<": - self.state = self.scriptDataEscapedLessThanSignState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - elif data == EOF: - self.state = self.dataState - else: - chars = self.stream.charsUntil(("<", "-", "\u0000")) - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": - data + chars}) - return True - - def scriptDataEscapedDashState(self): - data = self.stream.char() - if data == "-": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) - self.state = self.scriptDataEscapedDashDashState - elif data == "<": - self.state = self.scriptDataEscapedLessThanSignState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - self.state = self.scriptDataEscapedState - elif data == EOF: - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - self.state = self.scriptDataEscapedState - return True - - def scriptDataEscapedDashDashState(self): - data = self.stream.char() - if data == "-": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) - elif data == "<": - self.state = self.scriptDataEscapedLessThanSignState - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) - self.state = self.scriptDataState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - self.state = self.scriptDataEscapedState - elif data == EOF: - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - self.state = self.scriptDataEscapedState - return True - - def scriptDataEscapedLessThanSignState(self): - data = self.stream.char() - if data == "/": - self.temporaryBuffer = "" - self.state = self.scriptDataEscapedEndTagOpenState - elif data in asciiLetters: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<" + data}) - self.temporaryBuffer = data - self.state = self.scriptDataDoubleEscapeStartState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) - self.stream.unget(data) - self.state = self.scriptDataEscapedState - return True - - def scriptDataEscapedEndTagOpenState(self): - data = self.stream.char() - if data in asciiLetters: - self.temporaryBuffer = data - self.state = self.scriptDataEscapedEndTagNameState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) - self.stream.unget(data) - self.state = self.scriptDataEscapedState - return True - - def scriptDataEscapedEndTagNameState(self): - appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() - data = self.stream.char() - if data in spaceCharacters and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.state = self.beforeAttributeNameState - elif data == "/" and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.state = self.selfClosingStartTagState - elif data == ">" and appropriate: - self.currentToken = {"type": tokenTypes["EndTag"], - "name": self.temporaryBuffer, - "data": [], "selfClosing": False} - self.emitCurrentToken() - self.state = self.dataState - elif data in asciiLetters: - self.temporaryBuffer += data - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "</" + self.temporaryBuffer}) - self.stream.unget(data) - self.state = self.scriptDataEscapedState - return True - - def scriptDataDoubleEscapeStartState(self): - data = self.stream.char() - if data in (spaceCharacters | frozenset(("/", ">"))): - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - if self.temporaryBuffer.lower() == "script": - self.state = self.scriptDataDoubleEscapedState - else: - self.state = self.scriptDataEscapedState - elif data in asciiLetters: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - self.temporaryBuffer += data - else: - self.stream.unget(data) - self.state = self.scriptDataEscapedState - return True - - def scriptDataDoubleEscapedState(self): - data = self.stream.char() - if data == "-": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) - self.state = self.scriptDataDoubleEscapedDashState - elif data == "<": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) - self.state = self.scriptDataDoubleEscapedLessThanSignState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - elif data == EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-script-in-script"}) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - return True - - def scriptDataDoubleEscapedDashState(self): - data = self.stream.char() - if data == "-": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) - self.state = self.scriptDataDoubleEscapedDashDashState - elif data == "<": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) - self.state = self.scriptDataDoubleEscapedLessThanSignState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - self.state = self.scriptDataDoubleEscapedState - elif data == EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-script-in-script"}) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - self.state = self.scriptDataDoubleEscapedState - return True - - def scriptDataDoubleEscapedDashDashState(self): - data = self.stream.char() - if data == "-": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) - elif data == "<": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) - self.state = self.scriptDataDoubleEscapedLessThanSignState - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) - self.state = self.scriptDataState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": "\uFFFD"}) - self.state = self.scriptDataDoubleEscapedState - elif data == EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-script-in-script"}) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - self.state = self.scriptDataDoubleEscapedState - return True - - def scriptDataDoubleEscapedLessThanSignState(self): - data = self.stream.char() - if data == "/": - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "/"}) - self.temporaryBuffer = "" - self.state = self.scriptDataDoubleEscapeEndState - else: - self.stream.unget(data) - self.state = self.scriptDataDoubleEscapedState - return True - - def scriptDataDoubleEscapeEndState(self): - data = self.stream.char() - if data in (spaceCharacters | frozenset(("/", ">"))): - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - if self.temporaryBuffer.lower() == "script": - self.state = self.scriptDataEscapedState - else: - self.state = self.scriptDataDoubleEscapedState - elif data in asciiLetters: - self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) - self.temporaryBuffer += data - else: - self.stream.unget(data) - self.state = self.scriptDataDoubleEscapedState - return True - - def beforeAttributeNameState(self): - data = self.stream.char() - if data in spaceCharacters: - self.stream.charsUntil(spaceCharacters, True) - elif data in asciiLetters: - self.currentToken["data"].append([data, ""]) - self.state = self.attributeNameState - elif data == ">": - self.emitCurrentToken() - elif data == "/": - self.state = self.selfClosingStartTagState - elif data in ("'", '"', "=", "<"): - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "invalid-character-in-attribute-name"}) - self.currentToken["data"].append([data, ""]) - self.state = self.attributeNameState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"].append(["\uFFFD", ""]) - self.state = self.attributeNameState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-attribute-name-but-got-eof"}) - self.state = self.dataState - else: - self.currentToken["data"].append([data, ""]) - self.state = self.attributeNameState - return True - - def attributeNameState(self): - data = self.stream.char() - leavingThisState = True - emitToken = False - if data == "=": - self.state = self.beforeAttributeValueState - elif data in asciiLetters: - self.currentToken["data"][-1][0] += data +\ - self.stream.charsUntil(asciiLetters, True) - leavingThisState = False - elif data == ">": - # XXX If we emit here the attributes are converted to a dict - # without being checked and when the code below runs we error - # because data is a dict not a list - emitToken = True - elif data in spaceCharacters: - self.state = self.afterAttributeNameState - elif data == "/": - self.state = self.selfClosingStartTagState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"][-1][0] += "\uFFFD" - leavingThisState = False - elif data in ("'", '"', "<"): - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": - "invalid-character-in-attribute-name"}) - self.currentToken["data"][-1][0] += data - leavingThisState = False - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "eof-in-attribute-name"}) - self.state = self.dataState - else: - self.currentToken["data"][-1][0] += data - leavingThisState = False - - if leavingThisState: - # Attributes are not dropped at this stage. That happens when the - # start tag token is emitted so values can still be safely appended - # to attributes, but we do want to report the parse error in time. - self.currentToken["data"][-1][0] = ( - self.currentToken["data"][-1][0].translate(asciiUpper2Lower)) - for name, _ in self.currentToken["data"][:-1]: - if self.currentToken["data"][-1][0] == name: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "duplicate-attribute"}) - break - # XXX Fix for above XXX - if emitToken: - self.emitCurrentToken() - return True - - def afterAttributeNameState(self): - data = self.stream.char() - if data in spaceCharacters: - self.stream.charsUntil(spaceCharacters, True) - elif data == "=": - self.state = self.beforeAttributeValueState - elif data == ">": - self.emitCurrentToken() - elif data in asciiLetters: - self.currentToken["data"].append([data, ""]) - self.state = self.attributeNameState - elif data == "/": - self.state = self.selfClosingStartTagState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"].append(["\uFFFD", ""]) - self.state = self.attributeNameState - elif data in ("'", '"', "<"): - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "invalid-character-after-attribute-name"}) - self.currentToken["data"].append([data, ""]) - self.state = self.attributeNameState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-end-of-tag-but-got-eof"}) - self.state = self.dataState - else: - self.currentToken["data"].append([data, ""]) - self.state = self.attributeNameState - return True - - def beforeAttributeValueState(self): - data = self.stream.char() - if data in spaceCharacters: - self.stream.charsUntil(spaceCharacters, True) - elif data == "\"": - self.state = self.attributeValueDoubleQuotedState - elif data == "&": - self.state = self.attributeValueUnQuotedState - self.stream.unget(data) - elif data == "'": - self.state = self.attributeValueSingleQuotedState - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-attribute-value-but-got-right-bracket"}) - self.emitCurrentToken() - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"][-1][1] += "\uFFFD" - self.state = self.attributeValueUnQuotedState - elif data in ("=", "<", "`"): - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "equals-in-unquoted-attribute-value"}) - self.currentToken["data"][-1][1] += data - self.state = self.attributeValueUnQuotedState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-attribute-value-but-got-eof"}) - self.state = self.dataState - else: - self.currentToken["data"][-1][1] += data - self.state = self.attributeValueUnQuotedState - return True - - def attributeValueDoubleQuotedState(self): - data = self.stream.char() - if data == "\"": - self.state = self.afterAttributeValueState - elif data == "&": - self.processEntityInAttribute('"') - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"][-1][1] += "\uFFFD" - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-attribute-value-double-quote"}) - self.state = self.dataState - else: - self.currentToken["data"][-1][1] += data +\ - self.stream.charsUntil(("\"", "&", "\u0000")) - return True - - def attributeValueSingleQuotedState(self): - data = self.stream.char() - if data == "'": - self.state = self.afterAttributeValueState - elif data == "&": - self.processEntityInAttribute("'") - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"][-1][1] += "\uFFFD" - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-attribute-value-single-quote"}) - self.state = self.dataState - else: - self.currentToken["data"][-1][1] += data +\ - self.stream.charsUntil(("'", "&", "\u0000")) - return True - - def attributeValueUnQuotedState(self): - data = self.stream.char() - if data in spaceCharacters: - self.state = self.beforeAttributeNameState - elif data == "&": - self.processEntityInAttribute(">") - elif data == ">": - self.emitCurrentToken() - elif data in ('"', "'", "=", "<", "`"): - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-character-in-unquoted-attribute-value"}) - self.currentToken["data"][-1][1] += data - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"][-1][1] += "\uFFFD" - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-attribute-value-no-quotes"}) - self.state = self.dataState - else: - self.currentToken["data"][-1][1] += data + self.stream.charsUntil( - frozenset(("&", ">", '"', "'", "=", "<", "`", "\u0000")) | spaceCharacters) - return True - - def afterAttributeValueState(self): - data = self.stream.char() - if data in spaceCharacters: - self.state = self.beforeAttributeNameState - elif data == ">": - self.emitCurrentToken() - elif data == "/": - self.state = self.selfClosingStartTagState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-EOF-after-attribute-value"}) - self.stream.unget(data) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-character-after-attribute-value"}) - self.stream.unget(data) - self.state = self.beforeAttributeNameState - return True - - def selfClosingStartTagState(self): - data = self.stream.char() - if data == ">": - self.currentToken["selfClosing"] = True - self.emitCurrentToken() - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": - "unexpected-EOF-after-solidus-in-tag"}) - self.stream.unget(data) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-character-after-solidus-in-tag"}) - self.stream.unget(data) - self.state = self.beforeAttributeNameState - return True - - def bogusCommentState(self): - # Make a new comment token and give it as value all the characters - # until the first > or EOF (charsUntil checks for EOF automatically) - # and emit it. - data = self.stream.charsUntil(">") - data = data.replace("\u0000", "\uFFFD") - self.tokenQueue.append( - {"type": tokenTypes["Comment"], "data": data}) - - # Eat the character directly after the bogus comment which is either a - # ">" or an EOF. - self.stream.char() - self.state = self.dataState - return True - - def markupDeclarationOpenState(self): - charStack = [self.stream.char()] - if charStack[-1] == "-": - charStack.append(self.stream.char()) - if charStack[-1] == "-": - self.currentToken = {"type": tokenTypes["Comment"], "data": ""} - self.state = self.commentStartState - return True - elif charStack[-1] in ('d', 'D'): - matched = True - for expected in (('o', 'O'), ('c', 'C'), ('t', 'T'), - ('y', 'Y'), ('p', 'P'), ('e', 'E')): - charStack.append(self.stream.char()) - if charStack[-1] not in expected: - matched = False - break - if matched: - self.currentToken = {"type": tokenTypes["Doctype"], - "name": "", - "publicId": None, "systemId": None, - "correct": True} - self.state = self.doctypeState - return True - elif (charStack[-1] == "[" and - self.parser is not None and - self.parser.tree.openElements and - self.parser.tree.openElements[-1].namespace != self.parser.tree.defaultNamespace): - matched = True - for expected in ["C", "D", "A", "T", "A", "["]: - charStack.append(self.stream.char()) - if charStack[-1] != expected: - matched = False - break - if matched: - self.state = self.cdataSectionState - return True - - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-dashes-or-doctype"}) - - while charStack: - self.stream.unget(charStack.pop()) - self.state = self.bogusCommentState - return True - - def commentStartState(self): - data = self.stream.char() - if data == "-": - self.state = self.commentStartDashState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"] += "\uFFFD" - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "incorrect-comment"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-comment"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["data"] += data - self.state = self.commentState - return True - - def commentStartDashState(self): - data = self.stream.char() - if data == "-": - self.state = self.commentEndState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"] += "-\uFFFD" - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "incorrect-comment"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-comment"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["data"] += "-" + data - self.state = self.commentState - return True - - def commentState(self): - data = self.stream.char() - if data == "-": - self.state = self.commentEndDashState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"] += "\uFFFD" - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "eof-in-comment"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["data"] += data + \ - self.stream.charsUntil(("-", "\u0000")) - return True - - def commentEndDashState(self): - data = self.stream.char() - if data == "-": - self.state = self.commentEndState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"] += "-\uFFFD" - self.state = self.commentState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-comment-end-dash"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["data"] += "-" + data - self.state = self.commentState - return True - - def commentEndState(self): - data = self.stream.char() - if data == ">": - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"] += "--\uFFFD" - self.state = self.commentState - elif data == "!": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-bang-after-double-dash-in-comment"}) - self.state = self.commentEndBangState - elif data == "-": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-dash-after-double-dash-in-comment"}) - self.currentToken["data"] += data - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-comment-double-dash"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - # XXX - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-comment"}) - self.currentToken["data"] += "--" + data - self.state = self.commentState - return True - - def commentEndBangState(self): - data = self.stream.char() - if data == ">": - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data == "-": - self.currentToken["data"] += "--!" - self.state = self.commentEndDashState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["data"] += "--!\uFFFD" - self.state = self.commentState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-comment-end-bang-state"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["data"] += "--!" + data - self.state = self.commentState - return True - - def doctypeState(self): - data = self.stream.char() - if data in spaceCharacters: - self.state = self.beforeDoctypeNameState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-doctype-name-but-got-eof"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "need-space-after-doctype"}) - self.stream.unget(data) - self.state = self.beforeDoctypeNameState - return True - - def beforeDoctypeNameState(self): - data = self.stream.char() - if data in spaceCharacters: - pass - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-doctype-name-but-got-right-bracket"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["name"] = "\uFFFD" - self.state = self.doctypeNameState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-doctype-name-but-got-eof"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["name"] = data - self.state = self.doctypeNameState - return True - - def doctypeNameState(self): - data = self.stream.char() - if data in spaceCharacters: - self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) - self.state = self.afterDoctypeNameState - elif data == ">": - self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["name"] += "\uFFFD" - self.state = self.doctypeNameState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype-name"}) - self.currentToken["correct"] = False - self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["name"] += data - return True - - def afterDoctypeNameState(self): - data = self.stream.char() - if data in spaceCharacters: - pass - elif data == ">": - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.currentToken["correct"] = False - self.stream.unget(data) - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - if data in ("p", "P"): - matched = True - for expected in (("u", "U"), ("b", "B"), ("l", "L"), - ("i", "I"), ("c", "C")): - data = self.stream.char() - if data not in expected: - matched = False - break - if matched: - self.state = self.afterDoctypePublicKeywordState - return True - elif data in ("s", "S"): - matched = True - for expected in (("y", "Y"), ("s", "S"), ("t", "T"), - ("e", "E"), ("m", "M")): - data = self.stream.char() - if data not in expected: - matched = False - break - if matched: - self.state = self.afterDoctypeSystemKeywordState - return True - - # All the characters read before the current 'data' will be - # [a-zA-Z], so they're garbage in the bogus doctype and can be - # discarded; only the latest character might be '>' or EOF - # and needs to be ungetted - self.stream.unget(data) - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "expected-space-or-right-bracket-in-doctype", "datavars": - {"data": data}}) - self.currentToken["correct"] = False - self.state = self.bogusDoctypeState - - return True - - def afterDoctypePublicKeywordState(self): - data = self.stream.char() - if data in spaceCharacters: - self.state = self.beforeDoctypePublicIdentifierState - elif data in ("'", '"'): - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.stream.unget(data) - self.state = self.beforeDoctypePublicIdentifierState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.stream.unget(data) - self.state = self.beforeDoctypePublicIdentifierState - return True - - def beforeDoctypePublicIdentifierState(self): - data = self.stream.char() - if data in spaceCharacters: - pass - elif data == "\"": - self.currentToken["publicId"] = "" - self.state = self.doctypePublicIdentifierDoubleQuotedState - elif data == "'": - self.currentToken["publicId"] = "" - self.state = self.doctypePublicIdentifierSingleQuotedState - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-end-of-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.currentToken["correct"] = False - self.state = self.bogusDoctypeState - return True - - def doctypePublicIdentifierDoubleQuotedState(self): - data = self.stream.char() - if data == "\"": - self.state = self.afterDoctypePublicIdentifierState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["publicId"] += "\uFFFD" - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-end-of-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["publicId"] += data - return True - - def doctypePublicIdentifierSingleQuotedState(self): - data = self.stream.char() - if data == "'": - self.state = self.afterDoctypePublicIdentifierState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["publicId"] += "\uFFFD" - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-end-of-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["publicId"] += data - return True - - def afterDoctypePublicIdentifierState(self): - data = self.stream.char() - if data in spaceCharacters: - self.state = self.betweenDoctypePublicAndSystemIdentifiersState - elif data == ">": - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data == '"': - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.currentToken["systemId"] = "" - self.state = self.doctypeSystemIdentifierDoubleQuotedState - elif data == "'": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.currentToken["systemId"] = "" - self.state = self.doctypeSystemIdentifierSingleQuotedState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.currentToken["correct"] = False - self.state = self.bogusDoctypeState - return True - - def betweenDoctypePublicAndSystemIdentifiersState(self): - data = self.stream.char() - if data in spaceCharacters: - pass - elif data == ">": - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data == '"': - self.currentToken["systemId"] = "" - self.state = self.doctypeSystemIdentifierDoubleQuotedState - elif data == "'": - self.currentToken["systemId"] = "" - self.state = self.doctypeSystemIdentifierSingleQuotedState - elif data == EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.currentToken["correct"] = False - self.state = self.bogusDoctypeState - return True - - def afterDoctypeSystemKeywordState(self): - data = self.stream.char() - if data in spaceCharacters: - self.state = self.beforeDoctypeSystemIdentifierState - elif data in ("'", '"'): - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.stream.unget(data) - self.state = self.beforeDoctypeSystemIdentifierState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.stream.unget(data) - self.state = self.beforeDoctypeSystemIdentifierState - return True - - def beforeDoctypeSystemIdentifierState(self): - data = self.stream.char() - if data in spaceCharacters: - pass - elif data == "\"": - self.currentToken["systemId"] = "" - self.state = self.doctypeSystemIdentifierDoubleQuotedState - elif data == "'": - self.currentToken["systemId"] = "" - self.state = self.doctypeSystemIdentifierSingleQuotedState - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.currentToken["correct"] = False - self.state = self.bogusDoctypeState - return True - - def doctypeSystemIdentifierDoubleQuotedState(self): - data = self.stream.char() - if data == "\"": - self.state = self.afterDoctypeSystemIdentifierState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["systemId"] += "\uFFFD" - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-end-of-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["systemId"] += data - return True - - def doctypeSystemIdentifierSingleQuotedState(self): - data = self.stream.char() - if data == "'": - self.state = self.afterDoctypeSystemIdentifierState - elif data == "\u0000": - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - self.currentToken["systemId"] += "\uFFFD" - elif data == ">": - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-end-of-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.currentToken["systemId"] += data - return True - - def afterDoctypeSystemIdentifierState(self): - data = self.stream.char() - if data in spaceCharacters: - pass - elif data == ">": - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "eof-in-doctype"}) - self.currentToken["correct"] = False - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": - "unexpected-char-in-doctype"}) - self.state = self.bogusDoctypeState - return True - - def bogusDoctypeState(self): - data = self.stream.char() - if data == ">": - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - elif data is EOF: - # XXX EMIT - self.stream.unget(data) - self.tokenQueue.append(self.currentToken) - self.state = self.dataState - else: - pass - return True - - def cdataSectionState(self): - data = [] - while True: - data.append(self.stream.charsUntil("]")) - data.append(self.stream.charsUntil(">")) - char = self.stream.char() - if char == EOF: - break - else: - assert char == ">" - if data[-1][-2:] == "]]": - data[-1] = data[-1][:-2] - break - else: - data.append(char) - - data = "".join(data) # pylint:disable=redefined-variable-type - # Deal with null here rather than in the parser - nullCount = data.count("\u0000") - if nullCount > 0: - for _ in range(nullCount): - self.tokenQueue.append({"type": tokenTypes["ParseError"], - "data": "invalid-codepoint"}) - data = data.replace("\u0000", "\uFFFD") - if data: - self.tokenQueue.append({"type": tokenTypes["Characters"], - "data": data}) - self.state = self.dataState - return True diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/__init__.py deleted file mode 100644 index a5ba4bf..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from .py import Trie as PyTrie - -Trie = PyTrie - -# pylint:disable=wrong-import-position -try: - from .datrie import Trie as DATrie -except ImportError: - pass -else: - Trie = DATrie -# pylint:enable=wrong-import-position diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/_base.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/_base.py deleted file mode 100644 index a1158bb..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/_base.py +++ /dev/null @@ -1,37 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from collections import Mapping - - -class Trie(Mapping): - """Abstract base class for tries""" - - def keys(self, prefix=None): - # pylint:disable=arguments-differ - keys = super(Trie, self).keys() - - if prefix is None: - return set(keys) - - return {x for x in keys if x.startswith(prefix)} - - def has_keys_with_prefix(self, prefix): - for key in self.keys(): - if key.startswith(prefix): - return True - - return False - - def longest_prefix(self, prefix): - if prefix in self: - return prefix - - for i in range(1, len(prefix) + 1): - if prefix[:-i] in self: - return prefix[:-i] - - raise KeyError(prefix) - - def longest_prefix_item(self, prefix): - lprefix = self.longest_prefix(prefix) - return (lprefix, self[lprefix]) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/datrie.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/datrie.py deleted file mode 100644 index e2e5f86..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/datrie.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from datrie import Trie as DATrie -from pip._vendor.six import text_type - -from ._base import Trie as ABCTrie - - -class Trie(ABCTrie): - def __init__(self, data): - chars = set() - for key in data.keys(): - if not isinstance(key, text_type): - raise TypeError("All keys must be strings") - for char in key: - chars.add(char) - - self._data = DATrie("".join(chars)) - for key, value in data.items(): - self._data[key] = value - - def __contains__(self, key): - return key in self._data - - def __len__(self): - return len(self._data) - - def __iter__(self): - raise NotImplementedError() - - def __getitem__(self, key): - return self._data[key] - - def keys(self, prefix=None): - return self._data.keys(prefix) - - def has_keys_with_prefix(self, prefix): - return self._data.has_keys_with_prefix(prefix) - - def longest_prefix(self, prefix): - return self._data.longest_prefix(prefix) - - def longest_prefix_item(self, prefix): - return self._data.longest_prefix_item(prefix) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/py.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/py.py deleted file mode 100644 index c178b21..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_trie/py.py +++ /dev/null @@ -1,67 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals -from pip._vendor.six import text_type - -from bisect import bisect_left - -from ._base import Trie as ABCTrie - - -class Trie(ABCTrie): - def __init__(self, data): - if not all(isinstance(x, text_type) for x in data.keys()): - raise TypeError("All keys must be strings") - - self._data = data - self._keys = sorted(data.keys()) - self._cachestr = "" - self._cachepoints = (0, len(data)) - - def __contains__(self, key): - return key in self._data - - def __len__(self): - return len(self._data) - - def __iter__(self): - return iter(self._data) - - def __getitem__(self, key): - return self._data[key] - - def keys(self, prefix=None): - if prefix is None or prefix == "" or not self._keys: - return set(self._keys) - - if prefix.startswith(self._cachestr): - lo, hi = self._cachepoints - start = i = bisect_left(self._keys, prefix, lo, hi) - else: - start = i = bisect_left(self._keys, prefix) - - keys = set() - if start == len(self._keys): - return keys - - while self._keys[i].startswith(prefix): - keys.add(self._keys[i]) - i += 1 - - self._cachestr = prefix - self._cachepoints = (start, i) - - return keys - - def has_keys_with_prefix(self, prefix): - if prefix in self._data: - return True - - if prefix.startswith(self._cachestr): - lo, hi = self._cachepoints - i = bisect_left(self._keys, prefix, lo, hi) - else: - i = bisect_left(self._keys, prefix) - - if i == len(self._keys): - return False - - return self._keys[i].startswith(prefix) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_utils.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_utils.py deleted file mode 100644 index 0703afb..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/_utils.py +++ /dev/null @@ -1,124 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from types import ModuleType - -from pip._vendor.six import text_type - -try: - import xml.etree.cElementTree as default_etree -except ImportError: - import xml.etree.ElementTree as default_etree - - -__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", - "surrogatePairToCodepoint", "moduleFactoryFactory", - "supports_lone_surrogates"] - - -# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be -# caught by the below test. In general this would be any platform -# using UTF-16 as its encoding of unicode strings, such as -# Jython. This is because UTF-16 itself is based on the use of such -# surrogates, and there is no mechanism to further escape such -# escapes. -try: - _x = eval('"\\uD800"') # pylint:disable=eval-used - if not isinstance(_x, text_type): - # We need this with u"" because of http://bugs.jython.org/issue2039 - _x = eval('u"\\uD800"') # pylint:disable=eval-used - assert isinstance(_x, text_type) -except: # pylint:disable=bare-except - supports_lone_surrogates = False -else: - supports_lone_surrogates = True - - -class MethodDispatcher(dict): - """Dict with 2 special properties: - - On initiation, keys that are lists, sets or tuples are converted to - multiple keys so accessing any one of the items in the original - list-like object returns the matching value - - md = MethodDispatcher({("foo", "bar"):"baz"}) - md["foo"] == "baz" - - A default value which can be set through the default attribute. - """ - - def __init__(self, items=()): - # Using _dictEntries instead of directly assigning to self is about - # twice as fast. Please do careful performance testing before changing - # anything here. - _dictEntries = [] - for name, value in items: - if isinstance(name, (list, tuple, frozenset, set)): - for item in name: - _dictEntries.append((item, value)) - else: - _dictEntries.append((name, value)) - dict.__init__(self, _dictEntries) - assert len(self) == len(_dictEntries) - self.default = None - - def __getitem__(self, key): - return dict.get(self, key, self.default) - - -# Some utility functions to deal with weirdness around UCS2 vs UCS4 -# python builds - -def isSurrogatePair(data): - return (len(data) == 2 and - ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and - ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF) - - -def surrogatePairToCodepoint(data): - char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 + - (ord(data[1]) - 0xDC00)) - return char_val - -# Module Factory Factory (no, this isn't Java, I know) -# Here to stop this being duplicated all over the place. - - -def moduleFactoryFactory(factory): - moduleCache = {} - - def moduleFactory(baseModule, *args, **kwargs): - if isinstance(ModuleType.__name__, type("")): - name = "_%s_factory" % baseModule.__name__ - else: - name = b"_%s_factory" % baseModule.__name__ - - kwargs_tuple = tuple(kwargs.items()) - - try: - return moduleCache[name][args][kwargs_tuple] - except KeyError: - mod = ModuleType(name) - objs = factory(baseModule, *args, **kwargs) - mod.__dict__.update(objs) - if "name" not in moduleCache: - moduleCache[name] = {} - if "args" not in moduleCache[name]: - moduleCache[name][args] = {} - if "kwargs" not in moduleCache[name][args]: - moduleCache[name][args][kwargs_tuple] = {} - moduleCache[name][args][kwargs_tuple] = mod - return mod - - return moduleFactory - - -def memoize(func): - cache = {} - - def wrapped(*args, **kwargs): - key = (tuple(args), tuple(kwargs.items())) - if key not in cache: - cache[key] = func(*args, **kwargs) - return cache[key] - - return wrapped diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/constants.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/constants.py deleted file mode 100644 index 1ff8041..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/constants.py +++ /dev/null @@ -1,2947 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -import string - -EOF = None - -E = { - "null-character": - "Null character in input stream, replaced with U+FFFD.", - "invalid-codepoint": - "Invalid codepoint in stream.", - "incorrectly-placed-solidus": - "Solidus (/) incorrectly placed in tag.", - "incorrect-cr-newline-entity": - "Incorrect CR newline entity, replaced with LF.", - "illegal-windows-1252-entity": - "Entity used with illegal number (windows-1252 reference).", - "cant-convert-numeric-entity": - "Numeric entity couldn't be converted to character " - "(codepoint U+%(charAsInt)08x).", - "illegal-codepoint-for-numeric-entity": - "Numeric entity represents an illegal codepoint: " - "U+%(charAsInt)08x.", - "numeric-entity-without-semicolon": - "Numeric entity didn't end with ';'.", - "expected-numeric-entity-but-got-eof": - "Numeric entity expected. Got end of file instead.", - "expected-numeric-entity": - "Numeric entity expected but none found.", - "named-entity-without-semicolon": - "Named entity didn't end with ';'.", - "expected-named-entity": - "Named entity expected. Got none.", - "attributes-in-end-tag": - "End tag contains unexpected attributes.", - 'self-closing-flag-on-end-tag': - "End tag contains unexpected self-closing flag.", - "expected-tag-name-but-got-right-bracket": - "Expected tag name. Got '>' instead.", - "expected-tag-name-but-got-question-mark": - "Expected tag name. Got '?' instead. (HTML doesn't " - "support processing instructions.)", - "expected-tag-name": - "Expected tag name. Got something else instead", - "expected-closing-tag-but-got-right-bracket": - "Expected closing tag. Got '>' instead. Ignoring '</>'.", - "expected-closing-tag-but-got-eof": - "Expected closing tag. Unexpected end of file.", - "expected-closing-tag-but-got-char": - "Expected closing tag. Unexpected character '%(data)s' found.", - "eof-in-tag-name": - "Unexpected end of file in the tag name.", - "expected-attribute-name-but-got-eof": - "Unexpected end of file. Expected attribute name instead.", - "eof-in-attribute-name": - "Unexpected end of file in attribute name.", - "invalid-character-in-attribute-name": - "Invalid character in attribute name", - "duplicate-attribute": - "Dropped duplicate attribute on tag.", - "expected-end-of-tag-name-but-got-eof": - "Unexpected end of file. Expected = or end of tag.", - "expected-attribute-value-but-got-eof": - "Unexpected end of file. Expected attribute value.", - "expected-attribute-value-but-got-right-bracket": - "Expected attribute value. Got '>' instead.", - 'equals-in-unquoted-attribute-value': - "Unexpected = in unquoted attribute", - 'unexpected-character-in-unquoted-attribute-value': - "Unexpected character in unquoted attribute", - "invalid-character-after-attribute-name": - "Unexpected character after attribute name.", - "unexpected-character-after-attribute-value": - "Unexpected character after attribute value.", - "eof-in-attribute-value-double-quote": - "Unexpected end of file in attribute value (\").", - "eof-in-attribute-value-single-quote": - "Unexpected end of file in attribute value (').", - "eof-in-attribute-value-no-quotes": - "Unexpected end of file in attribute value.", - "unexpected-EOF-after-solidus-in-tag": - "Unexpected end of file in tag. Expected >", - "unexpected-character-after-solidus-in-tag": - "Unexpected character after / in tag. Expected >", - "expected-dashes-or-doctype": - "Expected '--' or 'DOCTYPE'. Not found.", - "unexpected-bang-after-double-dash-in-comment": - "Unexpected ! after -- in comment", - "unexpected-space-after-double-dash-in-comment": - "Unexpected space after -- in comment", - "incorrect-comment": - "Incorrect comment.", - "eof-in-comment": - "Unexpected end of file in comment.", - "eof-in-comment-end-dash": - "Unexpected end of file in comment (-)", - "unexpected-dash-after-double-dash-in-comment": - "Unexpected '-' after '--' found in comment.", - "eof-in-comment-double-dash": - "Unexpected end of file in comment (--).", - "eof-in-comment-end-space-state": - "Unexpected end of file in comment.", - "eof-in-comment-end-bang-state": - "Unexpected end of file in comment.", - "unexpected-char-in-comment": - "Unexpected character in comment found.", - "need-space-after-doctype": - "No space after literal string 'DOCTYPE'.", - "expected-doctype-name-but-got-right-bracket": - "Unexpected > character. Expected DOCTYPE name.", - "expected-doctype-name-but-got-eof": - "Unexpected end of file. Expected DOCTYPE name.", - "eof-in-doctype-name": - "Unexpected end of file in DOCTYPE name.", - "eof-in-doctype": - "Unexpected end of file in DOCTYPE.", - "expected-space-or-right-bracket-in-doctype": - "Expected space or '>'. Got '%(data)s'", - "unexpected-end-of-doctype": - "Unexpected end of DOCTYPE.", - "unexpected-char-in-doctype": - "Unexpected character in DOCTYPE.", - "eof-in-innerhtml": - "XXX innerHTML EOF", - "unexpected-doctype": - "Unexpected DOCTYPE. Ignored.", - "non-html-root": - "html needs to be the first start tag.", - "expected-doctype-but-got-eof": - "Unexpected End of file. Expected DOCTYPE.", - "unknown-doctype": - "Erroneous DOCTYPE.", - "expected-doctype-but-got-chars": - "Unexpected non-space characters. Expected DOCTYPE.", - "expected-doctype-but-got-start-tag": - "Unexpected start tag (%(name)s). Expected DOCTYPE.", - "expected-doctype-but-got-end-tag": - "Unexpected end tag (%(name)s). Expected DOCTYPE.", - "end-tag-after-implied-root": - "Unexpected end tag (%(name)s) after the (implied) root element.", - "expected-named-closing-tag-but-got-eof": - "Unexpected end of file. Expected end tag (%(name)s).", - "two-heads-are-not-better-than-one": - "Unexpected start tag head in existing head. Ignored.", - "unexpected-end-tag": - "Unexpected end tag (%(name)s). Ignored.", - "unexpected-start-tag-out-of-my-head": - "Unexpected start tag (%(name)s) that can be in head. Moved.", - "unexpected-start-tag": - "Unexpected start tag (%(name)s).", - "missing-end-tag": - "Missing end tag (%(name)s).", - "missing-end-tags": - "Missing end tags (%(name)s).", - "unexpected-start-tag-implies-end-tag": - "Unexpected start tag (%(startName)s) " - "implies end tag (%(endName)s).", - "unexpected-start-tag-treated-as": - "Unexpected start tag (%(originalName)s). Treated as %(newName)s.", - "deprecated-tag": - "Unexpected start tag %(name)s. Don't use it!", - "unexpected-start-tag-ignored": - "Unexpected start tag %(name)s. Ignored.", - "expected-one-end-tag-but-got-another": - "Unexpected end tag (%(gotName)s). " - "Missing end tag (%(expectedName)s).", - "end-tag-too-early": - "End tag (%(name)s) seen too early. Expected other end tag.", - "end-tag-too-early-named": - "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).", - "end-tag-too-early-ignored": - "End tag (%(name)s) seen too early. Ignored.", - "adoption-agency-1.1": - "End tag (%(name)s) violates step 1, " - "paragraph 1 of the adoption agency algorithm.", - "adoption-agency-1.2": - "End tag (%(name)s) violates step 1, " - "paragraph 2 of the adoption agency algorithm.", - "adoption-agency-1.3": - "End tag (%(name)s) violates step 1, " - "paragraph 3 of the adoption agency algorithm.", - "adoption-agency-4.4": - "End tag (%(name)s) violates step 4, " - "paragraph 4 of the adoption agency algorithm.", - "unexpected-end-tag-treated-as": - "Unexpected end tag (%(originalName)s). Treated as %(newName)s.", - "no-end-tag": - "This element (%(name)s) has no end tag.", - "unexpected-implied-end-tag-in-table": - "Unexpected implied end tag (%(name)s) in the table phase.", - "unexpected-implied-end-tag-in-table-body": - "Unexpected implied end tag (%(name)s) in the table body phase.", - "unexpected-char-implies-table-voodoo": - "Unexpected non-space characters in " - "table context caused voodoo mode.", - "unexpected-hidden-input-in-table": - "Unexpected input with type hidden in table context.", - "unexpected-form-in-table": - "Unexpected form in table context.", - "unexpected-start-tag-implies-table-voodoo": - "Unexpected start tag (%(name)s) in " - "table context caused voodoo mode.", - "unexpected-end-tag-implies-table-voodoo": - "Unexpected end tag (%(name)s) in " - "table context caused voodoo mode.", - "unexpected-cell-in-table-body": - "Unexpected table cell start tag (%(name)s) " - "in the table body phase.", - "unexpected-cell-end-tag": - "Got table cell end tag (%(name)s) " - "while required end tags are missing.", - "unexpected-end-tag-in-table-body": - "Unexpected end tag (%(name)s) in the table body phase. Ignored.", - "unexpected-implied-end-tag-in-table-row": - "Unexpected implied end tag (%(name)s) in the table row phase.", - "unexpected-end-tag-in-table-row": - "Unexpected end tag (%(name)s) in the table row phase. Ignored.", - "unexpected-select-in-select": - "Unexpected select start tag in the select phase " - "treated as select end tag.", - "unexpected-input-in-select": - "Unexpected input start tag in the select phase.", - "unexpected-start-tag-in-select": - "Unexpected start tag token (%(name)s in the select phase. " - "Ignored.", - "unexpected-end-tag-in-select": - "Unexpected end tag (%(name)s) in the select phase. Ignored.", - "unexpected-table-element-start-tag-in-select-in-table": - "Unexpected table element start tag (%(name)s) in the select in table phase.", - "unexpected-table-element-end-tag-in-select-in-table": - "Unexpected table element end tag (%(name)s) in the select in table phase.", - "unexpected-char-after-body": - "Unexpected non-space characters in the after body phase.", - "unexpected-start-tag-after-body": - "Unexpected start tag token (%(name)s)" - " in the after body phase.", - "unexpected-end-tag-after-body": - "Unexpected end tag token (%(name)s)" - " in the after body phase.", - "unexpected-char-in-frameset": - "Unexpected characters in the frameset phase. Characters ignored.", - "unexpected-start-tag-in-frameset": - "Unexpected start tag token (%(name)s)" - " in the frameset phase. Ignored.", - "unexpected-frameset-in-frameset-innerhtml": - "Unexpected end tag token (frameset) " - "in the frameset phase (innerHTML).", - "unexpected-end-tag-in-frameset": - "Unexpected end tag token (%(name)s)" - " in the frameset phase. Ignored.", - "unexpected-char-after-frameset": - "Unexpected non-space characters in the " - "after frameset phase. Ignored.", - "unexpected-start-tag-after-frameset": - "Unexpected start tag (%(name)s)" - " in the after frameset phase. Ignored.", - "unexpected-end-tag-after-frameset": - "Unexpected end tag (%(name)s)" - " in the after frameset phase. Ignored.", - "unexpected-end-tag-after-body-innerhtml": - "Unexpected end tag after body(innerHtml)", - "expected-eof-but-got-char": - "Unexpected non-space characters. Expected end of file.", - "expected-eof-but-got-start-tag": - "Unexpected start tag (%(name)s)" - ". Expected end of file.", - "expected-eof-but-got-end-tag": - "Unexpected end tag (%(name)s)" - ". Expected end of file.", - "eof-in-table": - "Unexpected end of file. Expected table content.", - "eof-in-select": - "Unexpected end of file. Expected select content.", - "eof-in-frameset": - "Unexpected end of file. Expected frameset content.", - "eof-in-script-in-script": - "Unexpected end of file. Expected script content.", - "eof-in-foreign-lands": - "Unexpected end of file. Expected foreign content", - "non-void-element-with-trailing-solidus": - "Trailing solidus not allowed on element %(name)s", - "unexpected-html-element-in-foreign-content": - "Element %(name)s not allowed in a non-html context", - "unexpected-end-tag-before-html": - "Unexpected end tag (%(name)s) before html.", - "unexpected-inhead-noscript-tag": - "Element %(name)s not allowed in a inhead-noscript context", - "eof-in-head-noscript": - "Unexpected end of file. Expected inhead-noscript content", - "char-in-head-noscript": - "Unexpected non-space character. Expected inhead-noscript content", - "XXX-undefined-error": - "Undefined error (this sucks and should be fixed)", -} - -namespaces = { - "html": "http://www.w3.org/1999/xhtml", - "mathml": "http://www.w3.org/1998/Math/MathML", - "svg": "http://www.w3.org/2000/svg", - "xlink": "http://www.w3.org/1999/xlink", - "xml": "http://www.w3.org/XML/1998/namespace", - "xmlns": "http://www.w3.org/2000/xmlns/" -} - -scopingElements = frozenset([ - (namespaces["html"], "applet"), - (namespaces["html"], "caption"), - (namespaces["html"], "html"), - (namespaces["html"], "marquee"), - (namespaces["html"], "object"), - (namespaces["html"], "table"), - (namespaces["html"], "td"), - (namespaces["html"], "th"), - (namespaces["mathml"], "mi"), - (namespaces["mathml"], "mo"), - (namespaces["mathml"], "mn"), - (namespaces["mathml"], "ms"), - (namespaces["mathml"], "mtext"), - (namespaces["mathml"], "annotation-xml"), - (namespaces["svg"], "foreignObject"), - (namespaces["svg"], "desc"), - (namespaces["svg"], "title"), -]) - -formattingElements = frozenset([ - (namespaces["html"], "a"), - (namespaces["html"], "b"), - (namespaces["html"], "big"), - (namespaces["html"], "code"), - (namespaces["html"], "em"), - (namespaces["html"], "font"), - (namespaces["html"], "i"), - (namespaces["html"], "nobr"), - (namespaces["html"], "s"), - (namespaces["html"], "small"), - (namespaces["html"], "strike"), - (namespaces["html"], "strong"), - (namespaces["html"], "tt"), - (namespaces["html"], "u") -]) - -specialElements = frozenset([ - (namespaces["html"], "address"), - (namespaces["html"], "applet"), - (namespaces["html"], "area"), - (namespaces["html"], "article"), - (namespaces["html"], "aside"), - (namespaces["html"], "base"), - (namespaces["html"], "basefont"), - (namespaces["html"], "bgsound"), - (namespaces["html"], "blockquote"), - (namespaces["html"], "body"), - (namespaces["html"], "br"), - (namespaces["html"], "button"), - (namespaces["html"], "caption"), - (namespaces["html"], "center"), - (namespaces["html"], "col"), - (namespaces["html"], "colgroup"), - (namespaces["html"], "command"), - (namespaces["html"], "dd"), - (namespaces["html"], "details"), - (namespaces["html"], "dir"), - (namespaces["html"], "div"), - (namespaces["html"], "dl"), - (namespaces["html"], "dt"), - (namespaces["html"], "embed"), - (namespaces["html"], "fieldset"), - (namespaces["html"], "figure"), - (namespaces["html"], "footer"), - (namespaces["html"], "form"), - (namespaces["html"], "frame"), - (namespaces["html"], "frameset"), - (namespaces["html"], "h1"), - (namespaces["html"], "h2"), - (namespaces["html"], "h3"), - (namespaces["html"], "h4"), - (namespaces["html"], "h5"), - (namespaces["html"], "h6"), - (namespaces["html"], "head"), - (namespaces["html"], "header"), - (namespaces["html"], "hr"), - (namespaces["html"], "html"), - (namespaces["html"], "iframe"), - # Note that image is commented out in the spec as "this isn't an - # element that can end up on the stack, so it doesn't matter," - (namespaces["html"], "image"), - (namespaces["html"], "img"), - (namespaces["html"], "input"), - (namespaces["html"], "isindex"), - (namespaces["html"], "li"), - (namespaces["html"], "link"), - (namespaces["html"], "listing"), - (namespaces["html"], "marquee"), - (namespaces["html"], "menu"), - (namespaces["html"], "meta"), - (namespaces["html"], "nav"), - (namespaces["html"], "noembed"), - (namespaces["html"], "noframes"), - (namespaces["html"], "noscript"), - (namespaces["html"], "object"), - (namespaces["html"], "ol"), - (namespaces["html"], "p"), - (namespaces["html"], "param"), - (namespaces["html"], "plaintext"), - (namespaces["html"], "pre"), - (namespaces["html"], "script"), - (namespaces["html"], "section"), - (namespaces["html"], "select"), - (namespaces["html"], "style"), - (namespaces["html"], "table"), - (namespaces["html"], "tbody"), - (namespaces["html"], "td"), - (namespaces["html"], "textarea"), - (namespaces["html"], "tfoot"), - (namespaces["html"], "th"), - (namespaces["html"], "thead"), - (namespaces["html"], "title"), - (namespaces["html"], "tr"), - (namespaces["html"], "ul"), - (namespaces["html"], "wbr"), - (namespaces["html"], "xmp"), - (namespaces["svg"], "foreignObject") -]) - -htmlIntegrationPointElements = frozenset([ - (namespaces["mathml"], "annotation-xml"), - (namespaces["svg"], "foreignObject"), - (namespaces["svg"], "desc"), - (namespaces["svg"], "title") -]) - -mathmlTextIntegrationPointElements = frozenset([ - (namespaces["mathml"], "mi"), - (namespaces["mathml"], "mo"), - (namespaces["mathml"], "mn"), - (namespaces["mathml"], "ms"), - (namespaces["mathml"], "mtext") -]) - -adjustSVGAttributes = { - "attributename": "attributeName", - "attributetype": "attributeType", - "basefrequency": "baseFrequency", - "baseprofile": "baseProfile", - "calcmode": "calcMode", - "clippathunits": "clipPathUnits", - "contentscripttype": "contentScriptType", - "contentstyletype": "contentStyleType", - "diffuseconstant": "diffuseConstant", - "edgemode": "edgeMode", - "externalresourcesrequired": "externalResourcesRequired", - "filterres": "filterRes", - "filterunits": "filterUnits", - "glyphref": "glyphRef", - "gradienttransform": "gradientTransform", - "gradientunits": "gradientUnits", - "kernelmatrix": "kernelMatrix", - "kernelunitlength": "kernelUnitLength", - "keypoints": "keyPoints", - "keysplines": "keySplines", - "keytimes": "keyTimes", - "lengthadjust": "lengthAdjust", - "limitingconeangle": "limitingConeAngle", - "markerheight": "markerHeight", - "markerunits": "markerUnits", - "markerwidth": "markerWidth", - "maskcontentunits": "maskContentUnits", - "maskunits": "maskUnits", - "numoctaves": "numOctaves", - "pathlength": "pathLength", - "patterncontentunits": "patternContentUnits", - "patterntransform": "patternTransform", - "patternunits": "patternUnits", - "pointsatx": "pointsAtX", - "pointsaty": "pointsAtY", - "pointsatz": "pointsAtZ", - "preservealpha": "preserveAlpha", - "preserveaspectratio": "preserveAspectRatio", - "primitiveunits": "primitiveUnits", - "refx": "refX", - "refy": "refY", - "repeatcount": "repeatCount", - "repeatdur": "repeatDur", - "requiredextensions": "requiredExtensions", - "requiredfeatures": "requiredFeatures", - "specularconstant": "specularConstant", - "specularexponent": "specularExponent", - "spreadmethod": "spreadMethod", - "startoffset": "startOffset", - "stddeviation": "stdDeviation", - "stitchtiles": "stitchTiles", - "surfacescale": "surfaceScale", - "systemlanguage": "systemLanguage", - "tablevalues": "tableValues", - "targetx": "targetX", - "targety": "targetY", - "textlength": "textLength", - "viewbox": "viewBox", - "viewtarget": "viewTarget", - "xchannelselector": "xChannelSelector", - "ychannelselector": "yChannelSelector", - "zoomandpan": "zoomAndPan" -} - -adjustMathMLAttributes = {"definitionurl": "definitionURL"} - -adjustForeignAttributes = { - "xlink:actuate": ("xlink", "actuate", namespaces["xlink"]), - "xlink:arcrole": ("xlink", "arcrole", namespaces["xlink"]), - "xlink:href": ("xlink", "href", namespaces["xlink"]), - "xlink:role": ("xlink", "role", namespaces["xlink"]), - "xlink:show": ("xlink", "show", namespaces["xlink"]), - "xlink:title": ("xlink", "title", namespaces["xlink"]), - "xlink:type": ("xlink", "type", namespaces["xlink"]), - "xml:base": ("xml", "base", namespaces["xml"]), - "xml:lang": ("xml", "lang", namespaces["xml"]), - "xml:space": ("xml", "space", namespaces["xml"]), - "xmlns": (None, "xmlns", namespaces["xmlns"]), - "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) -} - -unadjustForeignAttributes = dict([((ns, local), qname) for qname, (prefix, local, ns) in - adjustForeignAttributes.items()]) - -spaceCharacters = frozenset([ - "\t", - "\n", - "\u000C", - " ", - "\r" -]) - -tableInsertModeElements = frozenset([ - "table", - "tbody", - "tfoot", - "thead", - "tr" -]) - -asciiLowercase = frozenset(string.ascii_lowercase) -asciiUppercase = frozenset(string.ascii_uppercase) -asciiLetters = frozenset(string.ascii_letters) -digits = frozenset(string.digits) -hexDigits = frozenset(string.hexdigits) - -asciiUpper2Lower = dict([(ord(c), ord(c.lower())) - for c in string.ascii_uppercase]) - -# Heading elements need to be ordered -headingElements = ( - "h1", - "h2", - "h3", - "h4", - "h5", - "h6" -) - -voidElements = frozenset([ - "base", - "command", - "event-source", - "link", - "meta", - "hr", - "br", - "img", - "embed", - "param", - "area", - "col", - "input", - "source", - "track" -]) - -cdataElements = frozenset(['title', 'textarea']) - -rcdataElements = frozenset([ - 'style', - 'script', - 'xmp', - 'iframe', - 'noembed', - 'noframes', - 'noscript' -]) - -booleanAttributes = { - "": frozenset(["irrelevant", "itemscope"]), - "style": frozenset(["scoped"]), - "img": frozenset(["ismap"]), - "audio": frozenset(["autoplay", "controls"]), - "video": frozenset(["autoplay", "controls"]), - "script": frozenset(["defer", "async"]), - "details": frozenset(["open"]), - "datagrid": frozenset(["multiple", "disabled"]), - "command": frozenset(["hidden", "disabled", "checked", "default"]), - "hr": frozenset(["noshade"]), - "menu": frozenset(["autosubmit"]), - "fieldset": frozenset(["disabled", "readonly"]), - "option": frozenset(["disabled", "readonly", "selected"]), - "optgroup": frozenset(["disabled", "readonly"]), - "button": frozenset(["disabled", "autofocus"]), - "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]), - "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]), - "output": frozenset(["disabled", "readonly"]), - "iframe": frozenset(["seamless"]), -} - -# entitiesWindows1252 has to be _ordered_ and needs to have an index. It -# therefore can't be a frozenset. -entitiesWindows1252 = ( - 8364, # 0x80 0x20AC EURO SIGN - 65533, # 0x81 UNDEFINED - 8218, # 0x82 0x201A SINGLE LOW-9 QUOTATION MARK - 402, # 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK - 8222, # 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK - 8230, # 0x85 0x2026 HORIZONTAL ELLIPSIS - 8224, # 0x86 0x2020 DAGGER - 8225, # 0x87 0x2021 DOUBLE DAGGER - 710, # 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT - 8240, # 0x89 0x2030 PER MILLE SIGN - 352, # 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON - 8249, # 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK - 338, # 0x8C 0x0152 LATIN CAPITAL LIGATURE OE - 65533, # 0x8D UNDEFINED - 381, # 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON - 65533, # 0x8F UNDEFINED - 65533, # 0x90 UNDEFINED - 8216, # 0x91 0x2018 LEFT SINGLE QUOTATION MARK - 8217, # 0x92 0x2019 RIGHT SINGLE QUOTATION MARK - 8220, # 0x93 0x201C LEFT DOUBLE QUOTATION MARK - 8221, # 0x94 0x201D RIGHT DOUBLE QUOTATION MARK - 8226, # 0x95 0x2022 BULLET - 8211, # 0x96 0x2013 EN DASH - 8212, # 0x97 0x2014 EM DASH - 732, # 0x98 0x02DC SMALL TILDE - 8482, # 0x99 0x2122 TRADE MARK SIGN - 353, # 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON - 8250, # 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - 339, # 0x9C 0x0153 LATIN SMALL LIGATURE OE - 65533, # 0x9D UNDEFINED - 382, # 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON - 376 # 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS -) - -xmlEntities = frozenset(['lt;', 'gt;', 'amp;', 'apos;', 'quot;']) - -entities = { - "AElig": "\xc6", - "AElig;": "\xc6", - "AMP": "&", - "AMP;": "&", - "Aacute": "\xc1", - "Aacute;": "\xc1", - "Abreve;": "\u0102", - "Acirc": "\xc2", - "Acirc;": "\xc2", - "Acy;": "\u0410", - "Afr;": "\U0001d504", - "Agrave": "\xc0", - "Agrave;": "\xc0", - "Alpha;": "\u0391", - "Amacr;": "\u0100", - "And;": "\u2a53", - "Aogon;": "\u0104", - "Aopf;": "\U0001d538", - "ApplyFunction;": "\u2061", - "Aring": "\xc5", - "Aring;": "\xc5", - "Ascr;": "\U0001d49c", - "Assign;": "\u2254", - "Atilde": "\xc3", - "Atilde;": "\xc3", - "Auml": "\xc4", - "Auml;": "\xc4", - "Backslash;": "\u2216", - "Barv;": "\u2ae7", - "Barwed;": "\u2306", - "Bcy;": "\u0411", - "Because;": "\u2235", - "Bernoullis;": "\u212c", - "Beta;": "\u0392", - "Bfr;": "\U0001d505", - "Bopf;": "\U0001d539", - "Breve;": "\u02d8", - "Bscr;": "\u212c", - "Bumpeq;": "\u224e", - "CHcy;": "\u0427", - "COPY": "\xa9", - "COPY;": "\xa9", - "Cacute;": "\u0106", - "Cap;": "\u22d2", - "CapitalDifferentialD;": "\u2145", - "Cayleys;": "\u212d", - "Ccaron;": "\u010c", - "Ccedil": "\xc7", - "Ccedil;": "\xc7", - "Ccirc;": "\u0108", - "Cconint;": "\u2230", - "Cdot;": "\u010a", - "Cedilla;": "\xb8", - "CenterDot;": "\xb7", - "Cfr;": "\u212d", - "Chi;": "\u03a7", - "CircleDot;": "\u2299", - "CircleMinus;": "\u2296", - "CirclePlus;": "\u2295", - "CircleTimes;": "\u2297", - "ClockwiseContourIntegral;": "\u2232", - "CloseCurlyDoubleQuote;": "\u201d", - "CloseCurlyQuote;": "\u2019", - "Colon;": "\u2237", - "Colone;": "\u2a74", - "Congruent;": "\u2261", - "Conint;": "\u222f", - "ContourIntegral;": "\u222e", - "Copf;": "\u2102", - "Coproduct;": "\u2210", - "CounterClockwiseContourIntegral;": "\u2233", - "Cross;": "\u2a2f", - "Cscr;": "\U0001d49e", - "Cup;": "\u22d3", - "CupCap;": "\u224d", - "DD;": "\u2145", - "DDotrahd;": "\u2911", - "DJcy;": "\u0402", - "DScy;": "\u0405", - "DZcy;": "\u040f", - "Dagger;": "\u2021", - "Darr;": "\u21a1", - "Dashv;": "\u2ae4", - "Dcaron;": "\u010e", - "Dcy;": "\u0414", - "Del;": "\u2207", - "Delta;": "\u0394", - "Dfr;": "\U0001d507", - "DiacriticalAcute;": "\xb4", - "DiacriticalDot;": "\u02d9", - "DiacriticalDoubleAcute;": "\u02dd", - "DiacriticalGrave;": "`", - "DiacriticalTilde;": "\u02dc", - "Diamond;": "\u22c4", - "DifferentialD;": "\u2146", - "Dopf;": "\U0001d53b", - "Dot;": "\xa8", - "DotDot;": "\u20dc", - "DotEqual;": "\u2250", - "DoubleContourIntegral;": "\u222f", - "DoubleDot;": "\xa8", - "DoubleDownArrow;": "\u21d3", - "DoubleLeftArrow;": "\u21d0", - "DoubleLeftRightArrow;": "\u21d4", - "DoubleLeftTee;": "\u2ae4", - "DoubleLongLeftArrow;": "\u27f8", - "DoubleLongLeftRightArrow;": "\u27fa", - "DoubleLongRightArrow;": "\u27f9", - "DoubleRightArrow;": "\u21d2", - "DoubleRightTee;": "\u22a8", - "DoubleUpArrow;": "\u21d1", - "DoubleUpDownArrow;": "\u21d5", - "DoubleVerticalBar;": "\u2225", - "DownArrow;": "\u2193", - "DownArrowBar;": "\u2913", - "DownArrowUpArrow;": "\u21f5", - "DownBreve;": "\u0311", - "DownLeftRightVector;": "\u2950", - "DownLeftTeeVector;": "\u295e", - "DownLeftVector;": "\u21bd", - "DownLeftVectorBar;": "\u2956", - "DownRightTeeVector;": "\u295f", - "DownRightVector;": "\u21c1", - "DownRightVectorBar;": "\u2957", - "DownTee;": "\u22a4", - "DownTeeArrow;": "\u21a7", - "Downarrow;": "\u21d3", - "Dscr;": "\U0001d49f", - "Dstrok;": "\u0110", - "ENG;": "\u014a", - "ETH": "\xd0", - "ETH;": "\xd0", - "Eacute": "\xc9", - "Eacute;": "\xc9", - "Ecaron;": "\u011a", - "Ecirc": "\xca", - "Ecirc;": "\xca", - "Ecy;": "\u042d", - "Edot;": "\u0116", - "Efr;": "\U0001d508", - "Egrave": "\xc8", - "Egrave;": "\xc8", - "Element;": "\u2208", - "Emacr;": "\u0112", - "EmptySmallSquare;": "\u25fb", - "EmptyVerySmallSquare;": "\u25ab", - "Eogon;": "\u0118", - "Eopf;": "\U0001d53c", - "Epsilon;": "\u0395", - "Equal;": "\u2a75", - "EqualTilde;": "\u2242", - "Equilibrium;": "\u21cc", - "Escr;": "\u2130", - "Esim;": "\u2a73", - "Eta;": "\u0397", - "Euml": "\xcb", - "Euml;": "\xcb", - "Exists;": "\u2203", - "ExponentialE;": "\u2147", - "Fcy;": "\u0424", - "Ffr;": "\U0001d509", - "FilledSmallSquare;": "\u25fc", - "FilledVerySmallSquare;": "\u25aa", - "Fopf;": "\U0001d53d", - "ForAll;": "\u2200", - "Fouriertrf;": "\u2131", - "Fscr;": "\u2131", - "GJcy;": "\u0403", - "GT": ">", - "GT;": ">", - "Gamma;": "\u0393", - "Gammad;": "\u03dc", - "Gbreve;": "\u011e", - "Gcedil;": "\u0122", - "Gcirc;": "\u011c", - "Gcy;": "\u0413", - "Gdot;": "\u0120", - "Gfr;": "\U0001d50a", - "Gg;": "\u22d9", - "Gopf;": "\U0001d53e", - "GreaterEqual;": "\u2265", - "GreaterEqualLess;": "\u22db", - "GreaterFullEqual;": "\u2267", - "GreaterGreater;": "\u2aa2", - "GreaterLess;": "\u2277", - "GreaterSlantEqual;": "\u2a7e", - "GreaterTilde;": "\u2273", - "Gscr;": "\U0001d4a2", - "Gt;": "\u226b", - "HARDcy;": "\u042a", - "Hacek;": "\u02c7", - "Hat;": "^", - "Hcirc;": "\u0124", - "Hfr;": "\u210c", - "HilbertSpace;": "\u210b", - "Hopf;": "\u210d", - "HorizontalLine;": "\u2500", - "Hscr;": "\u210b", - "Hstrok;": "\u0126", - "HumpDownHump;": "\u224e", - "HumpEqual;": "\u224f", - "IEcy;": "\u0415", - "IJlig;": "\u0132", - "IOcy;": "\u0401", - "Iacute": "\xcd", - "Iacute;": "\xcd", - "Icirc": "\xce", - "Icirc;": "\xce", - "Icy;": "\u0418", - "Idot;": "\u0130", - "Ifr;": "\u2111", - "Igrave": "\xcc", - "Igrave;": "\xcc", - "Im;": "\u2111", - "Imacr;": "\u012a", - "ImaginaryI;": "\u2148", - "Implies;": "\u21d2", - "Int;": "\u222c", - "Integral;": "\u222b", - "Intersection;": "\u22c2", - "InvisibleComma;": "\u2063", - "InvisibleTimes;": "\u2062", - "Iogon;": "\u012e", - "Iopf;": "\U0001d540", - "Iota;": "\u0399", - "Iscr;": "\u2110", - "Itilde;": "\u0128", - "Iukcy;": "\u0406", - "Iuml": "\xcf", - "Iuml;": "\xcf", - "Jcirc;": "\u0134", - "Jcy;": "\u0419", - "Jfr;": "\U0001d50d", - "Jopf;": "\U0001d541", - "Jscr;": "\U0001d4a5", - "Jsercy;": "\u0408", - "Jukcy;": "\u0404", - "KHcy;": "\u0425", - "KJcy;": "\u040c", - "Kappa;": "\u039a", - "Kcedil;": "\u0136", - "Kcy;": "\u041a", - "Kfr;": "\U0001d50e", - "Kopf;": "\U0001d542", - "Kscr;": "\U0001d4a6", - "LJcy;": "\u0409", - "LT": "<", - "LT;": "<", - "Lacute;": "\u0139", - "Lambda;": "\u039b", - "Lang;": "\u27ea", - "Laplacetrf;": "\u2112", - "Larr;": "\u219e", - "Lcaron;": "\u013d", - "Lcedil;": "\u013b", - "Lcy;": "\u041b", - "LeftAngleBracket;": "\u27e8", - "LeftArrow;": "\u2190", - "LeftArrowBar;": "\u21e4", - "LeftArrowRightArrow;": "\u21c6", - "LeftCeiling;": "\u2308", - "LeftDoubleBracket;": "\u27e6", - "LeftDownTeeVector;": "\u2961", - "LeftDownVector;": "\u21c3", - "LeftDownVectorBar;": "\u2959", - "LeftFloor;": "\u230a", - "LeftRightArrow;": "\u2194", - "LeftRightVector;": "\u294e", - "LeftTee;": "\u22a3", - "LeftTeeArrow;": "\u21a4", - "LeftTeeVector;": "\u295a", - "LeftTriangle;": "\u22b2", - "LeftTriangleBar;": "\u29cf", - "LeftTriangleEqual;": "\u22b4", - "LeftUpDownVector;": "\u2951", - "LeftUpTeeVector;": "\u2960", - "LeftUpVector;": "\u21bf", - "LeftUpVectorBar;": "\u2958", - "LeftVector;": "\u21bc", - "LeftVectorBar;": "\u2952", - "Leftarrow;": "\u21d0", - "Leftrightarrow;": "\u21d4", - "LessEqualGreater;": "\u22da", - "LessFullEqual;": "\u2266", - "LessGreater;": "\u2276", - "LessLess;": "\u2aa1", - "LessSlantEqual;": "\u2a7d", - "LessTilde;": "\u2272", - "Lfr;": "\U0001d50f", - "Ll;": "\u22d8", - "Lleftarrow;": "\u21da", - "Lmidot;": "\u013f", - "LongLeftArrow;": "\u27f5", - "LongLeftRightArrow;": "\u27f7", - "LongRightArrow;": "\u27f6", - "Longleftarrow;": "\u27f8", - "Longleftrightarrow;": "\u27fa", - "Longrightarrow;": "\u27f9", - "Lopf;": "\U0001d543", - "LowerLeftArrow;": "\u2199", - "LowerRightArrow;": "\u2198", - "Lscr;": "\u2112", - "Lsh;": "\u21b0", - "Lstrok;": "\u0141", - "Lt;": "\u226a", - "Map;": "\u2905", - "Mcy;": "\u041c", - "MediumSpace;": "\u205f", - "Mellintrf;": "\u2133", - "Mfr;": "\U0001d510", - "MinusPlus;": "\u2213", - "Mopf;": "\U0001d544", - "Mscr;": "\u2133", - "Mu;": "\u039c", - "NJcy;": "\u040a", - "Nacute;": "\u0143", - "Ncaron;": "\u0147", - "Ncedil;": "\u0145", - "Ncy;": "\u041d", - "NegativeMediumSpace;": "\u200b", - "NegativeThickSpace;": "\u200b", - "NegativeThinSpace;": "\u200b", - "NegativeVeryThinSpace;": "\u200b", - "NestedGreaterGreater;": "\u226b", - "NestedLessLess;": "\u226a", - "NewLine;": "\n", - "Nfr;": "\U0001d511", - "NoBreak;": "\u2060", - "NonBreakingSpace;": "\xa0", - "Nopf;": "\u2115", - "Not;": "\u2aec", - "NotCongruent;": "\u2262", - "NotCupCap;": "\u226d", - "NotDoubleVerticalBar;": "\u2226", - "NotElement;": "\u2209", - "NotEqual;": "\u2260", - "NotEqualTilde;": "\u2242\u0338", - "NotExists;": "\u2204", - "NotGreater;": "\u226f", - "NotGreaterEqual;": "\u2271", - "NotGreaterFullEqual;": "\u2267\u0338", - "NotGreaterGreater;": "\u226b\u0338", - "NotGreaterLess;": "\u2279", - "NotGreaterSlantEqual;": "\u2a7e\u0338", - "NotGreaterTilde;": "\u2275", - "NotHumpDownHump;": "\u224e\u0338", - "NotHumpEqual;": "\u224f\u0338", - "NotLeftTriangle;": "\u22ea", - "NotLeftTriangleBar;": "\u29cf\u0338", - "NotLeftTriangleEqual;": "\u22ec", - "NotLess;": "\u226e", - "NotLessEqual;": "\u2270", - "NotLessGreater;": "\u2278", - "NotLessLess;": "\u226a\u0338", - "NotLessSlantEqual;": "\u2a7d\u0338", - "NotLessTilde;": "\u2274", - "NotNestedGreaterGreater;": "\u2aa2\u0338", - "NotNestedLessLess;": "\u2aa1\u0338", - "NotPrecedes;": "\u2280", - "NotPrecedesEqual;": "\u2aaf\u0338", - "NotPrecedesSlantEqual;": "\u22e0", - "NotReverseElement;": "\u220c", - "NotRightTriangle;": "\u22eb", - "NotRightTriangleBar;": "\u29d0\u0338", - "NotRightTriangleEqual;": "\u22ed", - "NotSquareSubset;": "\u228f\u0338", - "NotSquareSubsetEqual;": "\u22e2", - "NotSquareSuperset;": "\u2290\u0338", - "NotSquareSupersetEqual;": "\u22e3", - "NotSubset;": "\u2282\u20d2", - "NotSubsetEqual;": "\u2288", - "NotSucceeds;": "\u2281", - "NotSucceedsEqual;": "\u2ab0\u0338", - "NotSucceedsSlantEqual;": "\u22e1", - "NotSucceedsTilde;": "\u227f\u0338", - "NotSuperset;": "\u2283\u20d2", - "NotSupersetEqual;": "\u2289", - "NotTilde;": "\u2241", - "NotTildeEqual;": "\u2244", - "NotTildeFullEqual;": "\u2247", - "NotTildeTilde;": "\u2249", - "NotVerticalBar;": "\u2224", - "Nscr;": "\U0001d4a9", - "Ntilde": "\xd1", - "Ntilde;": "\xd1", - "Nu;": "\u039d", - "OElig;": "\u0152", - "Oacute": "\xd3", - "Oacute;": "\xd3", - "Ocirc": "\xd4", - "Ocirc;": "\xd4", - "Ocy;": "\u041e", - "Odblac;": "\u0150", - "Ofr;": "\U0001d512", - "Ograve": "\xd2", - "Ograve;": "\xd2", - "Omacr;": "\u014c", - "Omega;": "\u03a9", - "Omicron;": "\u039f", - "Oopf;": "\U0001d546", - "OpenCurlyDoubleQuote;": "\u201c", - "OpenCurlyQuote;": "\u2018", - "Or;": "\u2a54", - "Oscr;": "\U0001d4aa", - "Oslash": "\xd8", - "Oslash;": "\xd8", - "Otilde": "\xd5", - "Otilde;": "\xd5", - "Otimes;": "\u2a37", - "Ouml": "\xd6", - "Ouml;": "\xd6", - "OverBar;": "\u203e", - "OverBrace;": "\u23de", - "OverBracket;": "\u23b4", - "OverParenthesis;": "\u23dc", - "PartialD;": "\u2202", - "Pcy;": "\u041f", - "Pfr;": "\U0001d513", - "Phi;": "\u03a6", - "Pi;": "\u03a0", - "PlusMinus;": "\xb1", - "Poincareplane;": "\u210c", - "Popf;": "\u2119", - "Pr;": "\u2abb", - "Precedes;": "\u227a", - "PrecedesEqual;": "\u2aaf", - "PrecedesSlantEqual;": "\u227c", - "PrecedesTilde;": "\u227e", - "Prime;": "\u2033", - "Product;": "\u220f", - "Proportion;": "\u2237", - "Proportional;": "\u221d", - "Pscr;": "\U0001d4ab", - "Psi;": "\u03a8", - "QUOT": "\"", - "QUOT;": "\"", - "Qfr;": "\U0001d514", - "Qopf;": "\u211a", - "Qscr;": "\U0001d4ac", - "RBarr;": "\u2910", - "REG": "\xae", - "REG;": "\xae", - "Racute;": "\u0154", - "Rang;": "\u27eb", - "Rarr;": "\u21a0", - "Rarrtl;": "\u2916", - "Rcaron;": "\u0158", - "Rcedil;": "\u0156", - "Rcy;": "\u0420", - "Re;": "\u211c", - "ReverseElement;": "\u220b", - "ReverseEquilibrium;": "\u21cb", - "ReverseUpEquilibrium;": "\u296f", - "Rfr;": "\u211c", - "Rho;": "\u03a1", - "RightAngleBracket;": "\u27e9", - "RightArrow;": "\u2192", - "RightArrowBar;": "\u21e5", - "RightArrowLeftArrow;": "\u21c4", - "RightCeiling;": "\u2309", - "RightDoubleBracket;": "\u27e7", - "RightDownTeeVector;": "\u295d", - "RightDownVector;": "\u21c2", - "RightDownVectorBar;": "\u2955", - "RightFloor;": "\u230b", - "RightTee;": "\u22a2", - "RightTeeArrow;": "\u21a6", - "RightTeeVector;": "\u295b", - "RightTriangle;": "\u22b3", - "RightTriangleBar;": "\u29d0", - "RightTriangleEqual;": "\u22b5", - "RightUpDownVector;": "\u294f", - "RightUpTeeVector;": "\u295c", - "RightUpVector;": "\u21be", - "RightUpVectorBar;": "\u2954", - "RightVector;": "\u21c0", - "RightVectorBar;": "\u2953", - "Rightarrow;": "\u21d2", - "Ropf;": "\u211d", - "RoundImplies;": "\u2970", - "Rrightarrow;": "\u21db", - "Rscr;": "\u211b", - "Rsh;": "\u21b1", - "RuleDelayed;": "\u29f4", - "SHCHcy;": "\u0429", - "SHcy;": "\u0428", - "SOFTcy;": "\u042c", - "Sacute;": "\u015a", - "Sc;": "\u2abc", - "Scaron;": "\u0160", - "Scedil;": "\u015e", - "Scirc;": "\u015c", - "Scy;": "\u0421", - "Sfr;": "\U0001d516", - "ShortDownArrow;": "\u2193", - "ShortLeftArrow;": "\u2190", - "ShortRightArrow;": "\u2192", - "ShortUpArrow;": "\u2191", - "Sigma;": "\u03a3", - "SmallCircle;": "\u2218", - "Sopf;": "\U0001d54a", - "Sqrt;": "\u221a", - "Square;": "\u25a1", - "SquareIntersection;": "\u2293", - "SquareSubset;": "\u228f", - "SquareSubsetEqual;": "\u2291", - "SquareSuperset;": "\u2290", - "SquareSupersetEqual;": "\u2292", - "SquareUnion;": "\u2294", - "Sscr;": "\U0001d4ae", - "Star;": "\u22c6", - "Sub;": "\u22d0", - "Subset;": "\u22d0", - "SubsetEqual;": "\u2286", - "Succeeds;": "\u227b", - "SucceedsEqual;": "\u2ab0", - "SucceedsSlantEqual;": "\u227d", - "SucceedsTilde;": "\u227f", - "SuchThat;": "\u220b", - "Sum;": "\u2211", - "Sup;": "\u22d1", - "Superset;": "\u2283", - "SupersetEqual;": "\u2287", - "Supset;": "\u22d1", - "THORN": "\xde", - "THORN;": "\xde", - "TRADE;": "\u2122", - "TSHcy;": "\u040b", - "TScy;": "\u0426", - "Tab;": "\t", - "Tau;": "\u03a4", - "Tcaron;": "\u0164", - "Tcedil;": "\u0162", - "Tcy;": "\u0422", - "Tfr;": "\U0001d517", - "Therefore;": "\u2234", - "Theta;": "\u0398", - "ThickSpace;": "\u205f\u200a", - "ThinSpace;": "\u2009", - "Tilde;": "\u223c", - "TildeEqual;": "\u2243", - "TildeFullEqual;": "\u2245", - "TildeTilde;": "\u2248", - "Topf;": "\U0001d54b", - "TripleDot;": "\u20db", - "Tscr;": "\U0001d4af", - "Tstrok;": "\u0166", - "Uacute": "\xda", - "Uacute;": "\xda", - "Uarr;": "\u219f", - "Uarrocir;": "\u2949", - "Ubrcy;": "\u040e", - "Ubreve;": "\u016c", - "Ucirc": "\xdb", - "Ucirc;": "\xdb", - "Ucy;": "\u0423", - "Udblac;": "\u0170", - "Ufr;": "\U0001d518", - "Ugrave": "\xd9", - "Ugrave;": "\xd9", - "Umacr;": "\u016a", - "UnderBar;": "_", - "UnderBrace;": "\u23df", - "UnderBracket;": "\u23b5", - "UnderParenthesis;": "\u23dd", - "Union;": "\u22c3", - "UnionPlus;": "\u228e", - "Uogon;": "\u0172", - "Uopf;": "\U0001d54c", - "UpArrow;": "\u2191", - "UpArrowBar;": "\u2912", - "UpArrowDownArrow;": "\u21c5", - "UpDownArrow;": "\u2195", - "UpEquilibrium;": "\u296e", - "UpTee;": "\u22a5", - "UpTeeArrow;": "\u21a5", - "Uparrow;": "\u21d1", - "Updownarrow;": "\u21d5", - "UpperLeftArrow;": "\u2196", - "UpperRightArrow;": "\u2197", - "Upsi;": "\u03d2", - "Upsilon;": "\u03a5", - "Uring;": "\u016e", - "Uscr;": "\U0001d4b0", - "Utilde;": "\u0168", - "Uuml": "\xdc", - "Uuml;": "\xdc", - "VDash;": "\u22ab", - "Vbar;": "\u2aeb", - "Vcy;": "\u0412", - "Vdash;": "\u22a9", - "Vdashl;": "\u2ae6", - "Vee;": "\u22c1", - "Verbar;": "\u2016", - "Vert;": "\u2016", - "VerticalBar;": "\u2223", - "VerticalLine;": "|", - "VerticalSeparator;": "\u2758", - "VerticalTilde;": "\u2240", - "VeryThinSpace;": "\u200a", - "Vfr;": "\U0001d519", - "Vopf;": "\U0001d54d", - "Vscr;": "\U0001d4b1", - "Vvdash;": "\u22aa", - "Wcirc;": "\u0174", - "Wedge;": "\u22c0", - "Wfr;": "\U0001d51a", - "Wopf;": "\U0001d54e", - "Wscr;": "\U0001d4b2", - "Xfr;": "\U0001d51b", - "Xi;": "\u039e", - "Xopf;": "\U0001d54f", - "Xscr;": "\U0001d4b3", - "YAcy;": "\u042f", - "YIcy;": "\u0407", - "YUcy;": "\u042e", - "Yacute": "\xdd", - "Yacute;": "\xdd", - "Ycirc;": "\u0176", - "Ycy;": "\u042b", - "Yfr;": "\U0001d51c", - "Yopf;": "\U0001d550", - "Yscr;": "\U0001d4b4", - "Yuml;": "\u0178", - "ZHcy;": "\u0416", - "Zacute;": "\u0179", - "Zcaron;": "\u017d", - "Zcy;": "\u0417", - "Zdot;": "\u017b", - "ZeroWidthSpace;": "\u200b", - "Zeta;": "\u0396", - "Zfr;": "\u2128", - "Zopf;": "\u2124", - "Zscr;": "\U0001d4b5", - "aacute": "\xe1", - "aacute;": "\xe1", - "abreve;": "\u0103", - "ac;": "\u223e", - "acE;": "\u223e\u0333", - "acd;": "\u223f", - "acirc": "\xe2", - "acirc;": "\xe2", - "acute": "\xb4", - "acute;": "\xb4", - "acy;": "\u0430", - "aelig": "\xe6", - "aelig;": "\xe6", - "af;": "\u2061", - "afr;": "\U0001d51e", - "agrave": "\xe0", - "agrave;": "\xe0", - "alefsym;": "\u2135", - "aleph;": "\u2135", - "alpha;": "\u03b1", - "amacr;": "\u0101", - "amalg;": "\u2a3f", - "amp": "&", - "amp;": "&", - "and;": "\u2227", - "andand;": "\u2a55", - "andd;": "\u2a5c", - "andslope;": "\u2a58", - "andv;": "\u2a5a", - "ang;": "\u2220", - "ange;": "\u29a4", - "angle;": "\u2220", - "angmsd;": "\u2221", - "angmsdaa;": "\u29a8", - "angmsdab;": "\u29a9", - "angmsdac;": "\u29aa", - "angmsdad;": "\u29ab", - "angmsdae;": "\u29ac", - "angmsdaf;": "\u29ad", - "angmsdag;": "\u29ae", - "angmsdah;": "\u29af", - "angrt;": "\u221f", - "angrtvb;": "\u22be", - "angrtvbd;": "\u299d", - "angsph;": "\u2222", - "angst;": "\xc5", - "angzarr;": "\u237c", - "aogon;": "\u0105", - "aopf;": "\U0001d552", - "ap;": "\u2248", - "apE;": "\u2a70", - "apacir;": "\u2a6f", - "ape;": "\u224a", - "apid;": "\u224b", - "apos;": "'", - "approx;": "\u2248", - "approxeq;": "\u224a", - "aring": "\xe5", - "aring;": "\xe5", - "ascr;": "\U0001d4b6", - "ast;": "*", - "asymp;": "\u2248", - "asympeq;": "\u224d", - "atilde": "\xe3", - "atilde;": "\xe3", - "auml": "\xe4", - "auml;": "\xe4", - "awconint;": "\u2233", - "awint;": "\u2a11", - "bNot;": "\u2aed", - "backcong;": "\u224c", - "backepsilon;": "\u03f6", - "backprime;": "\u2035", - "backsim;": "\u223d", - "backsimeq;": "\u22cd", - "barvee;": "\u22bd", - "barwed;": "\u2305", - "barwedge;": "\u2305", - "bbrk;": "\u23b5", - "bbrktbrk;": "\u23b6", - "bcong;": "\u224c", - "bcy;": "\u0431", - "bdquo;": "\u201e", - "becaus;": "\u2235", - "because;": "\u2235", - "bemptyv;": "\u29b0", - "bepsi;": "\u03f6", - "bernou;": "\u212c", - "beta;": "\u03b2", - "beth;": "\u2136", - "between;": "\u226c", - "bfr;": "\U0001d51f", - "bigcap;": "\u22c2", - "bigcirc;": "\u25ef", - "bigcup;": "\u22c3", - "bigodot;": "\u2a00", - "bigoplus;": "\u2a01", - "bigotimes;": "\u2a02", - "bigsqcup;": "\u2a06", - "bigstar;": "\u2605", - "bigtriangledown;": "\u25bd", - "bigtriangleup;": "\u25b3", - "biguplus;": "\u2a04", - "bigvee;": "\u22c1", - "bigwedge;": "\u22c0", - "bkarow;": "\u290d", - "blacklozenge;": "\u29eb", - "blacksquare;": "\u25aa", - "blacktriangle;": "\u25b4", - "blacktriangledown;": "\u25be", - "blacktriangleleft;": "\u25c2", - "blacktriangleright;": "\u25b8", - "blank;": "\u2423", - "blk12;": "\u2592", - "blk14;": "\u2591", - "blk34;": "\u2593", - "block;": "\u2588", - "bne;": "=\u20e5", - "bnequiv;": "\u2261\u20e5", - "bnot;": "\u2310", - "bopf;": "\U0001d553", - "bot;": "\u22a5", - "bottom;": "\u22a5", - "bowtie;": "\u22c8", - "boxDL;": "\u2557", - "boxDR;": "\u2554", - "boxDl;": "\u2556", - "boxDr;": "\u2553", - "boxH;": "\u2550", - "boxHD;": "\u2566", - "boxHU;": "\u2569", - "boxHd;": "\u2564", - "boxHu;": "\u2567", - "boxUL;": "\u255d", - "boxUR;": "\u255a", - "boxUl;": "\u255c", - "boxUr;": "\u2559", - "boxV;": "\u2551", - "boxVH;": "\u256c", - "boxVL;": "\u2563", - "boxVR;": "\u2560", - "boxVh;": "\u256b", - "boxVl;": "\u2562", - "boxVr;": "\u255f", - "boxbox;": "\u29c9", - "boxdL;": "\u2555", - "boxdR;": "\u2552", - "boxdl;": "\u2510", - "boxdr;": "\u250c", - "boxh;": "\u2500", - "boxhD;": "\u2565", - "boxhU;": "\u2568", - "boxhd;": "\u252c", - "boxhu;": "\u2534", - "boxminus;": "\u229f", - "boxplus;": "\u229e", - "boxtimes;": "\u22a0", - "boxuL;": "\u255b", - "boxuR;": "\u2558", - "boxul;": "\u2518", - "boxur;": "\u2514", - "boxv;": "\u2502", - "boxvH;": "\u256a", - "boxvL;": "\u2561", - "boxvR;": "\u255e", - "boxvh;": "\u253c", - "boxvl;": "\u2524", - "boxvr;": "\u251c", - "bprime;": "\u2035", - "breve;": "\u02d8", - "brvbar": "\xa6", - "brvbar;": "\xa6", - "bscr;": "\U0001d4b7", - "bsemi;": "\u204f", - "bsim;": "\u223d", - "bsime;": "\u22cd", - "bsol;": "\\", - "bsolb;": "\u29c5", - "bsolhsub;": "\u27c8", - "bull;": "\u2022", - "bullet;": "\u2022", - "bump;": "\u224e", - "bumpE;": "\u2aae", - "bumpe;": "\u224f", - "bumpeq;": "\u224f", - "cacute;": "\u0107", - "cap;": "\u2229", - "capand;": "\u2a44", - "capbrcup;": "\u2a49", - "capcap;": "\u2a4b", - "capcup;": "\u2a47", - "capdot;": "\u2a40", - "caps;": "\u2229\ufe00", - "caret;": "\u2041", - "caron;": "\u02c7", - "ccaps;": "\u2a4d", - "ccaron;": "\u010d", - "ccedil": "\xe7", - "ccedil;": "\xe7", - "ccirc;": "\u0109", - "ccups;": "\u2a4c", - "ccupssm;": "\u2a50", - "cdot;": "\u010b", - "cedil": "\xb8", - "cedil;": "\xb8", - "cemptyv;": "\u29b2", - "cent": "\xa2", - "cent;": "\xa2", - "centerdot;": "\xb7", - "cfr;": "\U0001d520", - "chcy;": "\u0447", - "check;": "\u2713", - "checkmark;": "\u2713", - "chi;": "\u03c7", - "cir;": "\u25cb", - "cirE;": "\u29c3", - "circ;": "\u02c6", - "circeq;": "\u2257", - "circlearrowleft;": "\u21ba", - "circlearrowright;": "\u21bb", - "circledR;": "\xae", - "circledS;": "\u24c8", - "circledast;": "\u229b", - "circledcirc;": "\u229a", - "circleddash;": "\u229d", - "cire;": "\u2257", - "cirfnint;": "\u2a10", - "cirmid;": "\u2aef", - "cirscir;": "\u29c2", - "clubs;": "\u2663", - "clubsuit;": "\u2663", - "colon;": ":", - "colone;": "\u2254", - "coloneq;": "\u2254", - "comma;": ",", - "commat;": "@", - "comp;": "\u2201", - "compfn;": "\u2218", - "complement;": "\u2201", - "complexes;": "\u2102", - "cong;": "\u2245", - "congdot;": "\u2a6d", - "conint;": "\u222e", - "copf;": "\U0001d554", - "coprod;": "\u2210", - "copy": "\xa9", - "copy;": "\xa9", - "copysr;": "\u2117", - "crarr;": "\u21b5", - "cross;": "\u2717", - "cscr;": "\U0001d4b8", - "csub;": "\u2acf", - "csube;": "\u2ad1", - "csup;": "\u2ad0", - "csupe;": "\u2ad2", - "ctdot;": "\u22ef", - "cudarrl;": "\u2938", - "cudarrr;": "\u2935", - "cuepr;": "\u22de", - "cuesc;": "\u22df", - "cularr;": "\u21b6", - "cularrp;": "\u293d", - "cup;": "\u222a", - "cupbrcap;": "\u2a48", - "cupcap;": "\u2a46", - "cupcup;": "\u2a4a", - "cupdot;": "\u228d", - "cupor;": "\u2a45", - "cups;": "\u222a\ufe00", - "curarr;": "\u21b7", - "curarrm;": "\u293c", - "curlyeqprec;": "\u22de", - "curlyeqsucc;": "\u22df", - "curlyvee;": "\u22ce", - "curlywedge;": "\u22cf", - "curren": "\xa4", - "curren;": "\xa4", - "curvearrowleft;": "\u21b6", - "curvearrowright;": "\u21b7", - "cuvee;": "\u22ce", - "cuwed;": "\u22cf", - "cwconint;": "\u2232", - "cwint;": "\u2231", - "cylcty;": "\u232d", - "dArr;": "\u21d3", - "dHar;": "\u2965", - "dagger;": "\u2020", - "daleth;": "\u2138", - "darr;": "\u2193", - "dash;": "\u2010", - "dashv;": "\u22a3", - "dbkarow;": "\u290f", - "dblac;": "\u02dd", - "dcaron;": "\u010f", - "dcy;": "\u0434", - "dd;": "\u2146", - "ddagger;": "\u2021", - "ddarr;": "\u21ca", - "ddotseq;": "\u2a77", - "deg": "\xb0", - "deg;": "\xb0", - "delta;": "\u03b4", - "demptyv;": "\u29b1", - "dfisht;": "\u297f", - "dfr;": "\U0001d521", - "dharl;": "\u21c3", - "dharr;": "\u21c2", - "diam;": "\u22c4", - "diamond;": "\u22c4", - "diamondsuit;": "\u2666", - "diams;": "\u2666", - "die;": "\xa8", - "digamma;": "\u03dd", - "disin;": "\u22f2", - "div;": "\xf7", - "divide": "\xf7", - "divide;": "\xf7", - "divideontimes;": "\u22c7", - "divonx;": "\u22c7", - "djcy;": "\u0452", - "dlcorn;": "\u231e", - "dlcrop;": "\u230d", - "dollar;": "$", - "dopf;": "\U0001d555", - "dot;": "\u02d9", - "doteq;": "\u2250", - "doteqdot;": "\u2251", - "dotminus;": "\u2238", - "dotplus;": "\u2214", - "dotsquare;": "\u22a1", - "doublebarwedge;": "\u2306", - "downarrow;": "\u2193", - "downdownarrows;": "\u21ca", - "downharpoonleft;": "\u21c3", - "downharpoonright;": "\u21c2", - "drbkarow;": "\u2910", - "drcorn;": "\u231f", - "drcrop;": "\u230c", - "dscr;": "\U0001d4b9", - "dscy;": "\u0455", - "dsol;": "\u29f6", - "dstrok;": "\u0111", - "dtdot;": "\u22f1", - "dtri;": "\u25bf", - "dtrif;": "\u25be", - "duarr;": "\u21f5", - "duhar;": "\u296f", - "dwangle;": "\u29a6", - "dzcy;": "\u045f", - "dzigrarr;": "\u27ff", - "eDDot;": "\u2a77", - "eDot;": "\u2251", - "eacute": "\xe9", - "eacute;": "\xe9", - "easter;": "\u2a6e", - "ecaron;": "\u011b", - "ecir;": "\u2256", - "ecirc": "\xea", - "ecirc;": "\xea", - "ecolon;": "\u2255", - "ecy;": "\u044d", - "edot;": "\u0117", - "ee;": "\u2147", - "efDot;": "\u2252", - "efr;": "\U0001d522", - "eg;": "\u2a9a", - "egrave": "\xe8", - "egrave;": "\xe8", - "egs;": "\u2a96", - "egsdot;": "\u2a98", - "el;": "\u2a99", - "elinters;": "\u23e7", - "ell;": "\u2113", - "els;": "\u2a95", - "elsdot;": "\u2a97", - "emacr;": "\u0113", - "empty;": "\u2205", - "emptyset;": "\u2205", - "emptyv;": "\u2205", - "emsp13;": "\u2004", - "emsp14;": "\u2005", - "emsp;": "\u2003", - "eng;": "\u014b", - "ensp;": "\u2002", - "eogon;": "\u0119", - "eopf;": "\U0001d556", - "epar;": "\u22d5", - "eparsl;": "\u29e3", - "eplus;": "\u2a71", - "epsi;": "\u03b5", - "epsilon;": "\u03b5", - "epsiv;": "\u03f5", - "eqcirc;": "\u2256", - "eqcolon;": "\u2255", - "eqsim;": "\u2242", - "eqslantgtr;": "\u2a96", - "eqslantless;": "\u2a95", - "equals;": "=", - "equest;": "\u225f", - "equiv;": "\u2261", - "equivDD;": "\u2a78", - "eqvparsl;": "\u29e5", - "erDot;": "\u2253", - "erarr;": "\u2971", - "escr;": "\u212f", - "esdot;": "\u2250", - "esim;": "\u2242", - "eta;": "\u03b7", - "eth": "\xf0", - "eth;": "\xf0", - "euml": "\xeb", - "euml;": "\xeb", - "euro;": "\u20ac", - "excl;": "!", - "exist;": "\u2203", - "expectation;": "\u2130", - "exponentiale;": "\u2147", - "fallingdotseq;": "\u2252", - "fcy;": "\u0444", - "female;": "\u2640", - "ffilig;": "\ufb03", - "fflig;": "\ufb00", - "ffllig;": "\ufb04", - "ffr;": "\U0001d523", - "filig;": "\ufb01", - "fjlig;": "fj", - "flat;": "\u266d", - "fllig;": "\ufb02", - "fltns;": "\u25b1", - "fnof;": "\u0192", - "fopf;": "\U0001d557", - "forall;": "\u2200", - "fork;": "\u22d4", - "forkv;": "\u2ad9", - "fpartint;": "\u2a0d", - "frac12": "\xbd", - "frac12;": "\xbd", - "frac13;": "\u2153", - "frac14": "\xbc", - "frac14;": "\xbc", - "frac15;": "\u2155", - "frac16;": "\u2159", - "frac18;": "\u215b", - "frac23;": "\u2154", - "frac25;": "\u2156", - "frac34": "\xbe", - "frac34;": "\xbe", - "frac35;": "\u2157", - "frac38;": "\u215c", - "frac45;": "\u2158", - "frac56;": "\u215a", - "frac58;": "\u215d", - "frac78;": "\u215e", - "frasl;": "\u2044", - "frown;": "\u2322", - "fscr;": "\U0001d4bb", - "gE;": "\u2267", - "gEl;": "\u2a8c", - "gacute;": "\u01f5", - "gamma;": "\u03b3", - "gammad;": "\u03dd", - "gap;": "\u2a86", - "gbreve;": "\u011f", - "gcirc;": "\u011d", - "gcy;": "\u0433", - "gdot;": "\u0121", - "ge;": "\u2265", - "gel;": "\u22db", - "geq;": "\u2265", - "geqq;": "\u2267", - "geqslant;": "\u2a7e", - "ges;": "\u2a7e", - "gescc;": "\u2aa9", - "gesdot;": "\u2a80", - "gesdoto;": "\u2a82", - "gesdotol;": "\u2a84", - "gesl;": "\u22db\ufe00", - "gesles;": "\u2a94", - "gfr;": "\U0001d524", - "gg;": "\u226b", - "ggg;": "\u22d9", - "gimel;": "\u2137", - "gjcy;": "\u0453", - "gl;": "\u2277", - "glE;": "\u2a92", - "gla;": "\u2aa5", - "glj;": "\u2aa4", - "gnE;": "\u2269", - "gnap;": "\u2a8a", - "gnapprox;": "\u2a8a", - "gne;": "\u2a88", - "gneq;": "\u2a88", - "gneqq;": "\u2269", - "gnsim;": "\u22e7", - "gopf;": "\U0001d558", - "grave;": "`", - "gscr;": "\u210a", - "gsim;": "\u2273", - "gsime;": "\u2a8e", - "gsiml;": "\u2a90", - "gt": ">", - "gt;": ">", - "gtcc;": "\u2aa7", - "gtcir;": "\u2a7a", - "gtdot;": "\u22d7", - "gtlPar;": "\u2995", - "gtquest;": "\u2a7c", - "gtrapprox;": "\u2a86", - "gtrarr;": "\u2978", - "gtrdot;": "\u22d7", - "gtreqless;": "\u22db", - "gtreqqless;": "\u2a8c", - "gtrless;": "\u2277", - "gtrsim;": "\u2273", - "gvertneqq;": "\u2269\ufe00", - "gvnE;": "\u2269\ufe00", - "hArr;": "\u21d4", - "hairsp;": "\u200a", - "half;": "\xbd", - "hamilt;": "\u210b", - "hardcy;": "\u044a", - "harr;": "\u2194", - "harrcir;": "\u2948", - "harrw;": "\u21ad", - "hbar;": "\u210f", - "hcirc;": "\u0125", - "hearts;": "\u2665", - "heartsuit;": "\u2665", - "hellip;": "\u2026", - "hercon;": "\u22b9", - "hfr;": "\U0001d525", - "hksearow;": "\u2925", - "hkswarow;": "\u2926", - "hoarr;": "\u21ff", - "homtht;": "\u223b", - "hookleftarrow;": "\u21a9", - "hookrightarrow;": "\u21aa", - "hopf;": "\U0001d559", - "horbar;": "\u2015", - "hscr;": "\U0001d4bd", - "hslash;": "\u210f", - "hstrok;": "\u0127", - "hybull;": "\u2043", - "hyphen;": "\u2010", - "iacute": "\xed", - "iacute;": "\xed", - "ic;": "\u2063", - "icirc": "\xee", - "icirc;": "\xee", - "icy;": "\u0438", - "iecy;": "\u0435", - "iexcl": "\xa1", - "iexcl;": "\xa1", - "iff;": "\u21d4", - "ifr;": "\U0001d526", - "igrave": "\xec", - "igrave;": "\xec", - "ii;": "\u2148", - "iiiint;": "\u2a0c", - "iiint;": "\u222d", - "iinfin;": "\u29dc", - "iiota;": "\u2129", - "ijlig;": "\u0133", - "imacr;": "\u012b", - "image;": "\u2111", - "imagline;": "\u2110", - "imagpart;": "\u2111", - "imath;": "\u0131", - "imof;": "\u22b7", - "imped;": "\u01b5", - "in;": "\u2208", - "incare;": "\u2105", - "infin;": "\u221e", - "infintie;": "\u29dd", - "inodot;": "\u0131", - "int;": "\u222b", - "intcal;": "\u22ba", - "integers;": "\u2124", - "intercal;": "\u22ba", - "intlarhk;": "\u2a17", - "intprod;": "\u2a3c", - "iocy;": "\u0451", - "iogon;": "\u012f", - "iopf;": "\U0001d55a", - "iota;": "\u03b9", - "iprod;": "\u2a3c", - "iquest": "\xbf", - "iquest;": "\xbf", - "iscr;": "\U0001d4be", - "isin;": "\u2208", - "isinE;": "\u22f9", - "isindot;": "\u22f5", - "isins;": "\u22f4", - "isinsv;": "\u22f3", - "isinv;": "\u2208", - "it;": "\u2062", - "itilde;": "\u0129", - "iukcy;": "\u0456", - "iuml": "\xef", - "iuml;": "\xef", - "jcirc;": "\u0135", - "jcy;": "\u0439", - "jfr;": "\U0001d527", - "jmath;": "\u0237", - "jopf;": "\U0001d55b", - "jscr;": "\U0001d4bf", - "jsercy;": "\u0458", - "jukcy;": "\u0454", - "kappa;": "\u03ba", - "kappav;": "\u03f0", - "kcedil;": "\u0137", - "kcy;": "\u043a", - "kfr;": "\U0001d528", - "kgreen;": "\u0138", - "khcy;": "\u0445", - "kjcy;": "\u045c", - "kopf;": "\U0001d55c", - "kscr;": "\U0001d4c0", - "lAarr;": "\u21da", - "lArr;": "\u21d0", - "lAtail;": "\u291b", - "lBarr;": "\u290e", - "lE;": "\u2266", - "lEg;": "\u2a8b", - "lHar;": "\u2962", - "lacute;": "\u013a", - "laemptyv;": "\u29b4", - "lagran;": "\u2112", - "lambda;": "\u03bb", - "lang;": "\u27e8", - "langd;": "\u2991", - "langle;": "\u27e8", - "lap;": "\u2a85", - "laquo": "\xab", - "laquo;": "\xab", - "larr;": "\u2190", - "larrb;": "\u21e4", - "larrbfs;": "\u291f", - "larrfs;": "\u291d", - "larrhk;": "\u21a9", - "larrlp;": "\u21ab", - "larrpl;": "\u2939", - "larrsim;": "\u2973", - "larrtl;": "\u21a2", - "lat;": "\u2aab", - "latail;": "\u2919", - "late;": "\u2aad", - "lates;": "\u2aad\ufe00", - "lbarr;": "\u290c", - "lbbrk;": "\u2772", - "lbrace;": "{", - "lbrack;": "[", - "lbrke;": "\u298b", - "lbrksld;": "\u298f", - "lbrkslu;": "\u298d", - "lcaron;": "\u013e", - "lcedil;": "\u013c", - "lceil;": "\u2308", - "lcub;": "{", - "lcy;": "\u043b", - "ldca;": "\u2936", - "ldquo;": "\u201c", - "ldquor;": "\u201e", - "ldrdhar;": "\u2967", - "ldrushar;": "\u294b", - "ldsh;": "\u21b2", - "le;": "\u2264", - "leftarrow;": "\u2190", - "leftarrowtail;": "\u21a2", - "leftharpoondown;": "\u21bd", - "leftharpoonup;": "\u21bc", - "leftleftarrows;": "\u21c7", - "leftrightarrow;": "\u2194", - "leftrightarrows;": "\u21c6", - "leftrightharpoons;": "\u21cb", - "leftrightsquigarrow;": "\u21ad", - "leftthreetimes;": "\u22cb", - "leg;": "\u22da", - "leq;": "\u2264", - "leqq;": "\u2266", - "leqslant;": "\u2a7d", - "les;": "\u2a7d", - "lescc;": "\u2aa8", - "lesdot;": "\u2a7f", - "lesdoto;": "\u2a81", - "lesdotor;": "\u2a83", - "lesg;": "\u22da\ufe00", - "lesges;": "\u2a93", - "lessapprox;": "\u2a85", - "lessdot;": "\u22d6", - "lesseqgtr;": "\u22da", - "lesseqqgtr;": "\u2a8b", - "lessgtr;": "\u2276", - "lesssim;": "\u2272", - "lfisht;": "\u297c", - "lfloor;": "\u230a", - "lfr;": "\U0001d529", - "lg;": "\u2276", - "lgE;": "\u2a91", - "lhard;": "\u21bd", - "lharu;": "\u21bc", - "lharul;": "\u296a", - "lhblk;": "\u2584", - "ljcy;": "\u0459", - "ll;": "\u226a", - "llarr;": "\u21c7", - "llcorner;": "\u231e", - "llhard;": "\u296b", - "lltri;": "\u25fa", - "lmidot;": "\u0140", - "lmoust;": "\u23b0", - "lmoustache;": "\u23b0", - "lnE;": "\u2268", - "lnap;": "\u2a89", - "lnapprox;": "\u2a89", - "lne;": "\u2a87", - "lneq;": "\u2a87", - "lneqq;": "\u2268", - "lnsim;": "\u22e6", - "loang;": "\u27ec", - "loarr;": "\u21fd", - "lobrk;": "\u27e6", - "longleftarrow;": "\u27f5", - "longleftrightarrow;": "\u27f7", - "longmapsto;": "\u27fc", - "longrightarrow;": "\u27f6", - "looparrowleft;": "\u21ab", - "looparrowright;": "\u21ac", - "lopar;": "\u2985", - "lopf;": "\U0001d55d", - "loplus;": "\u2a2d", - "lotimes;": "\u2a34", - "lowast;": "\u2217", - "lowbar;": "_", - "loz;": "\u25ca", - "lozenge;": "\u25ca", - "lozf;": "\u29eb", - "lpar;": "(", - "lparlt;": "\u2993", - "lrarr;": "\u21c6", - "lrcorner;": "\u231f", - "lrhar;": "\u21cb", - "lrhard;": "\u296d", - "lrm;": "\u200e", - "lrtri;": "\u22bf", - "lsaquo;": "\u2039", - "lscr;": "\U0001d4c1", - "lsh;": "\u21b0", - "lsim;": "\u2272", - "lsime;": "\u2a8d", - "lsimg;": "\u2a8f", - "lsqb;": "[", - "lsquo;": "\u2018", - "lsquor;": "\u201a", - "lstrok;": "\u0142", - "lt": "<", - "lt;": "<", - "ltcc;": "\u2aa6", - "ltcir;": "\u2a79", - "ltdot;": "\u22d6", - "lthree;": "\u22cb", - "ltimes;": "\u22c9", - "ltlarr;": "\u2976", - "ltquest;": "\u2a7b", - "ltrPar;": "\u2996", - "ltri;": "\u25c3", - "ltrie;": "\u22b4", - "ltrif;": "\u25c2", - "lurdshar;": "\u294a", - "luruhar;": "\u2966", - "lvertneqq;": "\u2268\ufe00", - "lvnE;": "\u2268\ufe00", - "mDDot;": "\u223a", - "macr": "\xaf", - "macr;": "\xaf", - "male;": "\u2642", - "malt;": "\u2720", - "maltese;": "\u2720", - "map;": "\u21a6", - "mapsto;": "\u21a6", - "mapstodown;": "\u21a7", - "mapstoleft;": "\u21a4", - "mapstoup;": "\u21a5", - "marker;": "\u25ae", - "mcomma;": "\u2a29", - "mcy;": "\u043c", - "mdash;": "\u2014", - "measuredangle;": "\u2221", - "mfr;": "\U0001d52a", - "mho;": "\u2127", - "micro": "\xb5", - "micro;": "\xb5", - "mid;": "\u2223", - "midast;": "*", - "midcir;": "\u2af0", - "middot": "\xb7", - "middot;": "\xb7", - "minus;": "\u2212", - "minusb;": "\u229f", - "minusd;": "\u2238", - "minusdu;": "\u2a2a", - "mlcp;": "\u2adb", - "mldr;": "\u2026", - "mnplus;": "\u2213", - "models;": "\u22a7", - "mopf;": "\U0001d55e", - "mp;": "\u2213", - "mscr;": "\U0001d4c2", - "mstpos;": "\u223e", - "mu;": "\u03bc", - "multimap;": "\u22b8", - "mumap;": "\u22b8", - "nGg;": "\u22d9\u0338", - "nGt;": "\u226b\u20d2", - "nGtv;": "\u226b\u0338", - "nLeftarrow;": "\u21cd", - "nLeftrightarrow;": "\u21ce", - "nLl;": "\u22d8\u0338", - "nLt;": "\u226a\u20d2", - "nLtv;": "\u226a\u0338", - "nRightarrow;": "\u21cf", - "nVDash;": "\u22af", - "nVdash;": "\u22ae", - "nabla;": "\u2207", - "nacute;": "\u0144", - "nang;": "\u2220\u20d2", - "nap;": "\u2249", - "napE;": "\u2a70\u0338", - "napid;": "\u224b\u0338", - "napos;": "\u0149", - "napprox;": "\u2249", - "natur;": "\u266e", - "natural;": "\u266e", - "naturals;": "\u2115", - "nbsp": "\xa0", - "nbsp;": "\xa0", - "nbump;": "\u224e\u0338", - "nbumpe;": "\u224f\u0338", - "ncap;": "\u2a43", - "ncaron;": "\u0148", - "ncedil;": "\u0146", - "ncong;": "\u2247", - "ncongdot;": "\u2a6d\u0338", - "ncup;": "\u2a42", - "ncy;": "\u043d", - "ndash;": "\u2013", - "ne;": "\u2260", - "neArr;": "\u21d7", - "nearhk;": "\u2924", - "nearr;": "\u2197", - "nearrow;": "\u2197", - "nedot;": "\u2250\u0338", - "nequiv;": "\u2262", - "nesear;": "\u2928", - "nesim;": "\u2242\u0338", - "nexist;": "\u2204", - "nexists;": "\u2204", - "nfr;": "\U0001d52b", - "ngE;": "\u2267\u0338", - "nge;": "\u2271", - "ngeq;": "\u2271", - "ngeqq;": "\u2267\u0338", - "ngeqslant;": "\u2a7e\u0338", - "nges;": "\u2a7e\u0338", - "ngsim;": "\u2275", - "ngt;": "\u226f", - "ngtr;": "\u226f", - "nhArr;": "\u21ce", - "nharr;": "\u21ae", - "nhpar;": "\u2af2", - "ni;": "\u220b", - "nis;": "\u22fc", - "nisd;": "\u22fa", - "niv;": "\u220b", - "njcy;": "\u045a", - "nlArr;": "\u21cd", - "nlE;": "\u2266\u0338", - "nlarr;": "\u219a", - "nldr;": "\u2025", - "nle;": "\u2270", - "nleftarrow;": "\u219a", - "nleftrightarrow;": "\u21ae", - "nleq;": "\u2270", - "nleqq;": "\u2266\u0338", - "nleqslant;": "\u2a7d\u0338", - "nles;": "\u2a7d\u0338", - "nless;": "\u226e", - "nlsim;": "\u2274", - "nlt;": "\u226e", - "nltri;": "\u22ea", - "nltrie;": "\u22ec", - "nmid;": "\u2224", - "nopf;": "\U0001d55f", - "not": "\xac", - "not;": "\xac", - "notin;": "\u2209", - "notinE;": "\u22f9\u0338", - "notindot;": "\u22f5\u0338", - "notinva;": "\u2209", - "notinvb;": "\u22f7", - "notinvc;": "\u22f6", - "notni;": "\u220c", - "notniva;": "\u220c", - "notnivb;": "\u22fe", - "notnivc;": "\u22fd", - "npar;": "\u2226", - "nparallel;": "\u2226", - "nparsl;": "\u2afd\u20e5", - "npart;": "\u2202\u0338", - "npolint;": "\u2a14", - "npr;": "\u2280", - "nprcue;": "\u22e0", - "npre;": "\u2aaf\u0338", - "nprec;": "\u2280", - "npreceq;": "\u2aaf\u0338", - "nrArr;": "\u21cf", - "nrarr;": "\u219b", - "nrarrc;": "\u2933\u0338", - "nrarrw;": "\u219d\u0338", - "nrightarrow;": "\u219b", - "nrtri;": "\u22eb", - "nrtrie;": "\u22ed", - "nsc;": "\u2281", - "nsccue;": "\u22e1", - "nsce;": "\u2ab0\u0338", - "nscr;": "\U0001d4c3", - "nshortmid;": "\u2224", - "nshortparallel;": "\u2226", - "nsim;": "\u2241", - "nsime;": "\u2244", - "nsimeq;": "\u2244", - "nsmid;": "\u2224", - "nspar;": "\u2226", - "nsqsube;": "\u22e2", - "nsqsupe;": "\u22e3", - "nsub;": "\u2284", - "nsubE;": "\u2ac5\u0338", - "nsube;": "\u2288", - "nsubset;": "\u2282\u20d2", - "nsubseteq;": "\u2288", - "nsubseteqq;": "\u2ac5\u0338", - "nsucc;": "\u2281", - "nsucceq;": "\u2ab0\u0338", - "nsup;": "\u2285", - "nsupE;": "\u2ac6\u0338", - "nsupe;": "\u2289", - "nsupset;": "\u2283\u20d2", - "nsupseteq;": "\u2289", - "nsupseteqq;": "\u2ac6\u0338", - "ntgl;": "\u2279", - "ntilde": "\xf1", - "ntilde;": "\xf1", - "ntlg;": "\u2278", - "ntriangleleft;": "\u22ea", - "ntrianglelefteq;": "\u22ec", - "ntriangleright;": "\u22eb", - "ntrianglerighteq;": "\u22ed", - "nu;": "\u03bd", - "num;": "#", - "numero;": "\u2116", - "numsp;": "\u2007", - "nvDash;": "\u22ad", - "nvHarr;": "\u2904", - "nvap;": "\u224d\u20d2", - "nvdash;": "\u22ac", - "nvge;": "\u2265\u20d2", - "nvgt;": ">\u20d2", - "nvinfin;": "\u29de", - "nvlArr;": "\u2902", - "nvle;": "\u2264\u20d2", - "nvlt;": "<\u20d2", - "nvltrie;": "\u22b4\u20d2", - "nvrArr;": "\u2903", - "nvrtrie;": "\u22b5\u20d2", - "nvsim;": "\u223c\u20d2", - "nwArr;": "\u21d6", - "nwarhk;": "\u2923", - "nwarr;": "\u2196", - "nwarrow;": "\u2196", - "nwnear;": "\u2927", - "oS;": "\u24c8", - "oacute": "\xf3", - "oacute;": "\xf3", - "oast;": "\u229b", - "ocir;": "\u229a", - "ocirc": "\xf4", - "ocirc;": "\xf4", - "ocy;": "\u043e", - "odash;": "\u229d", - "odblac;": "\u0151", - "odiv;": "\u2a38", - "odot;": "\u2299", - "odsold;": "\u29bc", - "oelig;": "\u0153", - "ofcir;": "\u29bf", - "ofr;": "\U0001d52c", - "ogon;": "\u02db", - "ograve": "\xf2", - "ograve;": "\xf2", - "ogt;": "\u29c1", - "ohbar;": "\u29b5", - "ohm;": "\u03a9", - "oint;": "\u222e", - "olarr;": "\u21ba", - "olcir;": "\u29be", - "olcross;": "\u29bb", - "oline;": "\u203e", - "olt;": "\u29c0", - "omacr;": "\u014d", - "omega;": "\u03c9", - "omicron;": "\u03bf", - "omid;": "\u29b6", - "ominus;": "\u2296", - "oopf;": "\U0001d560", - "opar;": "\u29b7", - "operp;": "\u29b9", - "oplus;": "\u2295", - "or;": "\u2228", - "orarr;": "\u21bb", - "ord;": "\u2a5d", - "order;": "\u2134", - "orderof;": "\u2134", - "ordf": "\xaa", - "ordf;": "\xaa", - "ordm": "\xba", - "ordm;": "\xba", - "origof;": "\u22b6", - "oror;": "\u2a56", - "orslope;": "\u2a57", - "orv;": "\u2a5b", - "oscr;": "\u2134", - "oslash": "\xf8", - "oslash;": "\xf8", - "osol;": "\u2298", - "otilde": "\xf5", - "otilde;": "\xf5", - "otimes;": "\u2297", - "otimesas;": "\u2a36", - "ouml": "\xf6", - "ouml;": "\xf6", - "ovbar;": "\u233d", - "par;": "\u2225", - "para": "\xb6", - "para;": "\xb6", - "parallel;": "\u2225", - "parsim;": "\u2af3", - "parsl;": "\u2afd", - "part;": "\u2202", - "pcy;": "\u043f", - "percnt;": "%", - "period;": ".", - "permil;": "\u2030", - "perp;": "\u22a5", - "pertenk;": "\u2031", - "pfr;": "\U0001d52d", - "phi;": "\u03c6", - "phiv;": "\u03d5", - "phmmat;": "\u2133", - "phone;": "\u260e", - "pi;": "\u03c0", - "pitchfork;": "\u22d4", - "piv;": "\u03d6", - "planck;": "\u210f", - "planckh;": "\u210e", - "plankv;": "\u210f", - "plus;": "+", - "plusacir;": "\u2a23", - "plusb;": "\u229e", - "pluscir;": "\u2a22", - "plusdo;": "\u2214", - "plusdu;": "\u2a25", - "pluse;": "\u2a72", - "plusmn": "\xb1", - "plusmn;": "\xb1", - "plussim;": "\u2a26", - "plustwo;": "\u2a27", - "pm;": "\xb1", - "pointint;": "\u2a15", - "popf;": "\U0001d561", - "pound": "\xa3", - "pound;": "\xa3", - "pr;": "\u227a", - "prE;": "\u2ab3", - "prap;": "\u2ab7", - "prcue;": "\u227c", - "pre;": "\u2aaf", - "prec;": "\u227a", - "precapprox;": "\u2ab7", - "preccurlyeq;": "\u227c", - "preceq;": "\u2aaf", - "precnapprox;": "\u2ab9", - "precneqq;": "\u2ab5", - "precnsim;": "\u22e8", - "precsim;": "\u227e", - "prime;": "\u2032", - "primes;": "\u2119", - "prnE;": "\u2ab5", - "prnap;": "\u2ab9", - "prnsim;": "\u22e8", - "prod;": "\u220f", - "profalar;": "\u232e", - "profline;": "\u2312", - "profsurf;": "\u2313", - "prop;": "\u221d", - "propto;": "\u221d", - "prsim;": "\u227e", - "prurel;": "\u22b0", - "pscr;": "\U0001d4c5", - "psi;": "\u03c8", - "puncsp;": "\u2008", - "qfr;": "\U0001d52e", - "qint;": "\u2a0c", - "qopf;": "\U0001d562", - "qprime;": "\u2057", - "qscr;": "\U0001d4c6", - "quaternions;": "\u210d", - "quatint;": "\u2a16", - "quest;": "?", - "questeq;": "\u225f", - "quot": "\"", - "quot;": "\"", - "rAarr;": "\u21db", - "rArr;": "\u21d2", - "rAtail;": "\u291c", - "rBarr;": "\u290f", - "rHar;": "\u2964", - "race;": "\u223d\u0331", - "racute;": "\u0155", - "radic;": "\u221a", - "raemptyv;": "\u29b3", - "rang;": "\u27e9", - "rangd;": "\u2992", - "range;": "\u29a5", - "rangle;": "\u27e9", - "raquo": "\xbb", - "raquo;": "\xbb", - "rarr;": "\u2192", - "rarrap;": "\u2975", - "rarrb;": "\u21e5", - "rarrbfs;": "\u2920", - "rarrc;": "\u2933", - "rarrfs;": "\u291e", - "rarrhk;": "\u21aa", - "rarrlp;": "\u21ac", - "rarrpl;": "\u2945", - "rarrsim;": "\u2974", - "rarrtl;": "\u21a3", - "rarrw;": "\u219d", - "ratail;": "\u291a", - "ratio;": "\u2236", - "rationals;": "\u211a", - "rbarr;": "\u290d", - "rbbrk;": "\u2773", - "rbrace;": "}", - "rbrack;": "]", - "rbrke;": "\u298c", - "rbrksld;": "\u298e", - "rbrkslu;": "\u2990", - "rcaron;": "\u0159", - "rcedil;": "\u0157", - "rceil;": "\u2309", - "rcub;": "}", - "rcy;": "\u0440", - "rdca;": "\u2937", - "rdldhar;": "\u2969", - "rdquo;": "\u201d", - "rdquor;": "\u201d", - "rdsh;": "\u21b3", - "real;": "\u211c", - "realine;": "\u211b", - "realpart;": "\u211c", - "reals;": "\u211d", - "rect;": "\u25ad", - "reg": "\xae", - "reg;": "\xae", - "rfisht;": "\u297d", - "rfloor;": "\u230b", - "rfr;": "\U0001d52f", - "rhard;": "\u21c1", - "rharu;": "\u21c0", - "rharul;": "\u296c", - "rho;": "\u03c1", - "rhov;": "\u03f1", - "rightarrow;": "\u2192", - "rightarrowtail;": "\u21a3", - "rightharpoondown;": "\u21c1", - "rightharpoonup;": "\u21c0", - "rightleftarrows;": "\u21c4", - "rightleftharpoons;": "\u21cc", - "rightrightarrows;": "\u21c9", - "rightsquigarrow;": "\u219d", - "rightthreetimes;": "\u22cc", - "ring;": "\u02da", - "risingdotseq;": "\u2253", - "rlarr;": "\u21c4", - "rlhar;": "\u21cc", - "rlm;": "\u200f", - "rmoust;": "\u23b1", - "rmoustache;": "\u23b1", - "rnmid;": "\u2aee", - "roang;": "\u27ed", - "roarr;": "\u21fe", - "robrk;": "\u27e7", - "ropar;": "\u2986", - "ropf;": "\U0001d563", - "roplus;": "\u2a2e", - "rotimes;": "\u2a35", - "rpar;": ")", - "rpargt;": "\u2994", - "rppolint;": "\u2a12", - "rrarr;": "\u21c9", - "rsaquo;": "\u203a", - "rscr;": "\U0001d4c7", - "rsh;": "\u21b1", - "rsqb;": "]", - "rsquo;": "\u2019", - "rsquor;": "\u2019", - "rthree;": "\u22cc", - "rtimes;": "\u22ca", - "rtri;": "\u25b9", - "rtrie;": "\u22b5", - "rtrif;": "\u25b8", - "rtriltri;": "\u29ce", - "ruluhar;": "\u2968", - "rx;": "\u211e", - "sacute;": "\u015b", - "sbquo;": "\u201a", - "sc;": "\u227b", - "scE;": "\u2ab4", - "scap;": "\u2ab8", - "scaron;": "\u0161", - "sccue;": "\u227d", - "sce;": "\u2ab0", - "scedil;": "\u015f", - "scirc;": "\u015d", - "scnE;": "\u2ab6", - "scnap;": "\u2aba", - "scnsim;": "\u22e9", - "scpolint;": "\u2a13", - "scsim;": "\u227f", - "scy;": "\u0441", - "sdot;": "\u22c5", - "sdotb;": "\u22a1", - "sdote;": "\u2a66", - "seArr;": "\u21d8", - "searhk;": "\u2925", - "searr;": "\u2198", - "searrow;": "\u2198", - "sect": "\xa7", - "sect;": "\xa7", - "semi;": ";", - "seswar;": "\u2929", - "setminus;": "\u2216", - "setmn;": "\u2216", - "sext;": "\u2736", - "sfr;": "\U0001d530", - "sfrown;": "\u2322", - "sharp;": "\u266f", - "shchcy;": "\u0449", - "shcy;": "\u0448", - "shortmid;": "\u2223", - "shortparallel;": "\u2225", - "shy": "\xad", - "shy;": "\xad", - "sigma;": "\u03c3", - "sigmaf;": "\u03c2", - "sigmav;": "\u03c2", - "sim;": "\u223c", - "simdot;": "\u2a6a", - "sime;": "\u2243", - "simeq;": "\u2243", - "simg;": "\u2a9e", - "simgE;": "\u2aa0", - "siml;": "\u2a9d", - "simlE;": "\u2a9f", - "simne;": "\u2246", - "simplus;": "\u2a24", - "simrarr;": "\u2972", - "slarr;": "\u2190", - "smallsetminus;": "\u2216", - "smashp;": "\u2a33", - "smeparsl;": "\u29e4", - "smid;": "\u2223", - "smile;": "\u2323", - "smt;": "\u2aaa", - "smte;": "\u2aac", - "smtes;": "\u2aac\ufe00", - "softcy;": "\u044c", - "sol;": "/", - "solb;": "\u29c4", - "solbar;": "\u233f", - "sopf;": "\U0001d564", - "spades;": "\u2660", - "spadesuit;": "\u2660", - "spar;": "\u2225", - "sqcap;": "\u2293", - "sqcaps;": "\u2293\ufe00", - "sqcup;": "\u2294", - "sqcups;": "\u2294\ufe00", - "sqsub;": "\u228f", - "sqsube;": "\u2291", - "sqsubset;": "\u228f", - "sqsubseteq;": "\u2291", - "sqsup;": "\u2290", - "sqsupe;": "\u2292", - "sqsupset;": "\u2290", - "sqsupseteq;": "\u2292", - "squ;": "\u25a1", - "square;": "\u25a1", - "squarf;": "\u25aa", - "squf;": "\u25aa", - "srarr;": "\u2192", - "sscr;": "\U0001d4c8", - "ssetmn;": "\u2216", - "ssmile;": "\u2323", - "sstarf;": "\u22c6", - "star;": "\u2606", - "starf;": "\u2605", - "straightepsilon;": "\u03f5", - "straightphi;": "\u03d5", - "strns;": "\xaf", - "sub;": "\u2282", - "subE;": "\u2ac5", - "subdot;": "\u2abd", - "sube;": "\u2286", - "subedot;": "\u2ac3", - "submult;": "\u2ac1", - "subnE;": "\u2acb", - "subne;": "\u228a", - "subplus;": "\u2abf", - "subrarr;": "\u2979", - "subset;": "\u2282", - "subseteq;": "\u2286", - "subseteqq;": "\u2ac5", - "subsetneq;": "\u228a", - "subsetneqq;": "\u2acb", - "subsim;": "\u2ac7", - "subsub;": "\u2ad5", - "subsup;": "\u2ad3", - "succ;": "\u227b", - "succapprox;": "\u2ab8", - "succcurlyeq;": "\u227d", - "succeq;": "\u2ab0", - "succnapprox;": "\u2aba", - "succneqq;": "\u2ab6", - "succnsim;": "\u22e9", - "succsim;": "\u227f", - "sum;": "\u2211", - "sung;": "\u266a", - "sup1": "\xb9", - "sup1;": "\xb9", - "sup2": "\xb2", - "sup2;": "\xb2", - "sup3": "\xb3", - "sup3;": "\xb3", - "sup;": "\u2283", - "supE;": "\u2ac6", - "supdot;": "\u2abe", - "supdsub;": "\u2ad8", - "supe;": "\u2287", - "supedot;": "\u2ac4", - "suphsol;": "\u27c9", - "suphsub;": "\u2ad7", - "suplarr;": "\u297b", - "supmult;": "\u2ac2", - "supnE;": "\u2acc", - "supne;": "\u228b", - "supplus;": "\u2ac0", - "supset;": "\u2283", - "supseteq;": "\u2287", - "supseteqq;": "\u2ac6", - "supsetneq;": "\u228b", - "supsetneqq;": "\u2acc", - "supsim;": "\u2ac8", - "supsub;": "\u2ad4", - "supsup;": "\u2ad6", - "swArr;": "\u21d9", - "swarhk;": "\u2926", - "swarr;": "\u2199", - "swarrow;": "\u2199", - "swnwar;": "\u292a", - "szlig": "\xdf", - "szlig;": "\xdf", - "target;": "\u2316", - "tau;": "\u03c4", - "tbrk;": "\u23b4", - "tcaron;": "\u0165", - "tcedil;": "\u0163", - "tcy;": "\u0442", - "tdot;": "\u20db", - "telrec;": "\u2315", - "tfr;": "\U0001d531", - "there4;": "\u2234", - "therefore;": "\u2234", - "theta;": "\u03b8", - "thetasym;": "\u03d1", - "thetav;": "\u03d1", - "thickapprox;": "\u2248", - "thicksim;": "\u223c", - "thinsp;": "\u2009", - "thkap;": "\u2248", - "thksim;": "\u223c", - "thorn": "\xfe", - "thorn;": "\xfe", - "tilde;": "\u02dc", - "times": "\xd7", - "times;": "\xd7", - "timesb;": "\u22a0", - "timesbar;": "\u2a31", - "timesd;": "\u2a30", - "tint;": "\u222d", - "toea;": "\u2928", - "top;": "\u22a4", - "topbot;": "\u2336", - "topcir;": "\u2af1", - "topf;": "\U0001d565", - "topfork;": "\u2ada", - "tosa;": "\u2929", - "tprime;": "\u2034", - "trade;": "\u2122", - "triangle;": "\u25b5", - "triangledown;": "\u25bf", - "triangleleft;": "\u25c3", - "trianglelefteq;": "\u22b4", - "triangleq;": "\u225c", - "triangleright;": "\u25b9", - "trianglerighteq;": "\u22b5", - "tridot;": "\u25ec", - "trie;": "\u225c", - "triminus;": "\u2a3a", - "triplus;": "\u2a39", - "trisb;": "\u29cd", - "tritime;": "\u2a3b", - "trpezium;": "\u23e2", - "tscr;": "\U0001d4c9", - "tscy;": "\u0446", - "tshcy;": "\u045b", - "tstrok;": "\u0167", - "twixt;": "\u226c", - "twoheadleftarrow;": "\u219e", - "twoheadrightarrow;": "\u21a0", - "uArr;": "\u21d1", - "uHar;": "\u2963", - "uacute": "\xfa", - "uacute;": "\xfa", - "uarr;": "\u2191", - "ubrcy;": "\u045e", - "ubreve;": "\u016d", - "ucirc": "\xfb", - "ucirc;": "\xfb", - "ucy;": "\u0443", - "udarr;": "\u21c5", - "udblac;": "\u0171", - "udhar;": "\u296e", - "ufisht;": "\u297e", - "ufr;": "\U0001d532", - "ugrave": "\xf9", - "ugrave;": "\xf9", - "uharl;": "\u21bf", - "uharr;": "\u21be", - "uhblk;": "\u2580", - "ulcorn;": "\u231c", - "ulcorner;": "\u231c", - "ulcrop;": "\u230f", - "ultri;": "\u25f8", - "umacr;": "\u016b", - "uml": "\xa8", - "uml;": "\xa8", - "uogon;": "\u0173", - "uopf;": "\U0001d566", - "uparrow;": "\u2191", - "updownarrow;": "\u2195", - "upharpoonleft;": "\u21bf", - "upharpoonright;": "\u21be", - "uplus;": "\u228e", - "upsi;": "\u03c5", - "upsih;": "\u03d2", - "upsilon;": "\u03c5", - "upuparrows;": "\u21c8", - "urcorn;": "\u231d", - "urcorner;": "\u231d", - "urcrop;": "\u230e", - "uring;": "\u016f", - "urtri;": "\u25f9", - "uscr;": "\U0001d4ca", - "utdot;": "\u22f0", - "utilde;": "\u0169", - "utri;": "\u25b5", - "utrif;": "\u25b4", - "uuarr;": "\u21c8", - "uuml": "\xfc", - "uuml;": "\xfc", - "uwangle;": "\u29a7", - "vArr;": "\u21d5", - "vBar;": "\u2ae8", - "vBarv;": "\u2ae9", - "vDash;": "\u22a8", - "vangrt;": "\u299c", - "varepsilon;": "\u03f5", - "varkappa;": "\u03f0", - "varnothing;": "\u2205", - "varphi;": "\u03d5", - "varpi;": "\u03d6", - "varpropto;": "\u221d", - "varr;": "\u2195", - "varrho;": "\u03f1", - "varsigma;": "\u03c2", - "varsubsetneq;": "\u228a\ufe00", - "varsubsetneqq;": "\u2acb\ufe00", - "varsupsetneq;": "\u228b\ufe00", - "varsupsetneqq;": "\u2acc\ufe00", - "vartheta;": "\u03d1", - "vartriangleleft;": "\u22b2", - "vartriangleright;": "\u22b3", - "vcy;": "\u0432", - "vdash;": "\u22a2", - "vee;": "\u2228", - "veebar;": "\u22bb", - "veeeq;": "\u225a", - "vellip;": "\u22ee", - "verbar;": "|", - "vert;": "|", - "vfr;": "\U0001d533", - "vltri;": "\u22b2", - "vnsub;": "\u2282\u20d2", - "vnsup;": "\u2283\u20d2", - "vopf;": "\U0001d567", - "vprop;": "\u221d", - "vrtri;": "\u22b3", - "vscr;": "\U0001d4cb", - "vsubnE;": "\u2acb\ufe00", - "vsubne;": "\u228a\ufe00", - "vsupnE;": "\u2acc\ufe00", - "vsupne;": "\u228b\ufe00", - "vzigzag;": "\u299a", - "wcirc;": "\u0175", - "wedbar;": "\u2a5f", - "wedge;": "\u2227", - "wedgeq;": "\u2259", - "weierp;": "\u2118", - "wfr;": "\U0001d534", - "wopf;": "\U0001d568", - "wp;": "\u2118", - "wr;": "\u2240", - "wreath;": "\u2240", - "wscr;": "\U0001d4cc", - "xcap;": "\u22c2", - "xcirc;": "\u25ef", - "xcup;": "\u22c3", - "xdtri;": "\u25bd", - "xfr;": "\U0001d535", - "xhArr;": "\u27fa", - "xharr;": "\u27f7", - "xi;": "\u03be", - "xlArr;": "\u27f8", - "xlarr;": "\u27f5", - "xmap;": "\u27fc", - "xnis;": "\u22fb", - "xodot;": "\u2a00", - "xopf;": "\U0001d569", - "xoplus;": "\u2a01", - "xotime;": "\u2a02", - "xrArr;": "\u27f9", - "xrarr;": "\u27f6", - "xscr;": "\U0001d4cd", - "xsqcup;": "\u2a06", - "xuplus;": "\u2a04", - "xutri;": "\u25b3", - "xvee;": "\u22c1", - "xwedge;": "\u22c0", - "yacute": "\xfd", - "yacute;": "\xfd", - "yacy;": "\u044f", - "ycirc;": "\u0177", - "ycy;": "\u044b", - "yen": "\xa5", - "yen;": "\xa5", - "yfr;": "\U0001d536", - "yicy;": "\u0457", - "yopf;": "\U0001d56a", - "yscr;": "\U0001d4ce", - "yucy;": "\u044e", - "yuml": "\xff", - "yuml;": "\xff", - "zacute;": "\u017a", - "zcaron;": "\u017e", - "zcy;": "\u0437", - "zdot;": "\u017c", - "zeetrf;": "\u2128", - "zeta;": "\u03b6", - "zfr;": "\U0001d537", - "zhcy;": "\u0436", - "zigrarr;": "\u21dd", - "zopf;": "\U0001d56b", - "zscr;": "\U0001d4cf", - "zwj;": "\u200d", - "zwnj;": "\u200c", -} - -replacementCharacters = { - 0x0: "\uFFFD", - 0x0d: "\u000D", - 0x80: "\u20AC", - 0x81: "\u0081", - 0x82: "\u201A", - 0x83: "\u0192", - 0x84: "\u201E", - 0x85: "\u2026", - 0x86: "\u2020", - 0x87: "\u2021", - 0x88: "\u02C6", - 0x89: "\u2030", - 0x8A: "\u0160", - 0x8B: "\u2039", - 0x8C: "\u0152", - 0x8D: "\u008D", - 0x8E: "\u017D", - 0x8F: "\u008F", - 0x90: "\u0090", - 0x91: "\u2018", - 0x92: "\u2019", - 0x93: "\u201C", - 0x94: "\u201D", - 0x95: "\u2022", - 0x96: "\u2013", - 0x97: "\u2014", - 0x98: "\u02DC", - 0x99: "\u2122", - 0x9A: "\u0161", - 0x9B: "\u203A", - 0x9C: "\u0153", - 0x9D: "\u009D", - 0x9E: "\u017E", - 0x9F: "\u0178", -} - -tokenTypes = { - "Doctype": 0, - "Characters": 1, - "SpaceCharacters": 2, - "StartTag": 3, - "EndTag": 4, - "EmptyTag": 5, - "Comment": 6, - "ParseError": 7 -} - -tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], - tokenTypes["EmptyTag"]]) - - -prefixes = dict([(v, k) for k, v in namespaces.items()]) -prefixes["http://www.w3.org/1998/Math/MathML"] = "math" - - -class DataLossWarning(UserWarning): - """Raised when the current tree is unable to represent the input data""" - pass - - -class _ReparseException(Exception): - pass diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py deleted file mode 100644 index 5ba926e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py +++ /dev/null @@ -1,29 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from . import base - -from collections import OrderedDict - - -def _attr_key(attr): - """Return an appropriate key for an attribute for sorting - - Attributes have a namespace that can be either ``None`` or a string. We - can't compare the two because they're different types, so we convert - ``None`` to an empty string first. - - """ - return (attr[0][0] or ''), attr[0][1] - - -class Filter(base.Filter): - """Alphabetizes attributes for elements""" - def __iter__(self): - for token in base.Filter.__iter__(self): - if token["type"] in ("StartTag", "EmptyTag"): - attrs = OrderedDict() - for name, value in sorted(token["data"].items(), - key=_attr_key): - attrs[name] = value - token["data"] = attrs - yield token diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/base.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/base.py deleted file mode 100644 index c7dbaed..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/base.py +++ /dev/null @@ -1,12 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - - -class Filter(object): - def __init__(self, source): - self.source = source - - def __iter__(self): - return iter(self.source) - - def __getattr__(self, name): - return getattr(self.source, name) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py deleted file mode 100644 index aefb5c8..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py +++ /dev/null @@ -1,73 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from . import base - - -class Filter(base.Filter): - """Injects ``<meta charset=ENCODING>`` tag into head of document""" - def __init__(self, source, encoding): - """Creates a Filter - - :arg source: the source token stream - - :arg encoding: the encoding to set - - """ - base.Filter.__init__(self, source) - self.encoding = encoding - - def __iter__(self): - state = "pre_head" - meta_found = (self.encoding is None) - pending = [] - - for token in base.Filter.__iter__(self): - type = token["type"] - if type == "StartTag": - if token["name"].lower() == "head": - state = "in_head" - - elif type == "EmptyTag": - if token["name"].lower() == "meta": - # replace charset with actual encoding - has_http_equiv_content_type = False - for (namespace, name), value in token["data"].items(): - if namespace is not None: - continue - elif name.lower() == 'charset': - token["data"][(namespace, name)] = self.encoding - meta_found = True - break - elif name == 'http-equiv' and value.lower() == 'content-type': - has_http_equiv_content_type = True - else: - if has_http_equiv_content_type and (None, "content") in token["data"]: - token["data"][(None, "content")] = 'text/html; charset=%s' % self.encoding - meta_found = True - - elif token["name"].lower() == "head" and not meta_found: - # insert meta into empty head - yield {"type": "StartTag", "name": "head", - "data": token["data"]} - yield {"type": "EmptyTag", "name": "meta", - "data": {(None, "charset"): self.encoding}} - yield {"type": "EndTag", "name": "head"} - meta_found = True - continue - - elif type == "EndTag": - if token["name"].lower() == "head" and pending: - # insert meta into head (if necessary) and flush pending queue - yield pending.pop(0) - if not meta_found: - yield {"type": "EmptyTag", "name": "meta", - "data": {(None, "charset"): self.encoding}} - while pending: - yield pending.pop(0) - meta_found = True - state = "post_head" - - if state == "in_head": - pending.append(token) - else: - yield token diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/lint.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/lint.py deleted file mode 100644 index fcc07ee..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/lint.py +++ /dev/null @@ -1,93 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from pip._vendor.six import text_type - -from . import base -from ..constants import namespaces, voidElements - -from ..constants import spaceCharacters -spaceCharacters = "".join(spaceCharacters) - - -class Filter(base.Filter): - """Lints the token stream for errors - - If it finds any errors, it'll raise an ``AssertionError``. - - """ - def __init__(self, source, require_matching_tags=True): - """Creates a Filter - - :arg source: the source token stream - - :arg require_matching_tags: whether or not to require matching tags - - """ - super(Filter, self).__init__(source) - self.require_matching_tags = require_matching_tags - - def __iter__(self): - open_elements = [] - for token in base.Filter.__iter__(self): - type = token["type"] - if type in ("StartTag", "EmptyTag"): - namespace = token["namespace"] - name = token["name"] - assert namespace is None or isinstance(namespace, text_type) - assert namespace != "" - assert isinstance(name, text_type) - assert name != "" - assert isinstance(token["data"], dict) - if (not namespace or namespace == namespaces["html"]) and name in voidElements: - assert type == "EmptyTag" - else: - assert type == "StartTag" - if type == "StartTag" and self.require_matching_tags: - open_elements.append((namespace, name)) - for (namespace, name), value in token["data"].items(): - assert namespace is None or isinstance(namespace, text_type) - assert namespace != "" - assert isinstance(name, text_type) - assert name != "" - assert isinstance(value, text_type) - - elif type == "EndTag": - namespace = token["namespace"] - name = token["name"] - assert namespace is None or isinstance(namespace, text_type) - assert namespace != "" - assert isinstance(name, text_type) - assert name != "" - if (not namespace or namespace == namespaces["html"]) and name in voidElements: - assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name} - elif self.require_matching_tags: - start = open_elements.pop() - assert start == (namespace, name) - - elif type == "Comment": - data = token["data"] - assert isinstance(data, text_type) - - elif type in ("Characters", "SpaceCharacters"): - data = token["data"] - assert isinstance(data, text_type) - assert data != "" - if type == "SpaceCharacters": - assert data.strip(spaceCharacters) == "" - - elif type == "Doctype": - name = token["name"] - assert name is None or isinstance(name, text_type) - assert token["publicId"] is None or isinstance(name, text_type) - assert token["systemId"] is None or isinstance(name, text_type) - - elif type == "Entity": - assert isinstance(token["name"], text_type) - - elif type == "SerializerError": - assert isinstance(token["data"], text_type) - - else: - assert False, "Unknown token type: %(type)s" % {"type": type} - - yield token diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/optionaltags.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/optionaltags.py deleted file mode 100644 index 4a86501..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/optionaltags.py +++ /dev/null @@ -1,207 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from . import base - - -class Filter(base.Filter): - """Removes optional tags from the token stream""" - def slider(self): - previous1 = previous2 = None - for token in self.source: - if previous1 is not None: - yield previous2, previous1, token - previous2 = previous1 - previous1 = token - if previous1 is not None: - yield previous2, previous1, None - - def __iter__(self): - for previous, token, next in self.slider(): - type = token["type"] - if type == "StartTag": - if (token["data"] or - not self.is_optional_start(token["name"], previous, next)): - yield token - elif type == "EndTag": - if not self.is_optional_end(token["name"], next): - yield token - else: - yield token - - def is_optional_start(self, tagname, previous, next): - type = next and next["type"] or None - if tagname in 'html': - # An html element's start tag may be omitted if the first thing - # inside the html element is not a space character or a comment. - return type not in ("Comment", "SpaceCharacters") - elif tagname == 'head': - # A head element's start tag may be omitted if the first thing - # inside the head element is an element. - # XXX: we also omit the start tag if the head element is empty - if type in ("StartTag", "EmptyTag"): - return True - elif type == "EndTag": - return next["name"] == "head" - elif tagname == 'body': - # A body element's start tag may be omitted if the first thing - # inside the body element is not a space character or a comment, - # except if the first thing inside the body element is a script - # or style element and the node immediately preceding the body - # element is a head element whose end tag has been omitted. - if type in ("Comment", "SpaceCharacters"): - return False - elif type == "StartTag": - # XXX: we do not look at the preceding event, so we never omit - # the body element's start tag if it's followed by a script or - # a style element. - return next["name"] not in ('script', 'style') - else: - return True - elif tagname == 'colgroup': - # A colgroup element's start tag may be omitted if the first thing - # inside the colgroup element is a col element, and if the element - # is not immediately preceded by another colgroup element whose - # end tag has been omitted. - if type in ("StartTag", "EmptyTag"): - # XXX: we do not look at the preceding event, so instead we never - # omit the colgroup element's end tag when it is immediately - # followed by another colgroup element. See is_optional_end. - return next["name"] == "col" - else: - return False - elif tagname == 'tbody': - # A tbody element's start tag may be omitted if the first thing - # inside the tbody element is a tr element, and if the element is - # not immediately preceded by a tbody, thead, or tfoot element - # whose end tag has been omitted. - if type == "StartTag": - # omit the thead and tfoot elements' end tag when they are - # immediately followed by a tbody element. See is_optional_end. - if previous and previous['type'] == 'EndTag' and \ - previous['name'] in ('tbody', 'thead', 'tfoot'): - return False - return next["name"] == 'tr' - else: - return False - return False - - def is_optional_end(self, tagname, next): - type = next and next["type"] or None - if tagname in ('html', 'head', 'body'): - # An html element's end tag may be omitted if the html element - # is not immediately followed by a space character or a comment. - return type not in ("Comment", "SpaceCharacters") - elif tagname in ('li', 'optgroup', 'tr'): - # A li element's end tag may be omitted if the li element is - # immediately followed by another li element or if there is - # no more content in the parent element. - # An optgroup element's end tag may be omitted if the optgroup - # element is immediately followed by another optgroup element, - # or if there is no more content in the parent element. - # A tr element's end tag may be omitted if the tr element is - # immediately followed by another tr element, or if there is - # no more content in the parent element. - if type == "StartTag": - return next["name"] == tagname - else: - return type == "EndTag" or type is None - elif tagname in ('dt', 'dd'): - # A dt element's end tag may be omitted if the dt element is - # immediately followed by another dt element or a dd element. - # A dd element's end tag may be omitted if the dd element is - # immediately followed by another dd element or a dt element, - # or if there is no more content in the parent element. - if type == "StartTag": - return next["name"] in ('dt', 'dd') - elif tagname == 'dd': - return type == "EndTag" or type is None - else: - return False - elif tagname == 'p': - # A p element's end tag may be omitted if the p element is - # immediately followed by an address, article, aside, - # blockquote, datagrid, dialog, dir, div, dl, fieldset, - # footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, - # nav, ol, p, pre, section, table, or ul, element, or if - # there is no more content in the parent element. - if type in ("StartTag", "EmptyTag"): - return next["name"] in ('address', 'article', 'aside', - 'blockquote', 'datagrid', 'dialog', - 'dir', 'div', 'dl', 'fieldset', 'footer', - 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', - 'header', 'hr', 'menu', 'nav', 'ol', - 'p', 'pre', 'section', 'table', 'ul') - else: - return type == "EndTag" or type is None - elif tagname == 'option': - # An option element's end tag may be omitted if the option - # element is immediately followed by another option element, - # or if it is immediately followed by an <code>optgroup</code> - # element, or if there is no more content in the parent - # element. - if type == "StartTag": - return next["name"] in ('option', 'optgroup') - else: - return type == "EndTag" or type is None - elif tagname in ('rt', 'rp'): - # An rt element's end tag may be omitted if the rt element is - # immediately followed by an rt or rp element, or if there is - # no more content in the parent element. - # An rp element's end tag may be omitted if the rp element is - # immediately followed by an rt or rp element, or if there is - # no more content in the parent element. - if type == "StartTag": - return next["name"] in ('rt', 'rp') - else: - return type == "EndTag" or type is None - elif tagname == 'colgroup': - # A colgroup element's end tag may be omitted if the colgroup - # element is not immediately followed by a space character or - # a comment. - if type in ("Comment", "SpaceCharacters"): - return False - elif type == "StartTag": - # XXX: we also look for an immediately following colgroup - # element. See is_optional_start. - return next["name"] != 'colgroup' - else: - return True - elif tagname in ('thead', 'tbody'): - # A thead element's end tag may be omitted if the thead element - # is immediately followed by a tbody or tfoot element. - # A tbody element's end tag may be omitted if the tbody element - # is immediately followed by a tbody or tfoot element, or if - # there is no more content in the parent element. - # A tfoot element's end tag may be omitted if the tfoot element - # is immediately followed by a tbody element, or if there is no - # more content in the parent element. - # XXX: we never omit the end tag when the following element is - # a tbody. See is_optional_start. - if type == "StartTag": - return next["name"] in ['tbody', 'tfoot'] - elif tagname == 'tbody': - return type == "EndTag" or type is None - else: - return False - elif tagname == 'tfoot': - # A tfoot element's end tag may be omitted if the tfoot element - # is immediately followed by a tbody element, or if there is no - # more content in the parent element. - # XXX: we never omit the end tag when the following element is - # a tbody. See is_optional_start. - if type == "StartTag": - return next["name"] == 'tbody' - else: - return type == "EndTag" or type is None - elif tagname in ('td', 'th'): - # A td element's end tag may be omitted if the td element is - # immediately followed by a td or th element, or if there is - # no more content in the parent element. - # A th element's end tag may be omitted if the th element is - # immediately followed by a td or th element, or if there is - # no more content in the parent element. - if type == "StartTag": - return next["name"] in ('td', 'th') - else: - return type == "EndTag" or type is None - return False diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/sanitizer.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/sanitizer.py deleted file mode 100644 index af8e77b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/sanitizer.py +++ /dev/null @@ -1,896 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -import re -from xml.sax.saxutils import escape, unescape - -from pip._vendor.six.moves import urllib_parse as urlparse - -from . import base -from ..constants import namespaces, prefixes - -__all__ = ["Filter"] - - -allowed_elements = frozenset(( - (namespaces['html'], 'a'), - (namespaces['html'], 'abbr'), - (namespaces['html'], 'acronym'), - (namespaces['html'], 'address'), - (namespaces['html'], 'area'), - (namespaces['html'], 'article'), - (namespaces['html'], 'aside'), - (namespaces['html'], 'audio'), - (namespaces['html'], 'b'), - (namespaces['html'], 'big'), - (namespaces['html'], 'blockquote'), - (namespaces['html'], 'br'), - (namespaces['html'], 'button'), - (namespaces['html'], 'canvas'), - (namespaces['html'], 'caption'), - (namespaces['html'], 'center'), - (namespaces['html'], 'cite'), - (namespaces['html'], 'code'), - (namespaces['html'], 'col'), - (namespaces['html'], 'colgroup'), - (namespaces['html'], 'command'), - (namespaces['html'], 'datagrid'), - (namespaces['html'], 'datalist'), - (namespaces['html'], 'dd'), - (namespaces['html'], 'del'), - (namespaces['html'], 'details'), - (namespaces['html'], 'dfn'), - (namespaces['html'], 'dialog'), - (namespaces['html'], 'dir'), - (namespaces['html'], 'div'), - (namespaces['html'], 'dl'), - (namespaces['html'], 'dt'), - (namespaces['html'], 'em'), - (namespaces['html'], 'event-source'), - (namespaces['html'], 'fieldset'), - (namespaces['html'], 'figcaption'), - (namespaces['html'], 'figure'), - (namespaces['html'], 'footer'), - (namespaces['html'], 'font'), - (namespaces['html'], 'form'), - (namespaces['html'], 'header'), - (namespaces['html'], 'h1'), - (namespaces['html'], 'h2'), - (namespaces['html'], 'h3'), - (namespaces['html'], 'h4'), - (namespaces['html'], 'h5'), - (namespaces['html'], 'h6'), - (namespaces['html'], 'hr'), - (namespaces['html'], 'i'), - (namespaces['html'], 'img'), - (namespaces['html'], 'input'), - (namespaces['html'], 'ins'), - (namespaces['html'], 'keygen'), - (namespaces['html'], 'kbd'), - (namespaces['html'], 'label'), - (namespaces['html'], 'legend'), - (namespaces['html'], 'li'), - (namespaces['html'], 'm'), - (namespaces['html'], 'map'), - (namespaces['html'], 'menu'), - (namespaces['html'], 'meter'), - (namespaces['html'], 'multicol'), - (namespaces['html'], 'nav'), - (namespaces['html'], 'nextid'), - (namespaces['html'], 'ol'), - (namespaces['html'], 'output'), - (namespaces['html'], 'optgroup'), - (namespaces['html'], 'option'), - (namespaces['html'], 'p'), - (namespaces['html'], 'pre'), - (namespaces['html'], 'progress'), - (namespaces['html'], 'q'), - (namespaces['html'], 's'), - (namespaces['html'], 'samp'), - (namespaces['html'], 'section'), - (namespaces['html'], 'select'), - (namespaces['html'], 'small'), - (namespaces['html'], 'sound'), - (namespaces['html'], 'source'), - (namespaces['html'], 'spacer'), - (namespaces['html'], 'span'), - (namespaces['html'], 'strike'), - (namespaces['html'], 'strong'), - (namespaces['html'], 'sub'), - (namespaces['html'], 'sup'), - (namespaces['html'], 'table'), - (namespaces['html'], 'tbody'), - (namespaces['html'], 'td'), - (namespaces['html'], 'textarea'), - (namespaces['html'], 'time'), - (namespaces['html'], 'tfoot'), - (namespaces['html'], 'th'), - (namespaces['html'], 'thead'), - (namespaces['html'], 'tr'), - (namespaces['html'], 'tt'), - (namespaces['html'], 'u'), - (namespaces['html'], 'ul'), - (namespaces['html'], 'var'), - (namespaces['html'], 'video'), - (namespaces['mathml'], 'maction'), - (namespaces['mathml'], 'math'), - (namespaces['mathml'], 'merror'), - (namespaces['mathml'], 'mfrac'), - (namespaces['mathml'], 'mi'), - (namespaces['mathml'], 'mmultiscripts'), - (namespaces['mathml'], 'mn'), - (namespaces['mathml'], 'mo'), - (namespaces['mathml'], 'mover'), - (namespaces['mathml'], 'mpadded'), - (namespaces['mathml'], 'mphantom'), - (namespaces['mathml'], 'mprescripts'), - (namespaces['mathml'], 'mroot'), - (namespaces['mathml'], 'mrow'), - (namespaces['mathml'], 'mspace'), - (namespaces['mathml'], 'msqrt'), - (namespaces['mathml'], 'mstyle'), - (namespaces['mathml'], 'msub'), - (namespaces['mathml'], 'msubsup'), - (namespaces['mathml'], 'msup'), - (namespaces['mathml'], 'mtable'), - (namespaces['mathml'], 'mtd'), - (namespaces['mathml'], 'mtext'), - (namespaces['mathml'], 'mtr'), - (namespaces['mathml'], 'munder'), - (namespaces['mathml'], 'munderover'), - (namespaces['mathml'], 'none'), - (namespaces['svg'], 'a'), - (namespaces['svg'], 'animate'), - (namespaces['svg'], 'animateColor'), - (namespaces['svg'], 'animateMotion'), - (namespaces['svg'], 'animateTransform'), - (namespaces['svg'], 'clipPath'), - (namespaces['svg'], 'circle'), - (namespaces['svg'], 'defs'), - (namespaces['svg'], 'desc'), - (namespaces['svg'], 'ellipse'), - (namespaces['svg'], 'font-face'), - (namespaces['svg'], 'font-face-name'), - (namespaces['svg'], 'font-face-src'), - (namespaces['svg'], 'g'), - (namespaces['svg'], 'glyph'), - (namespaces['svg'], 'hkern'), - (namespaces['svg'], 'linearGradient'), - (namespaces['svg'], 'line'), - (namespaces['svg'], 'marker'), - (namespaces['svg'], 'metadata'), - (namespaces['svg'], 'missing-glyph'), - (namespaces['svg'], 'mpath'), - (namespaces['svg'], 'path'), - (namespaces['svg'], 'polygon'), - (namespaces['svg'], 'polyline'), - (namespaces['svg'], 'radialGradient'), - (namespaces['svg'], 'rect'), - (namespaces['svg'], 'set'), - (namespaces['svg'], 'stop'), - (namespaces['svg'], 'svg'), - (namespaces['svg'], 'switch'), - (namespaces['svg'], 'text'), - (namespaces['svg'], 'title'), - (namespaces['svg'], 'tspan'), - (namespaces['svg'], 'use'), -)) - -allowed_attributes = frozenset(( - # HTML attributes - (None, 'abbr'), - (None, 'accept'), - (None, 'accept-charset'), - (None, 'accesskey'), - (None, 'action'), - (None, 'align'), - (None, 'alt'), - (None, 'autocomplete'), - (None, 'autofocus'), - (None, 'axis'), - (None, 'background'), - (None, 'balance'), - (None, 'bgcolor'), - (None, 'bgproperties'), - (None, 'border'), - (None, 'bordercolor'), - (None, 'bordercolordark'), - (None, 'bordercolorlight'), - (None, 'bottompadding'), - (None, 'cellpadding'), - (None, 'cellspacing'), - (None, 'ch'), - (None, 'challenge'), - (None, 'char'), - (None, 'charoff'), - (None, 'choff'), - (None, 'charset'), - (None, 'checked'), - (None, 'cite'), - (None, 'class'), - (None, 'clear'), - (None, 'color'), - (None, 'cols'), - (None, 'colspan'), - (None, 'compact'), - (None, 'contenteditable'), - (None, 'controls'), - (None, 'coords'), - (None, 'data'), - (None, 'datafld'), - (None, 'datapagesize'), - (None, 'datasrc'), - (None, 'datetime'), - (None, 'default'), - (None, 'delay'), - (None, 'dir'), - (None, 'disabled'), - (None, 'draggable'), - (None, 'dynsrc'), - (None, 'enctype'), - (None, 'end'), - (None, 'face'), - (None, 'for'), - (None, 'form'), - (None, 'frame'), - (None, 'galleryimg'), - (None, 'gutter'), - (None, 'headers'), - (None, 'height'), - (None, 'hidefocus'), - (None, 'hidden'), - (None, 'high'), - (None, 'href'), - (None, 'hreflang'), - (None, 'hspace'), - (None, 'icon'), - (None, 'id'), - (None, 'inputmode'), - (None, 'ismap'), - (None, 'keytype'), - (None, 'label'), - (None, 'leftspacing'), - (None, 'lang'), - (None, 'list'), - (None, 'longdesc'), - (None, 'loop'), - (None, 'loopcount'), - (None, 'loopend'), - (None, 'loopstart'), - (None, 'low'), - (None, 'lowsrc'), - (None, 'max'), - (None, 'maxlength'), - (None, 'media'), - (None, 'method'), - (None, 'min'), - (None, 'multiple'), - (None, 'name'), - (None, 'nohref'), - (None, 'noshade'), - (None, 'nowrap'), - (None, 'open'), - (None, 'optimum'), - (None, 'pattern'), - (None, 'ping'), - (None, 'point-size'), - (None, 'poster'), - (None, 'pqg'), - (None, 'preload'), - (None, 'prompt'), - (None, 'radiogroup'), - (None, 'readonly'), - (None, 'rel'), - (None, 'repeat-max'), - (None, 'repeat-min'), - (None, 'replace'), - (None, 'required'), - (None, 'rev'), - (None, 'rightspacing'), - (None, 'rows'), - (None, 'rowspan'), - (None, 'rules'), - (None, 'scope'), - (None, 'selected'), - (None, 'shape'), - (None, 'size'), - (None, 'span'), - (None, 'src'), - (None, 'start'), - (None, 'step'), - (None, 'style'), - (None, 'summary'), - (None, 'suppress'), - (None, 'tabindex'), - (None, 'target'), - (None, 'template'), - (None, 'title'), - (None, 'toppadding'), - (None, 'type'), - (None, 'unselectable'), - (None, 'usemap'), - (None, 'urn'), - (None, 'valign'), - (None, 'value'), - (None, 'variable'), - (None, 'volume'), - (None, 'vspace'), - (None, 'vrml'), - (None, 'width'), - (None, 'wrap'), - (namespaces['xml'], 'lang'), - # MathML attributes - (None, 'actiontype'), - (None, 'align'), - (None, 'columnalign'), - (None, 'columnalign'), - (None, 'columnalign'), - (None, 'columnlines'), - (None, 'columnspacing'), - (None, 'columnspan'), - (None, 'depth'), - (None, 'display'), - (None, 'displaystyle'), - (None, 'equalcolumns'), - (None, 'equalrows'), - (None, 'fence'), - (None, 'fontstyle'), - (None, 'fontweight'), - (None, 'frame'), - (None, 'height'), - (None, 'linethickness'), - (None, 'lspace'), - (None, 'mathbackground'), - (None, 'mathcolor'), - (None, 'mathvariant'), - (None, 'mathvariant'), - (None, 'maxsize'), - (None, 'minsize'), - (None, 'other'), - (None, 'rowalign'), - (None, 'rowalign'), - (None, 'rowalign'), - (None, 'rowlines'), - (None, 'rowspacing'), - (None, 'rowspan'), - (None, 'rspace'), - (None, 'scriptlevel'), - (None, 'selection'), - (None, 'separator'), - (None, 'stretchy'), - (None, 'width'), - (None, 'width'), - (namespaces['xlink'], 'href'), - (namespaces['xlink'], 'show'), - (namespaces['xlink'], 'type'), - # SVG attributes - (None, 'accent-height'), - (None, 'accumulate'), - (None, 'additive'), - (None, 'alphabetic'), - (None, 'arabic-form'), - (None, 'ascent'), - (None, 'attributeName'), - (None, 'attributeType'), - (None, 'baseProfile'), - (None, 'bbox'), - (None, 'begin'), - (None, 'by'), - (None, 'calcMode'), - (None, 'cap-height'), - (None, 'class'), - (None, 'clip-path'), - (None, 'color'), - (None, 'color-rendering'), - (None, 'content'), - (None, 'cx'), - (None, 'cy'), - (None, 'd'), - (None, 'dx'), - (None, 'dy'), - (None, 'descent'), - (None, 'display'), - (None, 'dur'), - (None, 'end'), - (None, 'fill'), - (None, 'fill-opacity'), - (None, 'fill-rule'), - (None, 'font-family'), - (None, 'font-size'), - (None, 'font-stretch'), - (None, 'font-style'), - (None, 'font-variant'), - (None, 'font-weight'), - (None, 'from'), - (None, 'fx'), - (None, 'fy'), - (None, 'g1'), - (None, 'g2'), - (None, 'glyph-name'), - (None, 'gradientUnits'), - (None, 'hanging'), - (None, 'height'), - (None, 'horiz-adv-x'), - (None, 'horiz-origin-x'), - (None, 'id'), - (None, 'ideographic'), - (None, 'k'), - (None, 'keyPoints'), - (None, 'keySplines'), - (None, 'keyTimes'), - (None, 'lang'), - (None, 'marker-end'), - (None, 'marker-mid'), - (None, 'marker-start'), - (None, 'markerHeight'), - (None, 'markerUnits'), - (None, 'markerWidth'), - (None, 'mathematical'), - (None, 'max'), - (None, 'min'), - (None, 'name'), - (None, 'offset'), - (None, 'opacity'), - (None, 'orient'), - (None, 'origin'), - (None, 'overline-position'), - (None, 'overline-thickness'), - (None, 'panose-1'), - (None, 'path'), - (None, 'pathLength'), - (None, 'points'), - (None, 'preserveAspectRatio'), - (None, 'r'), - (None, 'refX'), - (None, 'refY'), - (None, 'repeatCount'), - (None, 'repeatDur'), - (None, 'requiredExtensions'), - (None, 'requiredFeatures'), - (None, 'restart'), - (None, 'rotate'), - (None, 'rx'), - (None, 'ry'), - (None, 'slope'), - (None, 'stemh'), - (None, 'stemv'), - (None, 'stop-color'), - (None, 'stop-opacity'), - (None, 'strikethrough-position'), - (None, 'strikethrough-thickness'), - (None, 'stroke'), - (None, 'stroke-dasharray'), - (None, 'stroke-dashoffset'), - (None, 'stroke-linecap'), - (None, 'stroke-linejoin'), - (None, 'stroke-miterlimit'), - (None, 'stroke-opacity'), - (None, 'stroke-width'), - (None, 'systemLanguage'), - (None, 'target'), - (None, 'text-anchor'), - (None, 'to'), - (None, 'transform'), - (None, 'type'), - (None, 'u1'), - (None, 'u2'), - (None, 'underline-position'), - (None, 'underline-thickness'), - (None, 'unicode'), - (None, 'unicode-range'), - (None, 'units-per-em'), - (None, 'values'), - (None, 'version'), - (None, 'viewBox'), - (None, 'visibility'), - (None, 'width'), - (None, 'widths'), - (None, 'x'), - (None, 'x-height'), - (None, 'x1'), - (None, 'x2'), - (namespaces['xlink'], 'actuate'), - (namespaces['xlink'], 'arcrole'), - (namespaces['xlink'], 'href'), - (namespaces['xlink'], 'role'), - (namespaces['xlink'], 'show'), - (namespaces['xlink'], 'title'), - (namespaces['xlink'], 'type'), - (namespaces['xml'], 'base'), - (namespaces['xml'], 'lang'), - (namespaces['xml'], 'space'), - (None, 'y'), - (None, 'y1'), - (None, 'y2'), - (None, 'zoomAndPan'), -)) - -attr_val_is_uri = frozenset(( - (None, 'href'), - (None, 'src'), - (None, 'cite'), - (None, 'action'), - (None, 'longdesc'), - (None, 'poster'), - (None, 'background'), - (None, 'datasrc'), - (None, 'dynsrc'), - (None, 'lowsrc'), - (None, 'ping'), - (namespaces['xlink'], 'href'), - (namespaces['xml'], 'base'), -)) - -svg_attr_val_allows_ref = frozenset(( - (None, 'clip-path'), - (None, 'color-profile'), - (None, 'cursor'), - (None, 'fill'), - (None, 'filter'), - (None, 'marker'), - (None, 'marker-start'), - (None, 'marker-mid'), - (None, 'marker-end'), - (None, 'mask'), - (None, 'stroke'), -)) - -svg_allow_local_href = frozenset(( - (None, 'altGlyph'), - (None, 'animate'), - (None, 'animateColor'), - (None, 'animateMotion'), - (None, 'animateTransform'), - (None, 'cursor'), - (None, 'feImage'), - (None, 'filter'), - (None, 'linearGradient'), - (None, 'pattern'), - (None, 'radialGradient'), - (None, 'textpath'), - (None, 'tref'), - (None, 'set'), - (None, 'use') -)) - -allowed_css_properties = frozenset(( - 'azimuth', - 'background-color', - 'border-bottom-color', - 'border-collapse', - 'border-color', - 'border-left-color', - 'border-right-color', - 'border-top-color', - 'clear', - 'color', - 'cursor', - 'direction', - 'display', - 'elevation', - 'float', - 'font', - 'font-family', - 'font-size', - 'font-style', - 'font-variant', - 'font-weight', - 'height', - 'letter-spacing', - 'line-height', - 'overflow', - 'pause', - 'pause-after', - 'pause-before', - 'pitch', - 'pitch-range', - 'richness', - 'speak', - 'speak-header', - 'speak-numeral', - 'speak-punctuation', - 'speech-rate', - 'stress', - 'text-align', - 'text-decoration', - 'text-indent', - 'unicode-bidi', - 'vertical-align', - 'voice-family', - 'volume', - 'white-space', - 'width', -)) - -allowed_css_keywords = frozenset(( - 'auto', - 'aqua', - 'black', - 'block', - 'blue', - 'bold', - 'both', - 'bottom', - 'brown', - 'center', - 'collapse', - 'dashed', - 'dotted', - 'fuchsia', - 'gray', - 'green', - '!important', - 'italic', - 'left', - 'lime', - 'maroon', - 'medium', - 'none', - 'navy', - 'normal', - 'nowrap', - 'olive', - 'pointer', - 'purple', - 'red', - 'right', - 'solid', - 'silver', - 'teal', - 'top', - 'transparent', - 'underline', - 'white', - 'yellow', -)) - -allowed_svg_properties = frozenset(( - 'fill', - 'fill-opacity', - 'fill-rule', - 'stroke', - 'stroke-width', - 'stroke-linecap', - 'stroke-linejoin', - 'stroke-opacity', -)) - -allowed_protocols = frozenset(( - 'ed2k', - 'ftp', - 'http', - 'https', - 'irc', - 'mailto', - 'news', - 'gopher', - 'nntp', - 'telnet', - 'webcal', - 'xmpp', - 'callto', - 'feed', - 'urn', - 'aim', - 'rsync', - 'tag', - 'ssh', - 'sftp', - 'rtsp', - 'afs', - 'data', -)) - -allowed_content_types = frozenset(( - 'image/png', - 'image/jpeg', - 'image/gif', - 'image/webp', - 'image/bmp', - 'text/plain', -)) - - -data_content_type = re.compile(r''' - ^ - # Match a content type <application>/<type> - (?P<content_type>[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) - # Match any character set and encoding - (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) - |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) - # Assume the rest is data - ,.* - $ - ''', - re.VERBOSE) - - -class Filter(base.Filter): - """Sanitizes token stream of XHTML+MathML+SVG and of inline style attributes""" - def __init__(self, - source, - allowed_elements=allowed_elements, - allowed_attributes=allowed_attributes, - allowed_css_properties=allowed_css_properties, - allowed_css_keywords=allowed_css_keywords, - allowed_svg_properties=allowed_svg_properties, - allowed_protocols=allowed_protocols, - allowed_content_types=allowed_content_types, - attr_val_is_uri=attr_val_is_uri, - svg_attr_val_allows_ref=svg_attr_val_allows_ref, - svg_allow_local_href=svg_allow_local_href): - """Creates a Filter - - :arg allowed_elements: set of elements to allow--everything else will - be escaped - - :arg allowed_attributes: set of attributes to allow in - elements--everything else will be stripped - - :arg allowed_css_properties: set of CSS properties to allow--everything - else will be stripped - - :arg allowed_css_keywords: set of CSS keywords to allow--everything - else will be stripped - - :arg allowed_svg_properties: set of SVG properties to allow--everything - else will be removed - - :arg allowed_protocols: set of allowed protocols for URIs - - :arg allowed_content_types: set of allowed content types for ``data`` URIs. - - :arg attr_val_is_uri: set of attributes that have URI values--values - that have a scheme not listed in ``allowed_protocols`` are removed - - :arg svg_attr_val_allows_ref: set of SVG attributes that can have - references - - :arg svg_allow_local_href: set of SVG elements that can have local - hrefs--these are removed - - """ - super(Filter, self).__init__(source) - self.allowed_elements = allowed_elements - self.allowed_attributes = allowed_attributes - self.allowed_css_properties = allowed_css_properties - self.allowed_css_keywords = allowed_css_keywords - self.allowed_svg_properties = allowed_svg_properties - self.allowed_protocols = allowed_protocols - self.allowed_content_types = allowed_content_types - self.attr_val_is_uri = attr_val_is_uri - self.svg_attr_val_allows_ref = svg_attr_val_allows_ref - self.svg_allow_local_href = svg_allow_local_href - - def __iter__(self): - for token in base.Filter.__iter__(self): - token = self.sanitize_token(token) - if token: - yield token - - # Sanitize the +html+, escaping all elements not in ALLOWED_ELEMENTS, and - # stripping out all attributes not in ALLOWED_ATTRIBUTES. Style attributes - # are parsed, and a restricted set, specified by ALLOWED_CSS_PROPERTIES and - # ALLOWED_CSS_KEYWORDS, are allowed through. attributes in ATTR_VAL_IS_URI - # are scanned, and only URI schemes specified in ALLOWED_PROTOCOLS are - # allowed. - # - # sanitize_html('<script> do_nasty_stuff() </script>') - # => <script> do_nasty_stuff() </script> - # sanitize_html('<a href="javascript: sucker();">Click here for $100</a>') - # => <a>Click here for $100</a> - def sanitize_token(self, token): - - # accommodate filters which use token_type differently - token_type = token["type"] - if token_type in ("StartTag", "EndTag", "EmptyTag"): - name = token["name"] - namespace = token["namespace"] - if ((namespace, name) in self.allowed_elements or - (namespace is None and - (namespaces["html"], name) in self.allowed_elements)): - return self.allowed_token(token) - else: - return self.disallowed_token(token) - elif token_type == "Comment": - pass - else: - return token - - def allowed_token(self, token): - if "data" in token: - attrs = token["data"] - attr_names = set(attrs.keys()) - - # Remove forbidden attributes - for to_remove in (attr_names - self.allowed_attributes): - del token["data"][to_remove] - attr_names.remove(to_remove) - - # Remove attributes with disallowed URL values - for attr in (attr_names & self.attr_val_is_uri): - assert attr in attrs - # I don't have a clue where this regexp comes from or why it matches those - # characters, nor why we call unescape. I just know it's always been here. - # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all - # this will do is remove *more* than it otherwise would. - val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', - unescape(attrs[attr])).lower() - # remove replacement characters from unescaped characters - val_unescaped = val_unescaped.replace("\ufffd", "") - try: - uri = urlparse.urlparse(val_unescaped) - except ValueError: - uri = None - del attrs[attr] - if uri and uri.scheme: - if uri.scheme not in self.allowed_protocols: - del attrs[attr] - if uri.scheme == 'data': - m = data_content_type.match(uri.path) - if not m: - del attrs[attr] - elif m.group('content_type') not in self.allowed_content_types: - del attrs[attr] - - for attr in self.svg_attr_val_allows_ref: - if attr in attrs: - attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', - ' ', - unescape(attrs[attr])) - if (token["name"] in self.svg_allow_local_href and - (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', - attrs[(namespaces['xlink'], 'href')])): - del attrs[(namespaces['xlink'], 'href')] - if (None, 'style') in attrs: - attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) - token["data"] = attrs - return token - - def disallowed_token(self, token): - token_type = token["type"] - if token_type == "EndTag": - token["data"] = "</%s>" % token["name"] - elif token["data"]: - assert token_type in ("StartTag", "EmptyTag") - attrs = [] - for (ns, name), v in token["data"].items(): - attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) - token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) - else: - token["data"] = "<%s>" % token["name"] - if token.get("selfClosing"): - token["data"] = token["data"][:-1] + "/>" - - token["type"] = "Characters" - - del token["name"] - return token - - def sanitize_css(self, style): - # disallow urls - style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) - - # gauntlet - if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): - return '' - if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): - return '' - - clean = [] - for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): - if not value: - continue - if prop.lower() in self.allowed_css_properties: - clean.append(prop + ': ' + value + ';') - elif prop.split('-')[0].lower() in ['background', 'border', 'margin', - 'padding']: - for keyword in value.split(): - if keyword not in self.allowed_css_keywords and \ - not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa - break - else: - clean.append(prop + ': ' + value + ';') - elif prop.lower() in self.allowed_svg_properties: - clean.append(prop + ': ' + value + ';') - - return ' '.join(clean) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/whitespace.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/whitespace.py deleted file mode 100644 index 0d12584..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/filters/whitespace.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -import re - -from . import base -from ..constants import rcdataElements, spaceCharacters -spaceCharacters = "".join(spaceCharacters) - -SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) - - -class Filter(base.Filter): - """Collapses whitespace except in pre, textarea, and script elements""" - spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) - - def __iter__(self): - preserve = 0 - for token in base.Filter.__iter__(self): - type = token["type"] - if type == "StartTag" \ - and (preserve or token["name"] in self.spacePreserveElements): - preserve += 1 - - elif type == "EndTag" and preserve: - preserve -= 1 - - elif not preserve and type == "SpaceCharacters" and token["data"]: - # Test on token["data"] above to not introduce spaces where there were not - token["data"] = " " - - elif not preserve and type == "Characters": - token["data"] = collapse_spaces(token["data"]) - - yield token - - -def collapse_spaces(text): - return SPACES_REGEX.sub(' ', text) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/html5parser.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/html5parser.py deleted file mode 100644 index ae41a13..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/html5parser.py +++ /dev/null @@ -1,2791 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals -from pip._vendor.six import with_metaclass, viewkeys - -import types -from collections import OrderedDict - -from . import _inputstream -from . import _tokenizer - -from . import treebuilders -from .treebuilders.base import Marker - -from . import _utils -from .constants import ( - spaceCharacters, asciiUpper2Lower, - specialElements, headingElements, cdataElements, rcdataElements, - tokenTypes, tagTokenTypes, - namespaces, - htmlIntegrationPointElements, mathmlTextIntegrationPointElements, - adjustForeignAttributes as adjustForeignAttributesMap, - adjustMathMLAttributes, adjustSVGAttributes, - E, - _ReparseException -) - - -def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): - """Parse an HTML document as a string or file-like object into a tree - - :arg doc: the document to parse as a string or file-like object - - :arg treebuilder: the treebuilder to use when parsing - - :arg namespaceHTMLElements: whether or not to namespace HTML elements - - :returns: parsed tree - - Example: - - >>> from html5lib.html5parser import parse - >>> parse('<html><body><p>This is a doc</p></body></html>') - <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> - - """ - tb = treebuilders.getTreeBuilder(treebuilder) - p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) - return p.parse(doc, **kwargs) - - -def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): - """Parse an HTML fragment as a string or file-like object into a tree - - :arg doc: the fragment to parse as a string or file-like object - - :arg container: the container context to parse the fragment in - - :arg treebuilder: the treebuilder to use when parsing - - :arg namespaceHTMLElements: whether or not to namespace HTML elements - - :returns: parsed tree - - Example: - - >>> from html5lib.html5libparser import parseFragment - >>> parseFragment('<b>this is a fragment</b>') - <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> - - """ - tb = treebuilders.getTreeBuilder(treebuilder) - p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) - return p.parseFragment(doc, container=container, **kwargs) - - -def method_decorator_metaclass(function): - class Decorated(type): - def __new__(meta, classname, bases, classDict): - for attributeName, attribute in classDict.items(): - if isinstance(attribute, types.FunctionType): - attribute = function(attribute) - - classDict[attributeName] = attribute - return type.__new__(meta, classname, bases, classDict) - return Decorated - - -class HTMLParser(object): - """HTML parser - - Generates a tree structure from a stream of (possibly malformed) HTML. - - """ - - def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): - """ - :arg tree: a treebuilder class controlling the type of tree that will be - returned. Built in treebuilders can be accessed through - html5lib.treebuilders.getTreeBuilder(treeType) - - :arg strict: raise an exception when a parse error is encountered - - :arg namespaceHTMLElements: whether or not to namespace HTML elements - - :arg debug: whether or not to enable debug mode which logs things - - Example: - - >>> from html5lib.html5parser import HTMLParser - >>> parser = HTMLParser() # generates parser with etree builder - >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict - - """ - - # Raise an exception on the first error encountered - self.strict = strict - - if tree is None: - tree = treebuilders.getTreeBuilder("etree") - self.tree = tree(namespaceHTMLElements) - self.errors = [] - - self.phases = dict([(name, cls(self, self.tree)) for name, cls in - getPhases(debug).items()]) - - def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): - - self.innerHTMLMode = innerHTML - self.container = container - self.scripting = scripting - self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) - self.reset() - - try: - self.mainLoop() - except _ReparseException: - self.reset() - self.mainLoop() - - def reset(self): - self.tree.reset() - self.firstStartTag = False - self.errors = [] - self.log = [] # only used with debug mode - # "quirks" / "limited quirks" / "no quirks" - self.compatMode = "no quirks" - - if self.innerHTMLMode: - self.innerHTML = self.container.lower() - - if self.innerHTML in cdataElements: - self.tokenizer.state = self.tokenizer.rcdataState - elif self.innerHTML in rcdataElements: - self.tokenizer.state = self.tokenizer.rawtextState - elif self.innerHTML == 'plaintext': - self.tokenizer.state = self.tokenizer.plaintextState - else: - # state already is data state - # self.tokenizer.state = self.tokenizer.dataState - pass - self.phase = self.phases["beforeHtml"] - self.phase.insertHtmlElement() - self.resetInsertionMode() - else: - self.innerHTML = False # pylint:disable=redefined-variable-type - self.phase = self.phases["initial"] - - self.lastPhase = None - - self.beforeRCDataPhase = None - - self.framesetOK = True - - @property - def documentEncoding(self): - """Name of the character encoding that was used to decode the input stream, or - :obj:`None` if that is not determined yet - - """ - if not hasattr(self, 'tokenizer'): - return None - return self.tokenizer.stream.charEncoding[0].name - - def isHTMLIntegrationPoint(self, element): - if (element.name == "annotation-xml" and - element.namespace == namespaces["mathml"]): - return ("encoding" in element.attributes and - element.attributes["encoding"].translate( - asciiUpper2Lower) in - ("text/html", "application/xhtml+xml")) - else: - return (element.namespace, element.name) in htmlIntegrationPointElements - - def isMathMLTextIntegrationPoint(self, element): - return (element.namespace, element.name) in mathmlTextIntegrationPointElements - - def mainLoop(self): - CharactersToken = tokenTypes["Characters"] - SpaceCharactersToken = tokenTypes["SpaceCharacters"] - StartTagToken = tokenTypes["StartTag"] - EndTagToken = tokenTypes["EndTag"] - CommentToken = tokenTypes["Comment"] - DoctypeToken = tokenTypes["Doctype"] - ParseErrorToken = tokenTypes["ParseError"] - - for token in self.normalizedTokens(): - prev_token = None - new_token = token - while new_token is not None: - prev_token = new_token - currentNode = self.tree.openElements[-1] if self.tree.openElements else None - currentNodeNamespace = currentNode.namespace if currentNode else None - currentNodeName = currentNode.name if currentNode else None - - type = new_token["type"] - - if type == ParseErrorToken: - self.parseError(new_token["data"], new_token.get("datavars", {})) - new_token = None - else: - if (len(self.tree.openElements) == 0 or - currentNodeNamespace == self.tree.defaultNamespace or - (self.isMathMLTextIntegrationPoint(currentNode) and - ((type == StartTagToken and - token["name"] not in frozenset(["mglyph", "malignmark"])) or - type in (CharactersToken, SpaceCharactersToken))) or - (currentNodeNamespace == namespaces["mathml"] and - currentNodeName == "annotation-xml" and - type == StartTagToken and - token["name"] == "svg") or - (self.isHTMLIntegrationPoint(currentNode) and - type in (StartTagToken, CharactersToken, SpaceCharactersToken))): - phase = self.phase - else: - phase = self.phases["inForeignContent"] - - if type == CharactersToken: - new_token = phase.processCharacters(new_token) - elif type == SpaceCharactersToken: - new_token = phase.processSpaceCharacters(new_token) - elif type == StartTagToken: - new_token = phase.processStartTag(new_token) - elif type == EndTagToken: - new_token = phase.processEndTag(new_token) - elif type == CommentToken: - new_token = phase.processComment(new_token) - elif type == DoctypeToken: - new_token = phase.processDoctype(new_token) - - if (type == StartTagToken and prev_token["selfClosing"] and - not prev_token["selfClosingAcknowledged"]): - self.parseError("non-void-element-with-trailing-solidus", - {"name": prev_token["name"]}) - - # When the loop finishes it's EOF - reprocess = True - phases = [] - while reprocess: - phases.append(self.phase) - reprocess = self.phase.processEOF() - if reprocess: - assert self.phase not in phases - - def normalizedTokens(self): - for token in self.tokenizer: - yield self.normalizeToken(token) - - def parse(self, stream, *args, **kwargs): - """Parse a HTML document into a well-formed tree - - :arg stream: a file-like object or string containing the HTML to be parsed - - The optional encoding parameter must be a string that indicates - the encoding. If specified, that encoding will be used, - regardless of any BOM or later declaration (such as in a meta - element). - - :arg scripting: treat noscript elements as if JavaScript was turned on - - :returns: parsed tree - - Example: - - >>> from html5lib.html5parser import HTMLParser - >>> parser = HTMLParser() - >>> parser.parse('<html><body><p>This is a doc</p></body></html>') - <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> - - """ - self._parse(stream, False, None, *args, **kwargs) - return self.tree.getDocument() - - def parseFragment(self, stream, *args, **kwargs): - """Parse a HTML fragment into a well-formed tree fragment - - :arg container: name of the element we're setting the innerHTML - property if set to None, default to 'div' - - :arg stream: a file-like object or string containing the HTML to be parsed - - The optional encoding parameter must be a string that indicates - the encoding. If specified, that encoding will be used, - regardless of any BOM or later declaration (such as in a meta - element) - - :arg scripting: treat noscript elements as if JavaScript was turned on - - :returns: parsed tree - - Example: - - >>> from html5lib.html5libparser import HTMLParser - >>> parser = HTMLParser() - >>> parser.parseFragment('<b>this is a fragment</b>') - <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> - - """ - self._parse(stream, True, *args, **kwargs) - return self.tree.getFragment() - - def parseError(self, errorcode="XXX-undefined-error", datavars=None): - # XXX The idea is to make errorcode mandatory. - if datavars is None: - datavars = {} - self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) - if self.strict: - raise ParseError(E[errorcode] % datavars) - - def normalizeToken(self, token): - # HTML5 specific normalizations to the token stream - if token["type"] == tokenTypes["StartTag"]: - raw = token["data"] - token["data"] = OrderedDict(raw) - if len(raw) > len(token["data"]): - # we had some duplicated attribute, fix so first wins - token["data"].update(raw[::-1]) - - return token - - def adjustMathMLAttributes(self, token): - adjust_attributes(token, adjustMathMLAttributes) - - def adjustSVGAttributes(self, token): - adjust_attributes(token, adjustSVGAttributes) - - def adjustForeignAttributes(self, token): - adjust_attributes(token, adjustForeignAttributesMap) - - def reparseTokenNormal(self, token): - # pylint:disable=unused-argument - self.parser.phase() - - def resetInsertionMode(self): - # The name of this method is mostly historical. (It's also used in the - # specification.) - last = False - newModes = { - "select": "inSelect", - "td": "inCell", - "th": "inCell", - "tr": "inRow", - "tbody": "inTableBody", - "thead": "inTableBody", - "tfoot": "inTableBody", - "caption": "inCaption", - "colgroup": "inColumnGroup", - "table": "inTable", - "head": "inBody", - "body": "inBody", - "frameset": "inFrameset", - "html": "beforeHead" - } - for node in self.tree.openElements[::-1]: - nodeName = node.name - new_phase = None - if node == self.tree.openElements[0]: - assert self.innerHTML - last = True - nodeName = self.innerHTML - # Check for conditions that should only happen in the innerHTML - # case - if nodeName in ("select", "colgroup", "head", "html"): - assert self.innerHTML - - if not last and node.namespace != self.tree.defaultNamespace: - continue - - if nodeName in newModes: - new_phase = self.phases[newModes[nodeName]] - break - elif last: - new_phase = self.phases["inBody"] - break - - self.phase = new_phase - - def parseRCDataRawtext(self, token, contentType): - # Generic RCDATA/RAWTEXT Parsing algorithm - assert contentType in ("RAWTEXT", "RCDATA") - - self.tree.insertElement(token) - - if contentType == "RAWTEXT": - self.tokenizer.state = self.tokenizer.rawtextState - else: - self.tokenizer.state = self.tokenizer.rcdataState - - self.originalPhase = self.phase - - self.phase = self.phases["text"] - - -@_utils.memoize -def getPhases(debug): - def log(function): - """Logger that records which phase processes each token""" - type_names = dict((value, key) for key, value in - tokenTypes.items()) - - def wrapped(self, *args, **kwargs): - if function.__name__.startswith("process") and len(args) > 0: - token = args[0] - try: - info = {"type": type_names[token['type']]} - except: - raise - if token['type'] in tagTokenTypes: - info["name"] = token['name'] - - self.parser.log.append((self.parser.tokenizer.state.__name__, - self.parser.phase.__class__.__name__, - self.__class__.__name__, - function.__name__, - info)) - return function(self, *args, **kwargs) - else: - return function(self, *args, **kwargs) - return wrapped - - def getMetaclass(use_metaclass, metaclass_func): - if use_metaclass: - return method_decorator_metaclass(metaclass_func) - else: - return type - - # pylint:disable=unused-argument - class Phase(with_metaclass(getMetaclass(debug, log))): - """Base class for helper object that implements each phase of processing - """ - - def __init__(self, parser, tree): - self.parser = parser - self.tree = tree - - def processEOF(self): - raise NotImplementedError - - def processComment(self, token): - # For most phases the following is correct. Where it's not it will be - # overridden. - self.tree.insertComment(token, self.tree.openElements[-1]) - - def processDoctype(self, token): - self.parser.parseError("unexpected-doctype") - - def processCharacters(self, token): - self.tree.insertText(token["data"]) - - def processSpaceCharacters(self, token): - self.tree.insertText(token["data"]) - - def processStartTag(self, token): - return self.startTagHandler[token["name"]](token) - - def startTagHtml(self, token): - if not self.parser.firstStartTag and token["name"] == "html": - self.parser.parseError("non-html-root") - # XXX Need a check here to see if the first start tag token emitted is - # this token... If it's not, invoke self.parser.parseError(). - for attr, value in token["data"].items(): - if attr not in self.tree.openElements[0].attributes: - self.tree.openElements[0].attributes[attr] = value - self.parser.firstStartTag = False - - def processEndTag(self, token): - return self.endTagHandler[token["name"]](token) - - class InitialPhase(Phase): - def processSpaceCharacters(self, token): - pass - - def processComment(self, token): - self.tree.insertComment(token, self.tree.document) - - def processDoctype(self, token): - name = token["name"] - publicId = token["publicId"] - systemId = token["systemId"] - correct = token["correct"] - - if (name != "html" or publicId is not None or - systemId is not None and systemId != "about:legacy-compat"): - self.parser.parseError("unknown-doctype") - - if publicId is None: - publicId = "" - - self.tree.insertDoctype(token) - - if publicId != "": - publicId = publicId.translate(asciiUpper2Lower) - - if (not correct or token["name"] != "html" or - publicId.startswith( - ("+//silmaril//dtd html pro v0r11 19970101//", - "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", - "-//as//dtd html 3.0 aswedit + extensions//", - "-//ietf//dtd html 2.0 level 1//", - "-//ietf//dtd html 2.0 level 2//", - "-//ietf//dtd html 2.0 strict level 1//", - "-//ietf//dtd html 2.0 strict level 2//", - "-//ietf//dtd html 2.0 strict//", - "-//ietf//dtd html 2.0//", - "-//ietf//dtd html 2.1e//", - "-//ietf//dtd html 3.0//", - "-//ietf//dtd html 3.2 final//", - "-//ietf//dtd html 3.2//", - "-//ietf//dtd html 3//", - "-//ietf//dtd html level 0//", - "-//ietf//dtd html level 1//", - "-//ietf//dtd html level 2//", - "-//ietf//dtd html level 3//", - "-//ietf//dtd html strict level 0//", - "-//ietf//dtd html strict level 1//", - "-//ietf//dtd html strict level 2//", - "-//ietf//dtd html strict level 3//", - "-//ietf//dtd html strict//", - "-//ietf//dtd html//", - "-//metrius//dtd metrius presentational//", - "-//microsoft//dtd internet explorer 2.0 html strict//", - "-//microsoft//dtd internet explorer 2.0 html//", - "-//microsoft//dtd internet explorer 2.0 tables//", - "-//microsoft//dtd internet explorer 3.0 html strict//", - "-//microsoft//dtd internet explorer 3.0 html//", - "-//microsoft//dtd internet explorer 3.0 tables//", - "-//netscape comm. corp.//dtd html//", - "-//netscape comm. corp.//dtd strict html//", - "-//o'reilly and associates//dtd html 2.0//", - "-//o'reilly and associates//dtd html extended 1.0//", - "-//o'reilly and associates//dtd html extended relaxed 1.0//", - "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", - "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", - "-//spyglass//dtd html 2.0 extended//", - "-//sq//dtd html 2.0 hotmetal + extensions//", - "-//sun microsystems corp.//dtd hotjava html//", - "-//sun microsystems corp.//dtd hotjava strict html//", - "-//w3c//dtd html 3 1995-03-24//", - "-//w3c//dtd html 3.2 draft//", - "-//w3c//dtd html 3.2 final//", - "-//w3c//dtd html 3.2//", - "-//w3c//dtd html 3.2s draft//", - "-//w3c//dtd html 4.0 frameset//", - "-//w3c//dtd html 4.0 transitional//", - "-//w3c//dtd html experimental 19960712//", - "-//w3c//dtd html experimental 970421//", - "-//w3c//dtd w3 html//", - "-//w3o//dtd w3 html 3.0//", - "-//webtechs//dtd mozilla html 2.0//", - "-//webtechs//dtd mozilla html//")) or - publicId in ("-//w3o//dtd w3 html strict 3.0//en//", - "-/w3c/dtd html 4.0 transitional/en", - "html") or - publicId.startswith( - ("-//w3c//dtd html 4.01 frameset//", - "-//w3c//dtd html 4.01 transitional//")) and - systemId is None or - systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): - self.parser.compatMode = "quirks" - elif (publicId.startswith( - ("-//w3c//dtd xhtml 1.0 frameset//", - "-//w3c//dtd xhtml 1.0 transitional//")) or - publicId.startswith( - ("-//w3c//dtd html 4.01 frameset//", - "-//w3c//dtd html 4.01 transitional//")) and - systemId is not None): - self.parser.compatMode = "limited quirks" - - self.parser.phase = self.parser.phases["beforeHtml"] - - def anythingElse(self): - self.parser.compatMode = "quirks" - self.parser.phase = self.parser.phases["beforeHtml"] - - def processCharacters(self, token): - self.parser.parseError("expected-doctype-but-got-chars") - self.anythingElse() - return token - - def processStartTag(self, token): - self.parser.parseError("expected-doctype-but-got-start-tag", - {"name": token["name"]}) - self.anythingElse() - return token - - def processEndTag(self, token): - self.parser.parseError("expected-doctype-but-got-end-tag", - {"name": token["name"]}) - self.anythingElse() - return token - - def processEOF(self): - self.parser.parseError("expected-doctype-but-got-eof") - self.anythingElse() - return True - - class BeforeHtmlPhase(Phase): - # helper methods - def insertHtmlElement(self): - self.tree.insertRoot(impliedTagToken("html", "StartTag")) - self.parser.phase = self.parser.phases["beforeHead"] - - # other - def processEOF(self): - self.insertHtmlElement() - return True - - def processComment(self, token): - self.tree.insertComment(token, self.tree.document) - - def processSpaceCharacters(self, token): - pass - - def processCharacters(self, token): - self.insertHtmlElement() - return token - - def processStartTag(self, token): - if token["name"] == "html": - self.parser.firstStartTag = True - self.insertHtmlElement() - return token - - def processEndTag(self, token): - if token["name"] not in ("head", "body", "html", "br"): - self.parser.parseError("unexpected-end-tag-before-html", - {"name": token["name"]}) - else: - self.insertHtmlElement() - return token - - class BeforeHeadPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("head", self.startTagHead) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - (("head", "body", "html", "br"), self.endTagImplyHead) - ]) - self.endTagHandler.default = self.endTagOther - - def processEOF(self): - self.startTagHead(impliedTagToken("head", "StartTag")) - return True - - def processSpaceCharacters(self, token): - pass - - def processCharacters(self, token): - self.startTagHead(impliedTagToken("head", "StartTag")) - return token - - def startTagHtml(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def startTagHead(self, token): - self.tree.insertElement(token) - self.tree.headPointer = self.tree.openElements[-1] - self.parser.phase = self.parser.phases["inHead"] - - def startTagOther(self, token): - self.startTagHead(impliedTagToken("head", "StartTag")) - return token - - def endTagImplyHead(self, token): - self.startTagHead(impliedTagToken("head", "StartTag")) - return token - - def endTagOther(self, token): - self.parser.parseError("end-tag-after-implied-root", - {"name": token["name"]}) - - class InHeadPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("title", self.startTagTitle), - (("noframes", "style"), self.startTagNoFramesStyle), - ("noscript", self.startTagNoscript), - ("script", self.startTagScript), - (("base", "basefont", "bgsound", "command", "link"), - self.startTagBaseLinkCommand), - ("meta", self.startTagMeta), - ("head", self.startTagHead) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("head", self.endTagHead), - (("br", "html", "body"), self.endTagHtmlBodyBr) - ]) - self.endTagHandler.default = self.endTagOther - - # the real thing - def processEOF(self): - self.anythingElse() - return True - - def processCharacters(self, token): - self.anythingElse() - return token - - def startTagHtml(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def startTagHead(self, token): - self.parser.parseError("two-heads-are-not-better-than-one") - - def startTagBaseLinkCommand(self, token): - self.tree.insertElement(token) - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - - def startTagMeta(self, token): - self.tree.insertElement(token) - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - - attributes = token["data"] - if self.parser.tokenizer.stream.charEncoding[1] == "tentative": - if "charset" in attributes: - self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) - elif ("content" in attributes and - "http-equiv" in attributes and - attributes["http-equiv"].lower() == "content-type"): - # Encoding it as UTF-8 here is a hack, as really we should pass - # the abstract Unicode string, and just use the - # ContentAttrParser on that, but using UTF-8 allows all chars - # to be encoded and as a ASCII-superset works. - data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) - parser = _inputstream.ContentAttrParser(data) - codec = parser.parse() - self.parser.tokenizer.stream.changeEncoding(codec) - - def startTagTitle(self, token): - self.parser.parseRCDataRawtext(token, "RCDATA") - - def startTagNoFramesStyle(self, token): - # Need to decide whether to implement the scripting-disabled case - self.parser.parseRCDataRawtext(token, "RAWTEXT") - - def startTagNoscript(self, token): - if self.parser.scripting: - self.parser.parseRCDataRawtext(token, "RAWTEXT") - else: - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inHeadNoscript"] - - def startTagScript(self, token): - self.tree.insertElement(token) - self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState - self.parser.originalPhase = self.parser.phase - self.parser.phase = self.parser.phases["text"] - - def startTagOther(self, token): - self.anythingElse() - return token - - def endTagHead(self, token): - node = self.parser.tree.openElements.pop() - assert node.name == "head", "Expected head got %s" % node.name - self.parser.phase = self.parser.phases["afterHead"] - - def endTagHtmlBodyBr(self, token): - self.anythingElse() - return token - - def endTagOther(self, token): - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - - def anythingElse(self): - self.endTagHead(impliedTagToken("head")) - - class InHeadNoscriptPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("basefont", "bgsound", "link", "meta", "noframes", "style"), self.startTagBaseLinkCommand), - (("head", "noscript"), self.startTagHeadNoscript), - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("noscript", self.endTagNoscript), - ("br", self.endTagBr), - ]) - self.endTagHandler.default = self.endTagOther - - def processEOF(self): - self.parser.parseError("eof-in-head-noscript") - self.anythingElse() - return True - - def processComment(self, token): - return self.parser.phases["inHead"].processComment(token) - - def processCharacters(self, token): - self.parser.parseError("char-in-head-noscript") - self.anythingElse() - return token - - def processSpaceCharacters(self, token): - return self.parser.phases["inHead"].processSpaceCharacters(token) - - def startTagHtml(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def startTagBaseLinkCommand(self, token): - return self.parser.phases["inHead"].processStartTag(token) - - def startTagHeadNoscript(self, token): - self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) - - def startTagOther(self, token): - self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) - self.anythingElse() - return token - - def endTagNoscript(self, token): - node = self.parser.tree.openElements.pop() - assert node.name == "noscript", "Expected noscript got %s" % node.name - self.parser.phase = self.parser.phases["inHead"] - - def endTagBr(self, token): - self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) - self.anythingElse() - return token - - def endTagOther(self, token): - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - - def anythingElse(self): - # Caller must raise parse error first! - self.endTagNoscript(impliedTagToken("noscript")) - - class AfterHeadPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("body", self.startTagBody), - ("frameset", self.startTagFrameset), - (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", - "style", "title"), - self.startTagFromHead), - ("head", self.startTagHead) - ]) - self.startTagHandler.default = self.startTagOther - self.endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), - self.endTagHtmlBodyBr)]) - self.endTagHandler.default = self.endTagOther - - def processEOF(self): - self.anythingElse() - return True - - def processCharacters(self, token): - self.anythingElse() - return token - - def startTagHtml(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def startTagBody(self, token): - self.parser.framesetOK = False - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inBody"] - - def startTagFrameset(self, token): - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inFrameset"] - - def startTagFromHead(self, token): - self.parser.parseError("unexpected-start-tag-out-of-my-head", - {"name": token["name"]}) - self.tree.openElements.append(self.tree.headPointer) - self.parser.phases["inHead"].processStartTag(token) - for node in self.tree.openElements[::-1]: - if node.name == "head": - self.tree.openElements.remove(node) - break - - def startTagHead(self, token): - self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) - - def startTagOther(self, token): - self.anythingElse() - return token - - def endTagHtmlBodyBr(self, token): - self.anythingElse() - return token - - def endTagOther(self, token): - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - - def anythingElse(self): - self.tree.insertElement(impliedTagToken("body", "StartTag")) - self.parser.phase = self.parser.phases["inBody"] - self.parser.framesetOK = True - - class InBodyPhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody - # the really-really-really-very crazy mode - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - # Set this to the default handler - self.processSpaceCharacters = self.processSpaceCharactersNonPre - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("base", "basefont", "bgsound", "command", "link", "meta", - "script", "style", "title"), - self.startTagProcessInHead), - ("body", self.startTagBody), - ("frameset", self.startTagFrameset), - (("address", "article", "aside", "blockquote", "center", "details", - "dir", "div", "dl", "fieldset", "figcaption", "figure", - "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", - "section", "summary", "ul"), - self.startTagCloseP), - (headingElements, self.startTagHeading), - (("pre", "listing"), self.startTagPreListing), - ("form", self.startTagForm), - (("li", "dd", "dt"), self.startTagListItem), - ("plaintext", self.startTagPlaintext), - ("a", self.startTagA), - (("b", "big", "code", "em", "font", "i", "s", "small", "strike", - "strong", "tt", "u"), self.startTagFormatting), - ("nobr", self.startTagNobr), - ("button", self.startTagButton), - (("applet", "marquee", "object"), self.startTagAppletMarqueeObject), - ("xmp", self.startTagXmp), - ("table", self.startTagTable), - (("area", "br", "embed", "img", "keygen", "wbr"), - self.startTagVoidFormatting), - (("param", "source", "track"), self.startTagParamSource), - ("input", self.startTagInput), - ("hr", self.startTagHr), - ("image", self.startTagImage), - ("isindex", self.startTagIsIndex), - ("textarea", self.startTagTextarea), - ("iframe", self.startTagIFrame), - ("noscript", self.startTagNoscript), - (("noembed", "noframes"), self.startTagRawtext), - ("select", self.startTagSelect), - (("rp", "rt"), self.startTagRpRt), - (("option", "optgroup"), self.startTagOpt), - (("math"), self.startTagMath), - (("svg"), self.startTagSvg), - (("caption", "col", "colgroup", "frame", "head", - "tbody", "td", "tfoot", "th", "thead", - "tr"), self.startTagMisplaced) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("body", self.endTagBody), - ("html", self.endTagHtml), - (("address", "article", "aside", "blockquote", "button", "center", - "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", - "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", - "section", "summary", "ul"), self.endTagBlock), - ("form", self.endTagForm), - ("p", self.endTagP), - (("dd", "dt", "li"), self.endTagListItem), - (headingElements, self.endTagHeading), - (("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", - "strike", "strong", "tt", "u"), self.endTagFormatting), - (("applet", "marquee", "object"), self.endTagAppletMarqueeObject), - ("br", self.endTagBr), - ]) - self.endTagHandler.default = self.endTagOther - - def isMatchingFormattingElement(self, node1, node2): - return (node1.name == node2.name and - node1.namespace == node2.namespace and - node1.attributes == node2.attributes) - - # helper - def addFormattingElement(self, token): - self.tree.insertElement(token) - element = self.tree.openElements[-1] - - matchingElements = [] - for node in self.tree.activeFormattingElements[::-1]: - if node is Marker: - break - elif self.isMatchingFormattingElement(node, element): - matchingElements.append(node) - - assert len(matchingElements) <= 3 - if len(matchingElements) == 3: - self.tree.activeFormattingElements.remove(matchingElements[-1]) - self.tree.activeFormattingElements.append(element) - - # the real deal - def processEOF(self): - allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", - "tfoot", "th", "thead", "tr", "body", - "html")) - for node in self.tree.openElements[::-1]: - if node.name not in allowed_elements: - self.parser.parseError("expected-closing-tag-but-got-eof") - break - # Stop parsing - - def processSpaceCharactersDropNewline(self, token): - # Sometimes (start of <pre>, <listing>, and <textarea> blocks) we - # want to drop leading newlines - data = token["data"] - self.processSpaceCharacters = self.processSpaceCharactersNonPre - if (data.startswith("\n") and - self.tree.openElements[-1].name in ("pre", "listing", "textarea") and - not self.tree.openElements[-1].hasContent()): - data = data[1:] - if data: - self.tree.reconstructActiveFormattingElements() - self.tree.insertText(data) - - def processCharacters(self, token): - if token["data"] == "\u0000": - # The tokenizer should always emit null on its own - return - self.tree.reconstructActiveFormattingElements() - self.tree.insertText(token["data"]) - # This must be bad for performance - if (self.parser.framesetOK and - any([char not in spaceCharacters - for char in token["data"]])): - self.parser.framesetOK = False - - def processSpaceCharactersNonPre(self, token): - self.tree.reconstructActiveFormattingElements() - self.tree.insertText(token["data"]) - - def startTagProcessInHead(self, token): - return self.parser.phases["inHead"].processStartTag(token) - - def startTagBody(self, token): - self.parser.parseError("unexpected-start-tag", {"name": "body"}) - if (len(self.tree.openElements) == 1 or - self.tree.openElements[1].name != "body"): - assert self.parser.innerHTML - else: - self.parser.framesetOK = False - for attr, value in token["data"].items(): - if attr not in self.tree.openElements[1].attributes: - self.tree.openElements[1].attributes[attr] = value - - def startTagFrameset(self, token): - self.parser.parseError("unexpected-start-tag", {"name": "frameset"}) - if (len(self.tree.openElements) == 1 or self.tree.openElements[1].name != "body"): - assert self.parser.innerHTML - elif not self.parser.framesetOK: - pass - else: - if self.tree.openElements[1].parent: - self.tree.openElements[1].parent.removeChild(self.tree.openElements[1]) - while self.tree.openElements[-1].name != "html": - self.tree.openElements.pop() - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inFrameset"] - - def startTagCloseP(self, token): - if self.tree.elementInScope("p", variant="button"): - self.endTagP(impliedTagToken("p")) - self.tree.insertElement(token) - - def startTagPreListing(self, token): - if self.tree.elementInScope("p", variant="button"): - self.endTagP(impliedTagToken("p")) - self.tree.insertElement(token) - self.parser.framesetOK = False - self.processSpaceCharacters = self.processSpaceCharactersDropNewline - - def startTagForm(self, token): - if self.tree.formPointer: - self.parser.parseError("unexpected-start-tag", {"name": "form"}) - else: - if self.tree.elementInScope("p", variant="button"): - self.endTagP(impliedTagToken("p")) - self.tree.insertElement(token) - self.tree.formPointer = self.tree.openElements[-1] - - def startTagListItem(self, token): - self.parser.framesetOK = False - - stopNamesMap = {"li": ["li"], - "dt": ["dt", "dd"], - "dd": ["dt", "dd"]} - stopNames = stopNamesMap[token["name"]] - for node in reversed(self.tree.openElements): - if node.name in stopNames: - self.parser.phase.processEndTag( - impliedTagToken(node.name, "EndTag")) - break - if (node.nameTuple in specialElements and - node.name not in ("address", "div", "p")): - break - - if self.tree.elementInScope("p", variant="button"): - self.parser.phase.processEndTag( - impliedTagToken("p", "EndTag")) - - self.tree.insertElement(token) - - def startTagPlaintext(self, token): - if self.tree.elementInScope("p", variant="button"): - self.endTagP(impliedTagToken("p")) - self.tree.insertElement(token) - self.parser.tokenizer.state = self.parser.tokenizer.plaintextState - - def startTagHeading(self, token): - if self.tree.elementInScope("p", variant="button"): - self.endTagP(impliedTagToken("p")) - if self.tree.openElements[-1].name in headingElements: - self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) - self.tree.openElements.pop() - self.tree.insertElement(token) - - def startTagA(self, token): - afeAElement = self.tree.elementInActiveFormattingElements("a") - if afeAElement: - self.parser.parseError("unexpected-start-tag-implies-end-tag", - {"startName": "a", "endName": "a"}) - self.endTagFormatting(impliedTagToken("a")) - if afeAElement in self.tree.openElements: - self.tree.openElements.remove(afeAElement) - if afeAElement in self.tree.activeFormattingElements: - self.tree.activeFormattingElements.remove(afeAElement) - self.tree.reconstructActiveFormattingElements() - self.addFormattingElement(token) - - def startTagFormatting(self, token): - self.tree.reconstructActiveFormattingElements() - self.addFormattingElement(token) - - def startTagNobr(self, token): - self.tree.reconstructActiveFormattingElements() - if self.tree.elementInScope("nobr"): - self.parser.parseError("unexpected-start-tag-implies-end-tag", - {"startName": "nobr", "endName": "nobr"}) - self.processEndTag(impliedTagToken("nobr")) - # XXX Need tests that trigger the following - self.tree.reconstructActiveFormattingElements() - self.addFormattingElement(token) - - def startTagButton(self, token): - if self.tree.elementInScope("button"): - self.parser.parseError("unexpected-start-tag-implies-end-tag", - {"startName": "button", "endName": "button"}) - self.processEndTag(impliedTagToken("button")) - return token - else: - self.tree.reconstructActiveFormattingElements() - self.tree.insertElement(token) - self.parser.framesetOK = False - - def startTagAppletMarqueeObject(self, token): - self.tree.reconstructActiveFormattingElements() - self.tree.insertElement(token) - self.tree.activeFormattingElements.append(Marker) - self.parser.framesetOK = False - - def startTagXmp(self, token): - if self.tree.elementInScope("p", variant="button"): - self.endTagP(impliedTagToken("p")) - self.tree.reconstructActiveFormattingElements() - self.parser.framesetOK = False - self.parser.parseRCDataRawtext(token, "RAWTEXT") - - def startTagTable(self, token): - if self.parser.compatMode != "quirks": - if self.tree.elementInScope("p", variant="button"): - self.processEndTag(impliedTagToken("p")) - self.tree.insertElement(token) - self.parser.framesetOK = False - self.parser.phase = self.parser.phases["inTable"] - - def startTagVoidFormatting(self, token): - self.tree.reconstructActiveFormattingElements() - self.tree.insertElement(token) - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - self.parser.framesetOK = False - - def startTagInput(self, token): - framesetOK = self.parser.framesetOK - self.startTagVoidFormatting(token) - if ("type" in token["data"] and - token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): - # input type=hidden doesn't change framesetOK - self.parser.framesetOK = framesetOK - - def startTagParamSource(self, token): - self.tree.insertElement(token) - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - - def startTagHr(self, token): - if self.tree.elementInScope("p", variant="button"): - self.endTagP(impliedTagToken("p")) - self.tree.insertElement(token) - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - self.parser.framesetOK = False - - def startTagImage(self, token): - # No really... - self.parser.parseError("unexpected-start-tag-treated-as", - {"originalName": "image", "newName": "img"}) - self.processStartTag(impliedTagToken("img", "StartTag", - attributes=token["data"], - selfClosing=token["selfClosing"])) - - def startTagIsIndex(self, token): - self.parser.parseError("deprecated-tag", {"name": "isindex"}) - if self.tree.formPointer: - return - form_attrs = {} - if "action" in token["data"]: - form_attrs["action"] = token["data"]["action"] - self.processStartTag(impliedTagToken("form", "StartTag", - attributes=form_attrs)) - self.processStartTag(impliedTagToken("hr", "StartTag")) - self.processStartTag(impliedTagToken("label", "StartTag")) - # XXX Localization ... - if "prompt" in token["data"]: - prompt = token["data"]["prompt"] - else: - prompt = "This is a searchable index. Enter search keywords: " - self.processCharacters( - {"type": tokenTypes["Characters"], "data": prompt}) - attributes = token["data"].copy() - if "action" in attributes: - del attributes["action"] - if "prompt" in attributes: - del attributes["prompt"] - attributes["name"] = "isindex" - self.processStartTag(impliedTagToken("input", "StartTag", - attributes=attributes, - selfClosing=token["selfClosing"])) - self.processEndTag(impliedTagToken("label")) - self.processStartTag(impliedTagToken("hr", "StartTag")) - self.processEndTag(impliedTagToken("form")) - - def startTagTextarea(self, token): - self.tree.insertElement(token) - self.parser.tokenizer.state = self.parser.tokenizer.rcdataState - self.processSpaceCharacters = self.processSpaceCharactersDropNewline - self.parser.framesetOK = False - - def startTagIFrame(self, token): - self.parser.framesetOK = False - self.startTagRawtext(token) - - def startTagNoscript(self, token): - if self.parser.scripting: - self.startTagRawtext(token) - else: - self.startTagOther(token) - - def startTagRawtext(self, token): - """iframe, noembed noframes, noscript(if scripting enabled)""" - self.parser.parseRCDataRawtext(token, "RAWTEXT") - - def startTagOpt(self, token): - if self.tree.openElements[-1].name == "option": - self.parser.phase.processEndTag(impliedTagToken("option")) - self.tree.reconstructActiveFormattingElements() - self.parser.tree.insertElement(token) - - def startTagSelect(self, token): - self.tree.reconstructActiveFormattingElements() - self.tree.insertElement(token) - self.parser.framesetOK = False - if self.parser.phase in (self.parser.phases["inTable"], - self.parser.phases["inCaption"], - self.parser.phases["inColumnGroup"], - self.parser.phases["inTableBody"], - self.parser.phases["inRow"], - self.parser.phases["inCell"]): - self.parser.phase = self.parser.phases["inSelectInTable"] - else: - self.parser.phase = self.parser.phases["inSelect"] - - def startTagRpRt(self, token): - if self.tree.elementInScope("ruby"): - self.tree.generateImpliedEndTags() - if self.tree.openElements[-1].name != "ruby": - self.parser.parseError() - self.tree.insertElement(token) - - def startTagMath(self, token): - self.tree.reconstructActiveFormattingElements() - self.parser.adjustMathMLAttributes(token) - self.parser.adjustForeignAttributes(token) - token["namespace"] = namespaces["mathml"] - self.tree.insertElement(token) - # Need to get the parse error right for the case where the token - # has a namespace not equal to the xmlns attribute - if token["selfClosing"]: - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - - def startTagSvg(self, token): - self.tree.reconstructActiveFormattingElements() - self.parser.adjustSVGAttributes(token) - self.parser.adjustForeignAttributes(token) - token["namespace"] = namespaces["svg"] - self.tree.insertElement(token) - # Need to get the parse error right for the case where the token - # has a namespace not equal to the xmlns attribute - if token["selfClosing"]: - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - - def startTagMisplaced(self, token): - """ Elements that should be children of other elements that have a - different insertion mode; here they are ignored - "caption", "col", "colgroup", "frame", "frameset", "head", - "option", "optgroup", "tbody", "td", "tfoot", "th", "thead", - "tr", "noscript" - """ - self.parser.parseError("unexpected-start-tag-ignored", {"name": token["name"]}) - - def startTagOther(self, token): - self.tree.reconstructActiveFormattingElements() - self.tree.insertElement(token) - - def endTagP(self, token): - if not self.tree.elementInScope("p", variant="button"): - self.startTagCloseP(impliedTagToken("p", "StartTag")) - self.parser.parseError("unexpected-end-tag", {"name": "p"}) - self.endTagP(impliedTagToken("p", "EndTag")) - else: - self.tree.generateImpliedEndTags("p") - if self.tree.openElements[-1].name != "p": - self.parser.parseError("unexpected-end-tag", {"name": "p"}) - node = self.tree.openElements.pop() - while node.name != "p": - node = self.tree.openElements.pop() - - def endTagBody(self, token): - if not self.tree.elementInScope("body"): - self.parser.parseError() - return - elif self.tree.openElements[-1].name != "body": - for node in self.tree.openElements[2:]: - if node.name not in frozenset(("dd", "dt", "li", "optgroup", - "option", "p", "rp", "rt", - "tbody", "td", "tfoot", - "th", "thead", "tr", "body", - "html")): - # Not sure this is the correct name for the parse error - self.parser.parseError( - "expected-one-end-tag-but-got-another", - {"gotName": "body", "expectedName": node.name}) - break - self.parser.phase = self.parser.phases["afterBody"] - - def endTagHtml(self, token): - # We repeat the test for the body end tag token being ignored here - if self.tree.elementInScope("body"): - self.endTagBody(impliedTagToken("body")) - return token - - def endTagBlock(self, token): - # Put us back in the right whitespace handling mode - if token["name"] == "pre": - self.processSpaceCharacters = self.processSpaceCharactersNonPre - inScope = self.tree.elementInScope(token["name"]) - if inScope: - self.tree.generateImpliedEndTags() - if self.tree.openElements[-1].name != token["name"]: - self.parser.parseError("end-tag-too-early", {"name": token["name"]}) - if inScope: - node = self.tree.openElements.pop() - while node.name != token["name"]: - node = self.tree.openElements.pop() - - def endTagForm(self, token): - node = self.tree.formPointer - self.tree.formPointer = None - if node is None or not self.tree.elementInScope(node): - self.parser.parseError("unexpected-end-tag", - {"name": "form"}) - else: - self.tree.generateImpliedEndTags() - if self.tree.openElements[-1] != node: - self.parser.parseError("end-tag-too-early-ignored", - {"name": "form"}) - self.tree.openElements.remove(node) - - def endTagListItem(self, token): - if token["name"] == "li": - variant = "list" - else: - variant = None - if not self.tree.elementInScope(token["name"], variant=variant): - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - else: - self.tree.generateImpliedEndTags(exclude=token["name"]) - if self.tree.openElements[-1].name != token["name"]: - self.parser.parseError( - "end-tag-too-early", - {"name": token["name"]}) - node = self.tree.openElements.pop() - while node.name != token["name"]: - node = self.tree.openElements.pop() - - def endTagHeading(self, token): - for item in headingElements: - if self.tree.elementInScope(item): - self.tree.generateImpliedEndTags() - break - if self.tree.openElements[-1].name != token["name"]: - self.parser.parseError("end-tag-too-early", {"name": token["name"]}) - - for item in headingElements: - if self.tree.elementInScope(item): - item = self.tree.openElements.pop() - while item.name not in headingElements: - item = self.tree.openElements.pop() - break - - def endTagFormatting(self, token): - """The much-feared adoption agency algorithm""" - # http://svn.whatwg.org/webapps/complete.html#adoptionAgency revision 7867 - # XXX Better parseError messages appreciated. - - # Step 1 - outerLoopCounter = 0 - - # Step 2 - while outerLoopCounter < 8: - - # Step 3 - outerLoopCounter += 1 - - # Step 4: - - # Let the formatting element be the last element in - # the list of active formatting elements that: - # - is between the end of the list and the last scope - # marker in the list, if any, or the start of the list - # otherwise, and - # - has the same tag name as the token. - formattingElement = self.tree.elementInActiveFormattingElements( - token["name"]) - if (not formattingElement or - (formattingElement in self.tree.openElements and - not self.tree.elementInScope(formattingElement.name))): - # If there is no such node, then abort these steps - # and instead act as described in the "any other - # end tag" entry below. - self.endTagOther(token) - return - - # Otherwise, if there is such a node, but that node is - # not in the stack of open elements, then this is a - # parse error; remove the element from the list, and - # abort these steps. - elif formattingElement not in self.tree.openElements: - self.parser.parseError("adoption-agency-1.2", {"name": token["name"]}) - self.tree.activeFormattingElements.remove(formattingElement) - return - - # Otherwise, if there is such a node, and that node is - # also in the stack of open elements, but the element - # is not in scope, then this is a parse error; ignore - # the token, and abort these steps. - elif not self.tree.elementInScope(formattingElement.name): - self.parser.parseError("adoption-agency-4.4", {"name": token["name"]}) - return - - # Otherwise, there is a formatting element and that - # element is in the stack and is in scope. If the - # element is not the current node, this is a parse - # error. In any case, proceed with the algorithm as - # written in the following steps. - else: - if formattingElement != self.tree.openElements[-1]: - self.parser.parseError("adoption-agency-1.3", {"name": token["name"]}) - - # Step 5: - - # Let the furthest block be the topmost node in the - # stack of open elements that is lower in the stack - # than the formatting element, and is an element in - # the special category. There might not be one. - afeIndex = self.tree.openElements.index(formattingElement) - furthestBlock = None - for element in self.tree.openElements[afeIndex:]: - if element.nameTuple in specialElements: - furthestBlock = element - break - - # Step 6: - - # If there is no furthest block, then the UA must - # first pop all the nodes from the bottom of the stack - # of open elements, from the current node up to and - # including the formatting element, then remove the - # formatting element from the list of active - # formatting elements, and finally abort these steps. - if furthestBlock is None: - element = self.tree.openElements.pop() - while element != formattingElement: - element = self.tree.openElements.pop() - self.tree.activeFormattingElements.remove(element) - return - - # Step 7 - commonAncestor = self.tree.openElements[afeIndex - 1] - - # Step 8: - # The bookmark is supposed to help us identify where to reinsert - # nodes in step 15. We have to ensure that we reinsert nodes after - # the node before the active formatting element. Note the bookmark - # can move in step 9.7 - bookmark = self.tree.activeFormattingElements.index(formattingElement) - - # Step 9 - lastNode = node = furthestBlock - innerLoopCounter = 0 - - index = self.tree.openElements.index(node) - while innerLoopCounter < 3: - innerLoopCounter += 1 - # Node is element before node in open elements - index -= 1 - node = self.tree.openElements[index] - if node not in self.tree.activeFormattingElements: - self.tree.openElements.remove(node) - continue - # Step 9.6 - if node == formattingElement: - break - # Step 9.7 - if lastNode == furthestBlock: - bookmark = self.tree.activeFormattingElements.index(node) + 1 - # Step 9.8 - clone = node.cloneNode() - # Replace node with clone - self.tree.activeFormattingElements[ - self.tree.activeFormattingElements.index(node)] = clone - self.tree.openElements[ - self.tree.openElements.index(node)] = clone - node = clone - # Step 9.9 - # Remove lastNode from its parents, if any - if lastNode.parent: - lastNode.parent.removeChild(lastNode) - node.appendChild(lastNode) - # Step 9.10 - lastNode = node - - # Step 10 - # Foster parent lastNode if commonAncestor is a - # table, tbody, tfoot, thead, or tr we need to foster - # parent the lastNode - if lastNode.parent: - lastNode.parent.removeChild(lastNode) - - if commonAncestor.name in frozenset(("table", "tbody", "tfoot", "thead", "tr")): - parent, insertBefore = self.tree.getTableMisnestedNodePosition() - parent.insertBefore(lastNode, insertBefore) - else: - commonAncestor.appendChild(lastNode) - - # Step 11 - clone = formattingElement.cloneNode() - - # Step 12 - furthestBlock.reparentChildren(clone) - - # Step 13 - furthestBlock.appendChild(clone) - - # Step 14 - self.tree.activeFormattingElements.remove(formattingElement) - self.tree.activeFormattingElements.insert(bookmark, clone) - - # Step 15 - self.tree.openElements.remove(formattingElement) - self.tree.openElements.insert( - self.tree.openElements.index(furthestBlock) + 1, clone) - - def endTagAppletMarqueeObject(self, token): - if self.tree.elementInScope(token["name"]): - self.tree.generateImpliedEndTags() - if self.tree.openElements[-1].name != token["name"]: - self.parser.parseError("end-tag-too-early", {"name": token["name"]}) - - if self.tree.elementInScope(token["name"]): - element = self.tree.openElements.pop() - while element.name != token["name"]: - element = self.tree.openElements.pop() - self.tree.clearActiveFormattingElements() - - def endTagBr(self, token): - self.parser.parseError("unexpected-end-tag-treated-as", - {"originalName": "br", "newName": "br element"}) - self.tree.reconstructActiveFormattingElements() - self.tree.insertElement(impliedTagToken("br", "StartTag")) - self.tree.openElements.pop() - - def endTagOther(self, token): - for node in self.tree.openElements[::-1]: - if node.name == token["name"]: - self.tree.generateImpliedEndTags(exclude=token["name"]) - if self.tree.openElements[-1].name != token["name"]: - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - while self.tree.openElements.pop() != node: - pass - break - else: - if node.nameTuple in specialElements: - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - break - - class TextPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([]) - self.startTagHandler.default = self.startTagOther - self.endTagHandler = _utils.MethodDispatcher([ - ("script", self.endTagScript)]) - self.endTagHandler.default = self.endTagOther - - def processCharacters(self, token): - self.tree.insertText(token["data"]) - - def processEOF(self): - self.parser.parseError("expected-named-closing-tag-but-got-eof", - {"name": self.tree.openElements[-1].name}) - self.tree.openElements.pop() - self.parser.phase = self.parser.originalPhase - return True - - def startTagOther(self, token): - assert False, "Tried to process start tag %s in RCDATA/RAWTEXT mode" % token['name'] - - def endTagScript(self, token): - node = self.tree.openElements.pop() - assert node.name == "script" - self.parser.phase = self.parser.originalPhase - # The rest of this method is all stuff that only happens if - # document.write works - - def endTagOther(self, token): - self.tree.openElements.pop() - self.parser.phase = self.parser.originalPhase - - class InTablePhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#in-table - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("caption", self.startTagCaption), - ("colgroup", self.startTagColgroup), - ("col", self.startTagCol), - (("tbody", "tfoot", "thead"), self.startTagRowGroup), - (("td", "th", "tr"), self.startTagImplyTbody), - ("table", self.startTagTable), - (("style", "script"), self.startTagStyleScript), - ("input", self.startTagInput), - ("form", self.startTagForm) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("table", self.endTagTable), - (("body", "caption", "col", "colgroup", "html", "tbody", "td", - "tfoot", "th", "thead", "tr"), self.endTagIgnore) - ]) - self.endTagHandler.default = self.endTagOther - - # helper methods - def clearStackToTableContext(self): - # "clear the stack back to a table context" - while self.tree.openElements[-1].name not in ("table", "html"): - # self.parser.parseError("unexpected-implied-end-tag-in-table", - # {"name": self.tree.openElements[-1].name}) - self.tree.openElements.pop() - # When the current node is <html> it's an innerHTML case - - # processing methods - def processEOF(self): - if self.tree.openElements[-1].name != "html": - self.parser.parseError("eof-in-table") - else: - assert self.parser.innerHTML - # Stop parsing - - def processSpaceCharacters(self, token): - originalPhase = self.parser.phase - self.parser.phase = self.parser.phases["inTableText"] - self.parser.phase.originalPhase = originalPhase - self.parser.phase.processSpaceCharacters(token) - - def processCharacters(self, token): - originalPhase = self.parser.phase - self.parser.phase = self.parser.phases["inTableText"] - self.parser.phase.originalPhase = originalPhase - self.parser.phase.processCharacters(token) - - def insertText(self, token): - # If we get here there must be at least one non-whitespace character - # Do the table magic! - self.tree.insertFromTable = True - self.parser.phases["inBody"].processCharacters(token) - self.tree.insertFromTable = False - - def startTagCaption(self, token): - self.clearStackToTableContext() - self.tree.activeFormattingElements.append(Marker) - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inCaption"] - - def startTagColgroup(self, token): - self.clearStackToTableContext() - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inColumnGroup"] - - def startTagCol(self, token): - self.startTagColgroup(impliedTagToken("colgroup", "StartTag")) - return token - - def startTagRowGroup(self, token): - self.clearStackToTableContext() - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inTableBody"] - - def startTagImplyTbody(self, token): - self.startTagRowGroup(impliedTagToken("tbody", "StartTag")) - return token - - def startTagTable(self, token): - self.parser.parseError("unexpected-start-tag-implies-end-tag", - {"startName": "table", "endName": "table"}) - self.parser.phase.processEndTag(impliedTagToken("table")) - if not self.parser.innerHTML: - return token - - def startTagStyleScript(self, token): - return self.parser.phases["inHead"].processStartTag(token) - - def startTagInput(self, token): - if ("type" in token["data"] and - token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): - self.parser.parseError("unexpected-hidden-input-in-table") - self.tree.insertElement(token) - # XXX associate with form - self.tree.openElements.pop() - else: - self.startTagOther(token) - - def startTagForm(self, token): - self.parser.parseError("unexpected-form-in-table") - if self.tree.formPointer is None: - self.tree.insertElement(token) - self.tree.formPointer = self.tree.openElements[-1] - self.tree.openElements.pop() - - def startTagOther(self, token): - self.parser.parseError("unexpected-start-tag-implies-table-voodoo", {"name": token["name"]}) - # Do the table magic! - self.tree.insertFromTable = True - self.parser.phases["inBody"].processStartTag(token) - self.tree.insertFromTable = False - - def endTagTable(self, token): - if self.tree.elementInScope("table", variant="table"): - self.tree.generateImpliedEndTags() - if self.tree.openElements[-1].name != "table": - self.parser.parseError("end-tag-too-early-named", - {"gotName": "table", - "expectedName": self.tree.openElements[-1].name}) - while self.tree.openElements[-1].name != "table": - self.tree.openElements.pop() - self.tree.openElements.pop() - self.parser.resetInsertionMode() - else: - # innerHTML case - assert self.parser.innerHTML - self.parser.parseError() - - def endTagIgnore(self, token): - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - - def endTagOther(self, token): - self.parser.parseError("unexpected-end-tag-implies-table-voodoo", {"name": token["name"]}) - # Do the table magic! - self.tree.insertFromTable = True - self.parser.phases["inBody"].processEndTag(token) - self.tree.insertFromTable = False - - class InTableTextPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.originalPhase = None - self.characterTokens = [] - - def flushCharacters(self): - data = "".join([item["data"] for item in self.characterTokens]) - if any([item not in spaceCharacters for item in data]): - token = {"type": tokenTypes["Characters"], "data": data} - self.parser.phases["inTable"].insertText(token) - elif data: - self.tree.insertText(data) - self.characterTokens = [] - - def processComment(self, token): - self.flushCharacters() - self.parser.phase = self.originalPhase - return token - - def processEOF(self): - self.flushCharacters() - self.parser.phase = self.originalPhase - return True - - def processCharacters(self, token): - if token["data"] == "\u0000": - return - self.characterTokens.append(token) - - def processSpaceCharacters(self, token): - # pretty sure we should never reach here - self.characterTokens.append(token) - # assert False - - def processStartTag(self, token): - self.flushCharacters() - self.parser.phase = self.originalPhase - return token - - def processEndTag(self, token): - self.flushCharacters() - self.parser.phase = self.originalPhase - return token - - class InCaptionPhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#in-caption - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", - "thead", "tr"), self.startTagTableElement) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("caption", self.endTagCaption), - ("table", self.endTagTable), - (("body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", - "thead", "tr"), self.endTagIgnore) - ]) - self.endTagHandler.default = self.endTagOther - - def ignoreEndTagCaption(self): - return not self.tree.elementInScope("caption", variant="table") - - def processEOF(self): - self.parser.phases["inBody"].processEOF() - - def processCharacters(self, token): - return self.parser.phases["inBody"].processCharacters(token) - - def startTagTableElement(self, token): - self.parser.parseError() - # XXX Have to duplicate logic here to find out if the tag is ignored - ignoreEndTag = self.ignoreEndTagCaption() - self.parser.phase.processEndTag(impliedTagToken("caption")) - if not ignoreEndTag: - return token - - def startTagOther(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def endTagCaption(self, token): - if not self.ignoreEndTagCaption(): - # AT this code is quite similar to endTagTable in "InTable" - self.tree.generateImpliedEndTags() - if self.tree.openElements[-1].name != "caption": - self.parser.parseError("expected-one-end-tag-but-got-another", - {"gotName": "caption", - "expectedName": self.tree.openElements[-1].name}) - while self.tree.openElements[-1].name != "caption": - self.tree.openElements.pop() - self.tree.openElements.pop() - self.tree.clearActiveFormattingElements() - self.parser.phase = self.parser.phases["inTable"] - else: - # innerHTML case - assert self.parser.innerHTML - self.parser.parseError() - - def endTagTable(self, token): - self.parser.parseError() - ignoreEndTag = self.ignoreEndTagCaption() - self.parser.phase.processEndTag(impliedTagToken("caption")) - if not ignoreEndTag: - return token - - def endTagIgnore(self, token): - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - - def endTagOther(self, token): - return self.parser.phases["inBody"].processEndTag(token) - - class InColumnGroupPhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#in-column - - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("col", self.startTagCol) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("colgroup", self.endTagColgroup), - ("col", self.endTagCol) - ]) - self.endTagHandler.default = self.endTagOther - - def ignoreEndTagColgroup(self): - return self.tree.openElements[-1].name == "html" - - def processEOF(self): - if self.tree.openElements[-1].name == "html": - assert self.parser.innerHTML - return - else: - ignoreEndTag = self.ignoreEndTagColgroup() - self.endTagColgroup(impliedTagToken("colgroup")) - if not ignoreEndTag: - return True - - def processCharacters(self, token): - ignoreEndTag = self.ignoreEndTagColgroup() - self.endTagColgroup(impliedTagToken("colgroup")) - if not ignoreEndTag: - return token - - def startTagCol(self, token): - self.tree.insertElement(token) - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - - def startTagOther(self, token): - ignoreEndTag = self.ignoreEndTagColgroup() - self.endTagColgroup(impliedTagToken("colgroup")) - if not ignoreEndTag: - return token - - def endTagColgroup(self, token): - if self.ignoreEndTagColgroup(): - # innerHTML case - assert self.parser.innerHTML - self.parser.parseError() - else: - self.tree.openElements.pop() - self.parser.phase = self.parser.phases["inTable"] - - def endTagCol(self, token): - self.parser.parseError("no-end-tag", {"name": "col"}) - - def endTagOther(self, token): - ignoreEndTag = self.ignoreEndTagColgroup() - self.endTagColgroup(impliedTagToken("colgroup")) - if not ignoreEndTag: - return token - - class InTableBodyPhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#in-table0 - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("tr", self.startTagTr), - (("td", "th"), self.startTagTableCell), - (("caption", "col", "colgroup", "tbody", "tfoot", "thead"), - self.startTagTableOther) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), - ("table", self.endTagTable), - (("body", "caption", "col", "colgroup", "html", "td", "th", - "tr"), self.endTagIgnore) - ]) - self.endTagHandler.default = self.endTagOther - - # helper methods - def clearStackToTableBodyContext(self): - while self.tree.openElements[-1].name not in ("tbody", "tfoot", - "thead", "html"): - # self.parser.parseError("unexpected-implied-end-tag-in-table", - # {"name": self.tree.openElements[-1].name}) - self.tree.openElements.pop() - if self.tree.openElements[-1].name == "html": - assert self.parser.innerHTML - - # the rest - def processEOF(self): - self.parser.phases["inTable"].processEOF() - - def processSpaceCharacters(self, token): - return self.parser.phases["inTable"].processSpaceCharacters(token) - - def processCharacters(self, token): - return self.parser.phases["inTable"].processCharacters(token) - - def startTagTr(self, token): - self.clearStackToTableBodyContext() - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inRow"] - - def startTagTableCell(self, token): - self.parser.parseError("unexpected-cell-in-table-body", - {"name": token["name"]}) - self.startTagTr(impliedTagToken("tr", "StartTag")) - return token - - def startTagTableOther(self, token): - # XXX AT Any ideas on how to share this with endTagTable? - if (self.tree.elementInScope("tbody", variant="table") or - self.tree.elementInScope("thead", variant="table") or - self.tree.elementInScope("tfoot", variant="table")): - self.clearStackToTableBodyContext() - self.endTagTableRowGroup( - impliedTagToken(self.tree.openElements[-1].name)) - return token - else: - # innerHTML case - assert self.parser.innerHTML - self.parser.parseError() - - def startTagOther(self, token): - return self.parser.phases["inTable"].processStartTag(token) - - def endTagTableRowGroup(self, token): - if self.tree.elementInScope(token["name"], variant="table"): - self.clearStackToTableBodyContext() - self.tree.openElements.pop() - self.parser.phase = self.parser.phases["inTable"] - else: - self.parser.parseError("unexpected-end-tag-in-table-body", - {"name": token["name"]}) - - def endTagTable(self, token): - if (self.tree.elementInScope("tbody", variant="table") or - self.tree.elementInScope("thead", variant="table") or - self.tree.elementInScope("tfoot", variant="table")): - self.clearStackToTableBodyContext() - self.endTagTableRowGroup( - impliedTagToken(self.tree.openElements[-1].name)) - return token - else: - # innerHTML case - assert self.parser.innerHTML - self.parser.parseError() - - def endTagIgnore(self, token): - self.parser.parseError("unexpected-end-tag-in-table-body", - {"name": token["name"]}) - - def endTagOther(self, token): - return self.parser.phases["inTable"].processEndTag(token) - - class InRowPhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#in-row - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("td", "th"), self.startTagTableCell), - (("caption", "col", "colgroup", "tbody", "tfoot", "thead", - "tr"), self.startTagTableOther) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("tr", self.endTagTr), - ("table", self.endTagTable), - (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), - (("body", "caption", "col", "colgroup", "html", "td", "th"), - self.endTagIgnore) - ]) - self.endTagHandler.default = self.endTagOther - - # helper methods (XXX unify this with other table helper methods) - def clearStackToTableRowContext(self): - while self.tree.openElements[-1].name not in ("tr", "html"): - self.parser.parseError("unexpected-implied-end-tag-in-table-row", - {"name": self.tree.openElements[-1].name}) - self.tree.openElements.pop() - - def ignoreEndTagTr(self): - return not self.tree.elementInScope("tr", variant="table") - - # the rest - def processEOF(self): - self.parser.phases["inTable"].processEOF() - - def processSpaceCharacters(self, token): - return self.parser.phases["inTable"].processSpaceCharacters(token) - - def processCharacters(self, token): - return self.parser.phases["inTable"].processCharacters(token) - - def startTagTableCell(self, token): - self.clearStackToTableRowContext() - self.tree.insertElement(token) - self.parser.phase = self.parser.phases["inCell"] - self.tree.activeFormattingElements.append(Marker) - - def startTagTableOther(self, token): - ignoreEndTag = self.ignoreEndTagTr() - self.endTagTr(impliedTagToken("tr")) - # XXX how are we sure it's always ignored in the innerHTML case? - if not ignoreEndTag: - return token - - def startTagOther(self, token): - return self.parser.phases["inTable"].processStartTag(token) - - def endTagTr(self, token): - if not self.ignoreEndTagTr(): - self.clearStackToTableRowContext() - self.tree.openElements.pop() - self.parser.phase = self.parser.phases["inTableBody"] - else: - # innerHTML case - assert self.parser.innerHTML - self.parser.parseError() - - def endTagTable(self, token): - ignoreEndTag = self.ignoreEndTagTr() - self.endTagTr(impliedTagToken("tr")) - # Reprocess the current tag if the tr end tag was not ignored - # XXX how are we sure it's always ignored in the innerHTML case? - if not ignoreEndTag: - return token - - def endTagTableRowGroup(self, token): - if self.tree.elementInScope(token["name"], variant="table"): - self.endTagTr(impliedTagToken("tr")) - return token - else: - self.parser.parseError() - - def endTagIgnore(self, token): - self.parser.parseError("unexpected-end-tag-in-table-row", - {"name": token["name"]}) - - def endTagOther(self, token): - return self.parser.phases["inTable"].processEndTag(token) - - class InCellPhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#in-cell - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", - "thead", "tr"), self.startTagTableOther) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - (("td", "th"), self.endTagTableCell), - (("body", "caption", "col", "colgroup", "html"), self.endTagIgnore), - (("table", "tbody", "tfoot", "thead", "tr"), self.endTagImply) - ]) - self.endTagHandler.default = self.endTagOther - - # helper - def closeCell(self): - if self.tree.elementInScope("td", variant="table"): - self.endTagTableCell(impliedTagToken("td")) - elif self.tree.elementInScope("th", variant="table"): - self.endTagTableCell(impliedTagToken("th")) - - # the rest - def processEOF(self): - self.parser.phases["inBody"].processEOF() - - def processCharacters(self, token): - return self.parser.phases["inBody"].processCharacters(token) - - def startTagTableOther(self, token): - if (self.tree.elementInScope("td", variant="table") or - self.tree.elementInScope("th", variant="table")): - self.closeCell() - return token - else: - # innerHTML case - assert self.parser.innerHTML - self.parser.parseError() - - def startTagOther(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def endTagTableCell(self, token): - if self.tree.elementInScope(token["name"], variant="table"): - self.tree.generateImpliedEndTags(token["name"]) - if self.tree.openElements[-1].name != token["name"]: - self.parser.parseError("unexpected-cell-end-tag", - {"name": token["name"]}) - while True: - node = self.tree.openElements.pop() - if node.name == token["name"]: - break - else: - self.tree.openElements.pop() - self.tree.clearActiveFormattingElements() - self.parser.phase = self.parser.phases["inRow"] - else: - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - - def endTagIgnore(self, token): - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - - def endTagImply(self, token): - if self.tree.elementInScope(token["name"], variant="table"): - self.closeCell() - return token - else: - # sometimes innerHTML case - self.parser.parseError() - - def endTagOther(self, token): - return self.parser.phases["inBody"].processEndTag(token) - - class InSelectPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("option", self.startTagOption), - ("optgroup", self.startTagOptgroup), - ("select", self.startTagSelect), - (("input", "keygen", "textarea"), self.startTagInput), - ("script", self.startTagScript) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("option", self.endTagOption), - ("optgroup", self.endTagOptgroup), - ("select", self.endTagSelect) - ]) - self.endTagHandler.default = self.endTagOther - - # http://www.whatwg.org/specs/web-apps/current-work/#in-select - def processEOF(self): - if self.tree.openElements[-1].name != "html": - self.parser.parseError("eof-in-select") - else: - assert self.parser.innerHTML - - def processCharacters(self, token): - if token["data"] == "\u0000": - return - self.tree.insertText(token["data"]) - - def startTagOption(self, token): - # We need to imply </option> if <option> is the current node. - if self.tree.openElements[-1].name == "option": - self.tree.openElements.pop() - self.tree.insertElement(token) - - def startTagOptgroup(self, token): - if self.tree.openElements[-1].name == "option": - self.tree.openElements.pop() - if self.tree.openElements[-1].name == "optgroup": - self.tree.openElements.pop() - self.tree.insertElement(token) - - def startTagSelect(self, token): - self.parser.parseError("unexpected-select-in-select") - self.endTagSelect(impliedTagToken("select")) - - def startTagInput(self, token): - self.parser.parseError("unexpected-input-in-select") - if self.tree.elementInScope("select", variant="select"): - self.endTagSelect(impliedTagToken("select")) - return token - else: - assert self.parser.innerHTML - - def startTagScript(self, token): - return self.parser.phases["inHead"].processStartTag(token) - - def startTagOther(self, token): - self.parser.parseError("unexpected-start-tag-in-select", - {"name": token["name"]}) - - def endTagOption(self, token): - if self.tree.openElements[-1].name == "option": - self.tree.openElements.pop() - else: - self.parser.parseError("unexpected-end-tag-in-select", - {"name": "option"}) - - def endTagOptgroup(self, token): - # </optgroup> implicitly closes <option> - if (self.tree.openElements[-1].name == "option" and - self.tree.openElements[-2].name == "optgroup"): - self.tree.openElements.pop() - # It also closes </optgroup> - if self.tree.openElements[-1].name == "optgroup": - self.tree.openElements.pop() - # But nothing else - else: - self.parser.parseError("unexpected-end-tag-in-select", - {"name": "optgroup"}) - - def endTagSelect(self, token): - if self.tree.elementInScope("select", variant="select"): - node = self.tree.openElements.pop() - while node.name != "select": - node = self.tree.openElements.pop() - self.parser.resetInsertionMode() - else: - # innerHTML case - assert self.parser.innerHTML - self.parser.parseError() - - def endTagOther(self, token): - self.parser.parseError("unexpected-end-tag-in-select", - {"name": token["name"]}) - - class InSelectInTablePhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), - self.startTagTable) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), - self.endTagTable) - ]) - self.endTagHandler.default = self.endTagOther - - def processEOF(self): - self.parser.phases["inSelect"].processEOF() - - def processCharacters(self, token): - return self.parser.phases["inSelect"].processCharacters(token) - - def startTagTable(self, token): - self.parser.parseError("unexpected-table-element-start-tag-in-select-in-table", {"name": token["name"]}) - self.endTagOther(impliedTagToken("select")) - return token - - def startTagOther(self, token): - return self.parser.phases["inSelect"].processStartTag(token) - - def endTagTable(self, token): - self.parser.parseError("unexpected-table-element-end-tag-in-select-in-table", {"name": token["name"]}) - if self.tree.elementInScope(token["name"], variant="table"): - self.endTagOther(impliedTagToken("select")) - return token - - def endTagOther(self, token): - return self.parser.phases["inSelect"].processEndTag(token) - - class InForeignContentPhase(Phase): - breakoutElements = frozenset(["b", "big", "blockquote", "body", "br", - "center", "code", "dd", "div", "dl", "dt", - "em", "embed", "h1", "h2", "h3", - "h4", "h5", "h6", "head", "hr", "i", "img", - "li", "listing", "menu", "meta", "nobr", - "ol", "p", "pre", "ruby", "s", "small", - "span", "strong", "strike", "sub", "sup", - "table", "tt", "u", "ul", "var"]) - - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - def adjustSVGTagNames(self, token): - replacements = {"altglyph": "altGlyph", - "altglyphdef": "altGlyphDef", - "altglyphitem": "altGlyphItem", - "animatecolor": "animateColor", - "animatemotion": "animateMotion", - "animatetransform": "animateTransform", - "clippath": "clipPath", - "feblend": "feBlend", - "fecolormatrix": "feColorMatrix", - "fecomponenttransfer": "feComponentTransfer", - "fecomposite": "feComposite", - "feconvolvematrix": "feConvolveMatrix", - "fediffuselighting": "feDiffuseLighting", - "fedisplacementmap": "feDisplacementMap", - "fedistantlight": "feDistantLight", - "feflood": "feFlood", - "fefunca": "feFuncA", - "fefuncb": "feFuncB", - "fefuncg": "feFuncG", - "fefuncr": "feFuncR", - "fegaussianblur": "feGaussianBlur", - "feimage": "feImage", - "femerge": "feMerge", - "femergenode": "feMergeNode", - "femorphology": "feMorphology", - "feoffset": "feOffset", - "fepointlight": "fePointLight", - "fespecularlighting": "feSpecularLighting", - "fespotlight": "feSpotLight", - "fetile": "feTile", - "feturbulence": "feTurbulence", - "foreignobject": "foreignObject", - "glyphref": "glyphRef", - "lineargradient": "linearGradient", - "radialgradient": "radialGradient", - "textpath": "textPath"} - - if token["name"] in replacements: - token["name"] = replacements[token["name"]] - - def processCharacters(self, token): - if token["data"] == "\u0000": - token["data"] = "\uFFFD" - elif (self.parser.framesetOK and - any(char not in spaceCharacters for char in token["data"])): - self.parser.framesetOK = False - Phase.processCharacters(self, token) - - def processStartTag(self, token): - currentNode = self.tree.openElements[-1] - if (token["name"] in self.breakoutElements or - (token["name"] == "font" and - set(token["data"].keys()) & set(["color", "face", "size"]))): - self.parser.parseError("unexpected-html-element-in-foreign-content", - {"name": token["name"]}) - while (self.tree.openElements[-1].namespace != - self.tree.defaultNamespace and - not self.parser.isHTMLIntegrationPoint(self.tree.openElements[-1]) and - not self.parser.isMathMLTextIntegrationPoint(self.tree.openElements[-1])): - self.tree.openElements.pop() - return token - - else: - if currentNode.namespace == namespaces["mathml"]: - self.parser.adjustMathMLAttributes(token) - elif currentNode.namespace == namespaces["svg"]: - self.adjustSVGTagNames(token) - self.parser.adjustSVGAttributes(token) - self.parser.adjustForeignAttributes(token) - token["namespace"] = currentNode.namespace - self.tree.insertElement(token) - if token["selfClosing"]: - self.tree.openElements.pop() - token["selfClosingAcknowledged"] = True - - def processEndTag(self, token): - nodeIndex = len(self.tree.openElements) - 1 - node = self.tree.openElements[-1] - if node.name.translate(asciiUpper2Lower) != token["name"]: - self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) - - while True: - if node.name.translate(asciiUpper2Lower) == token["name"]: - # XXX this isn't in the spec but it seems necessary - if self.parser.phase == self.parser.phases["inTableText"]: - self.parser.phase.flushCharacters() - self.parser.phase = self.parser.phase.originalPhase - while self.tree.openElements.pop() != node: - assert self.tree.openElements - new_token = None - break - nodeIndex -= 1 - - node = self.tree.openElements[nodeIndex] - if node.namespace != self.tree.defaultNamespace: - continue - else: - new_token = self.parser.phase.processEndTag(token) - break - return new_token - - class AfterBodyPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([("html", self.endTagHtml)]) - self.endTagHandler.default = self.endTagOther - - def processEOF(self): - # Stop parsing - pass - - def processComment(self, token): - # This is needed because data is to be appended to the <html> element - # here and not to whatever is currently open. - self.tree.insertComment(token, self.tree.openElements[0]) - - def processCharacters(self, token): - self.parser.parseError("unexpected-char-after-body") - self.parser.phase = self.parser.phases["inBody"] - return token - - def startTagHtml(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def startTagOther(self, token): - self.parser.parseError("unexpected-start-tag-after-body", - {"name": token["name"]}) - self.parser.phase = self.parser.phases["inBody"] - return token - - def endTagHtml(self, name): - if self.parser.innerHTML: - self.parser.parseError("unexpected-end-tag-after-body-innerhtml") - else: - self.parser.phase = self.parser.phases["afterAfterBody"] - - def endTagOther(self, token): - self.parser.parseError("unexpected-end-tag-after-body", - {"name": token["name"]}) - self.parser.phase = self.parser.phases["inBody"] - return token - - class InFramesetPhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#in-frameset - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("frameset", self.startTagFrameset), - ("frame", self.startTagFrame), - ("noframes", self.startTagNoframes) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("frameset", self.endTagFrameset) - ]) - self.endTagHandler.default = self.endTagOther - - def processEOF(self): - if self.tree.openElements[-1].name != "html": - self.parser.parseError("eof-in-frameset") - else: - assert self.parser.innerHTML - - def processCharacters(self, token): - self.parser.parseError("unexpected-char-in-frameset") - - def startTagFrameset(self, token): - self.tree.insertElement(token) - - def startTagFrame(self, token): - self.tree.insertElement(token) - self.tree.openElements.pop() - - def startTagNoframes(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def startTagOther(self, token): - self.parser.parseError("unexpected-start-tag-in-frameset", - {"name": token["name"]}) - - def endTagFrameset(self, token): - if self.tree.openElements[-1].name == "html": - # innerHTML case - self.parser.parseError("unexpected-frameset-in-frameset-innerhtml") - else: - self.tree.openElements.pop() - if (not self.parser.innerHTML and - self.tree.openElements[-1].name != "frameset"): - # If we're not in innerHTML mode and the current node is not a - # "frameset" element (anymore) then switch. - self.parser.phase = self.parser.phases["afterFrameset"] - - def endTagOther(self, token): - self.parser.parseError("unexpected-end-tag-in-frameset", - {"name": token["name"]}) - - class AfterFramesetPhase(Phase): - # http://www.whatwg.org/specs/web-apps/current-work/#after3 - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("noframes", self.startTagNoframes) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("html", self.endTagHtml) - ]) - self.endTagHandler.default = self.endTagOther - - def processEOF(self): - # Stop parsing - pass - - def processCharacters(self, token): - self.parser.parseError("unexpected-char-after-frameset") - - def startTagNoframes(self, token): - return self.parser.phases["inHead"].processStartTag(token) - - def startTagOther(self, token): - self.parser.parseError("unexpected-start-tag-after-frameset", - {"name": token["name"]}) - - def endTagHtml(self, token): - self.parser.phase = self.parser.phases["afterAfterFrameset"] - - def endTagOther(self, token): - self.parser.parseError("unexpected-end-tag-after-frameset", - {"name": token["name"]}) - - class AfterAfterBodyPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml) - ]) - self.startTagHandler.default = self.startTagOther - - def processEOF(self): - pass - - def processComment(self, token): - self.tree.insertComment(token, self.tree.document) - - def processSpaceCharacters(self, token): - return self.parser.phases["inBody"].processSpaceCharacters(token) - - def processCharacters(self, token): - self.parser.parseError("expected-eof-but-got-char") - self.parser.phase = self.parser.phases["inBody"] - return token - - def startTagHtml(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def startTagOther(self, token): - self.parser.parseError("expected-eof-but-got-start-tag", - {"name": token["name"]}) - self.parser.phase = self.parser.phases["inBody"] - return token - - def processEndTag(self, token): - self.parser.parseError("expected-eof-but-got-end-tag", - {"name": token["name"]}) - self.parser.phase = self.parser.phases["inBody"] - return token - - class AfterAfterFramesetPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("noframes", self.startTagNoFrames) - ]) - self.startTagHandler.default = self.startTagOther - - def processEOF(self): - pass - - def processComment(self, token): - self.tree.insertComment(token, self.tree.document) - - def processSpaceCharacters(self, token): - return self.parser.phases["inBody"].processSpaceCharacters(token) - - def processCharacters(self, token): - self.parser.parseError("expected-eof-but-got-char") - - def startTagHtml(self, token): - return self.parser.phases["inBody"].processStartTag(token) - - def startTagNoFrames(self, token): - return self.parser.phases["inHead"].processStartTag(token) - - def startTagOther(self, token): - self.parser.parseError("expected-eof-but-got-start-tag", - {"name": token["name"]}) - - def processEndTag(self, token): - self.parser.parseError("expected-eof-but-got-end-tag", - {"name": token["name"]}) - # pylint:enable=unused-argument - - return { - "initial": InitialPhase, - "beforeHtml": BeforeHtmlPhase, - "beforeHead": BeforeHeadPhase, - "inHead": InHeadPhase, - "inHeadNoscript": InHeadNoscriptPhase, - "afterHead": AfterHeadPhase, - "inBody": InBodyPhase, - "text": TextPhase, - "inTable": InTablePhase, - "inTableText": InTableTextPhase, - "inCaption": InCaptionPhase, - "inColumnGroup": InColumnGroupPhase, - "inTableBody": InTableBodyPhase, - "inRow": InRowPhase, - "inCell": InCellPhase, - "inSelect": InSelectPhase, - "inSelectInTable": InSelectInTablePhase, - "inForeignContent": InForeignContentPhase, - "afterBody": AfterBodyPhase, - "inFrameset": InFramesetPhase, - "afterFrameset": AfterFramesetPhase, - "afterAfterBody": AfterAfterBodyPhase, - "afterAfterFrameset": AfterAfterFramesetPhase, - # XXX after after frameset - } - - -def adjust_attributes(token, replacements): - needs_adjustment = viewkeys(token['data']) & viewkeys(replacements) - if needs_adjustment: - token['data'] = OrderedDict((replacements.get(k, k), v) - for k, v in token['data'].items()) - - -def impliedTagToken(name, type="EndTag", attributes=None, - selfClosing=False): - if attributes is None: - attributes = {} - return {"type": tokenTypes[type], "name": name, "data": attributes, - "selfClosing": selfClosing} - - -class ParseError(Exception): - """Error in parsed document""" - pass diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/serializer.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/serializer.py deleted file mode 100644 index 53f4d44..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/serializer.py +++ /dev/null @@ -1,409 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals -from pip._vendor.six import text_type - -import re - -from codecs import register_error, xmlcharrefreplace_errors - -from .constants import voidElements, booleanAttributes, spaceCharacters -from .constants import rcdataElements, entities, xmlEntities -from . import treewalkers, _utils -from xml.sax.saxutils import escape - -_quoteAttributeSpecChars = "".join(spaceCharacters) + "\"'=<>`" -_quoteAttributeSpec = re.compile("[" + _quoteAttributeSpecChars + "]") -_quoteAttributeLegacy = re.compile("[" + _quoteAttributeSpecChars + - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n" - "\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15" - "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" - "\x20\x2f\x60\xa0\u1680\u180e\u180f\u2000" - "\u2001\u2002\u2003\u2004\u2005\u2006\u2007" - "\u2008\u2009\u200a\u2028\u2029\u202f\u205f" - "\u3000]") - - -_encode_entity_map = {} -_is_ucs4 = len("\U0010FFFF") == 1 -for k, v in list(entities.items()): - # skip multi-character entities - if ((_is_ucs4 and len(v) > 1) or - (not _is_ucs4 and len(v) > 2)): - continue - if v != "&": - if len(v) == 2: - v = _utils.surrogatePairToCodepoint(v) - else: - v = ord(v) - if v not in _encode_entity_map or k.islower(): - # prefer < over < and similarly for &, >, etc. - _encode_entity_map[v] = k - - -def htmlentityreplace_errors(exc): - if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): - res = [] - codepoints = [] - skip = False - for i, c in enumerate(exc.object[exc.start:exc.end]): - if skip: - skip = False - continue - index = i + exc.start - if _utils.isSurrogatePair(exc.object[index:min([exc.end, index + 2])]): - codepoint = _utils.surrogatePairToCodepoint(exc.object[index:index + 2]) - skip = True - else: - codepoint = ord(c) - codepoints.append(codepoint) - for cp in codepoints: - e = _encode_entity_map.get(cp) - if e: - res.append("&") - res.append(e) - if not e.endswith(";"): - res.append(";") - else: - res.append("&#x%s;" % (hex(cp)[2:])) - return ("".join(res), exc.end) - else: - return xmlcharrefreplace_errors(exc) - - -register_error("htmlentityreplace", htmlentityreplace_errors) - - -def serialize(input, tree="etree", encoding=None, **serializer_opts): - """Serializes the input token stream using the specified treewalker - - :arg input: the token stream to serialize - - :arg tree: the treewalker to use - - :arg encoding: the encoding to use - - :arg serializer_opts: any options to pass to the - :py:class:`html5lib.serializer.HTMLSerializer` that gets created - - :returns: the tree serialized as a string - - Example: - - >>> from html5lib.html5parser import parse - >>> from html5lib.serializer import serialize - >>> token_stream = parse('<html><body><p>Hi!</p></body></html>') - >>> serialize(token_stream, omit_optional_tags=False) - '<html><head></head><body><p>Hi!</p></body></html>' - - """ - # XXX: Should we cache this? - walker = treewalkers.getTreeWalker(tree) - s = HTMLSerializer(**serializer_opts) - return s.render(walker(input), encoding) - - -class HTMLSerializer(object): - - # attribute quoting options - quote_attr_values = "legacy" # be secure by default - quote_char = '"' - use_best_quote_char = True - - # tag syntax options - omit_optional_tags = True - minimize_boolean_attributes = True - use_trailing_solidus = False - space_before_trailing_solidus = True - - # escaping options - escape_lt_in_attrs = False - escape_rcdata = False - resolve_entities = True - - # miscellaneous options - alphabetical_attributes = False - inject_meta_charset = True - strip_whitespace = False - sanitize = False - - options = ("quote_attr_values", "quote_char", "use_best_quote_char", - "omit_optional_tags", "minimize_boolean_attributes", - "use_trailing_solidus", "space_before_trailing_solidus", - "escape_lt_in_attrs", "escape_rcdata", "resolve_entities", - "alphabetical_attributes", "inject_meta_charset", - "strip_whitespace", "sanitize") - - def __init__(self, **kwargs): - """Initialize HTMLSerializer - - :arg inject_meta_charset: Whether or not to inject the meta charset. - - Defaults to ``True``. - - :arg quote_attr_values: Whether to quote attribute values that don't - require quoting per legacy browser behavior (``"legacy"``), when - required by the standard (``"spec"``), or always (``"always"``). - - Defaults to ``"legacy"``. - - :arg quote_char: Use given quote character for attribute quoting. - - Defaults to ``"`` which will use double quotes unless attribute - value contains a double quote, in which case single quotes are - used. - - :arg escape_lt_in_attrs: Whether or not to escape ``<`` in attribute - values. - - Defaults to ``False``. - - :arg escape_rcdata: Whether to escape characters that need to be - escaped within normal elements within rcdata elements such as - style. - - Defaults to ``False``. - - :arg resolve_entities: Whether to resolve named character entities that - appear in the source tree. The XML predefined entities < > - & " ' are unaffected by this setting. - - Defaults to ``True``. - - :arg strip_whitespace: Whether to remove semantically meaningless - whitespace. (This compresses all whitespace to a single space - except within ``pre``.) - - Defaults to ``False``. - - :arg minimize_boolean_attributes: Shortens boolean attributes to give - just the attribute value, for example:: - - <input disabled="disabled"> - - becomes:: - - <input disabled> - - Defaults to ``True``. - - :arg use_trailing_solidus: Includes a close-tag slash at the end of the - start tag of void elements (empty elements whose end tag is - forbidden). E.g. ``<hr/>``. - - Defaults to ``False``. - - :arg space_before_trailing_solidus: Places a space immediately before - the closing slash in a tag using a trailing solidus. E.g. - ``<hr />``. Requires ``use_trailing_solidus=True``. - - Defaults to ``True``. - - :arg sanitize: Strip all unsafe or unknown constructs from output. - See :py:class:`html5lib.filters.sanitizer.Filter`. - - Defaults to ``False``. - - :arg omit_optional_tags: Omit start/end tags that are optional. - - Defaults to ``True``. - - :arg alphabetical_attributes: Reorder attributes to be in alphabetical order. - - Defaults to ``False``. - - """ - unexpected_args = frozenset(kwargs) - frozenset(self.options) - if len(unexpected_args) > 0: - raise TypeError("__init__() got an unexpected keyword argument '%s'" % next(iter(unexpected_args))) - if 'quote_char' in kwargs: - self.use_best_quote_char = False - for attr in self.options: - setattr(self, attr, kwargs.get(attr, getattr(self, attr))) - self.errors = [] - self.strict = False - - def encode(self, string): - assert(isinstance(string, text_type)) - if self.encoding: - return string.encode(self.encoding, "htmlentityreplace") - else: - return string - - def encodeStrict(self, string): - assert(isinstance(string, text_type)) - if self.encoding: - return string.encode(self.encoding, "strict") - else: - return string - - def serialize(self, treewalker, encoding=None): - # pylint:disable=too-many-nested-blocks - self.encoding = encoding - in_cdata = False - self.errors = [] - - if encoding and self.inject_meta_charset: - from .filters.inject_meta_charset import Filter - treewalker = Filter(treewalker, encoding) - # Alphabetical attributes is here under the assumption that none of - # the later filters add or change order of attributes; it needs to be - # before the sanitizer so escaped elements come out correctly - if self.alphabetical_attributes: - from .filters.alphabeticalattributes import Filter - treewalker = Filter(treewalker) - # WhitespaceFilter should be used before OptionalTagFilter - # for maximum efficiently of this latter filter - if self.strip_whitespace: - from .filters.whitespace import Filter - treewalker = Filter(treewalker) - if self.sanitize: - from .filters.sanitizer import Filter - treewalker = Filter(treewalker) - if self.omit_optional_tags: - from .filters.optionaltags import Filter - treewalker = Filter(treewalker) - - for token in treewalker: - type = token["type"] - if type == "Doctype": - doctype = "<!DOCTYPE %s" % token["name"] - - if token["publicId"]: - doctype += ' PUBLIC "%s"' % token["publicId"] - elif token["systemId"]: - doctype += " SYSTEM" - if token["systemId"]: - if token["systemId"].find('"') >= 0: - if token["systemId"].find("'") >= 0: - self.serializeError("System identifer contains both single and double quote characters") - quote_char = "'" - else: - quote_char = '"' - doctype += " %s%s%s" % (quote_char, token["systemId"], quote_char) - - doctype += ">" - yield self.encodeStrict(doctype) - - elif type in ("Characters", "SpaceCharacters"): - if type == "SpaceCharacters" or in_cdata: - if in_cdata and token["data"].find("</") >= 0: - self.serializeError("Unexpected </ in CDATA") - yield self.encode(token["data"]) - else: - yield self.encode(escape(token["data"])) - - elif type in ("StartTag", "EmptyTag"): - name = token["name"] - yield self.encodeStrict("<%s" % name) - if name in rcdataElements and not self.escape_rcdata: - in_cdata = True - elif in_cdata: - self.serializeError("Unexpected child element of a CDATA element") - for (_, attr_name), attr_value in token["data"].items(): - # TODO: Add namespace support here - k = attr_name - v = attr_value - yield self.encodeStrict(' ') - - yield self.encodeStrict(k) - if not self.minimize_boolean_attributes or \ - (k not in booleanAttributes.get(name, tuple()) and - k not in booleanAttributes.get("", tuple())): - yield self.encodeStrict("=") - if self.quote_attr_values == "always" or len(v) == 0: - quote_attr = True - elif self.quote_attr_values == "spec": - quote_attr = _quoteAttributeSpec.search(v) is not None - elif self.quote_attr_values == "legacy": - quote_attr = _quoteAttributeLegacy.search(v) is not None - else: - raise ValueError("quote_attr_values must be one of: " - "'always', 'spec', or 'legacy'") - v = v.replace("&", "&") - if self.escape_lt_in_attrs: - v = v.replace("<", "<") - if quote_attr: - quote_char = self.quote_char - if self.use_best_quote_char: - if "'" in v and '"' not in v: - quote_char = '"' - elif '"' in v and "'" not in v: - quote_char = "'" - if quote_char == "'": - v = v.replace("'", "'") - else: - v = v.replace('"', """) - yield self.encodeStrict(quote_char) - yield self.encode(v) - yield self.encodeStrict(quote_char) - else: - yield self.encode(v) - if name in voidElements and self.use_trailing_solidus: - if self.space_before_trailing_solidus: - yield self.encodeStrict(" /") - else: - yield self.encodeStrict("/") - yield self.encode(">") - - elif type == "EndTag": - name = token["name"] - if name in rcdataElements: - in_cdata = False - elif in_cdata: - self.serializeError("Unexpected child element of a CDATA element") - yield self.encodeStrict("</%s>" % name) - - elif type == "Comment": - data = token["data"] - if data.find("--") >= 0: - self.serializeError("Comment contains --") - yield self.encodeStrict("<!--%s-->" % token["data"]) - - elif type == "Entity": - name = token["name"] - key = name + ";" - if key not in entities: - self.serializeError("Entity %s not recognized" % name) - if self.resolve_entities and key not in xmlEntities: - data = entities[key] - else: - data = "&%s;" % name - yield self.encodeStrict(data) - - else: - self.serializeError(token["data"]) - - def render(self, treewalker, encoding=None): - """Serializes the stream from the treewalker into a string - - :arg treewalker: the treewalker to serialize - - :arg encoding: the string encoding to use - - :returns: the serialized tree - - Example: - - >>> from html5lib import parse, getTreeWalker - >>> from html5lib.serializer import HTMLSerializer - >>> token_stream = parse('<html><body>Hi!</body></html>') - >>> walker = getTreeWalker('etree') - >>> serializer = HTMLSerializer(omit_optional_tags=False) - >>> serializer.render(walker(token_stream)) - '<html><head></head><body>Hi!</body></html>' - - """ - if encoding: - return b"".join(list(self.serialize(treewalker, encoding))) - else: - return "".join(list(self.serialize(treewalker))) - - def serializeError(self, data="XXX ERROR MESSAGE NEEDED"): - # XXX The idea is to make data mandatory. - self.errors.append(data) - if self.strict: - raise SerializeError - - -class SerializeError(Exception): - """Error in serialized tree""" - pass diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/__init__.py deleted file mode 100644 index 7ef5959..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -"""Tree adapters let you convert from one tree structure to another - -Example: - -.. code-block:: python - - from pip._vendor import html5lib - from pip._vendor.html5lib.treeadapters import genshi - - doc = '<html><body>Hi!</body></html>' - treebuilder = html5lib.getTreeBuilder('etree') - parser = html5lib.HTMLParser(tree=treebuilder) - tree = parser.parse(doc) - TreeWalker = html5lib.getTreeWalker('etree') - - genshi_tree = genshi.to_genshi(TreeWalker(tree)) - -""" -from __future__ import absolute_import, division, unicode_literals - -from . import sax - -__all__ = ["sax"] - -try: - from . import genshi # noqa -except ImportError: - pass -else: - __all__.append("genshi") diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/genshi.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/genshi.py deleted file mode 100644 index 61d5fb6..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/genshi.py +++ /dev/null @@ -1,54 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from genshi.core import QName, Attrs -from genshi.core import START, END, TEXT, COMMENT, DOCTYPE - - -def to_genshi(walker): - """Convert a tree to a genshi tree - - :arg walker: the treewalker to use to walk the tree to convert it - - :returns: generator of genshi nodes - - """ - text = [] - for token in walker: - type = token["type"] - if type in ("Characters", "SpaceCharacters"): - text.append(token["data"]) - elif text: - yield TEXT, "".join(text), (None, -1, -1) - text = [] - - if type in ("StartTag", "EmptyTag"): - if token["namespace"]: - name = "{%s}%s" % (token["namespace"], token["name"]) - else: - name = token["name"] - attrs = Attrs([(QName("{%s}%s" % attr if attr[0] is not None else attr[1]), value) - for attr, value in token["data"].items()]) - yield (START, (QName(name), attrs), (None, -1, -1)) - if type == "EmptyTag": - type = "EndTag" - - if type == "EndTag": - if token["namespace"]: - name = "{%s}%s" % (token["namespace"], token["name"]) - else: - name = token["name"] - - yield END, QName(name), (None, -1, -1) - - elif type == "Comment": - yield COMMENT, token["data"], (None, -1, -1) - - elif type == "Doctype": - yield DOCTYPE, (token["name"], token["publicId"], - token["systemId"]), (None, -1, -1) - - else: - pass # FIXME: What to do? - - if text: - yield TEXT, "".join(text), (None, -1, -1) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/sax.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/sax.py deleted file mode 100644 index f4ccea5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treeadapters/sax.py +++ /dev/null @@ -1,50 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from xml.sax.xmlreader import AttributesNSImpl - -from ..constants import adjustForeignAttributes, unadjustForeignAttributes - -prefix_mapping = {} -for prefix, localName, namespace in adjustForeignAttributes.values(): - if prefix is not None: - prefix_mapping[prefix] = namespace - - -def to_sax(walker, handler): - """Call SAX-like content handler based on treewalker walker - - :arg walker: the treewalker to use to walk the tree to convert it - - :arg handler: SAX handler to use - - """ - handler.startDocument() - for prefix, namespace in prefix_mapping.items(): - handler.startPrefixMapping(prefix, namespace) - - for token in walker: - type = token["type"] - if type == "Doctype": - continue - elif type in ("StartTag", "EmptyTag"): - attrs = AttributesNSImpl(token["data"], - unadjustForeignAttributes) - handler.startElementNS((token["namespace"], token["name"]), - token["name"], - attrs) - if type == "EmptyTag": - handler.endElementNS((token["namespace"], token["name"]), - token["name"]) - elif type == "EndTag": - handler.endElementNS((token["namespace"], token["name"]), - token["name"]) - elif type in ("Characters", "SpaceCharacters"): - handler.characters(token["data"]) - elif type == "Comment": - pass - else: - assert False, "Unknown token type" - - for prefix, namespace in prefix_mapping.items(): - handler.endPrefixMapping(prefix) - handler.endDocument() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/__init__.py deleted file mode 100644 index d44447e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/__init__.py +++ /dev/null @@ -1,88 +0,0 @@ -"""A collection of modules for building different kinds of trees from HTML -documents. - -To create a treebuilder for a new type of tree, you need to do -implement several things: - -1. A set of classes for various types of elements: Document, Doctype, Comment, - Element. These must implement the interface of ``base.treebuilders.Node`` - (although comment nodes have a different signature for their constructor, - see ``treebuilders.etree.Comment``) Textual content may also be implemented - as another node type, or not, as your tree implementation requires. - -2. A treebuilder object (called ``TreeBuilder`` by convention) that inherits - from ``treebuilders.base.TreeBuilder``. This has 4 required attributes: - - * ``documentClass`` - the class to use for the bottommost node of a document - * ``elementClass`` - the class to use for HTML Elements - * ``commentClass`` - the class to use for comments - * ``doctypeClass`` - the class to use for doctypes - - It also has one required method: - - * ``getDocument`` - Returns the root node of the complete document tree - -3. If you wish to run the unit tests, you must also create a ``testSerializer`` - method on your treebuilder which accepts a node and returns a string - containing Node and its children serialized according to the format used in - the unittests - -""" - -from __future__ import absolute_import, division, unicode_literals - -from .._utils import default_etree - -treeBuilderCache = {} - - -def getTreeBuilder(treeType, implementation=None, **kwargs): - """Get a TreeBuilder class for various types of trees with built-in support - - :arg treeType: the name of the tree type required (case-insensitive). Supported - values are: - - * "dom" - A generic builder for DOM implementations, defaulting to a - xml.dom.minidom based implementation. - * "etree" - A generic builder for tree implementations exposing an - ElementTree-like interface, defaulting to xml.etree.cElementTree if - available and xml.etree.ElementTree if not. - * "lxml" - A etree-based builder for lxml.etree, handling limitations - of lxml's implementation. - - :arg implementation: (Currently applies to the "etree" and "dom" tree - types). A module implementing the tree type e.g. xml.etree.ElementTree - or xml.etree.cElementTree. - - :arg kwargs: Any additional options to pass to the TreeBuilder when - creating it. - - Example: - - >>> from html5lib.treebuilders import getTreeBuilder - >>> builder = getTreeBuilder('etree') - - """ - - treeType = treeType.lower() - if treeType not in treeBuilderCache: - if treeType == "dom": - from . import dom - # Come up with a sane default (pref. from the stdlib) - if implementation is None: - from xml.dom import minidom - implementation = minidom - # NEVER cache here, caching is done in the dom submodule - return dom.getDomModule(implementation, **kwargs).TreeBuilder - elif treeType == "lxml": - from . import etree_lxml - treeBuilderCache[treeType] = etree_lxml.TreeBuilder - elif treeType == "etree": - from . import etree - if implementation is None: - implementation = default_etree - # NEVER cache here, caching is done in the etree submodule - return etree.getETreeModule(implementation, **kwargs).TreeBuilder - else: - raise ValueError("""Unrecognised treebuilder "%s" """ % treeType) - return treeBuilderCache.get(treeType) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/base.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/base.py deleted file mode 100644 index 73973db..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/base.py +++ /dev/null @@ -1,417 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals -from pip._vendor.six import text_type - -from ..constants import scopingElements, tableInsertModeElements, namespaces - -# The scope markers are inserted when entering object elements, -# marquees, table cells, and table captions, and are used to prevent formatting -# from "leaking" into tables, object elements, and marquees. -Marker = None - -listElementsMap = { - None: (frozenset(scopingElements), False), - "button": (frozenset(scopingElements | set([(namespaces["html"], "button")])), False), - "list": (frozenset(scopingElements | set([(namespaces["html"], "ol"), - (namespaces["html"], "ul")])), False), - "table": (frozenset([(namespaces["html"], "html"), - (namespaces["html"], "table")]), False), - "select": (frozenset([(namespaces["html"], "optgroup"), - (namespaces["html"], "option")]), True) -} - - -class Node(object): - """Represents an item in the tree""" - def __init__(self, name): - """Creates a Node - - :arg name: The tag name associated with the node - - """ - # The tag name assocaited with the node - self.name = name - # The parent of the current node (or None for the document node) - self.parent = None - # The value of the current node (applies to text nodes and comments) - self.value = None - # A dict holding name -> value pairs for attributes of the node - self.attributes = {} - # A list of child nodes of the current node. This must include all - # elements but not necessarily other node types. - self.childNodes = [] - # A list of miscellaneous flags that can be set on the node. - self._flags = [] - - def __str__(self): - attributesStr = " ".join(["%s=\"%s\"" % (name, value) - for name, value in - self.attributes.items()]) - if attributesStr: - return "<%s %s>" % (self.name, attributesStr) - else: - return "<%s>" % (self.name) - - def __repr__(self): - return "<%s>" % (self.name) - - def appendChild(self, node): - """Insert node as a child of the current node - - :arg node: the node to insert - - """ - raise NotImplementedError - - def insertText(self, data, insertBefore=None): - """Insert data as text in the current node, positioned before the - start of node insertBefore or to the end of the node's text. - - :arg data: the data to insert - - :arg insertBefore: True if you want to insert the text before the node - and False if you want to insert it after the node - - """ - raise NotImplementedError - - def insertBefore(self, node, refNode): - """Insert node as a child of the current node, before refNode in the - list of child nodes. Raises ValueError if refNode is not a child of - the current node - - :arg node: the node to insert - - :arg refNode: the child node to insert the node before - - """ - raise NotImplementedError - - def removeChild(self, node): - """Remove node from the children of the current node - - :arg node: the child node to remove - - """ - raise NotImplementedError - - def reparentChildren(self, newParent): - """Move all the children of the current node to newParent. - This is needed so that trees that don't store text as nodes move the - text in the correct way - - :arg newParent: the node to move all this node's children to - - """ - # XXX - should this method be made more general? - for child in self.childNodes: - newParent.appendChild(child) - self.childNodes = [] - - def cloneNode(self): - """Return a shallow copy of the current node i.e. a node with the same - name and attributes but with no parent or child nodes - """ - raise NotImplementedError - - def hasContent(self): - """Return true if the node has children or text, false otherwise - """ - raise NotImplementedError - - -class ActiveFormattingElements(list): - def append(self, node): - equalCount = 0 - if node != Marker: - for element in self[::-1]: - if element == Marker: - break - if self.nodesEqual(element, node): - equalCount += 1 - if equalCount == 3: - self.remove(element) - break - list.append(self, node) - - def nodesEqual(self, node1, node2): - if not node1.nameTuple == node2.nameTuple: - return False - - if not node1.attributes == node2.attributes: - return False - - return True - - -class TreeBuilder(object): - """Base treebuilder implementation - - * documentClass - the class to use for the bottommost node of a document - * elementClass - the class to use for HTML Elements - * commentClass - the class to use for comments - * doctypeClass - the class to use for doctypes - - """ - # pylint:disable=not-callable - - # Document class - documentClass = None - - # The class to use for creating a node - elementClass = None - - # The class to use for creating comments - commentClass = None - - # The class to use for creating doctypes - doctypeClass = None - - # Fragment class - fragmentClass = None - - def __init__(self, namespaceHTMLElements): - """Create a TreeBuilder - - :arg namespaceHTMLElements: whether or not to namespace HTML elements - - """ - if namespaceHTMLElements: - self.defaultNamespace = "http://www.w3.org/1999/xhtml" - else: - self.defaultNamespace = None - self.reset() - - def reset(self): - self.openElements = [] - self.activeFormattingElements = ActiveFormattingElements() - - # XXX - rename these to headElement, formElement - self.headPointer = None - self.formPointer = None - - self.insertFromTable = False - - self.document = self.documentClass() - - def elementInScope(self, target, variant=None): - - # If we pass a node in we match that. if we pass a string - # match any node with that name - exactNode = hasattr(target, "nameTuple") - if not exactNode: - if isinstance(target, text_type): - target = (namespaces["html"], target) - assert isinstance(target, tuple) - - listElements, invert = listElementsMap[variant] - - for node in reversed(self.openElements): - if exactNode and node == target: - return True - elif not exactNode and node.nameTuple == target: - return True - elif (invert ^ (node.nameTuple in listElements)): - return False - - assert False # We should never reach this point - - def reconstructActiveFormattingElements(self): - # Within this algorithm the order of steps described in the - # specification is not quite the same as the order of steps in the - # code. It should still do the same though. - - # Step 1: stop the algorithm when there's nothing to do. - if not self.activeFormattingElements: - return - - # Step 2 and step 3: we start with the last element. So i is -1. - i = len(self.activeFormattingElements) - 1 - entry = self.activeFormattingElements[i] - if entry == Marker or entry in self.openElements: - return - - # Step 6 - while entry != Marker and entry not in self.openElements: - if i == 0: - # This will be reset to 0 below - i = -1 - break - i -= 1 - # Step 5: let entry be one earlier in the list. - entry = self.activeFormattingElements[i] - - while True: - # Step 7 - i += 1 - - # Step 8 - entry = self.activeFormattingElements[i] - clone = entry.cloneNode() # Mainly to get a new copy of the attributes - - # Step 9 - element = self.insertElement({"type": "StartTag", - "name": clone.name, - "namespace": clone.namespace, - "data": clone.attributes}) - - # Step 10 - self.activeFormattingElements[i] = element - - # Step 11 - if element == self.activeFormattingElements[-1]: - break - - def clearActiveFormattingElements(self): - entry = self.activeFormattingElements.pop() - while self.activeFormattingElements and entry != Marker: - entry = self.activeFormattingElements.pop() - - def elementInActiveFormattingElements(self, name): - """Check if an element exists between the end of the active - formatting elements and the last marker. If it does, return it, else - return false""" - - for item in self.activeFormattingElements[::-1]: - # Check for Marker first because if it's a Marker it doesn't have a - # name attribute. - if item == Marker: - break - elif item.name == name: - return item - return False - - def insertRoot(self, token): - element = self.createElement(token) - self.openElements.append(element) - self.document.appendChild(element) - - def insertDoctype(self, token): - name = token["name"] - publicId = token["publicId"] - systemId = token["systemId"] - - doctype = self.doctypeClass(name, publicId, systemId) - self.document.appendChild(doctype) - - def insertComment(self, token, parent=None): - if parent is None: - parent = self.openElements[-1] - parent.appendChild(self.commentClass(token["data"])) - - def createElement(self, token): - """Create an element but don't insert it anywhere""" - name = token["name"] - namespace = token.get("namespace", self.defaultNamespace) - element = self.elementClass(name, namespace) - element.attributes = token["data"] - return element - - def _getInsertFromTable(self): - return self._insertFromTable - - def _setInsertFromTable(self, value): - """Switch the function used to insert an element from the - normal one to the misnested table one and back again""" - self._insertFromTable = value - if value: - self.insertElement = self.insertElementTable - else: - self.insertElement = self.insertElementNormal - - insertFromTable = property(_getInsertFromTable, _setInsertFromTable) - - def insertElementNormal(self, token): - name = token["name"] - assert isinstance(name, text_type), "Element %s not unicode" % name - namespace = token.get("namespace", self.defaultNamespace) - element = self.elementClass(name, namespace) - element.attributes = token["data"] - self.openElements[-1].appendChild(element) - self.openElements.append(element) - return element - - def insertElementTable(self, token): - """Create an element and insert it into the tree""" - element = self.createElement(token) - if self.openElements[-1].name not in tableInsertModeElements: - return self.insertElementNormal(token) - else: - # We should be in the InTable mode. This means we want to do - # special magic element rearranging - parent, insertBefore = self.getTableMisnestedNodePosition() - if insertBefore is None: - parent.appendChild(element) - else: - parent.insertBefore(element, insertBefore) - self.openElements.append(element) - return element - - def insertText(self, data, parent=None): - """Insert text data.""" - if parent is None: - parent = self.openElements[-1] - - if (not self.insertFromTable or (self.insertFromTable and - self.openElements[-1].name - not in tableInsertModeElements)): - parent.insertText(data) - else: - # We should be in the InTable mode. This means we want to do - # special magic element rearranging - parent, insertBefore = self.getTableMisnestedNodePosition() - parent.insertText(data, insertBefore) - - def getTableMisnestedNodePosition(self): - """Get the foster parent element, and sibling to insert before - (or None) when inserting a misnested table node""" - # The foster parent element is the one which comes before the most - # recently opened table element - # XXX - this is really inelegant - lastTable = None - fosterParent = None - insertBefore = None - for elm in self.openElements[::-1]: - if elm.name == "table": - lastTable = elm - break - if lastTable: - # XXX - we should really check that this parent is actually a - # node here - if lastTable.parent: - fosterParent = lastTable.parent - insertBefore = lastTable - else: - fosterParent = self.openElements[ - self.openElements.index(lastTable) - 1] - else: - fosterParent = self.openElements[0] - return fosterParent, insertBefore - - def generateImpliedEndTags(self, exclude=None): - name = self.openElements[-1].name - # XXX td, th and tr are not actually needed - if (name in frozenset(("dd", "dt", "li", "option", "optgroup", "p", "rp", "rt")) and - name != exclude): - self.openElements.pop() - # XXX This is not entirely what the specification says. We should - # investigate it more closely. - self.generateImpliedEndTags(exclude) - - def getDocument(self): - """Return the final tree""" - return self.document - - def getFragment(self): - """Return the final fragment""" - # assert self.innerHTML - fragment = self.fragmentClass() - self.openElements[0].reparentChildren(fragment) - return fragment - - def testSerializer(self, node): - """Serialize the subtree of node in the format required by unit tests - - :arg node: the node from which to start serializing - - """ - raise NotImplementedError diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/dom.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/dom.py deleted file mode 100644 index dcfac22..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/dom.py +++ /dev/null @@ -1,236 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - - -from collections import MutableMapping -from xml.dom import minidom, Node -import weakref - -from . import base -from .. import constants -from ..constants import namespaces -from .._utils import moduleFactoryFactory - - -def getDomBuilder(DomImplementation): - Dom = DomImplementation - - class AttrList(MutableMapping): - def __init__(self, element): - self.element = element - - def __iter__(self): - return iter(self.element.attributes.keys()) - - def __setitem__(self, name, value): - if isinstance(name, tuple): - raise NotImplementedError - else: - attr = self.element.ownerDocument.createAttribute(name) - attr.value = value - self.element.attributes[name] = attr - - def __len__(self): - return len(self.element.attributes) - - def items(self): - return list(self.element.attributes.items()) - - def values(self): - return list(self.element.attributes.values()) - - def __getitem__(self, name): - if isinstance(name, tuple): - raise NotImplementedError - else: - return self.element.attributes[name].value - - def __delitem__(self, name): - if isinstance(name, tuple): - raise NotImplementedError - else: - del self.element.attributes[name] - - class NodeBuilder(base.Node): - def __init__(self, element): - base.Node.__init__(self, element.nodeName) - self.element = element - - namespace = property(lambda self: hasattr(self.element, "namespaceURI") and - self.element.namespaceURI or None) - - def appendChild(self, node): - node.parent = self - self.element.appendChild(node.element) - - def insertText(self, data, insertBefore=None): - text = self.element.ownerDocument.createTextNode(data) - if insertBefore: - self.element.insertBefore(text, insertBefore.element) - else: - self.element.appendChild(text) - - def insertBefore(self, node, refNode): - self.element.insertBefore(node.element, refNode.element) - node.parent = self - - def removeChild(self, node): - if node.element.parentNode == self.element: - self.element.removeChild(node.element) - node.parent = None - - def reparentChildren(self, newParent): - while self.element.hasChildNodes(): - child = self.element.firstChild - self.element.removeChild(child) - newParent.element.appendChild(child) - self.childNodes = [] - - def getAttributes(self): - return AttrList(self.element) - - def setAttributes(self, attributes): - if attributes: - for name, value in list(attributes.items()): - if isinstance(name, tuple): - if name[0] is not None: - qualifiedName = (name[0] + ":" + name[1]) - else: - qualifiedName = name[1] - self.element.setAttributeNS(name[2], qualifiedName, - value) - else: - self.element.setAttribute( - name, value) - attributes = property(getAttributes, setAttributes) - - def cloneNode(self): - return NodeBuilder(self.element.cloneNode(False)) - - def hasContent(self): - return self.element.hasChildNodes() - - def getNameTuple(self): - if self.namespace is None: - return namespaces["html"], self.name - else: - return self.namespace, self.name - - nameTuple = property(getNameTuple) - - class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable - def documentClass(self): - self.dom = Dom.getDOMImplementation().createDocument(None, None, None) - return weakref.proxy(self) - - def insertDoctype(self, token): - name = token["name"] - publicId = token["publicId"] - systemId = token["systemId"] - - domimpl = Dom.getDOMImplementation() - doctype = domimpl.createDocumentType(name, publicId, systemId) - self.document.appendChild(NodeBuilder(doctype)) - if Dom == minidom: - doctype.ownerDocument = self.dom - - def elementClass(self, name, namespace=None): - if namespace is None and self.defaultNamespace is None: - node = self.dom.createElement(name) - else: - node = self.dom.createElementNS(namespace, name) - - return NodeBuilder(node) - - def commentClass(self, data): - return NodeBuilder(self.dom.createComment(data)) - - def fragmentClass(self): - return NodeBuilder(self.dom.createDocumentFragment()) - - def appendChild(self, node): - self.dom.appendChild(node.element) - - def testSerializer(self, element): - return testSerializer(element) - - def getDocument(self): - return self.dom - - def getFragment(self): - return base.TreeBuilder.getFragment(self).element - - def insertText(self, data, parent=None): - data = data - if parent != self: - base.TreeBuilder.insertText(self, data, parent) - else: - # HACK: allow text nodes as children of the document node - if hasattr(self.dom, '_child_node_types'): - # pylint:disable=protected-access - if Node.TEXT_NODE not in self.dom._child_node_types: - self.dom._child_node_types = list(self.dom._child_node_types) - self.dom._child_node_types.append(Node.TEXT_NODE) - self.dom.appendChild(self.dom.createTextNode(data)) - - implementation = DomImplementation - name = None - - def testSerializer(element): - element.normalize() - rv = [] - - def serializeElement(element, indent=0): - if element.nodeType == Node.DOCUMENT_TYPE_NODE: - if element.name: - if element.publicId or element.systemId: - publicId = element.publicId or "" - systemId = element.systemId or "" - rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" % - (' ' * indent, element.name, publicId, systemId)) - else: - rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name)) - else: - rv.append("|%s<!DOCTYPE >" % (' ' * indent,)) - elif element.nodeType == Node.DOCUMENT_NODE: - rv.append("#document") - elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE: - rv.append("#document-fragment") - elif element.nodeType == Node.COMMENT_NODE: - rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue)) - elif element.nodeType == Node.TEXT_NODE: - rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue)) - else: - if (hasattr(element, "namespaceURI") and - element.namespaceURI is not None): - name = "%s %s" % (constants.prefixes[element.namespaceURI], - element.nodeName) - else: - name = element.nodeName - rv.append("|%s<%s>" % (' ' * indent, name)) - if element.hasAttributes(): - attributes = [] - for i in range(len(element.attributes)): - attr = element.attributes.item(i) - name = attr.nodeName - value = attr.value - ns = attr.namespaceURI - if ns: - name = "%s %s" % (constants.prefixes[ns], attr.localName) - else: - name = attr.nodeName - attributes.append((name, value)) - - for name, value in sorted(attributes): - rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) - indent += 2 - for child in element.childNodes: - serializeElement(child, indent) - serializeElement(element, 0) - - return "\n".join(rv) - - return locals() - - -# The actual means to get a module! -getDomModule = moduleFactoryFactory(getDomBuilder) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/etree.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/etree.py deleted file mode 100644 index 0dedf44..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/etree.py +++ /dev/null @@ -1,340 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals -# pylint:disable=protected-access - -from pip._vendor.six import text_type - -import re - -from . import base -from .. import _ihatexml -from .. import constants -from ..constants import namespaces -from .._utils import moduleFactoryFactory - -tag_regexp = re.compile("{([^}]*)}(.*)") - - -def getETreeBuilder(ElementTreeImplementation, fullTree=False): - ElementTree = ElementTreeImplementation - ElementTreeCommentType = ElementTree.Comment("asd").tag - - class Element(base.Node): - def __init__(self, name, namespace=None): - self._name = name - self._namespace = namespace - self._element = ElementTree.Element(self._getETreeTag(name, - namespace)) - if namespace is None: - self.nameTuple = namespaces["html"], self._name - else: - self.nameTuple = self._namespace, self._name - self.parent = None - self._childNodes = [] - self._flags = [] - - def _getETreeTag(self, name, namespace): - if namespace is None: - etree_tag = name - else: - etree_tag = "{%s}%s" % (namespace, name) - return etree_tag - - def _setName(self, name): - self._name = name - self._element.tag = self._getETreeTag(self._name, self._namespace) - - def _getName(self): - return self._name - - name = property(_getName, _setName) - - def _setNamespace(self, namespace): - self._namespace = namespace - self._element.tag = self._getETreeTag(self._name, self._namespace) - - def _getNamespace(self): - return self._namespace - - namespace = property(_getNamespace, _setNamespace) - - def _getAttributes(self): - return self._element.attrib - - def _setAttributes(self, attributes): - # Delete existing attributes first - # XXX - there may be a better way to do this... - for key in list(self._element.attrib.keys()): - del self._element.attrib[key] - for key, value in attributes.items(): - if isinstance(key, tuple): - name = "{%s}%s" % (key[2], key[1]) - else: - name = key - self._element.set(name, value) - - attributes = property(_getAttributes, _setAttributes) - - def _getChildNodes(self): - return self._childNodes - - def _setChildNodes(self, value): - del self._element[:] - self._childNodes = [] - for element in value: - self.insertChild(element) - - childNodes = property(_getChildNodes, _setChildNodes) - - def hasContent(self): - """Return true if the node has children or text""" - return bool(self._element.text or len(self._element)) - - def appendChild(self, node): - self._childNodes.append(node) - self._element.append(node._element) - node.parent = self - - def insertBefore(self, node, refNode): - index = list(self._element).index(refNode._element) - self._element.insert(index, node._element) - node.parent = self - - def removeChild(self, node): - self._childNodes.remove(node) - self._element.remove(node._element) - node.parent = None - - def insertText(self, data, insertBefore=None): - if not(len(self._element)): - if not self._element.text: - self._element.text = "" - self._element.text += data - elif insertBefore is None: - # Insert the text as the tail of the last child element - if not self._element[-1].tail: - self._element[-1].tail = "" - self._element[-1].tail += data - else: - # Insert the text before the specified node - children = list(self._element) - index = children.index(insertBefore._element) - if index > 0: - if not self._element[index - 1].tail: - self._element[index - 1].tail = "" - self._element[index - 1].tail += data - else: - if not self._element.text: - self._element.text = "" - self._element.text += data - - def cloneNode(self): - element = type(self)(self.name, self.namespace) - for name, value in self.attributes.items(): - element.attributes[name] = value - return element - - def reparentChildren(self, newParent): - if newParent.childNodes: - newParent.childNodes[-1]._element.tail += self._element.text - else: - if not newParent._element.text: - newParent._element.text = "" - if self._element.text is not None: - newParent._element.text += self._element.text - self._element.text = "" - base.Node.reparentChildren(self, newParent) - - class Comment(Element): - def __init__(self, data): - # Use the superclass constructor to set all properties on the - # wrapper element - self._element = ElementTree.Comment(data) - self.parent = None - self._childNodes = [] - self._flags = [] - - def _getData(self): - return self._element.text - - def _setData(self, value): - self._element.text = value - - data = property(_getData, _setData) - - class DocumentType(Element): - def __init__(self, name, publicId, systemId): - Element.__init__(self, "<!DOCTYPE>") - self._element.text = name - self.publicId = publicId - self.systemId = systemId - - def _getPublicId(self): - return self._element.get("publicId", "") - - def _setPublicId(self, value): - if value is not None: - self._element.set("publicId", value) - - publicId = property(_getPublicId, _setPublicId) - - def _getSystemId(self): - return self._element.get("systemId", "") - - def _setSystemId(self, value): - if value is not None: - self._element.set("systemId", value) - - systemId = property(_getSystemId, _setSystemId) - - class Document(Element): - def __init__(self): - Element.__init__(self, "DOCUMENT_ROOT") - - class DocumentFragment(Element): - def __init__(self): - Element.__init__(self, "DOCUMENT_FRAGMENT") - - def testSerializer(element): - rv = [] - - def serializeElement(element, indent=0): - if not(hasattr(element, "tag")): - element = element.getroot() - if element.tag == "<!DOCTYPE>": - if element.get("publicId") or element.get("systemId"): - publicId = element.get("publicId") or "" - systemId = element.get("systemId") or "" - rv.append("""<!DOCTYPE %s "%s" "%s">""" % - (element.text, publicId, systemId)) - else: - rv.append("<!DOCTYPE %s>" % (element.text,)) - elif element.tag == "DOCUMENT_ROOT": - rv.append("#document") - if element.text is not None: - rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) - if element.tail is not None: - raise TypeError("Document node cannot have tail") - if hasattr(element, "attrib") and len(element.attrib): - raise TypeError("Document node cannot have attributes") - elif element.tag == ElementTreeCommentType: - rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) - else: - assert isinstance(element.tag, text_type), \ - "Expected unicode, got %s, %s" % (type(element.tag), element.tag) - nsmatch = tag_regexp.match(element.tag) - - if nsmatch is None: - name = element.tag - else: - ns, name = nsmatch.groups() - prefix = constants.prefixes[ns] - name = "%s %s" % (prefix, name) - rv.append("|%s<%s>" % (' ' * indent, name)) - - if hasattr(element, "attrib"): - attributes = [] - for name, value in element.attrib.items(): - nsmatch = tag_regexp.match(name) - if nsmatch is not None: - ns, name = nsmatch.groups() - prefix = constants.prefixes[ns] - attr_string = "%s %s" % (prefix, name) - else: - attr_string = name - attributes.append((attr_string, value)) - - for name, value in sorted(attributes): - rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) - if element.text: - rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) - indent += 2 - for child in element: - serializeElement(child, indent) - if element.tail: - rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) - serializeElement(element, 0) - - return "\n".join(rv) - - def tostring(element): # pylint:disable=unused-variable - """Serialize an element and its child nodes to a string""" - rv = [] - filter = _ihatexml.InfosetFilter() - - def serializeElement(element): - if isinstance(element, ElementTree.ElementTree): - element = element.getroot() - - if element.tag == "<!DOCTYPE>": - if element.get("publicId") or element.get("systemId"): - publicId = element.get("publicId") or "" - systemId = element.get("systemId") or "" - rv.append("""<!DOCTYPE %s PUBLIC "%s" "%s">""" % - (element.text, publicId, systemId)) - else: - rv.append("<!DOCTYPE %s>" % (element.text,)) - elif element.tag == "DOCUMENT_ROOT": - if element.text is not None: - rv.append(element.text) - if element.tail is not None: - raise TypeError("Document node cannot have tail") - if hasattr(element, "attrib") and len(element.attrib): - raise TypeError("Document node cannot have attributes") - - for child in element: - serializeElement(child) - - elif element.tag == ElementTreeCommentType: - rv.append("<!--%s-->" % (element.text,)) - else: - # This is assumed to be an ordinary element - if not element.attrib: - rv.append("<%s>" % (filter.fromXmlName(element.tag),)) - else: - attr = " ".join(["%s=\"%s\"" % ( - filter.fromXmlName(name), value) - for name, value in element.attrib.items()]) - rv.append("<%s %s>" % (element.tag, attr)) - if element.text: - rv.append(element.text) - - for child in element: - serializeElement(child) - - rv.append("</%s>" % (element.tag,)) - - if element.tail: - rv.append(element.tail) - - serializeElement(element) - - return "".join(rv) - - class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable - documentClass = Document - doctypeClass = DocumentType - elementClass = Element - commentClass = Comment - fragmentClass = DocumentFragment - implementation = ElementTreeImplementation - - def testSerializer(self, element): - return testSerializer(element) - - def getDocument(self): - if fullTree: - return self.document._element - else: - if self.defaultNamespace is not None: - return self.document._element.find( - "{%s}html" % self.defaultNamespace) - else: - return self.document._element.find("html") - - def getFragment(self): - return base.TreeBuilder.getFragment(self)._element - - return locals() - - -getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py deleted file mode 100644 index ca12a99..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py +++ /dev/null @@ -1,366 +0,0 @@ -"""Module for supporting the lxml.etree library. The idea here is to use as much -of the native library as possible, without using fragile hacks like custom element -names that break between releases. The downside of this is that we cannot represent -all possible trees; specifically the following are known to cause problems: - -Text or comments as siblings of the root element -Docypes with no name - -When any of these things occur, we emit a DataLossWarning -""" - -from __future__ import absolute_import, division, unicode_literals -# pylint:disable=protected-access - -import warnings -import re -import sys - -from . import base -from ..constants import DataLossWarning -from .. import constants -from . import etree as etree_builders -from .. import _ihatexml - -import lxml.etree as etree - - -fullTree = True -tag_regexp = re.compile("{([^}]*)}(.*)") - -comment_type = etree.Comment("asd").tag - - -class DocumentType(object): - def __init__(self, name, publicId, systemId): - self.name = name - self.publicId = publicId - self.systemId = systemId - - -class Document(object): - def __init__(self): - self._elementTree = None - self._childNodes = [] - - def appendChild(self, element): - self._elementTree.getroot().addnext(element._element) - - def _getChildNodes(self): - return self._childNodes - - childNodes = property(_getChildNodes) - - -def testSerializer(element): - rv = [] - infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) - - def serializeElement(element, indent=0): - if not hasattr(element, "tag"): - if hasattr(element, "getroot"): - # Full tree case - rv.append("#document") - if element.docinfo.internalDTD: - if not (element.docinfo.public_id or - element.docinfo.system_url): - dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name - else: - dtd_str = """<!DOCTYPE %s "%s" "%s">""" % ( - element.docinfo.root_name, - element.docinfo.public_id, - element.docinfo.system_url) - rv.append("|%s%s" % (' ' * (indent + 2), dtd_str)) - next_element = element.getroot() - while next_element.getprevious() is not None: - next_element = next_element.getprevious() - while next_element is not None: - serializeElement(next_element, indent + 2) - next_element = next_element.getnext() - elif isinstance(element, str) or isinstance(element, bytes): - # Text in a fragment - assert isinstance(element, str) or sys.version_info[0] == 2 - rv.append("|%s\"%s\"" % (' ' * indent, element)) - else: - # Fragment case - rv.append("#document-fragment") - for next_element in element: - serializeElement(next_element, indent + 2) - elif element.tag == comment_type: - rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) - if hasattr(element, "tail") and element.tail: - rv.append("|%s\"%s\"" % (' ' * indent, element.tail)) - else: - assert isinstance(element, etree._Element) - nsmatch = etree_builders.tag_regexp.match(element.tag) - if nsmatch is not None: - ns = nsmatch.group(1) - tag = nsmatch.group(2) - prefix = constants.prefixes[ns] - rv.append("|%s<%s %s>" % (' ' * indent, prefix, - infosetFilter.fromXmlName(tag))) - else: - rv.append("|%s<%s>" % (' ' * indent, - infosetFilter.fromXmlName(element.tag))) - - if hasattr(element, "attrib"): - attributes = [] - for name, value in element.attrib.items(): - nsmatch = tag_regexp.match(name) - if nsmatch is not None: - ns, name = nsmatch.groups() - name = infosetFilter.fromXmlName(name) - prefix = constants.prefixes[ns] - attr_string = "%s %s" % (prefix, name) - else: - attr_string = infosetFilter.fromXmlName(name) - attributes.append((attr_string, value)) - - for name, value in sorted(attributes): - rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) - - if element.text: - rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) - indent += 2 - for child in element: - serializeElement(child, indent) - if hasattr(element, "tail") and element.tail: - rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) - serializeElement(element, 0) - - return "\n".join(rv) - - -def tostring(element): - """Serialize an element and its child nodes to a string""" - rv = [] - - def serializeElement(element): - if not hasattr(element, "tag"): - if element.docinfo.internalDTD: - if element.docinfo.doctype: - dtd_str = element.docinfo.doctype - else: - dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name - rv.append(dtd_str) - serializeElement(element.getroot()) - - elif element.tag == comment_type: - rv.append("<!--%s-->" % (element.text,)) - - else: - # This is assumed to be an ordinary element - if not element.attrib: - rv.append("<%s>" % (element.tag,)) - else: - attr = " ".join(["%s=\"%s\"" % (name, value) - for name, value in element.attrib.items()]) - rv.append("<%s %s>" % (element.tag, attr)) - if element.text: - rv.append(element.text) - - for child in element: - serializeElement(child) - - rv.append("</%s>" % (element.tag,)) - - if hasattr(element, "tail") and element.tail: - rv.append(element.tail) - - serializeElement(element) - - return "".join(rv) - - -class TreeBuilder(base.TreeBuilder): - documentClass = Document - doctypeClass = DocumentType - elementClass = None - commentClass = None - fragmentClass = Document - implementation = etree - - def __init__(self, namespaceHTMLElements, fullTree=False): - builder = etree_builders.getETreeModule(etree, fullTree=fullTree) - infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) - self.namespaceHTMLElements = namespaceHTMLElements - - class Attributes(dict): - def __init__(self, element, value=None): - if value is None: - value = {} - self._element = element - dict.__init__(self, value) # pylint:disable=non-parent-init-called - for key, value in self.items(): - if isinstance(key, tuple): - name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) - else: - name = infosetFilter.coerceAttribute(key) - self._element._element.attrib[name] = value - - def __setitem__(self, key, value): - dict.__setitem__(self, key, value) - if isinstance(key, tuple): - name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) - else: - name = infosetFilter.coerceAttribute(key) - self._element._element.attrib[name] = value - - class Element(builder.Element): - def __init__(self, name, namespace): - name = infosetFilter.coerceElement(name) - builder.Element.__init__(self, name, namespace=namespace) - self._attributes = Attributes(self) - - def _setName(self, name): - self._name = infosetFilter.coerceElement(name) - self._element.tag = self._getETreeTag( - self._name, self._namespace) - - def _getName(self): - return infosetFilter.fromXmlName(self._name) - - name = property(_getName, _setName) - - def _getAttributes(self): - return self._attributes - - def _setAttributes(self, attributes): - self._attributes = Attributes(self, attributes) - - attributes = property(_getAttributes, _setAttributes) - - def insertText(self, data, insertBefore=None): - data = infosetFilter.coerceCharacters(data) - builder.Element.insertText(self, data, insertBefore) - - def appendChild(self, child): - builder.Element.appendChild(self, child) - - class Comment(builder.Comment): - def __init__(self, data): - data = infosetFilter.coerceComment(data) - builder.Comment.__init__(self, data) - - def _setData(self, data): - data = infosetFilter.coerceComment(data) - self._element.text = data - - def _getData(self): - return self._element.text - - data = property(_getData, _setData) - - self.elementClass = Element - self.commentClass = Comment - # self.fragmentClass = builder.DocumentFragment - base.TreeBuilder.__init__(self, namespaceHTMLElements) - - def reset(self): - base.TreeBuilder.reset(self) - self.insertComment = self.insertCommentInitial - self.initial_comments = [] - self.doctype = None - - def testSerializer(self, element): - return testSerializer(element) - - def getDocument(self): - if fullTree: - return self.document._elementTree - else: - return self.document._elementTree.getroot() - - def getFragment(self): - fragment = [] - element = self.openElements[0]._element - if element.text: - fragment.append(element.text) - fragment.extend(list(element)) - if element.tail: - fragment.append(element.tail) - return fragment - - def insertDoctype(self, token): - name = token["name"] - publicId = token["publicId"] - systemId = token["systemId"] - - if not name: - warnings.warn("lxml cannot represent empty doctype", DataLossWarning) - self.doctype = None - else: - coercedName = self.infosetFilter.coerceElement(name) - if coercedName != name: - warnings.warn("lxml cannot represent non-xml doctype", DataLossWarning) - - doctype = self.doctypeClass(coercedName, publicId, systemId) - self.doctype = doctype - - def insertCommentInitial(self, data, parent=None): - assert parent is None or parent is self.document - assert self.document._elementTree is None - self.initial_comments.append(data) - - def insertCommentMain(self, data, parent=None): - if (parent == self.document and - self.document._elementTree.getroot()[-1].tag == comment_type): - warnings.warn("lxml cannot represent adjacent comments beyond the root elements", DataLossWarning) - super(TreeBuilder, self).insertComment(data, parent) - - def insertRoot(self, token): - # Because of the way libxml2 works, it doesn't seem to be possible to - # alter information like the doctype after the tree has been parsed. - # Therefore we need to use the built-in parser to create our initial - # tree, after which we can add elements like normal - docStr = "" - if self.doctype: - assert self.doctype.name - docStr += "<!DOCTYPE %s" % self.doctype.name - if (self.doctype.publicId is not None or - self.doctype.systemId is not None): - docStr += (' PUBLIC "%s" ' % - (self.infosetFilter.coercePubid(self.doctype.publicId or ""))) - if self.doctype.systemId: - sysid = self.doctype.systemId - if sysid.find("'") >= 0 and sysid.find('"') >= 0: - warnings.warn("DOCTYPE system cannot contain single and double quotes", DataLossWarning) - sysid = sysid.replace("'", 'U00027') - if sysid.find("'") >= 0: - docStr += '"%s"' % sysid - else: - docStr += "'%s'" % sysid - else: - docStr += "''" - docStr += ">" - if self.doctype.name != token["name"]: - warnings.warn("lxml cannot represent doctype with a different name to the root element", DataLossWarning) - docStr += "<THIS_SHOULD_NEVER_APPEAR_PUBLICLY/>" - root = etree.fromstring(docStr) - - # Append the initial comments: - for comment_token in self.initial_comments: - comment = self.commentClass(comment_token["data"]) - root.addprevious(comment._element) - - # Create the root document and add the ElementTree to it - self.document = self.documentClass() - self.document._elementTree = root.getroottree() - - # Give the root element the right name - name = token["name"] - namespace = token.get("namespace", self.defaultNamespace) - if namespace is None: - etree_tag = name - else: - etree_tag = "{%s}%s" % (namespace, name) - root.tag = etree_tag - - # Add the root element to the internal child/open data structures - root_element = self.elementClass(name, namespace) - root_element._element = root - self.document._childNodes.append(root_element) - self.openElements.append(root_element) - - # Reset to the default insert comment function - self.insertComment = self.insertCommentMain diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/__init__.py deleted file mode 100644 index 9bec207..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/__init__.py +++ /dev/null @@ -1,154 +0,0 @@ -"""A collection of modules for iterating through different kinds of -tree, generating tokens identical to those produced by the tokenizer -module. - -To create a tree walker for a new type of tree, you need to do -implement a tree walker object (called TreeWalker by convention) that -implements a 'serialize' method taking a tree as sole argument and -returning an iterator generating tokens. -""" - -from __future__ import absolute_import, division, unicode_literals - -from .. import constants -from .._utils import default_etree - -__all__ = ["getTreeWalker", "pprint"] - -treeWalkerCache = {} - - -def getTreeWalker(treeType, implementation=None, **kwargs): - """Get a TreeWalker class for various types of tree with built-in support - - :arg str treeType: the name of the tree type required (case-insensitive). - Supported values are: - - * "dom": The xml.dom.minidom DOM implementation - * "etree": A generic walker for tree implementations exposing an - elementtree-like interface (known to work with ElementTree, - cElementTree and lxml.etree). - * "lxml": Optimized walker for lxml.etree - * "genshi": a Genshi stream - - :arg implementation: A module implementing the tree type e.g. - xml.etree.ElementTree or cElementTree (Currently applies to the "etree" - tree type only). - - :arg kwargs: keyword arguments passed to the etree walker--for other - walkers, this has no effect - - :returns: a TreeWalker class - - """ - - treeType = treeType.lower() - if treeType not in treeWalkerCache: - if treeType == "dom": - from . import dom - treeWalkerCache[treeType] = dom.TreeWalker - elif treeType == "genshi": - from . import genshi - treeWalkerCache[treeType] = genshi.TreeWalker - elif treeType == "lxml": - from . import etree_lxml - treeWalkerCache[treeType] = etree_lxml.TreeWalker - elif treeType == "etree": - from . import etree - if implementation is None: - implementation = default_etree - # XXX: NEVER cache here, caching is done in the etree submodule - return etree.getETreeModule(implementation, **kwargs).TreeWalker - return treeWalkerCache.get(treeType) - - -def concatenateCharacterTokens(tokens): - pendingCharacters = [] - for token in tokens: - type = token["type"] - if type in ("Characters", "SpaceCharacters"): - pendingCharacters.append(token["data"]) - else: - if pendingCharacters: - yield {"type": "Characters", "data": "".join(pendingCharacters)} - pendingCharacters = [] - yield token - if pendingCharacters: - yield {"type": "Characters", "data": "".join(pendingCharacters)} - - -def pprint(walker): - """Pretty printer for tree walkers - - Takes a TreeWalker instance and pretty prints the output of walking the tree. - - :arg walker: a TreeWalker instance - - """ - output = [] - indent = 0 - for token in concatenateCharacterTokens(walker): - type = token["type"] - if type in ("StartTag", "EmptyTag"): - # tag name - if token["namespace"] and token["namespace"] != constants.namespaces["html"]: - if token["namespace"] in constants.prefixes: - ns = constants.prefixes[token["namespace"]] - else: - ns = token["namespace"] - name = "%s %s" % (ns, token["name"]) - else: - name = token["name"] - output.append("%s<%s>" % (" " * indent, name)) - indent += 2 - # attributes (sorted for consistent ordering) - attrs = token["data"] - for (namespace, localname), value in sorted(attrs.items()): - if namespace: - if namespace in constants.prefixes: - ns = constants.prefixes[namespace] - else: - ns = namespace - name = "%s %s" % (ns, localname) - else: - name = localname - output.append("%s%s=\"%s\"" % (" " * indent, name, value)) - # self-closing - if type == "EmptyTag": - indent -= 2 - - elif type == "EndTag": - indent -= 2 - - elif type == "Comment": - output.append("%s<!-- %s -->" % (" " * indent, token["data"])) - - elif type == "Doctype": - if token["name"]: - if token["publicId"]: - output.append("""%s<!DOCTYPE %s "%s" "%s">""" % - (" " * indent, - token["name"], - token["publicId"], - token["systemId"] if token["systemId"] else "")) - elif token["systemId"]: - output.append("""%s<!DOCTYPE %s "" "%s">""" % - (" " * indent, - token["name"], - token["systemId"])) - else: - output.append("%s<!DOCTYPE %s>" % (" " * indent, - token["name"])) - else: - output.append("%s<!DOCTYPE >" % (" " * indent,)) - - elif type == "Characters": - output.append("%s\"%s\"" % (" " * indent, token["data"])) - - elif type == "SpaceCharacters": - assert False, "concatenateCharacterTokens should have got rid of all Space tokens" - - else: - raise ValueError("Unknown token type, %s" % type) - - return "\n".join(output) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/base.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/base.py deleted file mode 100644 index 80c474c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/base.py +++ /dev/null @@ -1,252 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from xml.dom import Node -from ..constants import namespaces, voidElements, spaceCharacters - -__all__ = ["DOCUMENT", "DOCTYPE", "TEXT", "ELEMENT", "COMMENT", "ENTITY", "UNKNOWN", - "TreeWalker", "NonRecursiveTreeWalker"] - -DOCUMENT = Node.DOCUMENT_NODE -DOCTYPE = Node.DOCUMENT_TYPE_NODE -TEXT = Node.TEXT_NODE -ELEMENT = Node.ELEMENT_NODE -COMMENT = Node.COMMENT_NODE -ENTITY = Node.ENTITY_NODE -UNKNOWN = "<#UNKNOWN#>" - -spaceCharacters = "".join(spaceCharacters) - - -class TreeWalker(object): - """Walks a tree yielding tokens - - Tokens are dicts that all have a ``type`` field specifying the type of the - token. - - """ - def __init__(self, tree): - """Creates a TreeWalker - - :arg tree: the tree to walk - - """ - self.tree = tree - - def __iter__(self): - raise NotImplementedError - - def error(self, msg): - """Generates an error token with the given message - - :arg msg: the error message - - :returns: SerializeError token - - """ - return {"type": "SerializeError", "data": msg} - - def emptyTag(self, namespace, name, attrs, hasChildren=False): - """Generates an EmptyTag token - - :arg namespace: the namespace of the token--can be ``None`` - - :arg name: the name of the element - - :arg attrs: the attributes of the element as a dict - - :arg hasChildren: whether or not to yield a SerializationError because - this tag shouldn't have children - - :returns: EmptyTag token - - """ - yield {"type": "EmptyTag", "name": name, - "namespace": namespace, - "data": attrs} - if hasChildren: - yield self.error("Void element has children") - - def startTag(self, namespace, name, attrs): - """Generates a StartTag token - - :arg namespace: the namespace of the token--can be ``None`` - - :arg name: the name of the element - - :arg attrs: the attributes of the element as a dict - - :returns: StartTag token - - """ - return {"type": "StartTag", - "name": name, - "namespace": namespace, - "data": attrs} - - def endTag(self, namespace, name): - """Generates an EndTag token - - :arg namespace: the namespace of the token--can be ``None`` - - :arg name: the name of the element - - :returns: EndTag token - - """ - return {"type": "EndTag", - "name": name, - "namespace": namespace} - - def text(self, data): - """Generates SpaceCharacters and Characters tokens - - Depending on what's in the data, this generates one or more - ``SpaceCharacters`` and ``Characters`` tokens. - - For example: - - >>> from html5lib.treewalkers.base import TreeWalker - >>> # Give it an empty tree just so it instantiates - >>> walker = TreeWalker([]) - >>> list(walker.text('')) - [] - >>> list(walker.text(' ')) - [{u'data': ' ', u'type': u'SpaceCharacters'}] - >>> list(walker.text(' abc ')) # doctest: +NORMALIZE_WHITESPACE - [{u'data': ' ', u'type': u'SpaceCharacters'}, - {u'data': u'abc', u'type': u'Characters'}, - {u'data': u' ', u'type': u'SpaceCharacters'}] - - :arg data: the text data - - :returns: one or more ``SpaceCharacters`` and ``Characters`` tokens - - """ - data = data - middle = data.lstrip(spaceCharacters) - left = data[:len(data) - len(middle)] - if left: - yield {"type": "SpaceCharacters", "data": left} - data = middle - middle = data.rstrip(spaceCharacters) - right = data[len(middle):] - if middle: - yield {"type": "Characters", "data": middle} - if right: - yield {"type": "SpaceCharacters", "data": right} - - def comment(self, data): - """Generates a Comment token - - :arg data: the comment - - :returns: Comment token - - """ - return {"type": "Comment", "data": data} - - def doctype(self, name, publicId=None, systemId=None): - """Generates a Doctype token - - :arg name: - - :arg publicId: - - :arg systemId: - - :returns: the Doctype token - - """ - return {"type": "Doctype", - "name": name, - "publicId": publicId, - "systemId": systemId} - - def entity(self, name): - """Generates an Entity token - - :arg name: the entity name - - :returns: an Entity token - - """ - return {"type": "Entity", "name": name} - - def unknown(self, nodeType): - """Handles unknown node types""" - return self.error("Unknown node type: " + nodeType) - - -class NonRecursiveTreeWalker(TreeWalker): - def getNodeDetails(self, node): - raise NotImplementedError - - def getFirstChild(self, node): - raise NotImplementedError - - def getNextSibling(self, node): - raise NotImplementedError - - def getParentNode(self, node): - raise NotImplementedError - - def __iter__(self): - currentNode = self.tree - while currentNode is not None: - details = self.getNodeDetails(currentNode) - type, details = details[0], details[1:] - hasChildren = False - - if type == DOCTYPE: - yield self.doctype(*details) - - elif type == TEXT: - for token in self.text(*details): - yield token - - elif type == ELEMENT: - namespace, name, attributes, hasChildren = details - if (not namespace or namespace == namespaces["html"]) and name in voidElements: - for token in self.emptyTag(namespace, name, attributes, - hasChildren): - yield token - hasChildren = False - else: - yield self.startTag(namespace, name, attributes) - - elif type == COMMENT: - yield self.comment(details[0]) - - elif type == ENTITY: - yield self.entity(details[0]) - - elif type == DOCUMENT: - hasChildren = True - - else: - yield self.unknown(details[0]) - - if hasChildren: - firstChild = self.getFirstChild(currentNode) - else: - firstChild = None - - if firstChild is not None: - currentNode = firstChild - else: - while currentNode is not None: - details = self.getNodeDetails(currentNode) - type, details = details[0], details[1:] - if type == ELEMENT: - namespace, name, attributes, hasChildren = details - if (namespace and namespace != namespaces["html"]) or name not in voidElements: - yield self.endTag(namespace, name) - if self.tree is currentNode: - currentNode = None - break - nextSibling = self.getNextSibling(currentNode) - if nextSibling is not None: - currentNode = nextSibling - break - else: - currentNode = self.getParentNode(currentNode) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/dom.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/dom.py deleted file mode 100644 index b0c89b0..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/dom.py +++ /dev/null @@ -1,43 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from xml.dom import Node - -from . import base - - -class TreeWalker(base.NonRecursiveTreeWalker): - def getNodeDetails(self, node): - if node.nodeType == Node.DOCUMENT_TYPE_NODE: - return base.DOCTYPE, node.name, node.publicId, node.systemId - - elif node.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): - return base.TEXT, node.nodeValue - - elif node.nodeType == Node.ELEMENT_NODE: - attrs = {} - for attr in list(node.attributes.keys()): - attr = node.getAttributeNode(attr) - if attr.namespaceURI: - attrs[(attr.namespaceURI, attr.localName)] = attr.value - else: - attrs[(None, attr.name)] = attr.value - return (base.ELEMENT, node.namespaceURI, node.nodeName, - attrs, node.hasChildNodes()) - - elif node.nodeType == Node.COMMENT_NODE: - return base.COMMENT, node.nodeValue - - elif node.nodeType in (Node.DOCUMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE): - return (base.DOCUMENT,) - - else: - return base.UNKNOWN, node.nodeType - - def getFirstChild(self, node): - return node.firstChild - - def getNextSibling(self, node): - return node.nextSibling - - def getParentNode(self, node): - return node.parentNode diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/etree.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/etree.py deleted file mode 100644 index 95fc0c1..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/etree.py +++ /dev/null @@ -1,130 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from collections import OrderedDict -import re - -from pip._vendor.six import string_types - -from . import base -from .._utils import moduleFactoryFactory - -tag_regexp = re.compile("{([^}]*)}(.*)") - - -def getETreeBuilder(ElementTreeImplementation): - ElementTree = ElementTreeImplementation - ElementTreeCommentType = ElementTree.Comment("asd").tag - - class TreeWalker(base.NonRecursiveTreeWalker): # pylint:disable=unused-variable - """Given the particular ElementTree representation, this implementation, - to avoid using recursion, returns "nodes" as tuples with the following - content: - - 1. The current element - - 2. The index of the element relative to its parent - - 3. A stack of ancestor elements - - 4. A flag "text", "tail" or None to indicate if the current node is a - text node; either the text or tail of the current element (1) - """ - def getNodeDetails(self, node): - if isinstance(node, tuple): # It might be the root Element - elt, _, _, flag = node - if flag in ("text", "tail"): - return base.TEXT, getattr(elt, flag) - else: - node = elt - - if not(hasattr(node, "tag")): - node = node.getroot() - - if node.tag in ("DOCUMENT_ROOT", "DOCUMENT_FRAGMENT"): - return (base.DOCUMENT,) - - elif node.tag == "<!DOCTYPE>": - return (base.DOCTYPE, node.text, - node.get("publicId"), node.get("systemId")) - - elif node.tag == ElementTreeCommentType: - return base.COMMENT, node.text - - else: - assert isinstance(node.tag, string_types), type(node.tag) - # This is assumed to be an ordinary element - match = tag_regexp.match(node.tag) - if match: - namespace, tag = match.groups() - else: - namespace = None - tag = node.tag - attrs = OrderedDict() - for name, value in list(node.attrib.items()): - match = tag_regexp.match(name) - if match: - attrs[(match.group(1), match.group(2))] = value - else: - attrs[(None, name)] = value - return (base.ELEMENT, namespace, tag, - attrs, len(node) or node.text) - - def getFirstChild(self, node): - if isinstance(node, tuple): - element, key, parents, flag = node - else: - element, key, parents, flag = node, None, [], None - - if flag in ("text", "tail"): - return None - else: - if element.text: - return element, key, parents, "text" - elif len(element): - parents.append(element) - return element[0], 0, parents, None - else: - return None - - def getNextSibling(self, node): - if isinstance(node, tuple): - element, key, parents, flag = node - else: - return None - - if flag == "text": - if len(element): - parents.append(element) - return element[0], 0, parents, None - else: - return None - else: - if element.tail and flag != "tail": - return element, key, parents, "tail" - elif key < len(parents[-1]) - 1: - return parents[-1][key + 1], key + 1, parents, None - else: - return None - - def getParentNode(self, node): - if isinstance(node, tuple): - element, key, parents, flag = node - else: - return None - - if flag == "text": - if not parents: - return element - else: - return element, key, parents, None - else: - parent = parents.pop() - if not parents: - return parent - else: - assert list(parents[-1]).count(parent) == 1 - return parent, list(parents[-1]).index(parent), parents, None - - return locals() - -getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py deleted file mode 100644 index e81ddf3..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py +++ /dev/null @@ -1,213 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals -from pip._vendor.six import text_type - -from lxml import etree -from ..treebuilders.etree import tag_regexp - -from . import base - -from .. import _ihatexml - - -def ensure_str(s): - if s is None: - return None - elif isinstance(s, text_type): - return s - else: - return s.decode("ascii", "strict") - - -class Root(object): - def __init__(self, et): - self.elementtree = et - self.children = [] - - try: - if et.docinfo.internalDTD: - self.children.append(Doctype(self, - ensure_str(et.docinfo.root_name), - ensure_str(et.docinfo.public_id), - ensure_str(et.docinfo.system_url))) - except AttributeError: - pass - - try: - node = et.getroot() - except AttributeError: - node = et - - while node.getprevious() is not None: - node = node.getprevious() - while node is not None: - self.children.append(node) - node = node.getnext() - - self.text = None - self.tail = None - - def __getitem__(self, key): - return self.children[key] - - def getnext(self): - return None - - def __len__(self): - return 1 - - -class Doctype(object): - def __init__(self, root_node, name, public_id, system_id): - self.root_node = root_node - self.name = name - self.public_id = public_id - self.system_id = system_id - - self.text = None - self.tail = None - - def getnext(self): - return self.root_node.children[1] - - -class FragmentRoot(Root): - def __init__(self, children): - self.children = [FragmentWrapper(self, child) for child in children] - self.text = self.tail = None - - def getnext(self): - return None - - -class FragmentWrapper(object): - def __init__(self, fragment_root, obj): - self.root_node = fragment_root - self.obj = obj - if hasattr(self.obj, 'text'): - self.text = ensure_str(self.obj.text) - else: - self.text = None - if hasattr(self.obj, 'tail'): - self.tail = ensure_str(self.obj.tail) - else: - self.tail = None - - def __getattr__(self, name): - return getattr(self.obj, name) - - def getnext(self): - siblings = self.root_node.children - idx = siblings.index(self) - if idx < len(siblings) - 1: - return siblings[idx + 1] - else: - return None - - def __getitem__(self, key): - return self.obj[key] - - def __bool__(self): - return bool(self.obj) - - def getparent(self): - return None - - def __str__(self): - return str(self.obj) - - def __unicode__(self): - return str(self.obj) - - def __len__(self): - return len(self.obj) - - -class TreeWalker(base.NonRecursiveTreeWalker): - def __init__(self, tree): - # pylint:disable=redefined-variable-type - if isinstance(tree, list): - self.fragmentChildren = set(tree) - tree = FragmentRoot(tree) - else: - self.fragmentChildren = set() - tree = Root(tree) - base.NonRecursiveTreeWalker.__init__(self, tree) - self.filter = _ihatexml.InfosetFilter() - - def getNodeDetails(self, node): - if isinstance(node, tuple): # Text node - node, key = node - assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key - return base.TEXT, ensure_str(getattr(node, key)) - - elif isinstance(node, Root): - return (base.DOCUMENT,) - - elif isinstance(node, Doctype): - return base.DOCTYPE, node.name, node.public_id, node.system_id - - elif isinstance(node, FragmentWrapper) and not hasattr(node, "tag"): - return base.TEXT, ensure_str(node.obj) - - elif node.tag == etree.Comment: - return base.COMMENT, ensure_str(node.text) - - elif node.tag == etree.Entity: - return base.ENTITY, ensure_str(node.text)[1:-1] # strip &; - - else: - # This is assumed to be an ordinary element - match = tag_regexp.match(ensure_str(node.tag)) - if match: - namespace, tag = match.groups() - else: - namespace = None - tag = ensure_str(node.tag) - attrs = {} - for name, value in list(node.attrib.items()): - name = ensure_str(name) - value = ensure_str(value) - match = tag_regexp.match(name) - if match: - attrs[(match.group(1), match.group(2))] = value - else: - attrs[(None, name)] = value - return (base.ELEMENT, namespace, self.filter.fromXmlName(tag), - attrs, len(node) > 0 or node.text) - - def getFirstChild(self, node): - assert not isinstance(node, tuple), "Text nodes have no children" - - assert len(node) or node.text, "Node has no children" - if node.text: - return (node, "text") - else: - return node[0] - - def getNextSibling(self, node): - if isinstance(node, tuple): # Text node - node, key = node - assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key - if key == "text": - # XXX: we cannot use a "bool(node) and node[0] or None" construct here - # because node[0] might evaluate to False if it has no child element - if len(node): - return node[0] - else: - return None - else: # tail - return node.getnext() - - return (node, "tail") if node.tail else node.getnext() - - def getParentNode(self, node): - if isinstance(node, tuple): # Text node - node, key = node - assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key - if key == "text": - return node - # else: fallback to "normal" processing - elif node in self.fragmentChildren: - return None - - return node.getparent() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/genshi.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/genshi.py deleted file mode 100644 index 7483be2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/html5lib/treewalkers/genshi.py +++ /dev/null @@ -1,69 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from genshi.core import QName -from genshi.core import START, END, XML_NAMESPACE, DOCTYPE, TEXT -from genshi.core import START_NS, END_NS, START_CDATA, END_CDATA, PI, COMMENT - -from . import base - -from ..constants import voidElements, namespaces - - -class TreeWalker(base.TreeWalker): - def __iter__(self): - # Buffer the events so we can pass in the following one - previous = None - for event in self.tree: - if previous is not None: - for token in self.tokens(previous, event): - yield token - previous = event - - # Don't forget the final event! - if previous is not None: - for token in self.tokens(previous, None): - yield token - - def tokens(self, event, next): - kind, data, _ = event - if kind == START: - tag, attribs = data - name = tag.localname - namespace = tag.namespace - converted_attribs = {} - for k, v in attribs: - if isinstance(k, QName): - converted_attribs[(k.namespace, k.localname)] = v - else: - converted_attribs[(None, k)] = v - - if namespace == namespaces["html"] and name in voidElements: - for token in self.emptyTag(namespace, name, converted_attribs, - not next or next[0] != END or - next[1] != tag): - yield token - else: - yield self.startTag(namespace, name, converted_attribs) - - elif kind == END: - name = data.localname - namespace = data.namespace - if namespace != namespaces["html"] or name not in voidElements: - yield self.endTag(namespace, name) - - elif kind == COMMENT: - yield self.comment(data) - - elif kind == TEXT: - for token in self.text(data): - yield token - - elif kind == DOCTYPE: - yield self.doctype(*data) - - elif kind in (XML_NAMESPACE, DOCTYPE, START_NS, END_NS, - START_CDATA, END_CDATA, PI): - pass - - else: - yield self.unknown(kind) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/__init__.py deleted file mode 100644 index 847bf93..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .package_data import __version__ -from .core import * diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/codec.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/codec.py deleted file mode 100644 index 98c65ea..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/codec.py +++ /dev/null @@ -1,118 +0,0 @@ -from .core import encode, decode, alabel, ulabel, IDNAError -import codecs -import re - -_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') - -class Codec(codecs.Codec): - - def encode(self, data, errors='strict'): - - if errors != 'strict': - raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) - - if not data: - return "", 0 - - return encode(data), len(data) - - def decode(self, data, errors='strict'): - - if errors != 'strict': - raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) - - if not data: - return u"", 0 - - return decode(data), len(data) - -class IncrementalEncoder(codecs.BufferedIncrementalEncoder): - def _buffer_encode(self, data, errors, final): - if errors != 'strict': - raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) - - if not data: - return ("", 0) - - labels = _unicode_dots_re.split(data) - trailing_dot = u'' - if labels: - if not labels[-1]: - trailing_dot = '.' - del labels[-1] - elif not final: - # Keep potentially unfinished label until the next call - del labels[-1] - if labels: - trailing_dot = '.' - - result = [] - size = 0 - for label in labels: - result.append(alabel(label)) - if size: - size += 1 - size += len(label) - - # Join with U+002E - result = ".".join(result) + trailing_dot - size += len(trailing_dot) - return (result, size) - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def _buffer_decode(self, data, errors, final): - if errors != 'strict': - raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) - - if not data: - return (u"", 0) - - # IDNA allows decoding to operate on Unicode strings, too. - if isinstance(data, unicode): - labels = _unicode_dots_re.split(data) - else: - # Must be ASCII string - data = str(data) - unicode(data, "ascii") - labels = data.split(".") - - trailing_dot = u'' - if labels: - if not labels[-1]: - trailing_dot = u'.' - del labels[-1] - elif not final: - # Keep potentially unfinished label until the next call - del labels[-1] - if labels: - trailing_dot = u'.' - - result = [] - size = 0 - for label in labels: - result.append(ulabel(label)) - if size: - size += 1 - size += len(label) - - result = u".".join(result) + trailing_dot - size += len(trailing_dot) - return (result, size) - - -class StreamWriter(Codec, codecs.StreamWriter): - pass - -class StreamReader(Codec, codecs.StreamReader): - pass - -def getregentry(): - return codecs.CodecInfo( - name='idna', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/compat.py deleted file mode 100644 index 4d47f33..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/compat.py +++ /dev/null @@ -1,12 +0,0 @@ -from .core import * -from .codec import * - -def ToASCII(label): - return encode(label) - -def ToUnicode(label): - return decode(label) - -def nameprep(s): - raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/core.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/core.py deleted file mode 100644 index 104624a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/core.py +++ /dev/null @@ -1,396 +0,0 @@ -from . import idnadata -import bisect -import unicodedata -import re -import sys -from .intranges import intranges_contain - -_virama_combining_class = 9 -_alabel_prefix = b'xn--' -_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') - -if sys.version_info[0] == 3: - unicode = str - unichr = chr - -class IDNAError(UnicodeError): - """ Base exception for all IDNA-encoding related problems """ - pass - - -class IDNABidiError(IDNAError): - """ Exception when bidirectional requirements are not satisfied """ - pass - - -class InvalidCodepoint(IDNAError): - """ Exception when a disallowed or unallocated codepoint is used """ - pass - - -class InvalidCodepointContext(IDNAError): - """ Exception when the codepoint is not valid in the context it is used """ - pass - - -def _combining_class(cp): - v = unicodedata.combining(unichr(cp)) - if v == 0: - if not unicodedata.name(unichr(cp)): - raise ValueError("Unknown character in unicodedata") - return v - -def _is_script(cp, script): - return intranges_contain(ord(cp), idnadata.scripts[script]) - -def _punycode(s): - return s.encode('punycode') - -def _unot(s): - return 'U+{0:04X}'.format(s) - - -def valid_label_length(label): - - if len(label) > 63: - return False - return True - - -def valid_string_length(label, trailing_dot): - - if len(label) > (254 if trailing_dot else 253): - return False - return True - - -def check_bidi(label, check_ltr=False): - - # Bidi rules should only be applied if string contains RTL characters - bidi_label = False - for (idx, cp) in enumerate(label, 1): - direction = unicodedata.bidirectional(cp) - if direction == '': - # String likely comes from a newer version of Unicode - raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx)) - if direction in ['R', 'AL', 'AN']: - bidi_label = True - if not bidi_label and not check_ltr: - return True - - # Bidi rule 1 - direction = unicodedata.bidirectional(label[0]) - if direction in ['R', 'AL']: - rtl = True - elif direction == 'L': - rtl = False - else: - raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label))) - - valid_ending = False - number_type = False - for (idx, cp) in enumerate(label, 1): - direction = unicodedata.bidirectional(cp) - - if rtl: - # Bidi rule 2 - if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: - raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx)) - # Bidi rule 3 - if direction in ['R', 'AL', 'EN', 'AN']: - valid_ending = True - elif direction != 'NSM': - valid_ending = False - # Bidi rule 4 - if direction in ['AN', 'EN']: - if not number_type: - number_type = direction - else: - if number_type != direction: - raise IDNABidiError('Can not mix numeral types in a right-to-left label') - else: - # Bidi rule 5 - if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: - raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx)) - # Bidi rule 6 - if direction in ['L', 'EN']: - valid_ending = True - elif direction != 'NSM': - valid_ending = False - - if not valid_ending: - raise IDNABidiError('Label ends with illegal codepoint directionality') - - return True - - -def check_initial_combiner(label): - - if unicodedata.category(label[0])[0] == 'M': - raise IDNAError('Label begins with an illegal combining character') - return True - - -def check_hyphen_ok(label): - - if label[2:4] == '--': - raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') - if label[0] == '-' or label[-1] == '-': - raise IDNAError('Label must not start or end with a hyphen') - return True - - -def check_nfc(label): - - if unicodedata.normalize('NFC', label) != label: - raise IDNAError('Label must be in Normalization Form C') - - -def valid_contextj(label, pos): - - cp_value = ord(label[pos]) - - if cp_value == 0x200c: - - if pos > 0: - if _combining_class(ord(label[pos - 1])) == _virama_combining_class: - return True - - ok = False - for i in range(pos-1, -1, -1): - joining_type = idnadata.joining_types.get(ord(label[i])) - if joining_type == ord('T'): - continue - if joining_type in [ord('L'), ord('D')]: - ok = True - break - - if not ok: - return False - - ok = False - for i in range(pos+1, len(label)): - joining_type = idnadata.joining_types.get(ord(label[i])) - if joining_type == ord('T'): - continue - if joining_type in [ord('R'), ord('D')]: - ok = True - break - return ok - - if cp_value == 0x200d: - - if pos > 0: - if _combining_class(ord(label[pos - 1])) == _virama_combining_class: - return True - return False - - else: - - return False - - -def valid_contexto(label, pos, exception=False): - - cp_value = ord(label[pos]) - - if cp_value == 0x00b7: - if 0 < pos < len(label)-1: - if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: - return True - return False - - elif cp_value == 0x0375: - if pos < len(label)-1 and len(label) > 1: - return _is_script(label[pos + 1], 'Greek') - return False - - elif cp_value == 0x05f3 or cp_value == 0x05f4: - if pos > 0: - return _is_script(label[pos - 1], 'Hebrew') - return False - - elif cp_value == 0x30fb: - for cp in label: - if cp == u'\u30fb': - continue - if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): - return True - return False - - elif 0x660 <= cp_value <= 0x669: - for cp in label: - if 0x6f0 <= ord(cp) <= 0x06f9: - return False - return True - - elif 0x6f0 <= cp_value <= 0x6f9: - for cp in label: - if 0x660 <= ord(cp) <= 0x0669: - return False - return True - - -def check_label(label): - - if isinstance(label, (bytes, bytearray)): - label = label.decode('utf-8') - if len(label) == 0: - raise IDNAError('Empty Label') - - check_nfc(label) - check_hyphen_ok(label) - check_initial_combiner(label) - - for (pos, cp) in enumerate(label): - cp_value = ord(cp) - if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): - continue - elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): - try: - if not valid_contextj(label, pos): - raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format( - _unot(cp_value), pos+1, repr(label))) - except ValueError: - raise IDNAError('Unknown codepoint adjacent to joiner {0} at position {1} in {2}'.format( - _unot(cp_value), pos+1, repr(label))) - elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): - if not valid_contexto(label, pos): - raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) - else: - raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) - - check_bidi(label) - - -def alabel(label): - - try: - label = label.encode('ascii') - ulabel(label) - if not valid_label_length(label): - raise IDNAError('Label too long') - return label - except UnicodeEncodeError: - pass - - if not label: - raise IDNAError('No Input') - - label = unicode(label) - check_label(label) - label = _punycode(label) - label = _alabel_prefix + label - - if not valid_label_length(label): - raise IDNAError('Label too long') - - return label - - -def ulabel(label): - - if not isinstance(label, (bytes, bytearray)): - try: - label = label.encode('ascii') - except UnicodeEncodeError: - check_label(label) - return label - - label = label.lower() - if label.startswith(_alabel_prefix): - label = label[len(_alabel_prefix):] - else: - check_label(label) - return label.decode('ascii') - - label = label.decode('punycode') - check_label(label) - return label - - -def uts46_remap(domain, std3_rules=True, transitional=False): - """Re-map the characters in the string according to UTS46 processing.""" - from .uts46data import uts46data - output = u"" - try: - for pos, char in enumerate(domain): - code_point = ord(char) - uts46row = uts46data[code_point if code_point < 256 else - bisect.bisect_left(uts46data, (code_point, "Z")) - 1] - status = uts46row[1] - replacement = uts46row[2] if len(uts46row) == 3 else None - if (status == "V" or - (status == "D" and not transitional) or - (status == "3" and not std3_rules and replacement is None)): - output += char - elif replacement is not None and (status == "M" or - (status == "3" and not std3_rules) or - (status == "D" and transitional)): - output += replacement - elif status != "I": - raise IndexError() - return unicodedata.normalize("NFC", output) - except IndexError: - raise InvalidCodepoint( - "Codepoint {0} not allowed at position {1} in {2}".format( - _unot(code_point), pos + 1, repr(domain))) - - -def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): - - if isinstance(s, (bytes, bytearray)): - s = s.decode("ascii") - if uts46: - s = uts46_remap(s, std3_rules, transitional) - trailing_dot = False - result = [] - if strict: - labels = s.split('.') - else: - labels = _unicode_dots_re.split(s) - if not labels or labels == ['']: - raise IDNAError('Empty domain') - if labels[-1] == '': - del labels[-1] - trailing_dot = True - for label in labels: - s = alabel(label) - if s: - result.append(s) - else: - raise IDNAError('Empty label') - if trailing_dot: - result.append(b'') - s = b'.'.join(result) - if not valid_string_length(s, trailing_dot): - raise IDNAError('Domain too long') - return s - - -def decode(s, strict=False, uts46=False, std3_rules=False): - - if isinstance(s, (bytes, bytearray)): - s = s.decode("ascii") - if uts46: - s = uts46_remap(s, std3_rules, False) - trailing_dot = False - result = [] - if not strict: - labels = _unicode_dots_re.split(s) - else: - labels = s.split(u'.') - if not labels or labels == ['']: - raise IDNAError('Empty domain') - if not labels[-1]: - del labels[-1] - trailing_dot = True - for label in labels: - s = ulabel(label) - if s: - result.append(s) - else: - raise IDNAError('Empty label') - if trailing_dot: - result.append(u'') - return u'.'.join(result) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/idnadata.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/idnadata.py deleted file mode 100644 index a80c959..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/idnadata.py +++ /dev/null @@ -1,1979 +0,0 @@ -# This file is automatically generated by tools/idna-data - -__version__ = "11.0.0" -scripts = { - 'Greek': ( - 0x37000000374, - 0x37500000378, - 0x37a0000037e, - 0x37f00000380, - 0x38400000385, - 0x38600000387, - 0x3880000038b, - 0x38c0000038d, - 0x38e000003a2, - 0x3a3000003e2, - 0x3f000000400, - 0x1d2600001d2b, - 0x1d5d00001d62, - 0x1d6600001d6b, - 0x1dbf00001dc0, - 0x1f0000001f16, - 0x1f1800001f1e, - 0x1f2000001f46, - 0x1f4800001f4e, - 0x1f5000001f58, - 0x1f5900001f5a, - 0x1f5b00001f5c, - 0x1f5d00001f5e, - 0x1f5f00001f7e, - 0x1f8000001fb5, - 0x1fb600001fc5, - 0x1fc600001fd4, - 0x1fd600001fdc, - 0x1fdd00001ff0, - 0x1ff200001ff5, - 0x1ff600001fff, - 0x212600002127, - 0xab650000ab66, - 0x101400001018f, - 0x101a0000101a1, - 0x1d2000001d246, - ), - 'Han': ( - 0x2e8000002e9a, - 0x2e9b00002ef4, - 0x2f0000002fd6, - 0x300500003006, - 0x300700003008, - 0x30210000302a, - 0x30380000303c, - 0x340000004db6, - 0x4e0000009ff0, - 0xf9000000fa6e, - 0xfa700000fada, - 0x200000002a6d7, - 0x2a7000002b735, - 0x2b7400002b81e, - 0x2b8200002cea2, - 0x2ceb00002ebe1, - 0x2f8000002fa1e, - ), - 'Hebrew': ( - 0x591000005c8, - 0x5d0000005eb, - 0x5ef000005f5, - 0xfb1d0000fb37, - 0xfb380000fb3d, - 0xfb3e0000fb3f, - 0xfb400000fb42, - 0xfb430000fb45, - 0xfb460000fb50, - ), - 'Hiragana': ( - 0x304100003097, - 0x309d000030a0, - 0x1b0010001b11f, - 0x1f2000001f201, - ), - 'Katakana': ( - 0x30a1000030fb, - 0x30fd00003100, - 0x31f000003200, - 0x32d0000032ff, - 0x330000003358, - 0xff660000ff70, - 0xff710000ff9e, - 0x1b0000001b001, - ), -} -joining_types = { - 0x600: 85, - 0x601: 85, - 0x602: 85, - 0x603: 85, - 0x604: 85, - 0x605: 85, - 0x608: 85, - 0x60b: 85, - 0x620: 68, - 0x621: 85, - 0x622: 82, - 0x623: 82, - 0x624: 82, - 0x625: 82, - 0x626: 68, - 0x627: 82, - 0x628: 68, - 0x629: 82, - 0x62a: 68, - 0x62b: 68, - 0x62c: 68, - 0x62d: 68, - 0x62e: 68, - 0x62f: 82, - 0x630: 82, - 0x631: 82, - 0x632: 82, - 0x633: 68, - 0x634: 68, - 0x635: 68, - 0x636: 68, - 0x637: 68, - 0x638: 68, - 0x639: 68, - 0x63a: 68, - 0x63b: 68, - 0x63c: 68, - 0x63d: 68, - 0x63e: 68, - 0x63f: 68, - 0x640: 67, - 0x641: 68, - 0x642: 68, - 0x643: 68, - 0x644: 68, - 0x645: 68, - 0x646: 68, - 0x647: 68, - 0x648: 82, - 0x649: 68, - 0x64a: 68, - 0x66e: 68, - 0x66f: 68, - 0x671: 82, - 0x672: 82, - 0x673: 82, - 0x674: 85, - 0x675: 82, - 0x676: 82, - 0x677: 82, - 0x678: 68, - 0x679: 68, - 0x67a: 68, - 0x67b: 68, - 0x67c: 68, - 0x67d: 68, - 0x67e: 68, - 0x67f: 68, - 0x680: 68, - 0x681: 68, - 0x682: 68, - 0x683: 68, - 0x684: 68, - 0x685: 68, - 0x686: 68, - 0x687: 68, - 0x688: 82, - 0x689: 82, - 0x68a: 82, - 0x68b: 82, - 0x68c: 82, - 0x68d: 82, - 0x68e: 82, - 0x68f: 82, - 0x690: 82, - 0x691: 82, - 0x692: 82, - 0x693: 82, - 0x694: 82, - 0x695: 82, - 0x696: 82, - 0x697: 82, - 0x698: 82, - 0x699: 82, - 0x69a: 68, - 0x69b: 68, - 0x69c: 68, - 0x69d: 68, - 0x69e: 68, - 0x69f: 68, - 0x6a0: 68, - 0x6a1: 68, - 0x6a2: 68, - 0x6a3: 68, - 0x6a4: 68, - 0x6a5: 68, - 0x6a6: 68, - 0x6a7: 68, - 0x6a8: 68, - 0x6a9: 68, - 0x6aa: 68, - 0x6ab: 68, - 0x6ac: 68, - 0x6ad: 68, - 0x6ae: 68, - 0x6af: 68, - 0x6b0: 68, - 0x6b1: 68, - 0x6b2: 68, - 0x6b3: 68, - 0x6b4: 68, - 0x6b5: 68, - 0x6b6: 68, - 0x6b7: 68, - 0x6b8: 68, - 0x6b9: 68, - 0x6ba: 68, - 0x6bb: 68, - 0x6bc: 68, - 0x6bd: 68, - 0x6be: 68, - 0x6bf: 68, - 0x6c0: 82, - 0x6c1: 68, - 0x6c2: 68, - 0x6c3: 82, - 0x6c4: 82, - 0x6c5: 82, - 0x6c6: 82, - 0x6c7: 82, - 0x6c8: 82, - 0x6c9: 82, - 0x6ca: 82, - 0x6cb: 82, - 0x6cc: 68, - 0x6cd: 82, - 0x6ce: 68, - 0x6cf: 82, - 0x6d0: 68, - 0x6d1: 68, - 0x6d2: 82, - 0x6d3: 82, - 0x6d5: 82, - 0x6dd: 85, - 0x6ee: 82, - 0x6ef: 82, - 0x6fa: 68, - 0x6fb: 68, - 0x6fc: 68, - 0x6ff: 68, - 0x70f: 84, - 0x710: 82, - 0x712: 68, - 0x713: 68, - 0x714: 68, - 0x715: 82, - 0x716: 82, - 0x717: 82, - 0x718: 82, - 0x719: 82, - 0x71a: 68, - 0x71b: 68, - 0x71c: 68, - 0x71d: 68, - 0x71e: 82, - 0x71f: 68, - 0x720: 68, - 0x721: 68, - 0x722: 68, - 0x723: 68, - 0x724: 68, - 0x725: 68, - 0x726: 68, - 0x727: 68, - 0x728: 82, - 0x729: 68, - 0x72a: 82, - 0x72b: 68, - 0x72c: 82, - 0x72d: 68, - 0x72e: 68, - 0x72f: 82, - 0x74d: 82, - 0x74e: 68, - 0x74f: 68, - 0x750: 68, - 0x751: 68, - 0x752: 68, - 0x753: 68, - 0x754: 68, - 0x755: 68, - 0x756: 68, - 0x757: 68, - 0x758: 68, - 0x759: 82, - 0x75a: 82, - 0x75b: 82, - 0x75c: 68, - 0x75d: 68, - 0x75e: 68, - 0x75f: 68, - 0x760: 68, - 0x761: 68, - 0x762: 68, - 0x763: 68, - 0x764: 68, - 0x765: 68, - 0x766: 68, - 0x767: 68, - 0x768: 68, - 0x769: 68, - 0x76a: 68, - 0x76b: 82, - 0x76c: 82, - 0x76d: 68, - 0x76e: 68, - 0x76f: 68, - 0x770: 68, - 0x771: 82, - 0x772: 68, - 0x773: 82, - 0x774: 82, - 0x775: 68, - 0x776: 68, - 0x777: 68, - 0x778: 82, - 0x779: 82, - 0x77a: 68, - 0x77b: 68, - 0x77c: 68, - 0x77d: 68, - 0x77e: 68, - 0x77f: 68, - 0x7ca: 68, - 0x7cb: 68, - 0x7cc: 68, - 0x7cd: 68, - 0x7ce: 68, - 0x7cf: 68, - 0x7d0: 68, - 0x7d1: 68, - 0x7d2: 68, - 0x7d3: 68, - 0x7d4: 68, - 0x7d5: 68, - 0x7d6: 68, - 0x7d7: 68, - 0x7d8: 68, - 0x7d9: 68, - 0x7da: 68, - 0x7db: 68, - 0x7dc: 68, - 0x7dd: 68, - 0x7de: 68, - 0x7df: 68, - 0x7e0: 68, - 0x7e1: 68, - 0x7e2: 68, - 0x7e3: 68, - 0x7e4: 68, - 0x7e5: 68, - 0x7e6: 68, - 0x7e7: 68, - 0x7e8: 68, - 0x7e9: 68, - 0x7ea: 68, - 0x7fa: 67, - 0x840: 82, - 0x841: 68, - 0x842: 68, - 0x843: 68, - 0x844: 68, - 0x845: 68, - 0x846: 82, - 0x847: 82, - 0x848: 68, - 0x849: 82, - 0x84a: 68, - 0x84b: 68, - 0x84c: 68, - 0x84d: 68, - 0x84e: 68, - 0x84f: 68, - 0x850: 68, - 0x851: 68, - 0x852: 68, - 0x853: 68, - 0x854: 82, - 0x855: 68, - 0x856: 85, - 0x857: 85, - 0x858: 85, - 0x860: 68, - 0x861: 85, - 0x862: 68, - 0x863: 68, - 0x864: 68, - 0x865: 68, - 0x866: 85, - 0x867: 82, - 0x868: 68, - 0x869: 82, - 0x86a: 82, - 0x8a0: 68, - 0x8a1: 68, - 0x8a2: 68, - 0x8a3: 68, - 0x8a4: 68, - 0x8a5: 68, - 0x8a6: 68, - 0x8a7: 68, - 0x8a8: 68, - 0x8a9: 68, - 0x8aa: 82, - 0x8ab: 82, - 0x8ac: 82, - 0x8ad: 85, - 0x8ae: 82, - 0x8af: 68, - 0x8b0: 68, - 0x8b1: 82, - 0x8b2: 82, - 0x8b3: 68, - 0x8b4: 68, - 0x8b6: 68, - 0x8b7: 68, - 0x8b8: 68, - 0x8b9: 82, - 0x8ba: 68, - 0x8bb: 68, - 0x8bc: 68, - 0x8bd: 68, - 0x8e2: 85, - 0x1806: 85, - 0x1807: 68, - 0x180a: 67, - 0x180e: 85, - 0x1820: 68, - 0x1821: 68, - 0x1822: 68, - 0x1823: 68, - 0x1824: 68, - 0x1825: 68, - 0x1826: 68, - 0x1827: 68, - 0x1828: 68, - 0x1829: 68, - 0x182a: 68, - 0x182b: 68, - 0x182c: 68, - 0x182d: 68, - 0x182e: 68, - 0x182f: 68, - 0x1830: 68, - 0x1831: 68, - 0x1832: 68, - 0x1833: 68, - 0x1834: 68, - 0x1835: 68, - 0x1836: 68, - 0x1837: 68, - 0x1838: 68, - 0x1839: 68, - 0x183a: 68, - 0x183b: 68, - 0x183c: 68, - 0x183d: 68, - 0x183e: 68, - 0x183f: 68, - 0x1840: 68, - 0x1841: 68, - 0x1842: 68, - 0x1843: 68, - 0x1844: 68, - 0x1845: 68, - 0x1846: 68, - 0x1847: 68, - 0x1848: 68, - 0x1849: 68, - 0x184a: 68, - 0x184b: 68, - 0x184c: 68, - 0x184d: 68, - 0x184e: 68, - 0x184f: 68, - 0x1850: 68, - 0x1851: 68, - 0x1852: 68, - 0x1853: 68, - 0x1854: 68, - 0x1855: 68, - 0x1856: 68, - 0x1857: 68, - 0x1858: 68, - 0x1859: 68, - 0x185a: 68, - 0x185b: 68, - 0x185c: 68, - 0x185d: 68, - 0x185e: 68, - 0x185f: 68, - 0x1860: 68, - 0x1861: 68, - 0x1862: 68, - 0x1863: 68, - 0x1864: 68, - 0x1865: 68, - 0x1866: 68, - 0x1867: 68, - 0x1868: 68, - 0x1869: 68, - 0x186a: 68, - 0x186b: 68, - 0x186c: 68, - 0x186d: 68, - 0x186e: 68, - 0x186f: 68, - 0x1870: 68, - 0x1871: 68, - 0x1872: 68, - 0x1873: 68, - 0x1874: 68, - 0x1875: 68, - 0x1876: 68, - 0x1877: 68, - 0x1878: 68, - 0x1880: 85, - 0x1881: 85, - 0x1882: 85, - 0x1883: 85, - 0x1884: 85, - 0x1885: 84, - 0x1886: 84, - 0x1887: 68, - 0x1888: 68, - 0x1889: 68, - 0x188a: 68, - 0x188b: 68, - 0x188c: 68, - 0x188d: 68, - 0x188e: 68, - 0x188f: 68, - 0x1890: 68, - 0x1891: 68, - 0x1892: 68, - 0x1893: 68, - 0x1894: 68, - 0x1895: 68, - 0x1896: 68, - 0x1897: 68, - 0x1898: 68, - 0x1899: 68, - 0x189a: 68, - 0x189b: 68, - 0x189c: 68, - 0x189d: 68, - 0x189e: 68, - 0x189f: 68, - 0x18a0: 68, - 0x18a1: 68, - 0x18a2: 68, - 0x18a3: 68, - 0x18a4: 68, - 0x18a5: 68, - 0x18a6: 68, - 0x18a7: 68, - 0x18a8: 68, - 0x18aa: 68, - 0x200c: 85, - 0x200d: 67, - 0x202f: 85, - 0x2066: 85, - 0x2067: 85, - 0x2068: 85, - 0x2069: 85, - 0xa840: 68, - 0xa841: 68, - 0xa842: 68, - 0xa843: 68, - 0xa844: 68, - 0xa845: 68, - 0xa846: 68, - 0xa847: 68, - 0xa848: 68, - 0xa849: 68, - 0xa84a: 68, - 0xa84b: 68, - 0xa84c: 68, - 0xa84d: 68, - 0xa84e: 68, - 0xa84f: 68, - 0xa850: 68, - 0xa851: 68, - 0xa852: 68, - 0xa853: 68, - 0xa854: 68, - 0xa855: 68, - 0xa856: 68, - 0xa857: 68, - 0xa858: 68, - 0xa859: 68, - 0xa85a: 68, - 0xa85b: 68, - 0xa85c: 68, - 0xa85d: 68, - 0xa85e: 68, - 0xa85f: 68, - 0xa860: 68, - 0xa861: 68, - 0xa862: 68, - 0xa863: 68, - 0xa864: 68, - 0xa865: 68, - 0xa866: 68, - 0xa867: 68, - 0xa868: 68, - 0xa869: 68, - 0xa86a: 68, - 0xa86b: 68, - 0xa86c: 68, - 0xa86d: 68, - 0xa86e: 68, - 0xa86f: 68, - 0xa870: 68, - 0xa871: 68, - 0xa872: 76, - 0xa873: 85, - 0x10ac0: 68, - 0x10ac1: 68, - 0x10ac2: 68, - 0x10ac3: 68, - 0x10ac4: 68, - 0x10ac5: 82, - 0x10ac6: 85, - 0x10ac7: 82, - 0x10ac8: 85, - 0x10ac9: 82, - 0x10aca: 82, - 0x10acb: 85, - 0x10acc: 85, - 0x10acd: 76, - 0x10ace: 82, - 0x10acf: 82, - 0x10ad0: 82, - 0x10ad1: 82, - 0x10ad2: 82, - 0x10ad3: 68, - 0x10ad4: 68, - 0x10ad5: 68, - 0x10ad6: 68, - 0x10ad7: 76, - 0x10ad8: 68, - 0x10ad9: 68, - 0x10ada: 68, - 0x10adb: 68, - 0x10adc: 68, - 0x10add: 82, - 0x10ade: 68, - 0x10adf: 68, - 0x10ae0: 68, - 0x10ae1: 82, - 0x10ae2: 85, - 0x10ae3: 85, - 0x10ae4: 82, - 0x10aeb: 68, - 0x10aec: 68, - 0x10aed: 68, - 0x10aee: 68, - 0x10aef: 82, - 0x10b80: 68, - 0x10b81: 82, - 0x10b82: 68, - 0x10b83: 82, - 0x10b84: 82, - 0x10b85: 82, - 0x10b86: 68, - 0x10b87: 68, - 0x10b88: 68, - 0x10b89: 82, - 0x10b8a: 68, - 0x10b8b: 68, - 0x10b8c: 82, - 0x10b8d: 68, - 0x10b8e: 82, - 0x10b8f: 82, - 0x10b90: 68, - 0x10b91: 82, - 0x10ba9: 82, - 0x10baa: 82, - 0x10bab: 82, - 0x10bac: 82, - 0x10bad: 68, - 0x10bae: 68, - 0x10baf: 85, - 0x10d00: 76, - 0x10d01: 68, - 0x10d02: 68, - 0x10d03: 68, - 0x10d04: 68, - 0x10d05: 68, - 0x10d06: 68, - 0x10d07: 68, - 0x10d08: 68, - 0x10d09: 68, - 0x10d0a: 68, - 0x10d0b: 68, - 0x10d0c: 68, - 0x10d0d: 68, - 0x10d0e: 68, - 0x10d0f: 68, - 0x10d10: 68, - 0x10d11: 68, - 0x10d12: 68, - 0x10d13: 68, - 0x10d14: 68, - 0x10d15: 68, - 0x10d16: 68, - 0x10d17: 68, - 0x10d18: 68, - 0x10d19: 68, - 0x10d1a: 68, - 0x10d1b: 68, - 0x10d1c: 68, - 0x10d1d: 68, - 0x10d1e: 68, - 0x10d1f: 68, - 0x10d20: 68, - 0x10d21: 68, - 0x10d22: 82, - 0x10d23: 68, - 0x10f30: 68, - 0x10f31: 68, - 0x10f32: 68, - 0x10f33: 82, - 0x10f34: 68, - 0x10f35: 68, - 0x10f36: 68, - 0x10f37: 68, - 0x10f38: 68, - 0x10f39: 68, - 0x10f3a: 68, - 0x10f3b: 68, - 0x10f3c: 68, - 0x10f3d: 68, - 0x10f3e: 68, - 0x10f3f: 68, - 0x10f40: 68, - 0x10f41: 68, - 0x10f42: 68, - 0x10f43: 68, - 0x10f44: 68, - 0x10f45: 85, - 0x10f51: 68, - 0x10f52: 68, - 0x10f53: 68, - 0x10f54: 82, - 0x110bd: 85, - 0x110cd: 85, - 0x1e900: 68, - 0x1e901: 68, - 0x1e902: 68, - 0x1e903: 68, - 0x1e904: 68, - 0x1e905: 68, - 0x1e906: 68, - 0x1e907: 68, - 0x1e908: 68, - 0x1e909: 68, - 0x1e90a: 68, - 0x1e90b: 68, - 0x1e90c: 68, - 0x1e90d: 68, - 0x1e90e: 68, - 0x1e90f: 68, - 0x1e910: 68, - 0x1e911: 68, - 0x1e912: 68, - 0x1e913: 68, - 0x1e914: 68, - 0x1e915: 68, - 0x1e916: 68, - 0x1e917: 68, - 0x1e918: 68, - 0x1e919: 68, - 0x1e91a: 68, - 0x1e91b: 68, - 0x1e91c: 68, - 0x1e91d: 68, - 0x1e91e: 68, - 0x1e91f: 68, - 0x1e920: 68, - 0x1e921: 68, - 0x1e922: 68, - 0x1e923: 68, - 0x1e924: 68, - 0x1e925: 68, - 0x1e926: 68, - 0x1e927: 68, - 0x1e928: 68, - 0x1e929: 68, - 0x1e92a: 68, - 0x1e92b: 68, - 0x1e92c: 68, - 0x1e92d: 68, - 0x1e92e: 68, - 0x1e92f: 68, - 0x1e930: 68, - 0x1e931: 68, - 0x1e932: 68, - 0x1e933: 68, - 0x1e934: 68, - 0x1e935: 68, - 0x1e936: 68, - 0x1e937: 68, - 0x1e938: 68, - 0x1e939: 68, - 0x1e93a: 68, - 0x1e93b: 68, - 0x1e93c: 68, - 0x1e93d: 68, - 0x1e93e: 68, - 0x1e93f: 68, - 0x1e940: 68, - 0x1e941: 68, - 0x1e942: 68, - 0x1e943: 68, -} -codepoint_classes = { - 'PVALID': ( - 0x2d0000002e, - 0x300000003a, - 0x610000007b, - 0xdf000000f7, - 0xf800000100, - 0x10100000102, - 0x10300000104, - 0x10500000106, - 0x10700000108, - 0x1090000010a, - 0x10b0000010c, - 0x10d0000010e, - 0x10f00000110, - 0x11100000112, - 0x11300000114, - 0x11500000116, - 0x11700000118, - 0x1190000011a, - 0x11b0000011c, - 0x11d0000011e, - 0x11f00000120, - 0x12100000122, - 0x12300000124, - 0x12500000126, - 0x12700000128, - 0x1290000012a, - 0x12b0000012c, - 0x12d0000012e, - 0x12f00000130, - 0x13100000132, - 0x13500000136, - 0x13700000139, - 0x13a0000013b, - 0x13c0000013d, - 0x13e0000013f, - 0x14200000143, - 0x14400000145, - 0x14600000147, - 0x14800000149, - 0x14b0000014c, - 0x14d0000014e, - 0x14f00000150, - 0x15100000152, - 0x15300000154, - 0x15500000156, - 0x15700000158, - 0x1590000015a, - 0x15b0000015c, - 0x15d0000015e, - 0x15f00000160, - 0x16100000162, - 0x16300000164, - 0x16500000166, - 0x16700000168, - 0x1690000016a, - 0x16b0000016c, - 0x16d0000016e, - 0x16f00000170, - 0x17100000172, - 0x17300000174, - 0x17500000176, - 0x17700000178, - 0x17a0000017b, - 0x17c0000017d, - 0x17e0000017f, - 0x18000000181, - 0x18300000184, - 0x18500000186, - 0x18800000189, - 0x18c0000018e, - 0x19200000193, - 0x19500000196, - 0x1990000019c, - 0x19e0000019f, - 0x1a1000001a2, - 0x1a3000001a4, - 0x1a5000001a6, - 0x1a8000001a9, - 0x1aa000001ac, - 0x1ad000001ae, - 0x1b0000001b1, - 0x1b4000001b5, - 0x1b6000001b7, - 0x1b9000001bc, - 0x1bd000001c4, - 0x1ce000001cf, - 0x1d0000001d1, - 0x1d2000001d3, - 0x1d4000001d5, - 0x1d6000001d7, - 0x1d8000001d9, - 0x1da000001db, - 0x1dc000001de, - 0x1df000001e0, - 0x1e1000001e2, - 0x1e3000001e4, - 0x1e5000001e6, - 0x1e7000001e8, - 0x1e9000001ea, - 0x1eb000001ec, - 0x1ed000001ee, - 0x1ef000001f1, - 0x1f5000001f6, - 0x1f9000001fa, - 0x1fb000001fc, - 0x1fd000001fe, - 0x1ff00000200, - 0x20100000202, - 0x20300000204, - 0x20500000206, - 0x20700000208, - 0x2090000020a, - 0x20b0000020c, - 0x20d0000020e, - 0x20f00000210, - 0x21100000212, - 0x21300000214, - 0x21500000216, - 0x21700000218, - 0x2190000021a, - 0x21b0000021c, - 0x21d0000021e, - 0x21f00000220, - 0x22100000222, - 0x22300000224, - 0x22500000226, - 0x22700000228, - 0x2290000022a, - 0x22b0000022c, - 0x22d0000022e, - 0x22f00000230, - 0x23100000232, - 0x2330000023a, - 0x23c0000023d, - 0x23f00000241, - 0x24200000243, - 0x24700000248, - 0x2490000024a, - 0x24b0000024c, - 0x24d0000024e, - 0x24f000002b0, - 0x2b9000002c2, - 0x2c6000002d2, - 0x2ec000002ed, - 0x2ee000002ef, - 0x30000000340, - 0x34200000343, - 0x3460000034f, - 0x35000000370, - 0x37100000372, - 0x37300000374, - 0x37700000378, - 0x37b0000037e, - 0x39000000391, - 0x3ac000003cf, - 0x3d7000003d8, - 0x3d9000003da, - 0x3db000003dc, - 0x3dd000003de, - 0x3df000003e0, - 0x3e1000003e2, - 0x3e3000003e4, - 0x3e5000003e6, - 0x3e7000003e8, - 0x3e9000003ea, - 0x3eb000003ec, - 0x3ed000003ee, - 0x3ef000003f0, - 0x3f3000003f4, - 0x3f8000003f9, - 0x3fb000003fd, - 0x43000000460, - 0x46100000462, - 0x46300000464, - 0x46500000466, - 0x46700000468, - 0x4690000046a, - 0x46b0000046c, - 0x46d0000046e, - 0x46f00000470, - 0x47100000472, - 0x47300000474, - 0x47500000476, - 0x47700000478, - 0x4790000047a, - 0x47b0000047c, - 0x47d0000047e, - 0x47f00000480, - 0x48100000482, - 0x48300000488, - 0x48b0000048c, - 0x48d0000048e, - 0x48f00000490, - 0x49100000492, - 0x49300000494, - 0x49500000496, - 0x49700000498, - 0x4990000049a, - 0x49b0000049c, - 0x49d0000049e, - 0x49f000004a0, - 0x4a1000004a2, - 0x4a3000004a4, - 0x4a5000004a6, - 0x4a7000004a8, - 0x4a9000004aa, - 0x4ab000004ac, - 0x4ad000004ae, - 0x4af000004b0, - 0x4b1000004b2, - 0x4b3000004b4, - 0x4b5000004b6, - 0x4b7000004b8, - 0x4b9000004ba, - 0x4bb000004bc, - 0x4bd000004be, - 0x4bf000004c0, - 0x4c2000004c3, - 0x4c4000004c5, - 0x4c6000004c7, - 0x4c8000004c9, - 0x4ca000004cb, - 0x4cc000004cd, - 0x4ce000004d0, - 0x4d1000004d2, - 0x4d3000004d4, - 0x4d5000004d6, - 0x4d7000004d8, - 0x4d9000004da, - 0x4db000004dc, - 0x4dd000004de, - 0x4df000004e0, - 0x4e1000004e2, - 0x4e3000004e4, - 0x4e5000004e6, - 0x4e7000004e8, - 0x4e9000004ea, - 0x4eb000004ec, - 0x4ed000004ee, - 0x4ef000004f0, - 0x4f1000004f2, - 0x4f3000004f4, - 0x4f5000004f6, - 0x4f7000004f8, - 0x4f9000004fa, - 0x4fb000004fc, - 0x4fd000004fe, - 0x4ff00000500, - 0x50100000502, - 0x50300000504, - 0x50500000506, - 0x50700000508, - 0x5090000050a, - 0x50b0000050c, - 0x50d0000050e, - 0x50f00000510, - 0x51100000512, - 0x51300000514, - 0x51500000516, - 0x51700000518, - 0x5190000051a, - 0x51b0000051c, - 0x51d0000051e, - 0x51f00000520, - 0x52100000522, - 0x52300000524, - 0x52500000526, - 0x52700000528, - 0x5290000052a, - 0x52b0000052c, - 0x52d0000052e, - 0x52f00000530, - 0x5590000055a, - 0x56000000587, - 0x58800000589, - 0x591000005be, - 0x5bf000005c0, - 0x5c1000005c3, - 0x5c4000005c6, - 0x5c7000005c8, - 0x5d0000005eb, - 0x5ef000005f3, - 0x6100000061b, - 0x62000000640, - 0x64100000660, - 0x66e00000675, - 0x679000006d4, - 0x6d5000006dd, - 0x6df000006e9, - 0x6ea000006f0, - 0x6fa00000700, - 0x7100000074b, - 0x74d000007b2, - 0x7c0000007f6, - 0x7fd000007fe, - 0x8000000082e, - 0x8400000085c, - 0x8600000086b, - 0x8a0000008b5, - 0x8b6000008be, - 0x8d3000008e2, - 0x8e300000958, - 0x96000000964, - 0x96600000970, - 0x97100000984, - 0x9850000098d, - 0x98f00000991, - 0x993000009a9, - 0x9aa000009b1, - 0x9b2000009b3, - 0x9b6000009ba, - 0x9bc000009c5, - 0x9c7000009c9, - 0x9cb000009cf, - 0x9d7000009d8, - 0x9e0000009e4, - 0x9e6000009f2, - 0x9fc000009fd, - 0x9fe000009ff, - 0xa0100000a04, - 0xa0500000a0b, - 0xa0f00000a11, - 0xa1300000a29, - 0xa2a00000a31, - 0xa3200000a33, - 0xa3500000a36, - 0xa3800000a3a, - 0xa3c00000a3d, - 0xa3e00000a43, - 0xa4700000a49, - 0xa4b00000a4e, - 0xa5100000a52, - 0xa5c00000a5d, - 0xa6600000a76, - 0xa8100000a84, - 0xa8500000a8e, - 0xa8f00000a92, - 0xa9300000aa9, - 0xaaa00000ab1, - 0xab200000ab4, - 0xab500000aba, - 0xabc00000ac6, - 0xac700000aca, - 0xacb00000ace, - 0xad000000ad1, - 0xae000000ae4, - 0xae600000af0, - 0xaf900000b00, - 0xb0100000b04, - 0xb0500000b0d, - 0xb0f00000b11, - 0xb1300000b29, - 0xb2a00000b31, - 0xb3200000b34, - 0xb3500000b3a, - 0xb3c00000b45, - 0xb4700000b49, - 0xb4b00000b4e, - 0xb5600000b58, - 0xb5f00000b64, - 0xb6600000b70, - 0xb7100000b72, - 0xb8200000b84, - 0xb8500000b8b, - 0xb8e00000b91, - 0xb9200000b96, - 0xb9900000b9b, - 0xb9c00000b9d, - 0xb9e00000ba0, - 0xba300000ba5, - 0xba800000bab, - 0xbae00000bba, - 0xbbe00000bc3, - 0xbc600000bc9, - 0xbca00000bce, - 0xbd000000bd1, - 0xbd700000bd8, - 0xbe600000bf0, - 0xc0000000c0d, - 0xc0e00000c11, - 0xc1200000c29, - 0xc2a00000c3a, - 0xc3d00000c45, - 0xc4600000c49, - 0xc4a00000c4e, - 0xc5500000c57, - 0xc5800000c5b, - 0xc6000000c64, - 0xc6600000c70, - 0xc8000000c84, - 0xc8500000c8d, - 0xc8e00000c91, - 0xc9200000ca9, - 0xcaa00000cb4, - 0xcb500000cba, - 0xcbc00000cc5, - 0xcc600000cc9, - 0xcca00000cce, - 0xcd500000cd7, - 0xcde00000cdf, - 0xce000000ce4, - 0xce600000cf0, - 0xcf100000cf3, - 0xd0000000d04, - 0xd0500000d0d, - 0xd0e00000d11, - 0xd1200000d45, - 0xd4600000d49, - 0xd4a00000d4f, - 0xd5400000d58, - 0xd5f00000d64, - 0xd6600000d70, - 0xd7a00000d80, - 0xd8200000d84, - 0xd8500000d97, - 0xd9a00000db2, - 0xdb300000dbc, - 0xdbd00000dbe, - 0xdc000000dc7, - 0xdca00000dcb, - 0xdcf00000dd5, - 0xdd600000dd7, - 0xdd800000de0, - 0xde600000df0, - 0xdf200000df4, - 0xe0100000e33, - 0xe3400000e3b, - 0xe4000000e4f, - 0xe5000000e5a, - 0xe8100000e83, - 0xe8400000e85, - 0xe8700000e89, - 0xe8a00000e8b, - 0xe8d00000e8e, - 0xe9400000e98, - 0xe9900000ea0, - 0xea100000ea4, - 0xea500000ea6, - 0xea700000ea8, - 0xeaa00000eac, - 0xead00000eb3, - 0xeb400000eba, - 0xebb00000ebe, - 0xec000000ec5, - 0xec600000ec7, - 0xec800000ece, - 0xed000000eda, - 0xede00000ee0, - 0xf0000000f01, - 0xf0b00000f0c, - 0xf1800000f1a, - 0xf2000000f2a, - 0xf3500000f36, - 0xf3700000f38, - 0xf3900000f3a, - 0xf3e00000f43, - 0xf4400000f48, - 0xf4900000f4d, - 0xf4e00000f52, - 0xf5300000f57, - 0xf5800000f5c, - 0xf5d00000f69, - 0xf6a00000f6d, - 0xf7100000f73, - 0xf7400000f75, - 0xf7a00000f81, - 0xf8200000f85, - 0xf8600000f93, - 0xf9400000f98, - 0xf9900000f9d, - 0xf9e00000fa2, - 0xfa300000fa7, - 0xfa800000fac, - 0xfad00000fb9, - 0xfba00000fbd, - 0xfc600000fc7, - 0x10000000104a, - 0x10500000109e, - 0x10d0000010fb, - 0x10fd00001100, - 0x120000001249, - 0x124a0000124e, - 0x125000001257, - 0x125800001259, - 0x125a0000125e, - 0x126000001289, - 0x128a0000128e, - 0x1290000012b1, - 0x12b2000012b6, - 0x12b8000012bf, - 0x12c0000012c1, - 0x12c2000012c6, - 0x12c8000012d7, - 0x12d800001311, - 0x131200001316, - 0x13180000135b, - 0x135d00001360, - 0x138000001390, - 0x13a0000013f6, - 0x14010000166d, - 0x166f00001680, - 0x16810000169b, - 0x16a0000016eb, - 0x16f1000016f9, - 0x17000000170d, - 0x170e00001715, - 0x172000001735, - 0x174000001754, - 0x17600000176d, - 0x176e00001771, - 0x177200001774, - 0x1780000017b4, - 0x17b6000017d4, - 0x17d7000017d8, - 0x17dc000017de, - 0x17e0000017ea, - 0x18100000181a, - 0x182000001879, - 0x1880000018ab, - 0x18b0000018f6, - 0x19000000191f, - 0x19200000192c, - 0x19300000193c, - 0x19460000196e, - 0x197000001975, - 0x1980000019ac, - 0x19b0000019ca, - 0x19d0000019da, - 0x1a0000001a1c, - 0x1a2000001a5f, - 0x1a6000001a7d, - 0x1a7f00001a8a, - 0x1a9000001a9a, - 0x1aa700001aa8, - 0x1ab000001abe, - 0x1b0000001b4c, - 0x1b5000001b5a, - 0x1b6b00001b74, - 0x1b8000001bf4, - 0x1c0000001c38, - 0x1c4000001c4a, - 0x1c4d00001c7e, - 0x1cd000001cd3, - 0x1cd400001cfa, - 0x1d0000001d2c, - 0x1d2f00001d30, - 0x1d3b00001d3c, - 0x1d4e00001d4f, - 0x1d6b00001d78, - 0x1d7900001d9b, - 0x1dc000001dfa, - 0x1dfb00001e00, - 0x1e0100001e02, - 0x1e0300001e04, - 0x1e0500001e06, - 0x1e0700001e08, - 0x1e0900001e0a, - 0x1e0b00001e0c, - 0x1e0d00001e0e, - 0x1e0f00001e10, - 0x1e1100001e12, - 0x1e1300001e14, - 0x1e1500001e16, - 0x1e1700001e18, - 0x1e1900001e1a, - 0x1e1b00001e1c, - 0x1e1d00001e1e, - 0x1e1f00001e20, - 0x1e2100001e22, - 0x1e2300001e24, - 0x1e2500001e26, - 0x1e2700001e28, - 0x1e2900001e2a, - 0x1e2b00001e2c, - 0x1e2d00001e2e, - 0x1e2f00001e30, - 0x1e3100001e32, - 0x1e3300001e34, - 0x1e3500001e36, - 0x1e3700001e38, - 0x1e3900001e3a, - 0x1e3b00001e3c, - 0x1e3d00001e3e, - 0x1e3f00001e40, - 0x1e4100001e42, - 0x1e4300001e44, - 0x1e4500001e46, - 0x1e4700001e48, - 0x1e4900001e4a, - 0x1e4b00001e4c, - 0x1e4d00001e4e, - 0x1e4f00001e50, - 0x1e5100001e52, - 0x1e5300001e54, - 0x1e5500001e56, - 0x1e5700001e58, - 0x1e5900001e5a, - 0x1e5b00001e5c, - 0x1e5d00001e5e, - 0x1e5f00001e60, - 0x1e6100001e62, - 0x1e6300001e64, - 0x1e6500001e66, - 0x1e6700001e68, - 0x1e6900001e6a, - 0x1e6b00001e6c, - 0x1e6d00001e6e, - 0x1e6f00001e70, - 0x1e7100001e72, - 0x1e7300001e74, - 0x1e7500001e76, - 0x1e7700001e78, - 0x1e7900001e7a, - 0x1e7b00001e7c, - 0x1e7d00001e7e, - 0x1e7f00001e80, - 0x1e8100001e82, - 0x1e8300001e84, - 0x1e8500001e86, - 0x1e8700001e88, - 0x1e8900001e8a, - 0x1e8b00001e8c, - 0x1e8d00001e8e, - 0x1e8f00001e90, - 0x1e9100001e92, - 0x1e9300001e94, - 0x1e9500001e9a, - 0x1e9c00001e9e, - 0x1e9f00001ea0, - 0x1ea100001ea2, - 0x1ea300001ea4, - 0x1ea500001ea6, - 0x1ea700001ea8, - 0x1ea900001eaa, - 0x1eab00001eac, - 0x1ead00001eae, - 0x1eaf00001eb0, - 0x1eb100001eb2, - 0x1eb300001eb4, - 0x1eb500001eb6, - 0x1eb700001eb8, - 0x1eb900001eba, - 0x1ebb00001ebc, - 0x1ebd00001ebe, - 0x1ebf00001ec0, - 0x1ec100001ec2, - 0x1ec300001ec4, - 0x1ec500001ec6, - 0x1ec700001ec8, - 0x1ec900001eca, - 0x1ecb00001ecc, - 0x1ecd00001ece, - 0x1ecf00001ed0, - 0x1ed100001ed2, - 0x1ed300001ed4, - 0x1ed500001ed6, - 0x1ed700001ed8, - 0x1ed900001eda, - 0x1edb00001edc, - 0x1edd00001ede, - 0x1edf00001ee0, - 0x1ee100001ee2, - 0x1ee300001ee4, - 0x1ee500001ee6, - 0x1ee700001ee8, - 0x1ee900001eea, - 0x1eeb00001eec, - 0x1eed00001eee, - 0x1eef00001ef0, - 0x1ef100001ef2, - 0x1ef300001ef4, - 0x1ef500001ef6, - 0x1ef700001ef8, - 0x1ef900001efa, - 0x1efb00001efc, - 0x1efd00001efe, - 0x1eff00001f08, - 0x1f1000001f16, - 0x1f2000001f28, - 0x1f3000001f38, - 0x1f4000001f46, - 0x1f5000001f58, - 0x1f6000001f68, - 0x1f7000001f71, - 0x1f7200001f73, - 0x1f7400001f75, - 0x1f7600001f77, - 0x1f7800001f79, - 0x1f7a00001f7b, - 0x1f7c00001f7d, - 0x1fb000001fb2, - 0x1fb600001fb7, - 0x1fc600001fc7, - 0x1fd000001fd3, - 0x1fd600001fd8, - 0x1fe000001fe3, - 0x1fe400001fe8, - 0x1ff600001ff7, - 0x214e0000214f, - 0x218400002185, - 0x2c3000002c5f, - 0x2c6100002c62, - 0x2c6500002c67, - 0x2c6800002c69, - 0x2c6a00002c6b, - 0x2c6c00002c6d, - 0x2c7100002c72, - 0x2c7300002c75, - 0x2c7600002c7c, - 0x2c8100002c82, - 0x2c8300002c84, - 0x2c8500002c86, - 0x2c8700002c88, - 0x2c8900002c8a, - 0x2c8b00002c8c, - 0x2c8d00002c8e, - 0x2c8f00002c90, - 0x2c9100002c92, - 0x2c9300002c94, - 0x2c9500002c96, - 0x2c9700002c98, - 0x2c9900002c9a, - 0x2c9b00002c9c, - 0x2c9d00002c9e, - 0x2c9f00002ca0, - 0x2ca100002ca2, - 0x2ca300002ca4, - 0x2ca500002ca6, - 0x2ca700002ca8, - 0x2ca900002caa, - 0x2cab00002cac, - 0x2cad00002cae, - 0x2caf00002cb0, - 0x2cb100002cb2, - 0x2cb300002cb4, - 0x2cb500002cb6, - 0x2cb700002cb8, - 0x2cb900002cba, - 0x2cbb00002cbc, - 0x2cbd00002cbe, - 0x2cbf00002cc0, - 0x2cc100002cc2, - 0x2cc300002cc4, - 0x2cc500002cc6, - 0x2cc700002cc8, - 0x2cc900002cca, - 0x2ccb00002ccc, - 0x2ccd00002cce, - 0x2ccf00002cd0, - 0x2cd100002cd2, - 0x2cd300002cd4, - 0x2cd500002cd6, - 0x2cd700002cd8, - 0x2cd900002cda, - 0x2cdb00002cdc, - 0x2cdd00002cde, - 0x2cdf00002ce0, - 0x2ce100002ce2, - 0x2ce300002ce5, - 0x2cec00002ced, - 0x2cee00002cf2, - 0x2cf300002cf4, - 0x2d0000002d26, - 0x2d2700002d28, - 0x2d2d00002d2e, - 0x2d3000002d68, - 0x2d7f00002d97, - 0x2da000002da7, - 0x2da800002daf, - 0x2db000002db7, - 0x2db800002dbf, - 0x2dc000002dc7, - 0x2dc800002dcf, - 0x2dd000002dd7, - 0x2dd800002ddf, - 0x2de000002e00, - 0x2e2f00002e30, - 0x300500003008, - 0x302a0000302e, - 0x303c0000303d, - 0x304100003097, - 0x30990000309b, - 0x309d0000309f, - 0x30a1000030fb, - 0x30fc000030ff, - 0x310500003130, - 0x31a0000031bb, - 0x31f000003200, - 0x340000004db6, - 0x4e0000009ff0, - 0xa0000000a48d, - 0xa4d00000a4fe, - 0xa5000000a60d, - 0xa6100000a62c, - 0xa6410000a642, - 0xa6430000a644, - 0xa6450000a646, - 0xa6470000a648, - 0xa6490000a64a, - 0xa64b0000a64c, - 0xa64d0000a64e, - 0xa64f0000a650, - 0xa6510000a652, - 0xa6530000a654, - 0xa6550000a656, - 0xa6570000a658, - 0xa6590000a65a, - 0xa65b0000a65c, - 0xa65d0000a65e, - 0xa65f0000a660, - 0xa6610000a662, - 0xa6630000a664, - 0xa6650000a666, - 0xa6670000a668, - 0xa6690000a66a, - 0xa66b0000a66c, - 0xa66d0000a670, - 0xa6740000a67e, - 0xa67f0000a680, - 0xa6810000a682, - 0xa6830000a684, - 0xa6850000a686, - 0xa6870000a688, - 0xa6890000a68a, - 0xa68b0000a68c, - 0xa68d0000a68e, - 0xa68f0000a690, - 0xa6910000a692, - 0xa6930000a694, - 0xa6950000a696, - 0xa6970000a698, - 0xa6990000a69a, - 0xa69b0000a69c, - 0xa69e0000a6e6, - 0xa6f00000a6f2, - 0xa7170000a720, - 0xa7230000a724, - 0xa7250000a726, - 0xa7270000a728, - 0xa7290000a72a, - 0xa72b0000a72c, - 0xa72d0000a72e, - 0xa72f0000a732, - 0xa7330000a734, - 0xa7350000a736, - 0xa7370000a738, - 0xa7390000a73a, - 0xa73b0000a73c, - 0xa73d0000a73e, - 0xa73f0000a740, - 0xa7410000a742, - 0xa7430000a744, - 0xa7450000a746, - 0xa7470000a748, - 0xa7490000a74a, - 0xa74b0000a74c, - 0xa74d0000a74e, - 0xa74f0000a750, - 0xa7510000a752, - 0xa7530000a754, - 0xa7550000a756, - 0xa7570000a758, - 0xa7590000a75a, - 0xa75b0000a75c, - 0xa75d0000a75e, - 0xa75f0000a760, - 0xa7610000a762, - 0xa7630000a764, - 0xa7650000a766, - 0xa7670000a768, - 0xa7690000a76a, - 0xa76b0000a76c, - 0xa76d0000a76e, - 0xa76f0000a770, - 0xa7710000a779, - 0xa77a0000a77b, - 0xa77c0000a77d, - 0xa77f0000a780, - 0xa7810000a782, - 0xa7830000a784, - 0xa7850000a786, - 0xa7870000a789, - 0xa78c0000a78d, - 0xa78e0000a790, - 0xa7910000a792, - 0xa7930000a796, - 0xa7970000a798, - 0xa7990000a79a, - 0xa79b0000a79c, - 0xa79d0000a79e, - 0xa79f0000a7a0, - 0xa7a10000a7a2, - 0xa7a30000a7a4, - 0xa7a50000a7a6, - 0xa7a70000a7a8, - 0xa7a90000a7aa, - 0xa7af0000a7b0, - 0xa7b50000a7b6, - 0xa7b70000a7b8, - 0xa7b90000a7ba, - 0xa7f70000a7f8, - 0xa7fa0000a828, - 0xa8400000a874, - 0xa8800000a8c6, - 0xa8d00000a8da, - 0xa8e00000a8f8, - 0xa8fb0000a8fc, - 0xa8fd0000a92e, - 0xa9300000a954, - 0xa9800000a9c1, - 0xa9cf0000a9da, - 0xa9e00000a9ff, - 0xaa000000aa37, - 0xaa400000aa4e, - 0xaa500000aa5a, - 0xaa600000aa77, - 0xaa7a0000aac3, - 0xaadb0000aade, - 0xaae00000aaf0, - 0xaaf20000aaf7, - 0xab010000ab07, - 0xab090000ab0f, - 0xab110000ab17, - 0xab200000ab27, - 0xab280000ab2f, - 0xab300000ab5b, - 0xab600000ab66, - 0xabc00000abeb, - 0xabec0000abee, - 0xabf00000abfa, - 0xac000000d7a4, - 0xfa0e0000fa10, - 0xfa110000fa12, - 0xfa130000fa15, - 0xfa1f0000fa20, - 0xfa210000fa22, - 0xfa230000fa25, - 0xfa270000fa2a, - 0xfb1e0000fb1f, - 0xfe200000fe30, - 0xfe730000fe74, - 0x100000001000c, - 0x1000d00010027, - 0x100280001003b, - 0x1003c0001003e, - 0x1003f0001004e, - 0x100500001005e, - 0x10080000100fb, - 0x101fd000101fe, - 0x102800001029d, - 0x102a0000102d1, - 0x102e0000102e1, - 0x1030000010320, - 0x1032d00010341, - 0x103420001034a, - 0x103500001037b, - 0x103800001039e, - 0x103a0000103c4, - 0x103c8000103d0, - 0x104280001049e, - 0x104a0000104aa, - 0x104d8000104fc, - 0x1050000010528, - 0x1053000010564, - 0x1060000010737, - 0x1074000010756, - 0x1076000010768, - 0x1080000010806, - 0x1080800010809, - 0x1080a00010836, - 0x1083700010839, - 0x1083c0001083d, - 0x1083f00010856, - 0x1086000010877, - 0x108800001089f, - 0x108e0000108f3, - 0x108f4000108f6, - 0x1090000010916, - 0x109200001093a, - 0x10980000109b8, - 0x109be000109c0, - 0x10a0000010a04, - 0x10a0500010a07, - 0x10a0c00010a14, - 0x10a1500010a18, - 0x10a1900010a36, - 0x10a3800010a3b, - 0x10a3f00010a40, - 0x10a6000010a7d, - 0x10a8000010a9d, - 0x10ac000010ac8, - 0x10ac900010ae7, - 0x10b0000010b36, - 0x10b4000010b56, - 0x10b6000010b73, - 0x10b8000010b92, - 0x10c0000010c49, - 0x10cc000010cf3, - 0x10d0000010d28, - 0x10d3000010d3a, - 0x10f0000010f1d, - 0x10f2700010f28, - 0x10f3000010f51, - 0x1100000011047, - 0x1106600011070, - 0x1107f000110bb, - 0x110d0000110e9, - 0x110f0000110fa, - 0x1110000011135, - 0x1113600011140, - 0x1114400011147, - 0x1115000011174, - 0x1117600011177, - 0x11180000111c5, - 0x111c9000111cd, - 0x111d0000111db, - 0x111dc000111dd, - 0x1120000011212, - 0x1121300011238, - 0x1123e0001123f, - 0x1128000011287, - 0x1128800011289, - 0x1128a0001128e, - 0x1128f0001129e, - 0x1129f000112a9, - 0x112b0000112eb, - 0x112f0000112fa, - 0x1130000011304, - 0x113050001130d, - 0x1130f00011311, - 0x1131300011329, - 0x1132a00011331, - 0x1133200011334, - 0x113350001133a, - 0x1133b00011345, - 0x1134700011349, - 0x1134b0001134e, - 0x1135000011351, - 0x1135700011358, - 0x1135d00011364, - 0x113660001136d, - 0x1137000011375, - 0x114000001144b, - 0x114500001145a, - 0x1145e0001145f, - 0x11480000114c6, - 0x114c7000114c8, - 0x114d0000114da, - 0x11580000115b6, - 0x115b8000115c1, - 0x115d8000115de, - 0x1160000011641, - 0x1164400011645, - 0x116500001165a, - 0x11680000116b8, - 0x116c0000116ca, - 0x117000001171b, - 0x1171d0001172c, - 0x117300001173a, - 0x118000001183b, - 0x118c0000118ea, - 0x118ff00011900, - 0x11a0000011a3f, - 0x11a4700011a48, - 0x11a5000011a84, - 0x11a8600011a9a, - 0x11a9d00011a9e, - 0x11ac000011af9, - 0x11c0000011c09, - 0x11c0a00011c37, - 0x11c3800011c41, - 0x11c5000011c5a, - 0x11c7200011c90, - 0x11c9200011ca8, - 0x11ca900011cb7, - 0x11d0000011d07, - 0x11d0800011d0a, - 0x11d0b00011d37, - 0x11d3a00011d3b, - 0x11d3c00011d3e, - 0x11d3f00011d48, - 0x11d5000011d5a, - 0x11d6000011d66, - 0x11d6700011d69, - 0x11d6a00011d8f, - 0x11d9000011d92, - 0x11d9300011d99, - 0x11da000011daa, - 0x11ee000011ef7, - 0x120000001239a, - 0x1248000012544, - 0x130000001342f, - 0x1440000014647, - 0x1680000016a39, - 0x16a4000016a5f, - 0x16a6000016a6a, - 0x16ad000016aee, - 0x16af000016af5, - 0x16b0000016b37, - 0x16b4000016b44, - 0x16b5000016b5a, - 0x16b6300016b78, - 0x16b7d00016b90, - 0x16e6000016e80, - 0x16f0000016f45, - 0x16f5000016f7f, - 0x16f8f00016fa0, - 0x16fe000016fe2, - 0x17000000187f2, - 0x1880000018af3, - 0x1b0000001b11f, - 0x1b1700001b2fc, - 0x1bc000001bc6b, - 0x1bc700001bc7d, - 0x1bc800001bc89, - 0x1bc900001bc9a, - 0x1bc9d0001bc9f, - 0x1da000001da37, - 0x1da3b0001da6d, - 0x1da750001da76, - 0x1da840001da85, - 0x1da9b0001daa0, - 0x1daa10001dab0, - 0x1e0000001e007, - 0x1e0080001e019, - 0x1e01b0001e022, - 0x1e0230001e025, - 0x1e0260001e02b, - 0x1e8000001e8c5, - 0x1e8d00001e8d7, - 0x1e9220001e94b, - 0x1e9500001e95a, - 0x200000002a6d7, - 0x2a7000002b735, - 0x2b7400002b81e, - 0x2b8200002cea2, - 0x2ceb00002ebe1, - ), - 'CONTEXTJ': ( - 0x200c0000200e, - ), - 'CONTEXTO': ( - 0xb7000000b8, - 0x37500000376, - 0x5f3000005f5, - 0x6600000066a, - 0x6f0000006fa, - 0x30fb000030fc, - ), -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/intranges.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/intranges.py deleted file mode 100644 index fa8a735..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/intranges.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -Given a list of integers, made up of (hopefully) a small number of long runs -of consecutive integers, compute a representation of the form -((start1, end1), (start2, end2) ...). Then answer the question "was x present -in the original list?" in time O(log(# runs)). -""" - -import bisect - -def intranges_from_list(list_): - """Represent a list of integers as a sequence of ranges: - ((start_0, end_0), (start_1, end_1), ...), such that the original - integers are exactly those x such that start_i <= x < end_i for some i. - - Ranges are encoded as single integers (start << 32 | end), not as tuples. - """ - - sorted_list = sorted(list_) - ranges = [] - last_write = -1 - for i in range(len(sorted_list)): - if i+1 < len(sorted_list): - if sorted_list[i] == sorted_list[i+1]-1: - continue - current_range = sorted_list[last_write+1:i+1] - ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) - last_write = i - - return tuple(ranges) - -def _encode_range(start, end): - return (start << 32) | end - -def _decode_range(r): - return (r >> 32), (r & ((1 << 32) - 1)) - - -def intranges_contain(int_, ranges): - """Determine if `int_` falls into one of the ranges in `ranges`.""" - tuple_ = _encode_range(int_, 0) - pos = bisect.bisect_left(ranges, tuple_) - # we could be immediately ahead of a tuple (start, end) - # with start < int_ <= end - if pos > 0: - left, right = _decode_range(ranges[pos-1]) - if left <= int_ < right: - return True - # or we could be immediately behind a tuple (int_, end) - if pos < len(ranges): - left, _ = _decode_range(ranges[pos]) - if left == int_: - return True - return False diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/package_data.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/package_data.py deleted file mode 100644 index 257e898..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/package_data.py +++ /dev/null @@ -1,2 +0,0 @@ -__version__ = '2.8' - diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/uts46data.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/uts46data.py deleted file mode 100644 index a68ed4c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/idna/uts46data.py +++ /dev/null @@ -1,8205 +0,0 @@ -# This file is automatically generated by tools/idna-data -# vim: set fileencoding=utf-8 : - -"""IDNA Mapping Table from UTS46.""" - - -__version__ = "11.0.0" -def _seg_0(): - return [ - (0x0, '3'), - (0x1, '3'), - (0x2, '3'), - (0x3, '3'), - (0x4, '3'), - (0x5, '3'), - (0x6, '3'), - (0x7, '3'), - (0x8, '3'), - (0x9, '3'), - (0xA, '3'), - (0xB, '3'), - (0xC, '3'), - (0xD, '3'), - (0xE, '3'), - (0xF, '3'), - (0x10, '3'), - (0x11, '3'), - (0x12, '3'), - (0x13, '3'), - (0x14, '3'), - (0x15, '3'), - (0x16, '3'), - (0x17, '3'), - (0x18, '3'), - (0x19, '3'), - (0x1A, '3'), - (0x1B, '3'), - (0x1C, '3'), - (0x1D, '3'), - (0x1E, '3'), - (0x1F, '3'), - (0x20, '3'), - (0x21, '3'), - (0x22, '3'), - (0x23, '3'), - (0x24, '3'), - (0x25, '3'), - (0x26, '3'), - (0x27, '3'), - (0x28, '3'), - (0x29, '3'), - (0x2A, '3'), - (0x2B, '3'), - (0x2C, '3'), - (0x2D, 'V'), - (0x2E, 'V'), - (0x2F, '3'), - (0x30, 'V'), - (0x31, 'V'), - (0x32, 'V'), - (0x33, 'V'), - (0x34, 'V'), - (0x35, 'V'), - (0x36, 'V'), - (0x37, 'V'), - (0x38, 'V'), - (0x39, 'V'), - (0x3A, '3'), - (0x3B, '3'), - (0x3C, '3'), - (0x3D, '3'), - (0x3E, '3'), - (0x3F, '3'), - (0x40, '3'), - (0x41, 'M', u'a'), - (0x42, 'M', u'b'), - (0x43, 'M', u'c'), - (0x44, 'M', u'd'), - (0x45, 'M', u'e'), - (0x46, 'M', u'f'), - (0x47, 'M', u'g'), - (0x48, 'M', u'h'), - (0x49, 'M', u'i'), - (0x4A, 'M', u'j'), - (0x4B, 'M', u'k'), - (0x4C, 'M', u'l'), - (0x4D, 'M', u'm'), - (0x4E, 'M', u'n'), - (0x4F, 'M', u'o'), - (0x50, 'M', u'p'), - (0x51, 'M', u'q'), - (0x52, 'M', u'r'), - (0x53, 'M', u's'), - (0x54, 'M', u't'), - (0x55, 'M', u'u'), - (0x56, 'M', u'v'), - (0x57, 'M', u'w'), - (0x58, 'M', u'x'), - (0x59, 'M', u'y'), - (0x5A, 'M', u'z'), - (0x5B, '3'), - (0x5C, '3'), - (0x5D, '3'), - (0x5E, '3'), - (0x5F, '3'), - (0x60, '3'), - (0x61, 'V'), - (0x62, 'V'), - (0x63, 'V'), - ] - -def _seg_1(): - return [ - (0x64, 'V'), - (0x65, 'V'), - (0x66, 'V'), - (0x67, 'V'), - (0x68, 'V'), - (0x69, 'V'), - (0x6A, 'V'), - (0x6B, 'V'), - (0x6C, 'V'), - (0x6D, 'V'), - (0x6E, 'V'), - (0x6F, 'V'), - (0x70, 'V'), - (0x71, 'V'), - (0x72, 'V'), - (0x73, 'V'), - (0x74, 'V'), - (0x75, 'V'), - (0x76, 'V'), - (0x77, 'V'), - (0x78, 'V'), - (0x79, 'V'), - (0x7A, 'V'), - (0x7B, '3'), - (0x7C, '3'), - (0x7D, '3'), - (0x7E, '3'), - (0x7F, '3'), - (0x80, 'X'), - (0x81, 'X'), - (0x82, 'X'), - (0x83, 'X'), - (0x84, 'X'), - (0x85, 'X'), - (0x86, 'X'), - (0x87, 'X'), - (0x88, 'X'), - (0x89, 'X'), - (0x8A, 'X'), - (0x8B, 'X'), - (0x8C, 'X'), - (0x8D, 'X'), - (0x8E, 'X'), - (0x8F, 'X'), - (0x90, 'X'), - (0x91, 'X'), - (0x92, 'X'), - (0x93, 'X'), - (0x94, 'X'), - (0x95, 'X'), - (0x96, 'X'), - (0x97, 'X'), - (0x98, 'X'), - (0x99, 'X'), - (0x9A, 'X'), - (0x9B, 'X'), - (0x9C, 'X'), - (0x9D, 'X'), - (0x9E, 'X'), - (0x9F, 'X'), - (0xA0, '3', u' '), - (0xA1, 'V'), - (0xA2, 'V'), - (0xA3, 'V'), - (0xA4, 'V'), - (0xA5, 'V'), - (0xA6, 'V'), - (0xA7, 'V'), - (0xA8, '3', u' ̈'), - (0xA9, 'V'), - (0xAA, 'M', u'a'), - (0xAB, 'V'), - (0xAC, 'V'), - (0xAD, 'I'), - (0xAE, 'V'), - (0xAF, '3', u' ̄'), - (0xB0, 'V'), - (0xB1, 'V'), - (0xB2, 'M', u'2'), - (0xB3, 'M', u'3'), - (0xB4, '3', u' ́'), - (0xB5, 'M', u'μ'), - (0xB6, 'V'), - (0xB7, 'V'), - (0xB8, '3', u' ̧'), - (0xB9, 'M', u'1'), - (0xBA, 'M', u'o'), - (0xBB, 'V'), - (0xBC, 'M', u'1⁄4'), - (0xBD, 'M', u'1⁄2'), - (0xBE, 'M', u'3⁄4'), - (0xBF, 'V'), - (0xC0, 'M', u'à'), - (0xC1, 'M', u'á'), - (0xC2, 'M', u'â'), - (0xC3, 'M', u'ã'), - (0xC4, 'M', u'ä'), - (0xC5, 'M', u'å'), - (0xC6, 'M', u'æ'), - (0xC7, 'M', u'ç'), - ] - -def _seg_2(): - return [ - (0xC8, 'M', u'è'), - (0xC9, 'M', u'é'), - (0xCA, 'M', u'ê'), - (0xCB, 'M', u'ë'), - (0xCC, 'M', u'ì'), - (0xCD, 'M', u'í'), - (0xCE, 'M', u'î'), - (0xCF, 'M', u'ï'), - (0xD0, 'M', u'ð'), - (0xD1, 'M', u'ñ'), - (0xD2, 'M', u'ò'), - (0xD3, 'M', u'ó'), - (0xD4, 'M', u'ô'), - (0xD5, 'M', u'õ'), - (0xD6, 'M', u'ö'), - (0xD7, 'V'), - (0xD8, 'M', u'ø'), - (0xD9, 'M', u'ù'), - (0xDA, 'M', u'ú'), - (0xDB, 'M', u'û'), - (0xDC, 'M', u'ü'), - (0xDD, 'M', u'ý'), - (0xDE, 'M', u'þ'), - (0xDF, 'D', u'ss'), - (0xE0, 'V'), - (0xE1, 'V'), - (0xE2, 'V'), - (0xE3, 'V'), - (0xE4, 'V'), - (0xE5, 'V'), - (0xE6, 'V'), - (0xE7, 'V'), - (0xE8, 'V'), - (0xE9, 'V'), - (0xEA, 'V'), - (0xEB, 'V'), - (0xEC, 'V'), - (0xED, 'V'), - (0xEE, 'V'), - (0xEF, 'V'), - (0xF0, 'V'), - (0xF1, 'V'), - (0xF2, 'V'), - (0xF3, 'V'), - (0xF4, 'V'), - (0xF5, 'V'), - (0xF6, 'V'), - (0xF7, 'V'), - (0xF8, 'V'), - (0xF9, 'V'), - (0xFA, 'V'), - (0xFB, 'V'), - (0xFC, 'V'), - (0xFD, 'V'), - (0xFE, 'V'), - (0xFF, 'V'), - (0x100, 'M', u'ā'), - (0x101, 'V'), - (0x102, 'M', u'ă'), - (0x103, 'V'), - (0x104, 'M', u'ą'), - (0x105, 'V'), - (0x106, 'M', u'ć'), - (0x107, 'V'), - (0x108, 'M', u'ĉ'), - (0x109, 'V'), - (0x10A, 'M', u'ċ'), - (0x10B, 'V'), - (0x10C, 'M', u'č'), - (0x10D, 'V'), - (0x10E, 'M', u'ď'), - (0x10F, 'V'), - (0x110, 'M', u'đ'), - (0x111, 'V'), - (0x112, 'M', u'ē'), - (0x113, 'V'), - (0x114, 'M', u'ĕ'), - (0x115, 'V'), - (0x116, 'M', u'ė'), - (0x117, 'V'), - (0x118, 'M', u'ę'), - (0x119, 'V'), - (0x11A, 'M', u'ě'), - (0x11B, 'V'), - (0x11C, 'M', u'ĝ'), - (0x11D, 'V'), - (0x11E, 'M', u'ğ'), - (0x11F, 'V'), - (0x120, 'M', u'ġ'), - (0x121, 'V'), - (0x122, 'M', u'ģ'), - (0x123, 'V'), - (0x124, 'M', u'ĥ'), - (0x125, 'V'), - (0x126, 'M', u'ħ'), - (0x127, 'V'), - (0x128, 'M', u'ĩ'), - (0x129, 'V'), - (0x12A, 'M', u'ī'), - (0x12B, 'V'), - ] - -def _seg_3(): - return [ - (0x12C, 'M', u'ĭ'), - (0x12D, 'V'), - (0x12E, 'M', u'į'), - (0x12F, 'V'), - (0x130, 'M', u'i̇'), - (0x131, 'V'), - (0x132, 'M', u'ij'), - (0x134, 'M', u'ĵ'), - (0x135, 'V'), - (0x136, 'M', u'ķ'), - (0x137, 'V'), - (0x139, 'M', u'ĺ'), - (0x13A, 'V'), - (0x13B, 'M', u'ļ'), - (0x13C, 'V'), - (0x13D, 'M', u'ľ'), - (0x13E, 'V'), - (0x13F, 'M', u'l·'), - (0x141, 'M', u'ł'), - (0x142, 'V'), - (0x143, 'M', u'ń'), - (0x144, 'V'), - (0x145, 'M', u'ņ'), - (0x146, 'V'), - (0x147, 'M', u'ň'), - (0x148, 'V'), - (0x149, 'M', u'ʼn'), - (0x14A, 'M', u'ŋ'), - (0x14B, 'V'), - (0x14C, 'M', u'ō'), - (0x14D, 'V'), - (0x14E, 'M', u'ŏ'), - (0x14F, 'V'), - (0x150, 'M', u'ő'), - (0x151, 'V'), - (0x152, 'M', u'œ'), - (0x153, 'V'), - (0x154, 'M', u'ŕ'), - (0x155, 'V'), - (0x156, 'M', u'ŗ'), - (0x157, 'V'), - (0x158, 'M', u'ř'), - (0x159, 'V'), - (0x15A, 'M', u'ś'), - (0x15B, 'V'), - (0x15C, 'M', u'ŝ'), - (0x15D, 'V'), - (0x15E, 'M', u'ş'), - (0x15F, 'V'), - (0x160, 'M', u'š'), - (0x161, 'V'), - (0x162, 'M', u'ţ'), - (0x163, 'V'), - (0x164, 'M', u'ť'), - (0x165, 'V'), - (0x166, 'M', u'ŧ'), - (0x167, 'V'), - (0x168, 'M', u'ũ'), - (0x169, 'V'), - (0x16A, 'M', u'ū'), - (0x16B, 'V'), - (0x16C, 'M', u'ŭ'), - (0x16D, 'V'), - (0x16E, 'M', u'ů'), - (0x16F, 'V'), - (0x170, 'M', u'ű'), - (0x171, 'V'), - (0x172, 'M', u'ų'), - (0x173, 'V'), - (0x174, 'M', u'ŵ'), - (0x175, 'V'), - (0x176, 'M', u'ŷ'), - (0x177, 'V'), - (0x178, 'M', u'ÿ'), - (0x179, 'M', u'ź'), - (0x17A, 'V'), - (0x17B, 'M', u'ż'), - (0x17C, 'V'), - (0x17D, 'M', u'ž'), - (0x17E, 'V'), - (0x17F, 'M', u's'), - (0x180, 'V'), - (0x181, 'M', u'ɓ'), - (0x182, 'M', u'ƃ'), - (0x183, 'V'), - (0x184, 'M', u'ƅ'), - (0x185, 'V'), - (0x186, 'M', u'ɔ'), - (0x187, 'M', u'ƈ'), - (0x188, 'V'), - (0x189, 'M', u'ɖ'), - (0x18A, 'M', u'ɗ'), - (0x18B, 'M', u'ƌ'), - (0x18C, 'V'), - (0x18E, 'M', u'ǝ'), - (0x18F, 'M', u'ə'), - (0x190, 'M', u'ɛ'), - (0x191, 'M', u'ƒ'), - (0x192, 'V'), - (0x193, 'M', u'ɠ'), - ] - -def _seg_4(): - return [ - (0x194, 'M', u'ɣ'), - (0x195, 'V'), - (0x196, 'M', u'ɩ'), - (0x197, 'M', u'ɨ'), - (0x198, 'M', u'ƙ'), - (0x199, 'V'), - (0x19C, 'M', u'ɯ'), - (0x19D, 'M', u'ɲ'), - (0x19E, 'V'), - (0x19F, 'M', u'ɵ'), - (0x1A0, 'M', u'ơ'), - (0x1A1, 'V'), - (0x1A2, 'M', u'ƣ'), - (0x1A3, 'V'), - (0x1A4, 'M', u'ƥ'), - (0x1A5, 'V'), - (0x1A6, 'M', u'ʀ'), - (0x1A7, 'M', u'ƨ'), - (0x1A8, 'V'), - (0x1A9, 'M', u'ʃ'), - (0x1AA, 'V'), - (0x1AC, 'M', u'ƭ'), - (0x1AD, 'V'), - (0x1AE, 'M', u'ʈ'), - (0x1AF, 'M', u'ư'), - (0x1B0, 'V'), - (0x1B1, 'M', u'ʊ'), - (0x1B2, 'M', u'ʋ'), - (0x1B3, 'M', u'ƴ'), - (0x1B4, 'V'), - (0x1B5, 'M', u'ƶ'), - (0x1B6, 'V'), - (0x1B7, 'M', u'ʒ'), - (0x1B8, 'M', u'ƹ'), - (0x1B9, 'V'), - (0x1BC, 'M', u'ƽ'), - (0x1BD, 'V'), - (0x1C4, 'M', u'dž'), - (0x1C7, 'M', u'lj'), - (0x1CA, 'M', u'nj'), - (0x1CD, 'M', u'ǎ'), - (0x1CE, 'V'), - (0x1CF, 'M', u'ǐ'), - (0x1D0, 'V'), - (0x1D1, 'M', u'ǒ'), - (0x1D2, 'V'), - (0x1D3, 'M', u'ǔ'), - (0x1D4, 'V'), - (0x1D5, 'M', u'ǖ'), - (0x1D6, 'V'), - (0x1D7, 'M', u'ǘ'), - (0x1D8, 'V'), - (0x1D9, 'M', u'ǚ'), - (0x1DA, 'V'), - (0x1DB, 'M', u'ǜ'), - (0x1DC, 'V'), - (0x1DE, 'M', u'ǟ'), - (0x1DF, 'V'), - (0x1E0, 'M', u'ǡ'), - (0x1E1, 'V'), - (0x1E2, 'M', u'ǣ'), - (0x1E3, 'V'), - (0x1E4, 'M', u'ǥ'), - (0x1E5, 'V'), - (0x1E6, 'M', u'ǧ'), - (0x1E7, 'V'), - (0x1E8, 'M', u'ǩ'), - (0x1E9, 'V'), - (0x1EA, 'M', u'ǫ'), - (0x1EB, 'V'), - (0x1EC, 'M', u'ǭ'), - (0x1ED, 'V'), - (0x1EE, 'M', u'ǯ'), - (0x1EF, 'V'), - (0x1F1, 'M', u'dz'), - (0x1F4, 'M', u'ǵ'), - (0x1F5, 'V'), - (0x1F6, 'M', u'ƕ'), - (0x1F7, 'M', u'ƿ'), - (0x1F8, 'M', u'ǹ'), - (0x1F9, 'V'), - (0x1FA, 'M', u'ǻ'), - (0x1FB, 'V'), - (0x1FC, 'M', u'ǽ'), - (0x1FD, 'V'), - (0x1FE, 'M', u'ǿ'), - (0x1FF, 'V'), - (0x200, 'M', u'ȁ'), - (0x201, 'V'), - (0x202, 'M', u'ȃ'), - (0x203, 'V'), - (0x204, 'M', u'ȅ'), - (0x205, 'V'), - (0x206, 'M', u'ȇ'), - (0x207, 'V'), - (0x208, 'M', u'ȉ'), - (0x209, 'V'), - (0x20A, 'M', u'ȋ'), - (0x20B, 'V'), - (0x20C, 'M', u'ȍ'), - ] - -def _seg_5(): - return [ - (0x20D, 'V'), - (0x20E, 'M', u'ȏ'), - (0x20F, 'V'), - (0x210, 'M', u'ȑ'), - (0x211, 'V'), - (0x212, 'M', u'ȓ'), - (0x213, 'V'), - (0x214, 'M', u'ȕ'), - (0x215, 'V'), - (0x216, 'M', u'ȗ'), - (0x217, 'V'), - (0x218, 'M', u'ș'), - (0x219, 'V'), - (0x21A, 'M', u'ț'), - (0x21B, 'V'), - (0x21C, 'M', u'ȝ'), - (0x21D, 'V'), - (0x21E, 'M', u'ȟ'), - (0x21F, 'V'), - (0x220, 'M', u'ƞ'), - (0x221, 'V'), - (0x222, 'M', u'ȣ'), - (0x223, 'V'), - (0x224, 'M', u'ȥ'), - (0x225, 'V'), - (0x226, 'M', u'ȧ'), - (0x227, 'V'), - (0x228, 'M', u'ȩ'), - (0x229, 'V'), - (0x22A, 'M', u'ȫ'), - (0x22B, 'V'), - (0x22C, 'M', u'ȭ'), - (0x22D, 'V'), - (0x22E, 'M', u'ȯ'), - (0x22F, 'V'), - (0x230, 'M', u'ȱ'), - (0x231, 'V'), - (0x232, 'M', u'ȳ'), - (0x233, 'V'), - (0x23A, 'M', u'ⱥ'), - (0x23B, 'M', u'ȼ'), - (0x23C, 'V'), - (0x23D, 'M', u'ƚ'), - (0x23E, 'M', u'ⱦ'), - (0x23F, 'V'), - (0x241, 'M', u'ɂ'), - (0x242, 'V'), - (0x243, 'M', u'ƀ'), - (0x244, 'M', u'ʉ'), - (0x245, 'M', u'ʌ'), - (0x246, 'M', u'ɇ'), - (0x247, 'V'), - (0x248, 'M', u'ɉ'), - (0x249, 'V'), - (0x24A, 'M', u'ɋ'), - (0x24B, 'V'), - (0x24C, 'M', u'ɍ'), - (0x24D, 'V'), - (0x24E, 'M', u'ɏ'), - (0x24F, 'V'), - (0x2B0, 'M', u'h'), - (0x2B1, 'M', u'ɦ'), - (0x2B2, 'M', u'j'), - (0x2B3, 'M', u'r'), - (0x2B4, 'M', u'ɹ'), - (0x2B5, 'M', u'ɻ'), - (0x2B6, 'M', u'ʁ'), - (0x2B7, 'M', u'w'), - (0x2B8, 'M', u'y'), - (0x2B9, 'V'), - (0x2D8, '3', u' ̆'), - (0x2D9, '3', u' ̇'), - (0x2DA, '3', u' ̊'), - (0x2DB, '3', u' ̨'), - (0x2DC, '3', u' ̃'), - (0x2DD, '3', u' ̋'), - (0x2DE, 'V'), - (0x2E0, 'M', u'ɣ'), - (0x2E1, 'M', u'l'), - (0x2E2, 'M', u's'), - (0x2E3, 'M', u'x'), - (0x2E4, 'M', u'ʕ'), - (0x2E5, 'V'), - (0x340, 'M', u'̀'), - (0x341, 'M', u'́'), - (0x342, 'V'), - (0x343, 'M', u'̓'), - (0x344, 'M', u'̈́'), - (0x345, 'M', u'ι'), - (0x346, 'V'), - (0x34F, 'I'), - (0x350, 'V'), - (0x370, 'M', u'ͱ'), - (0x371, 'V'), - (0x372, 'M', u'ͳ'), - (0x373, 'V'), - (0x374, 'M', u'ʹ'), - (0x375, 'V'), - (0x376, 'M', u'ͷ'), - (0x377, 'V'), - ] - -def _seg_6(): - return [ - (0x378, 'X'), - (0x37A, '3', u' ι'), - (0x37B, 'V'), - (0x37E, '3', u';'), - (0x37F, 'M', u'ϳ'), - (0x380, 'X'), - (0x384, '3', u' ́'), - (0x385, '3', u' ̈́'), - (0x386, 'M', u'ά'), - (0x387, 'M', u'·'), - (0x388, 'M', u'έ'), - (0x389, 'M', u'ή'), - (0x38A, 'M', u'ί'), - (0x38B, 'X'), - (0x38C, 'M', u'ό'), - (0x38D, 'X'), - (0x38E, 'M', u'ύ'), - (0x38F, 'M', u'ώ'), - (0x390, 'V'), - (0x391, 'M', u'α'), - (0x392, 'M', u'β'), - (0x393, 'M', u'γ'), - (0x394, 'M', u'δ'), - (0x395, 'M', u'ε'), - (0x396, 'M', u'ζ'), - (0x397, 'M', u'η'), - (0x398, 'M', u'θ'), - (0x399, 'M', u'ι'), - (0x39A, 'M', u'κ'), - (0x39B, 'M', u'λ'), - (0x39C, 'M', u'μ'), - (0x39D, 'M', u'ν'), - (0x39E, 'M', u'ξ'), - (0x39F, 'M', u'ο'), - (0x3A0, 'M', u'π'), - (0x3A1, 'M', u'ρ'), - (0x3A2, 'X'), - (0x3A3, 'M', u'σ'), - (0x3A4, 'M', u'τ'), - (0x3A5, 'M', u'υ'), - (0x3A6, 'M', u'φ'), - (0x3A7, 'M', u'χ'), - (0x3A8, 'M', u'ψ'), - (0x3A9, 'M', u'ω'), - (0x3AA, 'M', u'ϊ'), - (0x3AB, 'M', u'ϋ'), - (0x3AC, 'V'), - (0x3C2, 'D', u'σ'), - (0x3C3, 'V'), - (0x3CF, 'M', u'ϗ'), - (0x3D0, 'M', u'β'), - (0x3D1, 'M', u'θ'), - (0x3D2, 'M', u'υ'), - (0x3D3, 'M', u'ύ'), - (0x3D4, 'M', u'ϋ'), - (0x3D5, 'M', u'φ'), - (0x3D6, 'M', u'π'), - (0x3D7, 'V'), - (0x3D8, 'M', u'ϙ'), - (0x3D9, 'V'), - (0x3DA, 'M', u'ϛ'), - (0x3DB, 'V'), - (0x3DC, 'M', u'ϝ'), - (0x3DD, 'V'), - (0x3DE, 'M', u'ϟ'), - (0x3DF, 'V'), - (0x3E0, 'M', u'ϡ'), - (0x3E1, 'V'), - (0x3E2, 'M', u'ϣ'), - (0x3E3, 'V'), - (0x3E4, 'M', u'ϥ'), - (0x3E5, 'V'), - (0x3E6, 'M', u'ϧ'), - (0x3E7, 'V'), - (0x3E8, 'M', u'ϩ'), - (0x3E9, 'V'), - (0x3EA, 'M', u'ϫ'), - (0x3EB, 'V'), - (0x3EC, 'M', u'ϭ'), - (0x3ED, 'V'), - (0x3EE, 'M', u'ϯ'), - (0x3EF, 'V'), - (0x3F0, 'M', u'κ'), - (0x3F1, 'M', u'ρ'), - (0x3F2, 'M', u'σ'), - (0x3F3, 'V'), - (0x3F4, 'M', u'θ'), - (0x3F5, 'M', u'ε'), - (0x3F6, 'V'), - (0x3F7, 'M', u'ϸ'), - (0x3F8, 'V'), - (0x3F9, 'M', u'σ'), - (0x3FA, 'M', u'ϻ'), - (0x3FB, 'V'), - (0x3FD, 'M', u'ͻ'), - (0x3FE, 'M', u'ͼ'), - (0x3FF, 'M', u'ͽ'), - (0x400, 'M', u'ѐ'), - (0x401, 'M', u'ё'), - (0x402, 'M', u'ђ'), - ] - -def _seg_7(): - return [ - (0x403, 'M', u'ѓ'), - (0x404, 'M', u'є'), - (0x405, 'M', u'ѕ'), - (0x406, 'M', u'і'), - (0x407, 'M', u'ї'), - (0x408, 'M', u'ј'), - (0x409, 'M', u'љ'), - (0x40A, 'M', u'њ'), - (0x40B, 'M', u'ћ'), - (0x40C, 'M', u'ќ'), - (0x40D, 'M', u'ѝ'), - (0x40E, 'M', u'ў'), - (0x40F, 'M', u'џ'), - (0x410, 'M', u'а'), - (0x411, 'M', u'б'), - (0x412, 'M', u'в'), - (0x413, 'M', u'г'), - (0x414, 'M', u'д'), - (0x415, 'M', u'е'), - (0x416, 'M', u'ж'), - (0x417, 'M', u'з'), - (0x418, 'M', u'и'), - (0x419, 'M', u'й'), - (0x41A, 'M', u'к'), - (0x41B, 'M', u'л'), - (0x41C, 'M', u'м'), - (0x41D, 'M', u'н'), - (0x41E, 'M', u'о'), - (0x41F, 'M', u'п'), - (0x420, 'M', u'р'), - (0x421, 'M', u'с'), - (0x422, 'M', u'т'), - (0x423, 'M', u'у'), - (0x424, 'M', u'ф'), - (0x425, 'M', u'х'), - (0x426, 'M', u'ц'), - (0x427, 'M', u'ч'), - (0x428, 'M', u'ш'), - (0x429, 'M', u'щ'), - (0x42A, 'M', u'ъ'), - (0x42B, 'M', u'ы'), - (0x42C, 'M', u'ь'), - (0x42D, 'M', u'э'), - (0x42E, 'M', u'ю'), - (0x42F, 'M', u'я'), - (0x430, 'V'), - (0x460, 'M', u'ѡ'), - (0x461, 'V'), - (0x462, 'M', u'ѣ'), - (0x463, 'V'), - (0x464, 'M', u'ѥ'), - (0x465, 'V'), - (0x466, 'M', u'ѧ'), - (0x467, 'V'), - (0x468, 'M', u'ѩ'), - (0x469, 'V'), - (0x46A, 'M', u'ѫ'), - (0x46B, 'V'), - (0x46C, 'M', u'ѭ'), - (0x46D, 'V'), - (0x46E, 'M', u'ѯ'), - (0x46F, 'V'), - (0x470, 'M', u'ѱ'), - (0x471, 'V'), - (0x472, 'M', u'ѳ'), - (0x473, 'V'), - (0x474, 'M', u'ѵ'), - (0x475, 'V'), - (0x476, 'M', u'ѷ'), - (0x477, 'V'), - (0x478, 'M', u'ѹ'), - (0x479, 'V'), - (0x47A, 'M', u'ѻ'), - (0x47B, 'V'), - (0x47C, 'M', u'ѽ'), - (0x47D, 'V'), - (0x47E, 'M', u'ѿ'), - (0x47F, 'V'), - (0x480, 'M', u'ҁ'), - (0x481, 'V'), - (0x48A, 'M', u'ҋ'), - (0x48B, 'V'), - (0x48C, 'M', u'ҍ'), - (0x48D, 'V'), - (0x48E, 'M', u'ҏ'), - (0x48F, 'V'), - (0x490, 'M', u'ґ'), - (0x491, 'V'), - (0x492, 'M', u'ғ'), - (0x493, 'V'), - (0x494, 'M', u'ҕ'), - (0x495, 'V'), - (0x496, 'M', u'җ'), - (0x497, 'V'), - (0x498, 'M', u'ҙ'), - (0x499, 'V'), - (0x49A, 'M', u'қ'), - (0x49B, 'V'), - (0x49C, 'M', u'ҝ'), - (0x49D, 'V'), - ] - -def _seg_8(): - return [ - (0x49E, 'M', u'ҟ'), - (0x49F, 'V'), - (0x4A0, 'M', u'ҡ'), - (0x4A1, 'V'), - (0x4A2, 'M', u'ң'), - (0x4A3, 'V'), - (0x4A4, 'M', u'ҥ'), - (0x4A5, 'V'), - (0x4A6, 'M', u'ҧ'), - (0x4A7, 'V'), - (0x4A8, 'M', u'ҩ'), - (0x4A9, 'V'), - (0x4AA, 'M', u'ҫ'), - (0x4AB, 'V'), - (0x4AC, 'M', u'ҭ'), - (0x4AD, 'V'), - (0x4AE, 'M', u'ү'), - (0x4AF, 'V'), - (0x4B0, 'M', u'ұ'), - (0x4B1, 'V'), - (0x4B2, 'M', u'ҳ'), - (0x4B3, 'V'), - (0x4B4, 'M', u'ҵ'), - (0x4B5, 'V'), - (0x4B6, 'M', u'ҷ'), - (0x4B7, 'V'), - (0x4B8, 'M', u'ҹ'), - (0x4B9, 'V'), - (0x4BA, 'M', u'һ'), - (0x4BB, 'V'), - (0x4BC, 'M', u'ҽ'), - (0x4BD, 'V'), - (0x4BE, 'M', u'ҿ'), - (0x4BF, 'V'), - (0x4C0, 'X'), - (0x4C1, 'M', u'ӂ'), - (0x4C2, 'V'), - (0x4C3, 'M', u'ӄ'), - (0x4C4, 'V'), - (0x4C5, 'M', u'ӆ'), - (0x4C6, 'V'), - (0x4C7, 'M', u'ӈ'), - (0x4C8, 'V'), - (0x4C9, 'M', u'ӊ'), - (0x4CA, 'V'), - (0x4CB, 'M', u'ӌ'), - (0x4CC, 'V'), - (0x4CD, 'M', u'ӎ'), - (0x4CE, 'V'), - (0x4D0, 'M', u'ӑ'), - (0x4D1, 'V'), - (0x4D2, 'M', u'ӓ'), - (0x4D3, 'V'), - (0x4D4, 'M', u'ӕ'), - (0x4D5, 'V'), - (0x4D6, 'M', u'ӗ'), - (0x4D7, 'V'), - (0x4D8, 'M', u'ә'), - (0x4D9, 'V'), - (0x4DA, 'M', u'ӛ'), - (0x4DB, 'V'), - (0x4DC, 'M', u'ӝ'), - (0x4DD, 'V'), - (0x4DE, 'M', u'ӟ'), - (0x4DF, 'V'), - (0x4E0, 'M', u'ӡ'), - (0x4E1, 'V'), - (0x4E2, 'M', u'ӣ'), - (0x4E3, 'V'), - (0x4E4, 'M', u'ӥ'), - (0x4E5, 'V'), - (0x4E6, 'M', u'ӧ'), - (0x4E7, 'V'), - (0x4E8, 'M', u'ө'), - (0x4E9, 'V'), - (0x4EA, 'M', u'ӫ'), - (0x4EB, 'V'), - (0x4EC, 'M', u'ӭ'), - (0x4ED, 'V'), - (0x4EE, 'M', u'ӯ'), - (0x4EF, 'V'), - (0x4F0, 'M', u'ӱ'), - (0x4F1, 'V'), - (0x4F2, 'M', u'ӳ'), - (0x4F3, 'V'), - (0x4F4, 'M', u'ӵ'), - (0x4F5, 'V'), - (0x4F6, 'M', u'ӷ'), - (0x4F7, 'V'), - (0x4F8, 'M', u'ӹ'), - (0x4F9, 'V'), - (0x4FA, 'M', u'ӻ'), - (0x4FB, 'V'), - (0x4FC, 'M', u'ӽ'), - (0x4FD, 'V'), - (0x4FE, 'M', u'ӿ'), - (0x4FF, 'V'), - (0x500, 'M', u'ԁ'), - (0x501, 'V'), - (0x502, 'M', u'ԃ'), - ] - -def _seg_9(): - return [ - (0x503, 'V'), - (0x504, 'M', u'ԅ'), - (0x505, 'V'), - (0x506, 'M', u'ԇ'), - (0x507, 'V'), - (0x508, 'M', u'ԉ'), - (0x509, 'V'), - (0x50A, 'M', u'ԋ'), - (0x50B, 'V'), - (0x50C, 'M', u'ԍ'), - (0x50D, 'V'), - (0x50E, 'M', u'ԏ'), - (0x50F, 'V'), - (0x510, 'M', u'ԑ'), - (0x511, 'V'), - (0x512, 'M', u'ԓ'), - (0x513, 'V'), - (0x514, 'M', u'ԕ'), - (0x515, 'V'), - (0x516, 'M', u'ԗ'), - (0x517, 'V'), - (0x518, 'M', u'ԙ'), - (0x519, 'V'), - (0x51A, 'M', u'ԛ'), - (0x51B, 'V'), - (0x51C, 'M', u'ԝ'), - (0x51D, 'V'), - (0x51E, 'M', u'ԟ'), - (0x51F, 'V'), - (0x520, 'M', u'ԡ'), - (0x521, 'V'), - (0x522, 'M', u'ԣ'), - (0x523, 'V'), - (0x524, 'M', u'ԥ'), - (0x525, 'V'), - (0x526, 'M', u'ԧ'), - (0x527, 'V'), - (0x528, 'M', u'ԩ'), - (0x529, 'V'), - (0x52A, 'M', u'ԫ'), - (0x52B, 'V'), - (0x52C, 'M', u'ԭ'), - (0x52D, 'V'), - (0x52E, 'M', u'ԯ'), - (0x52F, 'V'), - (0x530, 'X'), - (0x531, 'M', u'ա'), - (0x532, 'M', u'բ'), - (0x533, 'M', u'գ'), - (0x534, 'M', u'դ'), - (0x535, 'M', u'ե'), - (0x536, 'M', u'զ'), - (0x537, 'M', u'է'), - (0x538, 'M', u'ը'), - (0x539, 'M', u'թ'), - (0x53A, 'M', u'ժ'), - (0x53B, 'M', u'ի'), - (0x53C, 'M', u'լ'), - (0x53D, 'M', u'խ'), - (0x53E, 'M', u'ծ'), - (0x53F, 'M', u'կ'), - (0x540, 'M', u'հ'), - (0x541, 'M', u'ձ'), - (0x542, 'M', u'ղ'), - (0x543, 'M', u'ճ'), - (0x544, 'M', u'մ'), - (0x545, 'M', u'յ'), - (0x546, 'M', u'ն'), - (0x547, 'M', u'շ'), - (0x548, 'M', u'ո'), - (0x549, 'M', u'չ'), - (0x54A, 'M', u'պ'), - (0x54B, 'M', u'ջ'), - (0x54C, 'M', u'ռ'), - (0x54D, 'M', u'ս'), - (0x54E, 'M', u'վ'), - (0x54F, 'M', u'տ'), - (0x550, 'M', u'ր'), - (0x551, 'M', u'ց'), - (0x552, 'M', u'ւ'), - (0x553, 'M', u'փ'), - (0x554, 'M', u'ք'), - (0x555, 'M', u'օ'), - (0x556, 'M', u'ֆ'), - (0x557, 'X'), - (0x559, 'V'), - (0x587, 'M', u'եւ'), - (0x588, 'V'), - (0x58B, 'X'), - (0x58D, 'V'), - (0x590, 'X'), - (0x591, 'V'), - (0x5C8, 'X'), - (0x5D0, 'V'), - (0x5EB, 'X'), - (0x5EF, 'V'), - (0x5F5, 'X'), - (0x606, 'V'), - (0x61C, 'X'), - (0x61E, 'V'), - ] - -def _seg_10(): - return [ - (0x675, 'M', u'اٴ'), - (0x676, 'M', u'وٴ'), - (0x677, 'M', u'ۇٴ'), - (0x678, 'M', u'يٴ'), - (0x679, 'V'), - (0x6DD, 'X'), - (0x6DE, 'V'), - (0x70E, 'X'), - (0x710, 'V'), - (0x74B, 'X'), - (0x74D, 'V'), - (0x7B2, 'X'), - (0x7C0, 'V'), - (0x7FB, 'X'), - (0x7FD, 'V'), - (0x82E, 'X'), - (0x830, 'V'), - (0x83F, 'X'), - (0x840, 'V'), - (0x85C, 'X'), - (0x85E, 'V'), - (0x85F, 'X'), - (0x860, 'V'), - (0x86B, 'X'), - (0x8A0, 'V'), - (0x8B5, 'X'), - (0x8B6, 'V'), - (0x8BE, 'X'), - (0x8D3, 'V'), - (0x8E2, 'X'), - (0x8E3, 'V'), - (0x958, 'M', u'क़'), - (0x959, 'M', u'ख़'), - (0x95A, 'M', u'ग़'), - (0x95B, 'M', u'ज़'), - (0x95C, 'M', u'ड़'), - (0x95D, 'M', u'ढ़'), - (0x95E, 'M', u'फ़'), - (0x95F, 'M', u'य़'), - (0x960, 'V'), - (0x984, 'X'), - (0x985, 'V'), - (0x98D, 'X'), - (0x98F, 'V'), - (0x991, 'X'), - (0x993, 'V'), - (0x9A9, 'X'), - (0x9AA, 'V'), - (0x9B1, 'X'), - (0x9B2, 'V'), - (0x9B3, 'X'), - (0x9B6, 'V'), - (0x9BA, 'X'), - (0x9BC, 'V'), - (0x9C5, 'X'), - (0x9C7, 'V'), - (0x9C9, 'X'), - (0x9CB, 'V'), - (0x9CF, 'X'), - (0x9D7, 'V'), - (0x9D8, 'X'), - (0x9DC, 'M', u'ড়'), - (0x9DD, 'M', u'ঢ়'), - (0x9DE, 'X'), - (0x9DF, 'M', u'য়'), - (0x9E0, 'V'), - (0x9E4, 'X'), - (0x9E6, 'V'), - (0x9FF, 'X'), - (0xA01, 'V'), - (0xA04, 'X'), - (0xA05, 'V'), - (0xA0B, 'X'), - (0xA0F, 'V'), - (0xA11, 'X'), - (0xA13, 'V'), - (0xA29, 'X'), - (0xA2A, 'V'), - (0xA31, 'X'), - (0xA32, 'V'), - (0xA33, 'M', u'ਲ਼'), - (0xA34, 'X'), - (0xA35, 'V'), - (0xA36, 'M', u'ਸ਼'), - (0xA37, 'X'), - (0xA38, 'V'), - (0xA3A, 'X'), - (0xA3C, 'V'), - (0xA3D, 'X'), - (0xA3E, 'V'), - (0xA43, 'X'), - (0xA47, 'V'), - (0xA49, 'X'), - (0xA4B, 'V'), - (0xA4E, 'X'), - (0xA51, 'V'), - (0xA52, 'X'), - (0xA59, 'M', u'ਖ਼'), - (0xA5A, 'M', u'ਗ਼'), - (0xA5B, 'M', u'ਜ਼'), - ] - -def _seg_11(): - return [ - (0xA5C, 'V'), - (0xA5D, 'X'), - (0xA5E, 'M', u'ਫ਼'), - (0xA5F, 'X'), - (0xA66, 'V'), - (0xA77, 'X'), - (0xA81, 'V'), - (0xA84, 'X'), - (0xA85, 'V'), - (0xA8E, 'X'), - (0xA8F, 'V'), - (0xA92, 'X'), - (0xA93, 'V'), - (0xAA9, 'X'), - (0xAAA, 'V'), - (0xAB1, 'X'), - (0xAB2, 'V'), - (0xAB4, 'X'), - (0xAB5, 'V'), - (0xABA, 'X'), - (0xABC, 'V'), - (0xAC6, 'X'), - (0xAC7, 'V'), - (0xACA, 'X'), - (0xACB, 'V'), - (0xACE, 'X'), - (0xAD0, 'V'), - (0xAD1, 'X'), - (0xAE0, 'V'), - (0xAE4, 'X'), - (0xAE6, 'V'), - (0xAF2, 'X'), - (0xAF9, 'V'), - (0xB00, 'X'), - (0xB01, 'V'), - (0xB04, 'X'), - (0xB05, 'V'), - (0xB0D, 'X'), - (0xB0F, 'V'), - (0xB11, 'X'), - (0xB13, 'V'), - (0xB29, 'X'), - (0xB2A, 'V'), - (0xB31, 'X'), - (0xB32, 'V'), - (0xB34, 'X'), - (0xB35, 'V'), - (0xB3A, 'X'), - (0xB3C, 'V'), - (0xB45, 'X'), - (0xB47, 'V'), - (0xB49, 'X'), - (0xB4B, 'V'), - (0xB4E, 'X'), - (0xB56, 'V'), - (0xB58, 'X'), - (0xB5C, 'M', u'ଡ଼'), - (0xB5D, 'M', u'ଢ଼'), - (0xB5E, 'X'), - (0xB5F, 'V'), - (0xB64, 'X'), - (0xB66, 'V'), - (0xB78, 'X'), - (0xB82, 'V'), - (0xB84, 'X'), - (0xB85, 'V'), - (0xB8B, 'X'), - (0xB8E, 'V'), - (0xB91, 'X'), - (0xB92, 'V'), - (0xB96, 'X'), - (0xB99, 'V'), - (0xB9B, 'X'), - (0xB9C, 'V'), - (0xB9D, 'X'), - (0xB9E, 'V'), - (0xBA0, 'X'), - (0xBA3, 'V'), - (0xBA5, 'X'), - (0xBA8, 'V'), - (0xBAB, 'X'), - (0xBAE, 'V'), - (0xBBA, 'X'), - (0xBBE, 'V'), - (0xBC3, 'X'), - (0xBC6, 'V'), - (0xBC9, 'X'), - (0xBCA, 'V'), - (0xBCE, 'X'), - (0xBD0, 'V'), - (0xBD1, 'X'), - (0xBD7, 'V'), - (0xBD8, 'X'), - (0xBE6, 'V'), - (0xBFB, 'X'), - (0xC00, 'V'), - (0xC0D, 'X'), - (0xC0E, 'V'), - (0xC11, 'X'), - (0xC12, 'V'), - ] - -def _seg_12(): - return [ - (0xC29, 'X'), - (0xC2A, 'V'), - (0xC3A, 'X'), - (0xC3D, 'V'), - (0xC45, 'X'), - (0xC46, 'V'), - (0xC49, 'X'), - (0xC4A, 'V'), - (0xC4E, 'X'), - (0xC55, 'V'), - (0xC57, 'X'), - (0xC58, 'V'), - (0xC5B, 'X'), - (0xC60, 'V'), - (0xC64, 'X'), - (0xC66, 'V'), - (0xC70, 'X'), - (0xC78, 'V'), - (0xC8D, 'X'), - (0xC8E, 'V'), - (0xC91, 'X'), - (0xC92, 'V'), - (0xCA9, 'X'), - (0xCAA, 'V'), - (0xCB4, 'X'), - (0xCB5, 'V'), - (0xCBA, 'X'), - (0xCBC, 'V'), - (0xCC5, 'X'), - (0xCC6, 'V'), - (0xCC9, 'X'), - (0xCCA, 'V'), - (0xCCE, 'X'), - (0xCD5, 'V'), - (0xCD7, 'X'), - (0xCDE, 'V'), - (0xCDF, 'X'), - (0xCE0, 'V'), - (0xCE4, 'X'), - (0xCE6, 'V'), - (0xCF0, 'X'), - (0xCF1, 'V'), - (0xCF3, 'X'), - (0xD00, 'V'), - (0xD04, 'X'), - (0xD05, 'V'), - (0xD0D, 'X'), - (0xD0E, 'V'), - (0xD11, 'X'), - (0xD12, 'V'), - (0xD45, 'X'), - (0xD46, 'V'), - (0xD49, 'X'), - (0xD4A, 'V'), - (0xD50, 'X'), - (0xD54, 'V'), - (0xD64, 'X'), - (0xD66, 'V'), - (0xD80, 'X'), - (0xD82, 'V'), - (0xD84, 'X'), - (0xD85, 'V'), - (0xD97, 'X'), - (0xD9A, 'V'), - (0xDB2, 'X'), - (0xDB3, 'V'), - (0xDBC, 'X'), - (0xDBD, 'V'), - (0xDBE, 'X'), - (0xDC0, 'V'), - (0xDC7, 'X'), - (0xDCA, 'V'), - (0xDCB, 'X'), - (0xDCF, 'V'), - (0xDD5, 'X'), - (0xDD6, 'V'), - (0xDD7, 'X'), - (0xDD8, 'V'), - (0xDE0, 'X'), - (0xDE6, 'V'), - (0xDF0, 'X'), - (0xDF2, 'V'), - (0xDF5, 'X'), - (0xE01, 'V'), - (0xE33, 'M', u'ํา'), - (0xE34, 'V'), - (0xE3B, 'X'), - (0xE3F, 'V'), - (0xE5C, 'X'), - (0xE81, 'V'), - (0xE83, 'X'), - (0xE84, 'V'), - (0xE85, 'X'), - (0xE87, 'V'), - (0xE89, 'X'), - (0xE8A, 'V'), - (0xE8B, 'X'), - (0xE8D, 'V'), - (0xE8E, 'X'), - (0xE94, 'V'), - ] - -def _seg_13(): - return [ - (0xE98, 'X'), - (0xE99, 'V'), - (0xEA0, 'X'), - (0xEA1, 'V'), - (0xEA4, 'X'), - (0xEA5, 'V'), - (0xEA6, 'X'), - (0xEA7, 'V'), - (0xEA8, 'X'), - (0xEAA, 'V'), - (0xEAC, 'X'), - (0xEAD, 'V'), - (0xEB3, 'M', u'ໍາ'), - (0xEB4, 'V'), - (0xEBA, 'X'), - (0xEBB, 'V'), - (0xEBE, 'X'), - (0xEC0, 'V'), - (0xEC5, 'X'), - (0xEC6, 'V'), - (0xEC7, 'X'), - (0xEC8, 'V'), - (0xECE, 'X'), - (0xED0, 'V'), - (0xEDA, 'X'), - (0xEDC, 'M', u'ຫນ'), - (0xEDD, 'M', u'ຫມ'), - (0xEDE, 'V'), - (0xEE0, 'X'), - (0xF00, 'V'), - (0xF0C, 'M', u'་'), - (0xF0D, 'V'), - (0xF43, 'M', u'གྷ'), - (0xF44, 'V'), - (0xF48, 'X'), - (0xF49, 'V'), - (0xF4D, 'M', u'ཌྷ'), - (0xF4E, 'V'), - (0xF52, 'M', u'དྷ'), - (0xF53, 'V'), - (0xF57, 'M', u'བྷ'), - (0xF58, 'V'), - (0xF5C, 'M', u'ཛྷ'), - (0xF5D, 'V'), - (0xF69, 'M', u'ཀྵ'), - (0xF6A, 'V'), - (0xF6D, 'X'), - (0xF71, 'V'), - (0xF73, 'M', u'ཱི'), - (0xF74, 'V'), - (0xF75, 'M', u'ཱུ'), - (0xF76, 'M', u'ྲྀ'), - (0xF77, 'M', u'ྲཱྀ'), - (0xF78, 'M', u'ླྀ'), - (0xF79, 'M', u'ླཱྀ'), - (0xF7A, 'V'), - (0xF81, 'M', u'ཱྀ'), - (0xF82, 'V'), - (0xF93, 'M', u'ྒྷ'), - (0xF94, 'V'), - (0xF98, 'X'), - (0xF99, 'V'), - (0xF9D, 'M', u'ྜྷ'), - (0xF9E, 'V'), - (0xFA2, 'M', u'ྡྷ'), - (0xFA3, 'V'), - (0xFA7, 'M', u'ྦྷ'), - (0xFA8, 'V'), - (0xFAC, 'M', u'ྫྷ'), - (0xFAD, 'V'), - (0xFB9, 'M', u'ྐྵ'), - (0xFBA, 'V'), - (0xFBD, 'X'), - (0xFBE, 'V'), - (0xFCD, 'X'), - (0xFCE, 'V'), - (0xFDB, 'X'), - (0x1000, 'V'), - (0x10A0, 'X'), - (0x10C7, 'M', u'ⴧ'), - (0x10C8, 'X'), - (0x10CD, 'M', u'ⴭ'), - (0x10CE, 'X'), - (0x10D0, 'V'), - (0x10FC, 'M', u'ნ'), - (0x10FD, 'V'), - (0x115F, 'X'), - (0x1161, 'V'), - (0x1249, 'X'), - (0x124A, 'V'), - (0x124E, 'X'), - (0x1250, 'V'), - (0x1257, 'X'), - (0x1258, 'V'), - (0x1259, 'X'), - (0x125A, 'V'), - (0x125E, 'X'), - (0x1260, 'V'), - (0x1289, 'X'), - (0x128A, 'V'), - ] - -def _seg_14(): - return [ - (0x128E, 'X'), - (0x1290, 'V'), - (0x12B1, 'X'), - (0x12B2, 'V'), - (0x12B6, 'X'), - (0x12B8, 'V'), - (0x12BF, 'X'), - (0x12C0, 'V'), - (0x12C1, 'X'), - (0x12C2, 'V'), - (0x12C6, 'X'), - (0x12C8, 'V'), - (0x12D7, 'X'), - (0x12D8, 'V'), - (0x1311, 'X'), - (0x1312, 'V'), - (0x1316, 'X'), - (0x1318, 'V'), - (0x135B, 'X'), - (0x135D, 'V'), - (0x137D, 'X'), - (0x1380, 'V'), - (0x139A, 'X'), - (0x13A0, 'V'), - (0x13F6, 'X'), - (0x13F8, 'M', u'Ᏸ'), - (0x13F9, 'M', u'Ᏹ'), - (0x13FA, 'M', u'Ᏺ'), - (0x13FB, 'M', u'Ᏻ'), - (0x13FC, 'M', u'Ᏼ'), - (0x13FD, 'M', u'Ᏽ'), - (0x13FE, 'X'), - (0x1400, 'V'), - (0x1680, 'X'), - (0x1681, 'V'), - (0x169D, 'X'), - (0x16A0, 'V'), - (0x16F9, 'X'), - (0x1700, 'V'), - (0x170D, 'X'), - (0x170E, 'V'), - (0x1715, 'X'), - (0x1720, 'V'), - (0x1737, 'X'), - (0x1740, 'V'), - (0x1754, 'X'), - (0x1760, 'V'), - (0x176D, 'X'), - (0x176E, 'V'), - (0x1771, 'X'), - (0x1772, 'V'), - (0x1774, 'X'), - (0x1780, 'V'), - (0x17B4, 'X'), - (0x17B6, 'V'), - (0x17DE, 'X'), - (0x17E0, 'V'), - (0x17EA, 'X'), - (0x17F0, 'V'), - (0x17FA, 'X'), - (0x1800, 'V'), - (0x1806, 'X'), - (0x1807, 'V'), - (0x180B, 'I'), - (0x180E, 'X'), - (0x1810, 'V'), - (0x181A, 'X'), - (0x1820, 'V'), - (0x1879, 'X'), - (0x1880, 'V'), - (0x18AB, 'X'), - (0x18B0, 'V'), - (0x18F6, 'X'), - (0x1900, 'V'), - (0x191F, 'X'), - (0x1920, 'V'), - (0x192C, 'X'), - (0x1930, 'V'), - (0x193C, 'X'), - (0x1940, 'V'), - (0x1941, 'X'), - (0x1944, 'V'), - (0x196E, 'X'), - (0x1970, 'V'), - (0x1975, 'X'), - (0x1980, 'V'), - (0x19AC, 'X'), - (0x19B0, 'V'), - (0x19CA, 'X'), - (0x19D0, 'V'), - (0x19DB, 'X'), - (0x19DE, 'V'), - (0x1A1C, 'X'), - (0x1A1E, 'V'), - (0x1A5F, 'X'), - (0x1A60, 'V'), - (0x1A7D, 'X'), - (0x1A7F, 'V'), - (0x1A8A, 'X'), - (0x1A90, 'V'), - ] - -def _seg_15(): - return [ - (0x1A9A, 'X'), - (0x1AA0, 'V'), - (0x1AAE, 'X'), - (0x1AB0, 'V'), - (0x1ABF, 'X'), - (0x1B00, 'V'), - (0x1B4C, 'X'), - (0x1B50, 'V'), - (0x1B7D, 'X'), - (0x1B80, 'V'), - (0x1BF4, 'X'), - (0x1BFC, 'V'), - (0x1C38, 'X'), - (0x1C3B, 'V'), - (0x1C4A, 'X'), - (0x1C4D, 'V'), - (0x1C80, 'M', u'в'), - (0x1C81, 'M', u'д'), - (0x1C82, 'M', u'о'), - (0x1C83, 'M', u'с'), - (0x1C84, 'M', u'т'), - (0x1C86, 'M', u'ъ'), - (0x1C87, 'M', u'ѣ'), - (0x1C88, 'M', u'ꙋ'), - (0x1C89, 'X'), - (0x1CC0, 'V'), - (0x1CC8, 'X'), - (0x1CD0, 'V'), - (0x1CFA, 'X'), - (0x1D00, 'V'), - (0x1D2C, 'M', u'a'), - (0x1D2D, 'M', u'æ'), - (0x1D2E, 'M', u'b'), - (0x1D2F, 'V'), - (0x1D30, 'M', u'd'), - (0x1D31, 'M', u'e'), - (0x1D32, 'M', u'ǝ'), - (0x1D33, 'M', u'g'), - (0x1D34, 'M', u'h'), - (0x1D35, 'M', u'i'), - (0x1D36, 'M', u'j'), - (0x1D37, 'M', u'k'), - (0x1D38, 'M', u'l'), - (0x1D39, 'M', u'm'), - (0x1D3A, 'M', u'n'), - (0x1D3B, 'V'), - (0x1D3C, 'M', u'o'), - (0x1D3D, 'M', u'ȣ'), - (0x1D3E, 'M', u'p'), - (0x1D3F, 'M', u'r'), - (0x1D40, 'M', u't'), - (0x1D41, 'M', u'u'), - (0x1D42, 'M', u'w'), - (0x1D43, 'M', u'a'), - (0x1D44, 'M', u'ɐ'), - (0x1D45, 'M', u'ɑ'), - (0x1D46, 'M', u'ᴂ'), - (0x1D47, 'M', u'b'), - (0x1D48, 'M', u'd'), - (0x1D49, 'M', u'e'), - (0x1D4A, 'M', u'ə'), - (0x1D4B, 'M', u'ɛ'), - (0x1D4C, 'M', u'ɜ'), - (0x1D4D, 'M', u'g'), - (0x1D4E, 'V'), - (0x1D4F, 'M', u'k'), - (0x1D50, 'M', u'm'), - (0x1D51, 'M', u'ŋ'), - (0x1D52, 'M', u'o'), - (0x1D53, 'M', u'ɔ'), - (0x1D54, 'M', u'ᴖ'), - (0x1D55, 'M', u'ᴗ'), - (0x1D56, 'M', u'p'), - (0x1D57, 'M', u't'), - (0x1D58, 'M', u'u'), - (0x1D59, 'M', u'ᴝ'), - (0x1D5A, 'M', u'ɯ'), - (0x1D5B, 'M', u'v'), - (0x1D5C, 'M', u'ᴥ'), - (0x1D5D, 'M', u'β'), - (0x1D5E, 'M', u'γ'), - (0x1D5F, 'M', u'δ'), - (0x1D60, 'M', u'φ'), - (0x1D61, 'M', u'χ'), - (0x1D62, 'M', u'i'), - (0x1D63, 'M', u'r'), - (0x1D64, 'M', u'u'), - (0x1D65, 'M', u'v'), - (0x1D66, 'M', u'β'), - (0x1D67, 'M', u'γ'), - (0x1D68, 'M', u'ρ'), - (0x1D69, 'M', u'φ'), - (0x1D6A, 'M', u'χ'), - (0x1D6B, 'V'), - (0x1D78, 'M', u'н'), - (0x1D79, 'V'), - (0x1D9B, 'M', u'ɒ'), - (0x1D9C, 'M', u'c'), - (0x1D9D, 'M', u'ɕ'), - (0x1D9E, 'M', u'ð'), - ] - -def _seg_16(): - return [ - (0x1D9F, 'M', u'ɜ'), - (0x1DA0, 'M', u'f'), - (0x1DA1, 'M', u'ɟ'), - (0x1DA2, 'M', u'ɡ'), - (0x1DA3, 'M', u'ɥ'), - (0x1DA4, 'M', u'ɨ'), - (0x1DA5, 'M', u'ɩ'), - (0x1DA6, 'M', u'ɪ'), - (0x1DA7, 'M', u'ᵻ'), - (0x1DA8, 'M', u'ʝ'), - (0x1DA9, 'M', u'ɭ'), - (0x1DAA, 'M', u'ᶅ'), - (0x1DAB, 'M', u'ʟ'), - (0x1DAC, 'M', u'ɱ'), - (0x1DAD, 'M', u'ɰ'), - (0x1DAE, 'M', u'ɲ'), - (0x1DAF, 'M', u'ɳ'), - (0x1DB0, 'M', u'ɴ'), - (0x1DB1, 'M', u'ɵ'), - (0x1DB2, 'M', u'ɸ'), - (0x1DB3, 'M', u'ʂ'), - (0x1DB4, 'M', u'ʃ'), - (0x1DB5, 'M', u'ƫ'), - (0x1DB6, 'M', u'ʉ'), - (0x1DB7, 'M', u'ʊ'), - (0x1DB8, 'M', u'ᴜ'), - (0x1DB9, 'M', u'ʋ'), - (0x1DBA, 'M', u'ʌ'), - (0x1DBB, 'M', u'z'), - (0x1DBC, 'M', u'ʐ'), - (0x1DBD, 'M', u'ʑ'), - (0x1DBE, 'M', u'ʒ'), - (0x1DBF, 'M', u'θ'), - (0x1DC0, 'V'), - (0x1DFA, 'X'), - (0x1DFB, 'V'), - (0x1E00, 'M', u'ḁ'), - (0x1E01, 'V'), - (0x1E02, 'M', u'ḃ'), - (0x1E03, 'V'), - (0x1E04, 'M', u'ḅ'), - (0x1E05, 'V'), - (0x1E06, 'M', u'ḇ'), - (0x1E07, 'V'), - (0x1E08, 'M', u'ḉ'), - (0x1E09, 'V'), - (0x1E0A, 'M', u'ḋ'), - (0x1E0B, 'V'), - (0x1E0C, 'M', u'ḍ'), - (0x1E0D, 'V'), - (0x1E0E, 'M', u'ḏ'), - (0x1E0F, 'V'), - (0x1E10, 'M', u'ḑ'), - (0x1E11, 'V'), - (0x1E12, 'M', u'ḓ'), - (0x1E13, 'V'), - (0x1E14, 'M', u'ḕ'), - (0x1E15, 'V'), - (0x1E16, 'M', u'ḗ'), - (0x1E17, 'V'), - (0x1E18, 'M', u'ḙ'), - (0x1E19, 'V'), - (0x1E1A, 'M', u'ḛ'), - (0x1E1B, 'V'), - (0x1E1C, 'M', u'ḝ'), - (0x1E1D, 'V'), - (0x1E1E, 'M', u'ḟ'), - (0x1E1F, 'V'), - (0x1E20, 'M', u'ḡ'), - (0x1E21, 'V'), - (0x1E22, 'M', u'ḣ'), - (0x1E23, 'V'), - (0x1E24, 'M', u'ḥ'), - (0x1E25, 'V'), - (0x1E26, 'M', u'ḧ'), - (0x1E27, 'V'), - (0x1E28, 'M', u'ḩ'), - (0x1E29, 'V'), - (0x1E2A, 'M', u'ḫ'), - (0x1E2B, 'V'), - (0x1E2C, 'M', u'ḭ'), - (0x1E2D, 'V'), - (0x1E2E, 'M', u'ḯ'), - (0x1E2F, 'V'), - (0x1E30, 'M', u'ḱ'), - (0x1E31, 'V'), - (0x1E32, 'M', u'ḳ'), - (0x1E33, 'V'), - (0x1E34, 'M', u'ḵ'), - (0x1E35, 'V'), - (0x1E36, 'M', u'ḷ'), - (0x1E37, 'V'), - (0x1E38, 'M', u'ḹ'), - (0x1E39, 'V'), - (0x1E3A, 'M', u'ḻ'), - (0x1E3B, 'V'), - (0x1E3C, 'M', u'ḽ'), - (0x1E3D, 'V'), - (0x1E3E, 'M', u'ḿ'), - (0x1E3F, 'V'), - ] - -def _seg_17(): - return [ - (0x1E40, 'M', u'ṁ'), - (0x1E41, 'V'), - (0x1E42, 'M', u'ṃ'), - (0x1E43, 'V'), - (0x1E44, 'M', u'ṅ'), - (0x1E45, 'V'), - (0x1E46, 'M', u'ṇ'), - (0x1E47, 'V'), - (0x1E48, 'M', u'ṉ'), - (0x1E49, 'V'), - (0x1E4A, 'M', u'ṋ'), - (0x1E4B, 'V'), - (0x1E4C, 'M', u'ṍ'), - (0x1E4D, 'V'), - (0x1E4E, 'M', u'ṏ'), - (0x1E4F, 'V'), - (0x1E50, 'M', u'ṑ'), - (0x1E51, 'V'), - (0x1E52, 'M', u'ṓ'), - (0x1E53, 'V'), - (0x1E54, 'M', u'ṕ'), - (0x1E55, 'V'), - (0x1E56, 'M', u'ṗ'), - (0x1E57, 'V'), - (0x1E58, 'M', u'ṙ'), - (0x1E59, 'V'), - (0x1E5A, 'M', u'ṛ'), - (0x1E5B, 'V'), - (0x1E5C, 'M', u'ṝ'), - (0x1E5D, 'V'), - (0x1E5E, 'M', u'ṟ'), - (0x1E5F, 'V'), - (0x1E60, 'M', u'ṡ'), - (0x1E61, 'V'), - (0x1E62, 'M', u'ṣ'), - (0x1E63, 'V'), - (0x1E64, 'M', u'ṥ'), - (0x1E65, 'V'), - (0x1E66, 'M', u'ṧ'), - (0x1E67, 'V'), - (0x1E68, 'M', u'ṩ'), - (0x1E69, 'V'), - (0x1E6A, 'M', u'ṫ'), - (0x1E6B, 'V'), - (0x1E6C, 'M', u'ṭ'), - (0x1E6D, 'V'), - (0x1E6E, 'M', u'ṯ'), - (0x1E6F, 'V'), - (0x1E70, 'M', u'ṱ'), - (0x1E71, 'V'), - (0x1E72, 'M', u'ṳ'), - (0x1E73, 'V'), - (0x1E74, 'M', u'ṵ'), - (0x1E75, 'V'), - (0x1E76, 'M', u'ṷ'), - (0x1E77, 'V'), - (0x1E78, 'M', u'ṹ'), - (0x1E79, 'V'), - (0x1E7A, 'M', u'ṻ'), - (0x1E7B, 'V'), - (0x1E7C, 'M', u'ṽ'), - (0x1E7D, 'V'), - (0x1E7E, 'M', u'ṿ'), - (0x1E7F, 'V'), - (0x1E80, 'M', u'ẁ'), - (0x1E81, 'V'), - (0x1E82, 'M', u'ẃ'), - (0x1E83, 'V'), - (0x1E84, 'M', u'ẅ'), - (0x1E85, 'V'), - (0x1E86, 'M', u'ẇ'), - (0x1E87, 'V'), - (0x1E88, 'M', u'ẉ'), - (0x1E89, 'V'), - (0x1E8A, 'M', u'ẋ'), - (0x1E8B, 'V'), - (0x1E8C, 'M', u'ẍ'), - (0x1E8D, 'V'), - (0x1E8E, 'M', u'ẏ'), - (0x1E8F, 'V'), - (0x1E90, 'M', u'ẑ'), - (0x1E91, 'V'), - (0x1E92, 'M', u'ẓ'), - (0x1E93, 'V'), - (0x1E94, 'M', u'ẕ'), - (0x1E95, 'V'), - (0x1E9A, 'M', u'aʾ'), - (0x1E9B, 'M', u'ṡ'), - (0x1E9C, 'V'), - (0x1E9E, 'M', u'ss'), - (0x1E9F, 'V'), - (0x1EA0, 'M', u'ạ'), - (0x1EA1, 'V'), - (0x1EA2, 'M', u'ả'), - (0x1EA3, 'V'), - (0x1EA4, 'M', u'ấ'), - (0x1EA5, 'V'), - (0x1EA6, 'M', u'ầ'), - (0x1EA7, 'V'), - (0x1EA8, 'M', u'ẩ'), - ] - -def _seg_18(): - return [ - (0x1EA9, 'V'), - (0x1EAA, 'M', u'ẫ'), - (0x1EAB, 'V'), - (0x1EAC, 'M', u'ậ'), - (0x1EAD, 'V'), - (0x1EAE, 'M', u'ắ'), - (0x1EAF, 'V'), - (0x1EB0, 'M', u'ằ'), - (0x1EB1, 'V'), - (0x1EB2, 'M', u'ẳ'), - (0x1EB3, 'V'), - (0x1EB4, 'M', u'ẵ'), - (0x1EB5, 'V'), - (0x1EB6, 'M', u'ặ'), - (0x1EB7, 'V'), - (0x1EB8, 'M', u'ẹ'), - (0x1EB9, 'V'), - (0x1EBA, 'M', u'ẻ'), - (0x1EBB, 'V'), - (0x1EBC, 'M', u'ẽ'), - (0x1EBD, 'V'), - (0x1EBE, 'M', u'ế'), - (0x1EBF, 'V'), - (0x1EC0, 'M', u'ề'), - (0x1EC1, 'V'), - (0x1EC2, 'M', u'ể'), - (0x1EC3, 'V'), - (0x1EC4, 'M', u'ễ'), - (0x1EC5, 'V'), - (0x1EC6, 'M', u'ệ'), - (0x1EC7, 'V'), - (0x1EC8, 'M', u'ỉ'), - (0x1EC9, 'V'), - (0x1ECA, 'M', u'ị'), - (0x1ECB, 'V'), - (0x1ECC, 'M', u'ọ'), - (0x1ECD, 'V'), - (0x1ECE, 'M', u'ỏ'), - (0x1ECF, 'V'), - (0x1ED0, 'M', u'ố'), - (0x1ED1, 'V'), - (0x1ED2, 'M', u'ồ'), - (0x1ED3, 'V'), - (0x1ED4, 'M', u'ổ'), - (0x1ED5, 'V'), - (0x1ED6, 'M', u'ỗ'), - (0x1ED7, 'V'), - (0x1ED8, 'M', u'ộ'), - (0x1ED9, 'V'), - (0x1EDA, 'M', u'ớ'), - (0x1EDB, 'V'), - (0x1EDC, 'M', u'ờ'), - (0x1EDD, 'V'), - (0x1EDE, 'M', u'ở'), - (0x1EDF, 'V'), - (0x1EE0, 'M', u'ỡ'), - (0x1EE1, 'V'), - (0x1EE2, 'M', u'ợ'), - (0x1EE3, 'V'), - (0x1EE4, 'M', u'ụ'), - (0x1EE5, 'V'), - (0x1EE6, 'M', u'ủ'), - (0x1EE7, 'V'), - (0x1EE8, 'M', u'ứ'), - (0x1EE9, 'V'), - (0x1EEA, 'M', u'ừ'), - (0x1EEB, 'V'), - (0x1EEC, 'M', u'ử'), - (0x1EED, 'V'), - (0x1EEE, 'M', u'ữ'), - (0x1EEF, 'V'), - (0x1EF0, 'M', u'ự'), - (0x1EF1, 'V'), - (0x1EF2, 'M', u'ỳ'), - (0x1EF3, 'V'), - (0x1EF4, 'M', u'ỵ'), - (0x1EF5, 'V'), - (0x1EF6, 'M', u'ỷ'), - (0x1EF7, 'V'), - (0x1EF8, 'M', u'ỹ'), - (0x1EF9, 'V'), - (0x1EFA, 'M', u'ỻ'), - (0x1EFB, 'V'), - (0x1EFC, 'M', u'ỽ'), - (0x1EFD, 'V'), - (0x1EFE, 'M', u'ỿ'), - (0x1EFF, 'V'), - (0x1F08, 'M', u'ἀ'), - (0x1F09, 'M', u'ἁ'), - (0x1F0A, 'M', u'ἂ'), - (0x1F0B, 'M', u'ἃ'), - (0x1F0C, 'M', u'ἄ'), - (0x1F0D, 'M', u'ἅ'), - (0x1F0E, 'M', u'ἆ'), - (0x1F0F, 'M', u'ἇ'), - (0x1F10, 'V'), - (0x1F16, 'X'), - (0x1F18, 'M', u'ἐ'), - (0x1F19, 'M', u'ἑ'), - (0x1F1A, 'M', u'ἒ'), - ] - -def _seg_19(): - return [ - (0x1F1B, 'M', u'ἓ'), - (0x1F1C, 'M', u'ἔ'), - (0x1F1D, 'M', u'ἕ'), - (0x1F1E, 'X'), - (0x1F20, 'V'), - (0x1F28, 'M', u'ἠ'), - (0x1F29, 'M', u'ἡ'), - (0x1F2A, 'M', u'ἢ'), - (0x1F2B, 'M', u'ἣ'), - (0x1F2C, 'M', u'ἤ'), - (0x1F2D, 'M', u'ἥ'), - (0x1F2E, 'M', u'ἦ'), - (0x1F2F, 'M', u'ἧ'), - (0x1F30, 'V'), - (0x1F38, 'M', u'ἰ'), - (0x1F39, 'M', u'ἱ'), - (0x1F3A, 'M', u'ἲ'), - (0x1F3B, 'M', u'ἳ'), - (0x1F3C, 'M', u'ἴ'), - (0x1F3D, 'M', u'ἵ'), - (0x1F3E, 'M', u'ἶ'), - (0x1F3F, 'M', u'ἷ'), - (0x1F40, 'V'), - (0x1F46, 'X'), - (0x1F48, 'M', u'ὀ'), - (0x1F49, 'M', u'ὁ'), - (0x1F4A, 'M', u'ὂ'), - (0x1F4B, 'M', u'ὃ'), - (0x1F4C, 'M', u'ὄ'), - (0x1F4D, 'M', u'ὅ'), - (0x1F4E, 'X'), - (0x1F50, 'V'), - (0x1F58, 'X'), - (0x1F59, 'M', u'ὑ'), - (0x1F5A, 'X'), - (0x1F5B, 'M', u'ὓ'), - (0x1F5C, 'X'), - (0x1F5D, 'M', u'ὕ'), - (0x1F5E, 'X'), - (0x1F5F, 'M', u'ὗ'), - (0x1F60, 'V'), - (0x1F68, 'M', u'ὠ'), - (0x1F69, 'M', u'ὡ'), - (0x1F6A, 'M', u'ὢ'), - (0x1F6B, 'M', u'ὣ'), - (0x1F6C, 'M', u'ὤ'), - (0x1F6D, 'M', u'ὥ'), - (0x1F6E, 'M', u'ὦ'), - (0x1F6F, 'M', u'ὧ'), - (0x1F70, 'V'), - (0x1F71, 'M', u'ά'), - (0x1F72, 'V'), - (0x1F73, 'M', u'έ'), - (0x1F74, 'V'), - (0x1F75, 'M', u'ή'), - (0x1F76, 'V'), - (0x1F77, 'M', u'ί'), - (0x1F78, 'V'), - (0x1F79, 'M', u'ό'), - (0x1F7A, 'V'), - (0x1F7B, 'M', u'ύ'), - (0x1F7C, 'V'), - (0x1F7D, 'M', u'ώ'), - (0x1F7E, 'X'), - (0x1F80, 'M', u'ἀι'), - (0x1F81, 'M', u'ἁι'), - (0x1F82, 'M', u'ἂι'), - (0x1F83, 'M', u'ἃι'), - (0x1F84, 'M', u'ἄι'), - (0x1F85, 'M', u'ἅι'), - (0x1F86, 'M', u'ἆι'), - (0x1F87, 'M', u'ἇι'), - (0x1F88, 'M', u'ἀι'), - (0x1F89, 'M', u'ἁι'), - (0x1F8A, 'M', u'ἂι'), - (0x1F8B, 'M', u'ἃι'), - (0x1F8C, 'M', u'ἄι'), - (0x1F8D, 'M', u'ἅι'), - (0x1F8E, 'M', u'ἆι'), - (0x1F8F, 'M', u'ἇι'), - (0x1F90, 'M', u'ἠι'), - (0x1F91, 'M', u'ἡι'), - (0x1F92, 'M', u'ἢι'), - (0x1F93, 'M', u'ἣι'), - (0x1F94, 'M', u'ἤι'), - (0x1F95, 'M', u'ἥι'), - (0x1F96, 'M', u'ἦι'), - (0x1F97, 'M', u'ἧι'), - (0x1F98, 'M', u'ἠι'), - (0x1F99, 'M', u'ἡι'), - (0x1F9A, 'M', u'ἢι'), - (0x1F9B, 'M', u'ἣι'), - (0x1F9C, 'M', u'ἤι'), - (0x1F9D, 'M', u'ἥι'), - (0x1F9E, 'M', u'ἦι'), - (0x1F9F, 'M', u'ἧι'), - (0x1FA0, 'M', u'ὠι'), - (0x1FA1, 'M', u'ὡι'), - (0x1FA2, 'M', u'ὢι'), - (0x1FA3, 'M', u'ὣι'), - ] - -def _seg_20(): - return [ - (0x1FA4, 'M', u'ὤι'), - (0x1FA5, 'M', u'ὥι'), - (0x1FA6, 'M', u'ὦι'), - (0x1FA7, 'M', u'ὧι'), - (0x1FA8, 'M', u'ὠι'), - (0x1FA9, 'M', u'ὡι'), - (0x1FAA, 'M', u'ὢι'), - (0x1FAB, 'M', u'ὣι'), - (0x1FAC, 'M', u'ὤι'), - (0x1FAD, 'M', u'ὥι'), - (0x1FAE, 'M', u'ὦι'), - (0x1FAF, 'M', u'ὧι'), - (0x1FB0, 'V'), - (0x1FB2, 'M', u'ὰι'), - (0x1FB3, 'M', u'αι'), - (0x1FB4, 'M', u'άι'), - (0x1FB5, 'X'), - (0x1FB6, 'V'), - (0x1FB7, 'M', u'ᾶι'), - (0x1FB8, 'M', u'ᾰ'), - (0x1FB9, 'M', u'ᾱ'), - (0x1FBA, 'M', u'ὰ'), - (0x1FBB, 'M', u'ά'), - (0x1FBC, 'M', u'αι'), - (0x1FBD, '3', u' ̓'), - (0x1FBE, 'M', u'ι'), - (0x1FBF, '3', u' ̓'), - (0x1FC0, '3', u' ͂'), - (0x1FC1, '3', u' ̈͂'), - (0x1FC2, 'M', u'ὴι'), - (0x1FC3, 'M', u'ηι'), - (0x1FC4, 'M', u'ήι'), - (0x1FC5, 'X'), - (0x1FC6, 'V'), - (0x1FC7, 'M', u'ῆι'), - (0x1FC8, 'M', u'ὲ'), - (0x1FC9, 'M', u'έ'), - (0x1FCA, 'M', u'ὴ'), - (0x1FCB, 'M', u'ή'), - (0x1FCC, 'M', u'ηι'), - (0x1FCD, '3', u' ̓̀'), - (0x1FCE, '3', u' ̓́'), - (0x1FCF, '3', u' ̓͂'), - (0x1FD0, 'V'), - (0x1FD3, 'M', u'ΐ'), - (0x1FD4, 'X'), - (0x1FD6, 'V'), - (0x1FD8, 'M', u'ῐ'), - (0x1FD9, 'M', u'ῑ'), - (0x1FDA, 'M', u'ὶ'), - (0x1FDB, 'M', u'ί'), - (0x1FDC, 'X'), - (0x1FDD, '3', u' ̔̀'), - (0x1FDE, '3', u' ̔́'), - (0x1FDF, '3', u' ̔͂'), - (0x1FE0, 'V'), - (0x1FE3, 'M', u'ΰ'), - (0x1FE4, 'V'), - (0x1FE8, 'M', u'ῠ'), - (0x1FE9, 'M', u'ῡ'), - (0x1FEA, 'M', u'ὺ'), - (0x1FEB, 'M', u'ύ'), - (0x1FEC, 'M', u'ῥ'), - (0x1FED, '3', u' ̈̀'), - (0x1FEE, '3', u' ̈́'), - (0x1FEF, '3', u'`'), - (0x1FF0, 'X'), - (0x1FF2, 'M', u'ὼι'), - (0x1FF3, 'M', u'ωι'), - (0x1FF4, 'M', u'ώι'), - (0x1FF5, 'X'), - (0x1FF6, 'V'), - (0x1FF7, 'M', u'ῶι'), - (0x1FF8, 'M', u'ὸ'), - (0x1FF9, 'M', u'ό'), - (0x1FFA, 'M', u'ὼ'), - (0x1FFB, 'M', u'ώ'), - (0x1FFC, 'M', u'ωι'), - (0x1FFD, '3', u' ́'), - (0x1FFE, '3', u' ̔'), - (0x1FFF, 'X'), - (0x2000, '3', u' '), - (0x200B, 'I'), - (0x200C, 'D', u''), - (0x200E, 'X'), - (0x2010, 'V'), - (0x2011, 'M', u'‐'), - (0x2012, 'V'), - (0x2017, '3', u' ̳'), - (0x2018, 'V'), - (0x2024, 'X'), - (0x2027, 'V'), - (0x2028, 'X'), - (0x202F, '3', u' '), - (0x2030, 'V'), - (0x2033, 'M', u'′′'), - (0x2034, 'M', u'′′′'), - (0x2035, 'V'), - (0x2036, 'M', u'‵‵'), - (0x2037, 'M', u'‵‵‵'), - ] - -def _seg_21(): - return [ - (0x2038, 'V'), - (0x203C, '3', u'!!'), - (0x203D, 'V'), - (0x203E, '3', u' ̅'), - (0x203F, 'V'), - (0x2047, '3', u'??'), - (0x2048, '3', u'?!'), - (0x2049, '3', u'!?'), - (0x204A, 'V'), - (0x2057, 'M', u'′′′′'), - (0x2058, 'V'), - (0x205F, '3', u' '), - (0x2060, 'I'), - (0x2061, 'X'), - (0x2064, 'I'), - (0x2065, 'X'), - (0x2070, 'M', u'0'), - (0x2071, 'M', u'i'), - (0x2072, 'X'), - (0x2074, 'M', u'4'), - (0x2075, 'M', u'5'), - (0x2076, 'M', u'6'), - (0x2077, 'M', u'7'), - (0x2078, 'M', u'8'), - (0x2079, 'M', u'9'), - (0x207A, '3', u'+'), - (0x207B, 'M', u'−'), - (0x207C, '3', u'='), - (0x207D, '3', u'('), - (0x207E, '3', u')'), - (0x207F, 'M', u'n'), - (0x2080, 'M', u'0'), - (0x2081, 'M', u'1'), - (0x2082, 'M', u'2'), - (0x2083, 'M', u'3'), - (0x2084, 'M', u'4'), - (0x2085, 'M', u'5'), - (0x2086, 'M', u'6'), - (0x2087, 'M', u'7'), - (0x2088, 'M', u'8'), - (0x2089, 'M', u'9'), - (0x208A, '3', u'+'), - (0x208B, 'M', u'−'), - (0x208C, '3', u'='), - (0x208D, '3', u'('), - (0x208E, '3', u')'), - (0x208F, 'X'), - (0x2090, 'M', u'a'), - (0x2091, 'M', u'e'), - (0x2092, 'M', u'o'), - (0x2093, 'M', u'x'), - (0x2094, 'M', u'ə'), - (0x2095, 'M', u'h'), - (0x2096, 'M', u'k'), - (0x2097, 'M', u'l'), - (0x2098, 'M', u'm'), - (0x2099, 'M', u'n'), - (0x209A, 'M', u'p'), - (0x209B, 'M', u's'), - (0x209C, 'M', u't'), - (0x209D, 'X'), - (0x20A0, 'V'), - (0x20A8, 'M', u'rs'), - (0x20A9, 'V'), - (0x20C0, 'X'), - (0x20D0, 'V'), - (0x20F1, 'X'), - (0x2100, '3', u'a/c'), - (0x2101, '3', u'a/s'), - (0x2102, 'M', u'c'), - (0x2103, 'M', u'°c'), - (0x2104, 'V'), - (0x2105, '3', u'c/o'), - (0x2106, '3', u'c/u'), - (0x2107, 'M', u'ɛ'), - (0x2108, 'V'), - (0x2109, 'M', u'°f'), - (0x210A, 'M', u'g'), - (0x210B, 'M', u'h'), - (0x210F, 'M', u'ħ'), - (0x2110, 'M', u'i'), - (0x2112, 'M', u'l'), - (0x2114, 'V'), - (0x2115, 'M', u'n'), - (0x2116, 'M', u'no'), - (0x2117, 'V'), - (0x2119, 'M', u'p'), - (0x211A, 'M', u'q'), - (0x211B, 'M', u'r'), - (0x211E, 'V'), - (0x2120, 'M', u'sm'), - (0x2121, 'M', u'tel'), - (0x2122, 'M', u'tm'), - (0x2123, 'V'), - (0x2124, 'M', u'z'), - (0x2125, 'V'), - (0x2126, 'M', u'ω'), - (0x2127, 'V'), - (0x2128, 'M', u'z'), - (0x2129, 'V'), - ] - -def _seg_22(): - return [ - (0x212A, 'M', u'k'), - (0x212B, 'M', u'å'), - (0x212C, 'M', u'b'), - (0x212D, 'M', u'c'), - (0x212E, 'V'), - (0x212F, 'M', u'e'), - (0x2131, 'M', u'f'), - (0x2132, 'X'), - (0x2133, 'M', u'm'), - (0x2134, 'M', u'o'), - (0x2135, 'M', u'א'), - (0x2136, 'M', u'ב'), - (0x2137, 'M', u'ג'), - (0x2138, 'M', u'ד'), - (0x2139, 'M', u'i'), - (0x213A, 'V'), - (0x213B, 'M', u'fax'), - (0x213C, 'M', u'π'), - (0x213D, 'M', u'γ'), - (0x213F, 'M', u'π'), - (0x2140, 'M', u'∑'), - (0x2141, 'V'), - (0x2145, 'M', u'd'), - (0x2147, 'M', u'e'), - (0x2148, 'M', u'i'), - (0x2149, 'M', u'j'), - (0x214A, 'V'), - (0x2150, 'M', u'1⁄7'), - (0x2151, 'M', u'1⁄9'), - (0x2152, 'M', u'1⁄10'), - (0x2153, 'M', u'1⁄3'), - (0x2154, 'M', u'2⁄3'), - (0x2155, 'M', u'1⁄5'), - (0x2156, 'M', u'2⁄5'), - (0x2157, 'M', u'3⁄5'), - (0x2158, 'M', u'4⁄5'), - (0x2159, 'M', u'1⁄6'), - (0x215A, 'M', u'5⁄6'), - (0x215B, 'M', u'1⁄8'), - (0x215C, 'M', u'3⁄8'), - (0x215D, 'M', u'5⁄8'), - (0x215E, 'M', u'7⁄8'), - (0x215F, 'M', u'1⁄'), - (0x2160, 'M', u'i'), - (0x2161, 'M', u'ii'), - (0x2162, 'M', u'iii'), - (0x2163, 'M', u'iv'), - (0x2164, 'M', u'v'), - (0x2165, 'M', u'vi'), - (0x2166, 'M', u'vii'), - (0x2167, 'M', u'viii'), - (0x2168, 'M', u'ix'), - (0x2169, 'M', u'x'), - (0x216A, 'M', u'xi'), - (0x216B, 'M', u'xii'), - (0x216C, 'M', u'l'), - (0x216D, 'M', u'c'), - (0x216E, 'M', u'd'), - (0x216F, 'M', u'm'), - (0x2170, 'M', u'i'), - (0x2171, 'M', u'ii'), - (0x2172, 'M', u'iii'), - (0x2173, 'M', u'iv'), - (0x2174, 'M', u'v'), - (0x2175, 'M', u'vi'), - (0x2176, 'M', u'vii'), - (0x2177, 'M', u'viii'), - (0x2178, 'M', u'ix'), - (0x2179, 'M', u'x'), - (0x217A, 'M', u'xi'), - (0x217B, 'M', u'xii'), - (0x217C, 'M', u'l'), - (0x217D, 'M', u'c'), - (0x217E, 'M', u'd'), - (0x217F, 'M', u'm'), - (0x2180, 'V'), - (0x2183, 'X'), - (0x2184, 'V'), - (0x2189, 'M', u'0⁄3'), - (0x218A, 'V'), - (0x218C, 'X'), - (0x2190, 'V'), - (0x222C, 'M', u'∫∫'), - (0x222D, 'M', u'∫∫∫'), - (0x222E, 'V'), - (0x222F, 'M', u'∮∮'), - (0x2230, 'M', u'∮∮∮'), - (0x2231, 'V'), - (0x2260, '3'), - (0x2261, 'V'), - (0x226E, '3'), - (0x2270, 'V'), - (0x2329, 'M', u'〈'), - (0x232A, 'M', u'〉'), - (0x232B, 'V'), - (0x2427, 'X'), - (0x2440, 'V'), - (0x244B, 'X'), - (0x2460, 'M', u'1'), - (0x2461, 'M', u'2'), - ] - -def _seg_23(): - return [ - (0x2462, 'M', u'3'), - (0x2463, 'M', u'4'), - (0x2464, 'M', u'5'), - (0x2465, 'M', u'6'), - (0x2466, 'M', u'7'), - (0x2467, 'M', u'8'), - (0x2468, 'M', u'9'), - (0x2469, 'M', u'10'), - (0x246A, 'M', u'11'), - (0x246B, 'M', u'12'), - (0x246C, 'M', u'13'), - (0x246D, 'M', u'14'), - (0x246E, 'M', u'15'), - (0x246F, 'M', u'16'), - (0x2470, 'M', u'17'), - (0x2471, 'M', u'18'), - (0x2472, 'M', u'19'), - (0x2473, 'M', u'20'), - (0x2474, '3', u'(1)'), - (0x2475, '3', u'(2)'), - (0x2476, '3', u'(3)'), - (0x2477, '3', u'(4)'), - (0x2478, '3', u'(5)'), - (0x2479, '3', u'(6)'), - (0x247A, '3', u'(7)'), - (0x247B, '3', u'(8)'), - (0x247C, '3', u'(9)'), - (0x247D, '3', u'(10)'), - (0x247E, '3', u'(11)'), - (0x247F, '3', u'(12)'), - (0x2480, '3', u'(13)'), - (0x2481, '3', u'(14)'), - (0x2482, '3', u'(15)'), - (0x2483, '3', u'(16)'), - (0x2484, '3', u'(17)'), - (0x2485, '3', u'(18)'), - (0x2486, '3', u'(19)'), - (0x2487, '3', u'(20)'), - (0x2488, 'X'), - (0x249C, '3', u'(a)'), - (0x249D, '3', u'(b)'), - (0x249E, '3', u'(c)'), - (0x249F, '3', u'(d)'), - (0x24A0, '3', u'(e)'), - (0x24A1, '3', u'(f)'), - (0x24A2, '3', u'(g)'), - (0x24A3, '3', u'(h)'), - (0x24A4, '3', u'(i)'), - (0x24A5, '3', u'(j)'), - (0x24A6, '3', u'(k)'), - (0x24A7, '3', u'(l)'), - (0x24A8, '3', u'(m)'), - (0x24A9, '3', u'(n)'), - (0x24AA, '3', u'(o)'), - (0x24AB, '3', u'(p)'), - (0x24AC, '3', u'(q)'), - (0x24AD, '3', u'(r)'), - (0x24AE, '3', u'(s)'), - (0x24AF, '3', u'(t)'), - (0x24B0, '3', u'(u)'), - (0x24B1, '3', u'(v)'), - (0x24B2, '3', u'(w)'), - (0x24B3, '3', u'(x)'), - (0x24B4, '3', u'(y)'), - (0x24B5, '3', u'(z)'), - (0x24B6, 'M', u'a'), - (0x24B7, 'M', u'b'), - (0x24B8, 'M', u'c'), - (0x24B9, 'M', u'd'), - (0x24BA, 'M', u'e'), - (0x24BB, 'M', u'f'), - (0x24BC, 'M', u'g'), - (0x24BD, 'M', u'h'), - (0x24BE, 'M', u'i'), - (0x24BF, 'M', u'j'), - (0x24C0, 'M', u'k'), - (0x24C1, 'M', u'l'), - (0x24C2, 'M', u'm'), - (0x24C3, 'M', u'n'), - (0x24C4, 'M', u'o'), - (0x24C5, 'M', u'p'), - (0x24C6, 'M', u'q'), - (0x24C7, 'M', u'r'), - (0x24C8, 'M', u's'), - (0x24C9, 'M', u't'), - (0x24CA, 'M', u'u'), - (0x24CB, 'M', u'v'), - (0x24CC, 'M', u'w'), - (0x24CD, 'M', u'x'), - (0x24CE, 'M', u'y'), - (0x24CF, 'M', u'z'), - (0x24D0, 'M', u'a'), - (0x24D1, 'M', u'b'), - (0x24D2, 'M', u'c'), - (0x24D3, 'M', u'd'), - (0x24D4, 'M', u'e'), - (0x24D5, 'M', u'f'), - (0x24D6, 'M', u'g'), - (0x24D7, 'M', u'h'), - (0x24D8, 'M', u'i'), - ] - -def _seg_24(): - return [ - (0x24D9, 'M', u'j'), - (0x24DA, 'M', u'k'), - (0x24DB, 'M', u'l'), - (0x24DC, 'M', u'm'), - (0x24DD, 'M', u'n'), - (0x24DE, 'M', u'o'), - (0x24DF, 'M', u'p'), - (0x24E0, 'M', u'q'), - (0x24E1, 'M', u'r'), - (0x24E2, 'M', u's'), - (0x24E3, 'M', u't'), - (0x24E4, 'M', u'u'), - (0x24E5, 'M', u'v'), - (0x24E6, 'M', u'w'), - (0x24E7, 'M', u'x'), - (0x24E8, 'M', u'y'), - (0x24E9, 'M', u'z'), - (0x24EA, 'M', u'0'), - (0x24EB, 'V'), - (0x2A0C, 'M', u'∫∫∫∫'), - (0x2A0D, 'V'), - (0x2A74, '3', u'::='), - (0x2A75, '3', u'=='), - (0x2A76, '3', u'==='), - (0x2A77, 'V'), - (0x2ADC, 'M', u'⫝̸'), - (0x2ADD, 'V'), - (0x2B74, 'X'), - (0x2B76, 'V'), - (0x2B96, 'X'), - (0x2B98, 'V'), - (0x2BC9, 'X'), - (0x2BCA, 'V'), - (0x2BFF, 'X'), - (0x2C00, 'M', u'ⰰ'), - (0x2C01, 'M', u'ⰱ'), - (0x2C02, 'M', u'ⰲ'), - (0x2C03, 'M', u'ⰳ'), - (0x2C04, 'M', u'ⰴ'), - (0x2C05, 'M', u'ⰵ'), - (0x2C06, 'M', u'ⰶ'), - (0x2C07, 'M', u'ⰷ'), - (0x2C08, 'M', u'ⰸ'), - (0x2C09, 'M', u'ⰹ'), - (0x2C0A, 'M', u'ⰺ'), - (0x2C0B, 'M', u'ⰻ'), - (0x2C0C, 'M', u'ⰼ'), - (0x2C0D, 'M', u'ⰽ'), - (0x2C0E, 'M', u'ⰾ'), - (0x2C0F, 'M', u'ⰿ'), - (0x2C10, 'M', u'ⱀ'), - (0x2C11, 'M', u'ⱁ'), - (0x2C12, 'M', u'ⱂ'), - (0x2C13, 'M', u'ⱃ'), - (0x2C14, 'M', u'ⱄ'), - (0x2C15, 'M', u'ⱅ'), - (0x2C16, 'M', u'ⱆ'), - (0x2C17, 'M', u'ⱇ'), - (0x2C18, 'M', u'ⱈ'), - (0x2C19, 'M', u'ⱉ'), - (0x2C1A, 'M', u'ⱊ'), - (0x2C1B, 'M', u'ⱋ'), - (0x2C1C, 'M', u'ⱌ'), - (0x2C1D, 'M', u'ⱍ'), - (0x2C1E, 'M', u'ⱎ'), - (0x2C1F, 'M', u'ⱏ'), - (0x2C20, 'M', u'ⱐ'), - (0x2C21, 'M', u'ⱑ'), - (0x2C22, 'M', u'ⱒ'), - (0x2C23, 'M', u'ⱓ'), - (0x2C24, 'M', u'ⱔ'), - (0x2C25, 'M', u'ⱕ'), - (0x2C26, 'M', u'ⱖ'), - (0x2C27, 'M', u'ⱗ'), - (0x2C28, 'M', u'ⱘ'), - (0x2C29, 'M', u'ⱙ'), - (0x2C2A, 'M', u'ⱚ'), - (0x2C2B, 'M', u'ⱛ'), - (0x2C2C, 'M', u'ⱜ'), - (0x2C2D, 'M', u'ⱝ'), - (0x2C2E, 'M', u'ⱞ'), - (0x2C2F, 'X'), - (0x2C30, 'V'), - (0x2C5F, 'X'), - (0x2C60, 'M', u'ⱡ'), - (0x2C61, 'V'), - (0x2C62, 'M', u'ɫ'), - (0x2C63, 'M', u'ᵽ'), - (0x2C64, 'M', u'ɽ'), - (0x2C65, 'V'), - (0x2C67, 'M', u'ⱨ'), - (0x2C68, 'V'), - (0x2C69, 'M', u'ⱪ'), - (0x2C6A, 'V'), - (0x2C6B, 'M', u'ⱬ'), - (0x2C6C, 'V'), - (0x2C6D, 'M', u'ɑ'), - (0x2C6E, 'M', u'ɱ'), - (0x2C6F, 'M', u'ɐ'), - (0x2C70, 'M', u'ɒ'), - ] - -def _seg_25(): - return [ - (0x2C71, 'V'), - (0x2C72, 'M', u'ⱳ'), - (0x2C73, 'V'), - (0x2C75, 'M', u'ⱶ'), - (0x2C76, 'V'), - (0x2C7C, 'M', u'j'), - (0x2C7D, 'M', u'v'), - (0x2C7E, 'M', u'ȿ'), - (0x2C7F, 'M', u'ɀ'), - (0x2C80, 'M', u'ⲁ'), - (0x2C81, 'V'), - (0x2C82, 'M', u'ⲃ'), - (0x2C83, 'V'), - (0x2C84, 'M', u'ⲅ'), - (0x2C85, 'V'), - (0x2C86, 'M', u'ⲇ'), - (0x2C87, 'V'), - (0x2C88, 'M', u'ⲉ'), - (0x2C89, 'V'), - (0x2C8A, 'M', u'ⲋ'), - (0x2C8B, 'V'), - (0x2C8C, 'M', u'ⲍ'), - (0x2C8D, 'V'), - (0x2C8E, 'M', u'ⲏ'), - (0x2C8F, 'V'), - (0x2C90, 'M', u'ⲑ'), - (0x2C91, 'V'), - (0x2C92, 'M', u'ⲓ'), - (0x2C93, 'V'), - (0x2C94, 'M', u'ⲕ'), - (0x2C95, 'V'), - (0x2C96, 'M', u'ⲗ'), - (0x2C97, 'V'), - (0x2C98, 'M', u'ⲙ'), - (0x2C99, 'V'), - (0x2C9A, 'M', u'ⲛ'), - (0x2C9B, 'V'), - (0x2C9C, 'M', u'ⲝ'), - (0x2C9D, 'V'), - (0x2C9E, 'M', u'ⲟ'), - (0x2C9F, 'V'), - (0x2CA0, 'M', u'ⲡ'), - (0x2CA1, 'V'), - (0x2CA2, 'M', u'ⲣ'), - (0x2CA3, 'V'), - (0x2CA4, 'M', u'ⲥ'), - (0x2CA5, 'V'), - (0x2CA6, 'M', u'ⲧ'), - (0x2CA7, 'V'), - (0x2CA8, 'M', u'ⲩ'), - (0x2CA9, 'V'), - (0x2CAA, 'M', u'ⲫ'), - (0x2CAB, 'V'), - (0x2CAC, 'M', u'ⲭ'), - (0x2CAD, 'V'), - (0x2CAE, 'M', u'ⲯ'), - (0x2CAF, 'V'), - (0x2CB0, 'M', u'ⲱ'), - (0x2CB1, 'V'), - (0x2CB2, 'M', u'ⲳ'), - (0x2CB3, 'V'), - (0x2CB4, 'M', u'ⲵ'), - (0x2CB5, 'V'), - (0x2CB6, 'M', u'ⲷ'), - (0x2CB7, 'V'), - (0x2CB8, 'M', u'ⲹ'), - (0x2CB9, 'V'), - (0x2CBA, 'M', u'ⲻ'), - (0x2CBB, 'V'), - (0x2CBC, 'M', u'ⲽ'), - (0x2CBD, 'V'), - (0x2CBE, 'M', u'ⲿ'), - (0x2CBF, 'V'), - (0x2CC0, 'M', u'ⳁ'), - (0x2CC1, 'V'), - (0x2CC2, 'M', u'ⳃ'), - (0x2CC3, 'V'), - (0x2CC4, 'M', u'ⳅ'), - (0x2CC5, 'V'), - (0x2CC6, 'M', u'ⳇ'), - (0x2CC7, 'V'), - (0x2CC8, 'M', u'ⳉ'), - (0x2CC9, 'V'), - (0x2CCA, 'M', u'ⳋ'), - (0x2CCB, 'V'), - (0x2CCC, 'M', u'ⳍ'), - (0x2CCD, 'V'), - (0x2CCE, 'M', u'ⳏ'), - (0x2CCF, 'V'), - (0x2CD0, 'M', u'ⳑ'), - (0x2CD1, 'V'), - (0x2CD2, 'M', u'ⳓ'), - (0x2CD3, 'V'), - (0x2CD4, 'M', u'ⳕ'), - (0x2CD5, 'V'), - (0x2CD6, 'M', u'ⳗ'), - (0x2CD7, 'V'), - (0x2CD8, 'M', u'ⳙ'), - (0x2CD9, 'V'), - (0x2CDA, 'M', u'ⳛ'), - ] - -def _seg_26(): - return [ - (0x2CDB, 'V'), - (0x2CDC, 'M', u'ⳝ'), - (0x2CDD, 'V'), - (0x2CDE, 'M', u'ⳟ'), - (0x2CDF, 'V'), - (0x2CE0, 'M', u'ⳡ'), - (0x2CE1, 'V'), - (0x2CE2, 'M', u'ⳣ'), - (0x2CE3, 'V'), - (0x2CEB, 'M', u'ⳬ'), - (0x2CEC, 'V'), - (0x2CED, 'M', u'ⳮ'), - (0x2CEE, 'V'), - (0x2CF2, 'M', u'ⳳ'), - (0x2CF3, 'V'), - (0x2CF4, 'X'), - (0x2CF9, 'V'), - (0x2D26, 'X'), - (0x2D27, 'V'), - (0x2D28, 'X'), - (0x2D2D, 'V'), - (0x2D2E, 'X'), - (0x2D30, 'V'), - (0x2D68, 'X'), - (0x2D6F, 'M', u'ⵡ'), - (0x2D70, 'V'), - (0x2D71, 'X'), - (0x2D7F, 'V'), - (0x2D97, 'X'), - (0x2DA0, 'V'), - (0x2DA7, 'X'), - (0x2DA8, 'V'), - (0x2DAF, 'X'), - (0x2DB0, 'V'), - (0x2DB7, 'X'), - (0x2DB8, 'V'), - (0x2DBF, 'X'), - (0x2DC0, 'V'), - (0x2DC7, 'X'), - (0x2DC8, 'V'), - (0x2DCF, 'X'), - (0x2DD0, 'V'), - (0x2DD7, 'X'), - (0x2DD8, 'V'), - (0x2DDF, 'X'), - (0x2DE0, 'V'), - (0x2E4F, 'X'), - (0x2E80, 'V'), - (0x2E9A, 'X'), - (0x2E9B, 'V'), - (0x2E9F, 'M', u'母'), - (0x2EA0, 'V'), - (0x2EF3, 'M', u'龟'), - (0x2EF4, 'X'), - (0x2F00, 'M', u'一'), - (0x2F01, 'M', u'丨'), - (0x2F02, 'M', u'丶'), - (0x2F03, 'M', u'丿'), - (0x2F04, 'M', u'乙'), - (0x2F05, 'M', u'亅'), - (0x2F06, 'M', u'二'), - (0x2F07, 'M', u'亠'), - (0x2F08, 'M', u'人'), - (0x2F09, 'M', u'儿'), - (0x2F0A, 'M', u'入'), - (0x2F0B, 'M', u'八'), - (0x2F0C, 'M', u'冂'), - (0x2F0D, 'M', u'冖'), - (0x2F0E, 'M', u'冫'), - (0x2F0F, 'M', u'几'), - (0x2F10, 'M', u'凵'), - (0x2F11, 'M', u'刀'), - (0x2F12, 'M', u'力'), - (0x2F13, 'M', u'勹'), - (0x2F14, 'M', u'匕'), - (0x2F15, 'M', u'匚'), - (0x2F16, 'M', u'匸'), - (0x2F17, 'M', u'十'), - (0x2F18, 'M', u'卜'), - (0x2F19, 'M', u'卩'), - (0x2F1A, 'M', u'厂'), - (0x2F1B, 'M', u'厶'), - (0x2F1C, 'M', u'又'), - (0x2F1D, 'M', u'口'), - (0x2F1E, 'M', u'囗'), - (0x2F1F, 'M', u'土'), - (0x2F20, 'M', u'士'), - (0x2F21, 'M', u'夂'), - (0x2F22, 'M', u'夊'), - (0x2F23, 'M', u'夕'), - (0x2F24, 'M', u'大'), - (0x2F25, 'M', u'女'), - (0x2F26, 'M', u'子'), - (0x2F27, 'M', u'宀'), - (0x2F28, 'M', u'寸'), - (0x2F29, 'M', u'小'), - (0x2F2A, 'M', u'尢'), - (0x2F2B, 'M', u'尸'), - (0x2F2C, 'M', u'屮'), - (0x2F2D, 'M', u'山'), - ] - -def _seg_27(): - return [ - (0x2F2E, 'M', u'巛'), - (0x2F2F, 'M', u'工'), - (0x2F30, 'M', u'己'), - (0x2F31, 'M', u'巾'), - (0x2F32, 'M', u'干'), - (0x2F33, 'M', u'幺'), - (0x2F34, 'M', u'广'), - (0x2F35, 'M', u'廴'), - (0x2F36, 'M', u'廾'), - (0x2F37, 'M', u'弋'), - (0x2F38, 'M', u'弓'), - (0x2F39, 'M', u'彐'), - (0x2F3A, 'M', u'彡'), - (0x2F3B, 'M', u'彳'), - (0x2F3C, 'M', u'心'), - (0x2F3D, 'M', u'戈'), - (0x2F3E, 'M', u'戶'), - (0x2F3F, 'M', u'手'), - (0x2F40, 'M', u'支'), - (0x2F41, 'M', u'攴'), - (0x2F42, 'M', u'文'), - (0x2F43, 'M', u'斗'), - (0x2F44, 'M', u'斤'), - (0x2F45, 'M', u'方'), - (0x2F46, 'M', u'无'), - (0x2F47, 'M', u'日'), - (0x2F48, 'M', u'曰'), - (0x2F49, 'M', u'月'), - (0x2F4A, 'M', u'木'), - (0x2F4B, 'M', u'欠'), - (0x2F4C, 'M', u'止'), - (0x2F4D, 'M', u'歹'), - (0x2F4E, 'M', u'殳'), - (0x2F4F, 'M', u'毋'), - (0x2F50, 'M', u'比'), - (0x2F51, 'M', u'毛'), - (0x2F52, 'M', u'氏'), - (0x2F53, 'M', u'气'), - (0x2F54, 'M', u'水'), - (0x2F55, 'M', u'火'), - (0x2F56, 'M', u'爪'), - (0x2F57, 'M', u'父'), - (0x2F58, 'M', u'爻'), - (0x2F59, 'M', u'爿'), - (0x2F5A, 'M', u'片'), - (0x2F5B, 'M', u'牙'), - (0x2F5C, 'M', u'牛'), - (0x2F5D, 'M', u'犬'), - (0x2F5E, 'M', u'玄'), - (0x2F5F, 'M', u'玉'), - (0x2F60, 'M', u'瓜'), - (0x2F61, 'M', u'瓦'), - (0x2F62, 'M', u'甘'), - (0x2F63, 'M', u'生'), - (0x2F64, 'M', u'用'), - (0x2F65, 'M', u'田'), - (0x2F66, 'M', u'疋'), - (0x2F67, 'M', u'疒'), - (0x2F68, 'M', u'癶'), - (0x2F69, 'M', u'白'), - (0x2F6A, 'M', u'皮'), - (0x2F6B, 'M', u'皿'), - (0x2F6C, 'M', u'目'), - (0x2F6D, 'M', u'矛'), - (0x2F6E, 'M', u'矢'), - (0x2F6F, 'M', u'石'), - (0x2F70, 'M', u'示'), - (0x2F71, 'M', u'禸'), - (0x2F72, 'M', u'禾'), - (0x2F73, 'M', u'穴'), - (0x2F74, 'M', u'立'), - (0x2F75, 'M', u'竹'), - (0x2F76, 'M', u'米'), - (0x2F77, 'M', u'糸'), - (0x2F78, 'M', u'缶'), - (0x2F79, 'M', u'网'), - (0x2F7A, 'M', u'羊'), - (0x2F7B, 'M', u'羽'), - (0x2F7C, 'M', u'老'), - (0x2F7D, 'M', u'而'), - (0x2F7E, 'M', u'耒'), - (0x2F7F, 'M', u'耳'), - (0x2F80, 'M', u'聿'), - (0x2F81, 'M', u'肉'), - (0x2F82, 'M', u'臣'), - (0x2F83, 'M', u'自'), - (0x2F84, 'M', u'至'), - (0x2F85, 'M', u'臼'), - (0x2F86, 'M', u'舌'), - (0x2F87, 'M', u'舛'), - (0x2F88, 'M', u'舟'), - (0x2F89, 'M', u'艮'), - (0x2F8A, 'M', u'色'), - (0x2F8B, 'M', u'艸'), - (0x2F8C, 'M', u'虍'), - (0x2F8D, 'M', u'虫'), - (0x2F8E, 'M', u'血'), - (0x2F8F, 'M', u'行'), - (0x2F90, 'M', u'衣'), - (0x2F91, 'M', u'襾'), - ] - -def _seg_28(): - return [ - (0x2F92, 'M', u'見'), - (0x2F93, 'M', u'角'), - (0x2F94, 'M', u'言'), - (0x2F95, 'M', u'谷'), - (0x2F96, 'M', u'豆'), - (0x2F97, 'M', u'豕'), - (0x2F98, 'M', u'豸'), - (0x2F99, 'M', u'貝'), - (0x2F9A, 'M', u'赤'), - (0x2F9B, 'M', u'走'), - (0x2F9C, 'M', u'足'), - (0x2F9D, 'M', u'身'), - (0x2F9E, 'M', u'車'), - (0x2F9F, 'M', u'辛'), - (0x2FA0, 'M', u'辰'), - (0x2FA1, 'M', u'辵'), - (0x2FA2, 'M', u'邑'), - (0x2FA3, 'M', u'酉'), - (0x2FA4, 'M', u'釆'), - (0x2FA5, 'M', u'里'), - (0x2FA6, 'M', u'金'), - (0x2FA7, 'M', u'長'), - (0x2FA8, 'M', u'門'), - (0x2FA9, 'M', u'阜'), - (0x2FAA, 'M', u'隶'), - (0x2FAB, 'M', u'隹'), - (0x2FAC, 'M', u'雨'), - (0x2FAD, 'M', u'靑'), - (0x2FAE, 'M', u'非'), - (0x2FAF, 'M', u'面'), - (0x2FB0, 'M', u'革'), - (0x2FB1, 'M', u'韋'), - (0x2FB2, 'M', u'韭'), - (0x2FB3, 'M', u'音'), - (0x2FB4, 'M', u'頁'), - (0x2FB5, 'M', u'風'), - (0x2FB6, 'M', u'飛'), - (0x2FB7, 'M', u'食'), - (0x2FB8, 'M', u'首'), - (0x2FB9, 'M', u'香'), - (0x2FBA, 'M', u'馬'), - (0x2FBB, 'M', u'骨'), - (0x2FBC, 'M', u'高'), - (0x2FBD, 'M', u'髟'), - (0x2FBE, 'M', u'鬥'), - (0x2FBF, 'M', u'鬯'), - (0x2FC0, 'M', u'鬲'), - (0x2FC1, 'M', u'鬼'), - (0x2FC2, 'M', u'魚'), - (0x2FC3, 'M', u'鳥'), - (0x2FC4, 'M', u'鹵'), - (0x2FC5, 'M', u'鹿'), - (0x2FC6, 'M', u'麥'), - (0x2FC7, 'M', u'麻'), - (0x2FC8, 'M', u'黃'), - (0x2FC9, 'M', u'黍'), - (0x2FCA, 'M', u'黑'), - (0x2FCB, 'M', u'黹'), - (0x2FCC, 'M', u'黽'), - (0x2FCD, 'M', u'鼎'), - (0x2FCE, 'M', u'鼓'), - (0x2FCF, 'M', u'鼠'), - (0x2FD0, 'M', u'鼻'), - (0x2FD1, 'M', u'齊'), - (0x2FD2, 'M', u'齒'), - (0x2FD3, 'M', u'龍'), - (0x2FD4, 'M', u'龜'), - (0x2FD5, 'M', u'龠'), - (0x2FD6, 'X'), - (0x3000, '3', u' '), - (0x3001, 'V'), - (0x3002, 'M', u'.'), - (0x3003, 'V'), - (0x3036, 'M', u'〒'), - (0x3037, 'V'), - (0x3038, 'M', u'十'), - (0x3039, 'M', u'卄'), - (0x303A, 'M', u'卅'), - (0x303B, 'V'), - (0x3040, 'X'), - (0x3041, 'V'), - (0x3097, 'X'), - (0x3099, 'V'), - (0x309B, '3', u' ゙'), - (0x309C, '3', u' ゚'), - (0x309D, 'V'), - (0x309F, 'M', u'より'), - (0x30A0, 'V'), - (0x30FF, 'M', u'コト'), - (0x3100, 'X'), - (0x3105, 'V'), - (0x3130, 'X'), - (0x3131, 'M', u'ᄀ'), - (0x3132, 'M', u'ᄁ'), - (0x3133, 'M', u'ᆪ'), - (0x3134, 'M', u'ᄂ'), - (0x3135, 'M', u'ᆬ'), - (0x3136, 'M', u'ᆭ'), - (0x3137, 'M', u'ᄃ'), - (0x3138, 'M', u'ᄄ'), - ] - -def _seg_29(): - return [ - (0x3139, 'M', u'ᄅ'), - (0x313A, 'M', u'ᆰ'), - (0x313B, 'M', u'ᆱ'), - (0x313C, 'M', u'ᆲ'), - (0x313D, 'M', u'ᆳ'), - (0x313E, 'M', u'ᆴ'), - (0x313F, 'M', u'ᆵ'), - (0x3140, 'M', u'ᄚ'), - (0x3141, 'M', u'ᄆ'), - (0x3142, 'M', u'ᄇ'), - (0x3143, 'M', u'ᄈ'), - (0x3144, 'M', u'ᄡ'), - (0x3145, 'M', u'ᄉ'), - (0x3146, 'M', u'ᄊ'), - (0x3147, 'M', u'ᄋ'), - (0x3148, 'M', u'ᄌ'), - (0x3149, 'M', u'ᄍ'), - (0x314A, 'M', u'ᄎ'), - (0x314B, 'M', u'ᄏ'), - (0x314C, 'M', u'ᄐ'), - (0x314D, 'M', u'ᄑ'), - (0x314E, 'M', u'ᄒ'), - (0x314F, 'M', u'ᅡ'), - (0x3150, 'M', u'ᅢ'), - (0x3151, 'M', u'ᅣ'), - (0x3152, 'M', u'ᅤ'), - (0x3153, 'M', u'ᅥ'), - (0x3154, 'M', u'ᅦ'), - (0x3155, 'M', u'ᅧ'), - (0x3156, 'M', u'ᅨ'), - (0x3157, 'M', u'ᅩ'), - (0x3158, 'M', u'ᅪ'), - (0x3159, 'M', u'ᅫ'), - (0x315A, 'M', u'ᅬ'), - (0x315B, 'M', u'ᅭ'), - (0x315C, 'M', u'ᅮ'), - (0x315D, 'M', u'ᅯ'), - (0x315E, 'M', u'ᅰ'), - (0x315F, 'M', u'ᅱ'), - (0x3160, 'M', u'ᅲ'), - (0x3161, 'M', u'ᅳ'), - (0x3162, 'M', u'ᅴ'), - (0x3163, 'M', u'ᅵ'), - (0x3164, 'X'), - (0x3165, 'M', u'ᄔ'), - (0x3166, 'M', u'ᄕ'), - (0x3167, 'M', u'ᇇ'), - (0x3168, 'M', u'ᇈ'), - (0x3169, 'M', u'ᇌ'), - (0x316A, 'M', u'ᇎ'), - (0x316B, 'M', u'ᇓ'), - (0x316C, 'M', u'ᇗ'), - (0x316D, 'M', u'ᇙ'), - (0x316E, 'M', u'ᄜ'), - (0x316F, 'M', u'ᇝ'), - (0x3170, 'M', u'ᇟ'), - (0x3171, 'M', u'ᄝ'), - (0x3172, 'M', u'ᄞ'), - (0x3173, 'M', u'ᄠ'), - (0x3174, 'M', u'ᄢ'), - (0x3175, 'M', u'ᄣ'), - (0x3176, 'M', u'ᄧ'), - (0x3177, 'M', u'ᄩ'), - (0x3178, 'M', u'ᄫ'), - (0x3179, 'M', u'ᄬ'), - (0x317A, 'M', u'ᄭ'), - (0x317B, 'M', u'ᄮ'), - (0x317C, 'M', u'ᄯ'), - (0x317D, 'M', u'ᄲ'), - (0x317E, 'M', u'ᄶ'), - (0x317F, 'M', u'ᅀ'), - (0x3180, 'M', u'ᅇ'), - (0x3181, 'M', u'ᅌ'), - (0x3182, 'M', u'ᇱ'), - (0x3183, 'M', u'ᇲ'), - (0x3184, 'M', u'ᅗ'), - (0x3185, 'M', u'ᅘ'), - (0x3186, 'M', u'ᅙ'), - (0x3187, 'M', u'ᆄ'), - (0x3188, 'M', u'ᆅ'), - (0x3189, 'M', u'ᆈ'), - (0x318A, 'M', u'ᆑ'), - (0x318B, 'M', u'ᆒ'), - (0x318C, 'M', u'ᆔ'), - (0x318D, 'M', u'ᆞ'), - (0x318E, 'M', u'ᆡ'), - (0x318F, 'X'), - (0x3190, 'V'), - (0x3192, 'M', u'一'), - (0x3193, 'M', u'二'), - (0x3194, 'M', u'三'), - (0x3195, 'M', u'四'), - (0x3196, 'M', u'上'), - (0x3197, 'M', u'中'), - (0x3198, 'M', u'下'), - (0x3199, 'M', u'甲'), - (0x319A, 'M', u'乙'), - (0x319B, 'M', u'丙'), - (0x319C, 'M', u'丁'), - (0x319D, 'M', u'天'), - ] - -def _seg_30(): - return [ - (0x319E, 'M', u'地'), - (0x319F, 'M', u'人'), - (0x31A0, 'V'), - (0x31BB, 'X'), - (0x31C0, 'V'), - (0x31E4, 'X'), - (0x31F0, 'V'), - (0x3200, '3', u'(ᄀ)'), - (0x3201, '3', u'(ᄂ)'), - (0x3202, '3', u'(ᄃ)'), - (0x3203, '3', u'(ᄅ)'), - (0x3204, '3', u'(ᄆ)'), - (0x3205, '3', u'(ᄇ)'), - (0x3206, '3', u'(ᄉ)'), - (0x3207, '3', u'(ᄋ)'), - (0x3208, '3', u'(ᄌ)'), - (0x3209, '3', u'(ᄎ)'), - (0x320A, '3', u'(ᄏ)'), - (0x320B, '3', u'(ᄐ)'), - (0x320C, '3', u'(ᄑ)'), - (0x320D, '3', u'(ᄒ)'), - (0x320E, '3', u'(가)'), - (0x320F, '3', u'(나)'), - (0x3210, '3', u'(다)'), - (0x3211, '3', u'(라)'), - (0x3212, '3', u'(마)'), - (0x3213, '3', u'(바)'), - (0x3214, '3', u'(사)'), - (0x3215, '3', u'(아)'), - (0x3216, '3', u'(자)'), - (0x3217, '3', u'(차)'), - (0x3218, '3', u'(카)'), - (0x3219, '3', u'(타)'), - (0x321A, '3', u'(파)'), - (0x321B, '3', u'(하)'), - (0x321C, '3', u'(주)'), - (0x321D, '3', u'(오전)'), - (0x321E, '3', u'(오후)'), - (0x321F, 'X'), - (0x3220, '3', u'(一)'), - (0x3221, '3', u'(二)'), - (0x3222, '3', u'(三)'), - (0x3223, '3', u'(四)'), - (0x3224, '3', u'(五)'), - (0x3225, '3', u'(六)'), - (0x3226, '3', u'(七)'), - (0x3227, '3', u'(八)'), - (0x3228, '3', u'(九)'), - (0x3229, '3', u'(十)'), - (0x322A, '3', u'(月)'), - (0x322B, '3', u'(火)'), - (0x322C, '3', u'(水)'), - (0x322D, '3', u'(木)'), - (0x322E, '3', u'(金)'), - (0x322F, '3', u'(土)'), - (0x3230, '3', u'(日)'), - (0x3231, '3', u'(株)'), - (0x3232, '3', u'(有)'), - (0x3233, '3', u'(社)'), - (0x3234, '3', u'(名)'), - (0x3235, '3', u'(特)'), - (0x3236, '3', u'(財)'), - (0x3237, '3', u'(祝)'), - (0x3238, '3', u'(労)'), - (0x3239, '3', u'(代)'), - (0x323A, '3', u'(呼)'), - (0x323B, '3', u'(学)'), - (0x323C, '3', u'(監)'), - (0x323D, '3', u'(企)'), - (0x323E, '3', u'(資)'), - (0x323F, '3', u'(協)'), - (0x3240, '3', u'(祭)'), - (0x3241, '3', u'(休)'), - (0x3242, '3', u'(自)'), - (0x3243, '3', u'(至)'), - (0x3244, 'M', u'問'), - (0x3245, 'M', u'幼'), - (0x3246, 'M', u'文'), - (0x3247, 'M', u'箏'), - (0x3248, 'V'), - (0x3250, 'M', u'pte'), - (0x3251, 'M', u'21'), - (0x3252, 'M', u'22'), - (0x3253, 'M', u'23'), - (0x3254, 'M', u'24'), - (0x3255, 'M', u'25'), - (0x3256, 'M', u'26'), - (0x3257, 'M', u'27'), - (0x3258, 'M', u'28'), - (0x3259, 'M', u'29'), - (0x325A, 'M', u'30'), - (0x325B, 'M', u'31'), - (0x325C, 'M', u'32'), - (0x325D, 'M', u'33'), - (0x325E, 'M', u'34'), - (0x325F, 'M', u'35'), - (0x3260, 'M', u'ᄀ'), - (0x3261, 'M', u'ᄂ'), - (0x3262, 'M', u'ᄃ'), - (0x3263, 'M', u'ᄅ'), - ] - -def _seg_31(): - return [ - (0x3264, 'M', u'ᄆ'), - (0x3265, 'M', u'ᄇ'), - (0x3266, 'M', u'ᄉ'), - (0x3267, 'M', u'ᄋ'), - (0x3268, 'M', u'ᄌ'), - (0x3269, 'M', u'ᄎ'), - (0x326A, 'M', u'ᄏ'), - (0x326B, 'M', u'ᄐ'), - (0x326C, 'M', u'ᄑ'), - (0x326D, 'M', u'ᄒ'), - (0x326E, 'M', u'가'), - (0x326F, 'M', u'나'), - (0x3270, 'M', u'다'), - (0x3271, 'M', u'라'), - (0x3272, 'M', u'마'), - (0x3273, 'M', u'바'), - (0x3274, 'M', u'사'), - (0x3275, 'M', u'아'), - (0x3276, 'M', u'자'), - (0x3277, 'M', u'차'), - (0x3278, 'M', u'카'), - (0x3279, 'M', u'타'), - (0x327A, 'M', u'파'), - (0x327B, 'M', u'하'), - (0x327C, 'M', u'참고'), - (0x327D, 'M', u'주의'), - (0x327E, 'M', u'우'), - (0x327F, 'V'), - (0x3280, 'M', u'一'), - (0x3281, 'M', u'二'), - (0x3282, 'M', u'三'), - (0x3283, 'M', u'四'), - (0x3284, 'M', u'五'), - (0x3285, 'M', u'六'), - (0x3286, 'M', u'七'), - (0x3287, 'M', u'八'), - (0x3288, 'M', u'九'), - (0x3289, 'M', u'十'), - (0x328A, 'M', u'月'), - (0x328B, 'M', u'火'), - (0x328C, 'M', u'水'), - (0x328D, 'M', u'木'), - (0x328E, 'M', u'金'), - (0x328F, 'M', u'土'), - (0x3290, 'M', u'日'), - (0x3291, 'M', u'株'), - (0x3292, 'M', u'有'), - (0x3293, 'M', u'社'), - (0x3294, 'M', u'名'), - (0x3295, 'M', u'特'), - (0x3296, 'M', u'財'), - (0x3297, 'M', u'祝'), - (0x3298, 'M', u'労'), - (0x3299, 'M', u'秘'), - (0x329A, 'M', u'男'), - (0x329B, 'M', u'女'), - (0x329C, 'M', u'適'), - (0x329D, 'M', u'優'), - (0x329E, 'M', u'印'), - (0x329F, 'M', u'注'), - (0x32A0, 'M', u'項'), - (0x32A1, 'M', u'休'), - (0x32A2, 'M', u'写'), - (0x32A3, 'M', u'正'), - (0x32A4, 'M', u'上'), - (0x32A5, 'M', u'中'), - (0x32A6, 'M', u'下'), - (0x32A7, 'M', u'左'), - (0x32A8, 'M', u'右'), - (0x32A9, 'M', u'医'), - (0x32AA, 'M', u'宗'), - (0x32AB, 'M', u'学'), - (0x32AC, 'M', u'監'), - (0x32AD, 'M', u'企'), - (0x32AE, 'M', u'資'), - (0x32AF, 'M', u'協'), - (0x32B0, 'M', u'夜'), - (0x32B1, 'M', u'36'), - (0x32B2, 'M', u'37'), - (0x32B3, 'M', u'38'), - (0x32B4, 'M', u'39'), - (0x32B5, 'M', u'40'), - (0x32B6, 'M', u'41'), - (0x32B7, 'M', u'42'), - (0x32B8, 'M', u'43'), - (0x32B9, 'M', u'44'), - (0x32BA, 'M', u'45'), - (0x32BB, 'M', u'46'), - (0x32BC, 'M', u'47'), - (0x32BD, 'M', u'48'), - (0x32BE, 'M', u'49'), - (0x32BF, 'M', u'50'), - (0x32C0, 'M', u'1月'), - (0x32C1, 'M', u'2月'), - (0x32C2, 'M', u'3月'), - (0x32C3, 'M', u'4月'), - (0x32C4, 'M', u'5月'), - (0x32C5, 'M', u'6月'), - (0x32C6, 'M', u'7月'), - (0x32C7, 'M', u'8月'), - ] - -def _seg_32(): - return [ - (0x32C8, 'M', u'9月'), - (0x32C9, 'M', u'10月'), - (0x32CA, 'M', u'11月'), - (0x32CB, 'M', u'12月'), - (0x32CC, 'M', u'hg'), - (0x32CD, 'M', u'erg'), - (0x32CE, 'M', u'ev'), - (0x32CF, 'M', u'ltd'), - (0x32D0, 'M', u'ア'), - (0x32D1, 'M', u'イ'), - (0x32D2, 'M', u'ウ'), - (0x32D3, 'M', u'エ'), - (0x32D4, 'M', u'オ'), - (0x32D5, 'M', u'カ'), - (0x32D6, 'M', u'キ'), - (0x32D7, 'M', u'ク'), - (0x32D8, 'M', u'ケ'), - (0x32D9, 'M', u'コ'), - (0x32DA, 'M', u'サ'), - (0x32DB, 'M', u'シ'), - (0x32DC, 'M', u'ス'), - (0x32DD, 'M', u'セ'), - (0x32DE, 'M', u'ソ'), - (0x32DF, 'M', u'タ'), - (0x32E0, 'M', u'チ'), - (0x32E1, 'M', u'ツ'), - (0x32E2, 'M', u'テ'), - (0x32E3, 'M', u'ト'), - (0x32E4, 'M', u'ナ'), - (0x32E5, 'M', u'ニ'), - (0x32E6, 'M', u'ヌ'), - (0x32E7, 'M', u'ネ'), - (0x32E8, 'M', u'ノ'), - (0x32E9, 'M', u'ハ'), - (0x32EA, 'M', u'ヒ'), - (0x32EB, 'M', u'フ'), - (0x32EC, 'M', u'ヘ'), - (0x32ED, 'M', u'ホ'), - (0x32EE, 'M', u'マ'), - (0x32EF, 'M', u'ミ'), - (0x32F0, 'M', u'ム'), - (0x32F1, 'M', u'メ'), - (0x32F2, 'M', u'モ'), - (0x32F3, 'M', u'ヤ'), - (0x32F4, 'M', u'ユ'), - (0x32F5, 'M', u'ヨ'), - (0x32F6, 'M', u'ラ'), - (0x32F7, 'M', u'リ'), - (0x32F8, 'M', u'ル'), - (0x32F9, 'M', u'レ'), - (0x32FA, 'M', u'ロ'), - (0x32FB, 'M', u'ワ'), - (0x32FC, 'M', u'ヰ'), - (0x32FD, 'M', u'ヱ'), - (0x32FE, 'M', u'ヲ'), - (0x32FF, 'X'), - (0x3300, 'M', u'アパート'), - (0x3301, 'M', u'アルファ'), - (0x3302, 'M', u'アンペア'), - (0x3303, 'M', u'アール'), - (0x3304, 'M', u'イニング'), - (0x3305, 'M', u'インチ'), - (0x3306, 'M', u'ウォン'), - (0x3307, 'M', u'エスクード'), - (0x3308, 'M', u'エーカー'), - (0x3309, 'M', u'オンス'), - (0x330A, 'M', u'オーム'), - (0x330B, 'M', u'カイリ'), - (0x330C, 'M', u'カラット'), - (0x330D, 'M', u'カロリー'), - (0x330E, 'M', u'ガロン'), - (0x330F, 'M', u'ガンマ'), - (0x3310, 'M', u'ギガ'), - (0x3311, 'M', u'ギニー'), - (0x3312, 'M', u'キュリー'), - (0x3313, 'M', u'ギルダー'), - (0x3314, 'M', u'キロ'), - (0x3315, 'M', u'キログラム'), - (0x3316, 'M', u'キロメートル'), - (0x3317, 'M', u'キロワット'), - (0x3318, 'M', u'グラム'), - (0x3319, 'M', u'グラムトン'), - (0x331A, 'M', u'クルゼイロ'), - (0x331B, 'M', u'クローネ'), - (0x331C, 'M', u'ケース'), - (0x331D, 'M', u'コルナ'), - (0x331E, 'M', u'コーポ'), - (0x331F, 'M', u'サイクル'), - (0x3320, 'M', u'サンチーム'), - (0x3321, 'M', u'シリング'), - (0x3322, 'M', u'センチ'), - (0x3323, 'M', u'セント'), - (0x3324, 'M', u'ダース'), - (0x3325, 'M', u'デシ'), - (0x3326, 'M', u'ドル'), - (0x3327, 'M', u'トン'), - (0x3328, 'M', u'ナノ'), - (0x3329, 'M', u'ノット'), - (0x332A, 'M', u'ハイツ'), - (0x332B, 'M', u'パーセント'), - ] - -def _seg_33(): - return [ - (0x332C, 'M', u'パーツ'), - (0x332D, 'M', u'バーレル'), - (0x332E, 'M', u'ピアストル'), - (0x332F, 'M', u'ピクル'), - (0x3330, 'M', u'ピコ'), - (0x3331, 'M', u'ビル'), - (0x3332, 'M', u'ファラッド'), - (0x3333, 'M', u'フィート'), - (0x3334, 'M', u'ブッシェル'), - (0x3335, 'M', u'フラン'), - (0x3336, 'M', u'ヘクタール'), - (0x3337, 'M', u'ペソ'), - (0x3338, 'M', u'ペニヒ'), - (0x3339, 'M', u'ヘルツ'), - (0x333A, 'M', u'ペンス'), - (0x333B, 'M', u'ページ'), - (0x333C, 'M', u'ベータ'), - (0x333D, 'M', u'ポイント'), - (0x333E, 'M', u'ボルト'), - (0x333F, 'M', u'ホン'), - (0x3340, 'M', u'ポンド'), - (0x3341, 'M', u'ホール'), - (0x3342, 'M', u'ホーン'), - (0x3343, 'M', u'マイクロ'), - (0x3344, 'M', u'マイル'), - (0x3345, 'M', u'マッハ'), - (0x3346, 'M', u'マルク'), - (0x3347, 'M', u'マンション'), - (0x3348, 'M', u'ミクロン'), - (0x3349, 'M', u'ミリ'), - (0x334A, 'M', u'ミリバール'), - (0x334B, 'M', u'メガ'), - (0x334C, 'M', u'メガトン'), - (0x334D, 'M', u'メートル'), - (0x334E, 'M', u'ヤード'), - (0x334F, 'M', u'ヤール'), - (0x3350, 'M', u'ユアン'), - (0x3351, 'M', u'リットル'), - (0x3352, 'M', u'リラ'), - (0x3353, 'M', u'ルピー'), - (0x3354, 'M', u'ルーブル'), - (0x3355, 'M', u'レム'), - (0x3356, 'M', u'レントゲン'), - (0x3357, 'M', u'ワット'), - (0x3358, 'M', u'0点'), - (0x3359, 'M', u'1点'), - (0x335A, 'M', u'2点'), - (0x335B, 'M', u'3点'), - (0x335C, 'M', u'4点'), - (0x335D, 'M', u'5点'), - (0x335E, 'M', u'6点'), - (0x335F, 'M', u'7点'), - (0x3360, 'M', u'8点'), - (0x3361, 'M', u'9点'), - (0x3362, 'M', u'10点'), - (0x3363, 'M', u'11点'), - (0x3364, 'M', u'12点'), - (0x3365, 'M', u'13点'), - (0x3366, 'M', u'14点'), - (0x3367, 'M', u'15点'), - (0x3368, 'M', u'16点'), - (0x3369, 'M', u'17点'), - (0x336A, 'M', u'18点'), - (0x336B, 'M', u'19点'), - (0x336C, 'M', u'20点'), - (0x336D, 'M', u'21点'), - (0x336E, 'M', u'22点'), - (0x336F, 'M', u'23点'), - (0x3370, 'M', u'24点'), - (0x3371, 'M', u'hpa'), - (0x3372, 'M', u'da'), - (0x3373, 'M', u'au'), - (0x3374, 'M', u'bar'), - (0x3375, 'M', u'ov'), - (0x3376, 'M', u'pc'), - (0x3377, 'M', u'dm'), - (0x3378, 'M', u'dm2'), - (0x3379, 'M', u'dm3'), - (0x337A, 'M', u'iu'), - (0x337B, 'M', u'平成'), - (0x337C, 'M', u'昭和'), - (0x337D, 'M', u'大正'), - (0x337E, 'M', u'明治'), - (0x337F, 'M', u'株式会社'), - (0x3380, 'M', u'pa'), - (0x3381, 'M', u'na'), - (0x3382, 'M', u'μa'), - (0x3383, 'M', u'ma'), - (0x3384, 'M', u'ka'), - (0x3385, 'M', u'kb'), - (0x3386, 'M', u'mb'), - (0x3387, 'M', u'gb'), - (0x3388, 'M', u'cal'), - (0x3389, 'M', u'kcal'), - (0x338A, 'M', u'pf'), - (0x338B, 'M', u'nf'), - (0x338C, 'M', u'μf'), - (0x338D, 'M', u'μg'), - (0x338E, 'M', u'mg'), - (0x338F, 'M', u'kg'), - ] - -def _seg_34(): - return [ - (0x3390, 'M', u'hz'), - (0x3391, 'M', u'khz'), - (0x3392, 'M', u'mhz'), - (0x3393, 'M', u'ghz'), - (0x3394, 'M', u'thz'), - (0x3395, 'M', u'μl'), - (0x3396, 'M', u'ml'), - (0x3397, 'M', u'dl'), - (0x3398, 'M', u'kl'), - (0x3399, 'M', u'fm'), - (0x339A, 'M', u'nm'), - (0x339B, 'M', u'μm'), - (0x339C, 'M', u'mm'), - (0x339D, 'M', u'cm'), - (0x339E, 'M', u'km'), - (0x339F, 'M', u'mm2'), - (0x33A0, 'M', u'cm2'), - (0x33A1, 'M', u'm2'), - (0x33A2, 'M', u'km2'), - (0x33A3, 'M', u'mm3'), - (0x33A4, 'M', u'cm3'), - (0x33A5, 'M', u'm3'), - (0x33A6, 'M', u'km3'), - (0x33A7, 'M', u'm∕s'), - (0x33A8, 'M', u'm∕s2'), - (0x33A9, 'M', u'pa'), - (0x33AA, 'M', u'kpa'), - (0x33AB, 'M', u'mpa'), - (0x33AC, 'M', u'gpa'), - (0x33AD, 'M', u'rad'), - (0x33AE, 'M', u'rad∕s'), - (0x33AF, 'M', u'rad∕s2'), - (0x33B0, 'M', u'ps'), - (0x33B1, 'M', u'ns'), - (0x33B2, 'M', u'μs'), - (0x33B3, 'M', u'ms'), - (0x33B4, 'M', u'pv'), - (0x33B5, 'M', u'nv'), - (0x33B6, 'M', u'μv'), - (0x33B7, 'M', u'mv'), - (0x33B8, 'M', u'kv'), - (0x33B9, 'M', u'mv'), - (0x33BA, 'M', u'pw'), - (0x33BB, 'M', u'nw'), - (0x33BC, 'M', u'μw'), - (0x33BD, 'M', u'mw'), - (0x33BE, 'M', u'kw'), - (0x33BF, 'M', u'mw'), - (0x33C0, 'M', u'kω'), - (0x33C1, 'M', u'mω'), - (0x33C2, 'X'), - (0x33C3, 'M', u'bq'), - (0x33C4, 'M', u'cc'), - (0x33C5, 'M', u'cd'), - (0x33C6, 'M', u'c∕kg'), - (0x33C7, 'X'), - (0x33C8, 'M', u'db'), - (0x33C9, 'M', u'gy'), - (0x33CA, 'M', u'ha'), - (0x33CB, 'M', u'hp'), - (0x33CC, 'M', u'in'), - (0x33CD, 'M', u'kk'), - (0x33CE, 'M', u'km'), - (0x33CF, 'M', u'kt'), - (0x33D0, 'M', u'lm'), - (0x33D1, 'M', u'ln'), - (0x33D2, 'M', u'log'), - (0x33D3, 'M', u'lx'), - (0x33D4, 'M', u'mb'), - (0x33D5, 'M', u'mil'), - (0x33D6, 'M', u'mol'), - (0x33D7, 'M', u'ph'), - (0x33D8, 'X'), - (0x33D9, 'M', u'ppm'), - (0x33DA, 'M', u'pr'), - (0x33DB, 'M', u'sr'), - (0x33DC, 'M', u'sv'), - (0x33DD, 'M', u'wb'), - (0x33DE, 'M', u'v∕m'), - (0x33DF, 'M', u'a∕m'), - (0x33E0, 'M', u'1日'), - (0x33E1, 'M', u'2日'), - (0x33E2, 'M', u'3日'), - (0x33E3, 'M', u'4日'), - (0x33E4, 'M', u'5日'), - (0x33E5, 'M', u'6日'), - (0x33E6, 'M', u'7日'), - (0x33E7, 'M', u'8日'), - (0x33E8, 'M', u'9日'), - (0x33E9, 'M', u'10日'), - (0x33EA, 'M', u'11日'), - (0x33EB, 'M', u'12日'), - (0x33EC, 'M', u'13日'), - (0x33ED, 'M', u'14日'), - (0x33EE, 'M', u'15日'), - (0x33EF, 'M', u'16日'), - (0x33F0, 'M', u'17日'), - (0x33F1, 'M', u'18日'), - (0x33F2, 'M', u'19日'), - (0x33F3, 'M', u'20日'), - ] - -def _seg_35(): - return [ - (0x33F4, 'M', u'21日'), - (0x33F5, 'M', u'22日'), - (0x33F6, 'M', u'23日'), - (0x33F7, 'M', u'24日'), - (0x33F8, 'M', u'25日'), - (0x33F9, 'M', u'26日'), - (0x33FA, 'M', u'27日'), - (0x33FB, 'M', u'28日'), - (0x33FC, 'M', u'29日'), - (0x33FD, 'M', u'30日'), - (0x33FE, 'M', u'31日'), - (0x33FF, 'M', u'gal'), - (0x3400, 'V'), - (0x4DB6, 'X'), - (0x4DC0, 'V'), - (0x9FF0, 'X'), - (0xA000, 'V'), - (0xA48D, 'X'), - (0xA490, 'V'), - (0xA4C7, 'X'), - (0xA4D0, 'V'), - (0xA62C, 'X'), - (0xA640, 'M', u'ꙁ'), - (0xA641, 'V'), - (0xA642, 'M', u'ꙃ'), - (0xA643, 'V'), - (0xA644, 'M', u'ꙅ'), - (0xA645, 'V'), - (0xA646, 'M', u'ꙇ'), - (0xA647, 'V'), - (0xA648, 'M', u'ꙉ'), - (0xA649, 'V'), - (0xA64A, 'M', u'ꙋ'), - (0xA64B, 'V'), - (0xA64C, 'M', u'ꙍ'), - (0xA64D, 'V'), - (0xA64E, 'M', u'ꙏ'), - (0xA64F, 'V'), - (0xA650, 'M', u'ꙑ'), - (0xA651, 'V'), - (0xA652, 'M', u'ꙓ'), - (0xA653, 'V'), - (0xA654, 'M', u'ꙕ'), - (0xA655, 'V'), - (0xA656, 'M', u'ꙗ'), - (0xA657, 'V'), - (0xA658, 'M', u'ꙙ'), - (0xA659, 'V'), - (0xA65A, 'M', u'ꙛ'), - (0xA65B, 'V'), - (0xA65C, 'M', u'ꙝ'), - (0xA65D, 'V'), - (0xA65E, 'M', u'ꙟ'), - (0xA65F, 'V'), - (0xA660, 'M', u'ꙡ'), - (0xA661, 'V'), - (0xA662, 'M', u'ꙣ'), - (0xA663, 'V'), - (0xA664, 'M', u'ꙥ'), - (0xA665, 'V'), - (0xA666, 'M', u'ꙧ'), - (0xA667, 'V'), - (0xA668, 'M', u'ꙩ'), - (0xA669, 'V'), - (0xA66A, 'M', u'ꙫ'), - (0xA66B, 'V'), - (0xA66C, 'M', u'ꙭ'), - (0xA66D, 'V'), - (0xA680, 'M', u'ꚁ'), - (0xA681, 'V'), - (0xA682, 'M', u'ꚃ'), - (0xA683, 'V'), - (0xA684, 'M', u'ꚅ'), - (0xA685, 'V'), - (0xA686, 'M', u'ꚇ'), - (0xA687, 'V'), - (0xA688, 'M', u'ꚉ'), - (0xA689, 'V'), - (0xA68A, 'M', u'ꚋ'), - (0xA68B, 'V'), - (0xA68C, 'M', u'ꚍ'), - (0xA68D, 'V'), - (0xA68E, 'M', u'ꚏ'), - (0xA68F, 'V'), - (0xA690, 'M', u'ꚑ'), - (0xA691, 'V'), - (0xA692, 'M', u'ꚓ'), - (0xA693, 'V'), - (0xA694, 'M', u'ꚕ'), - (0xA695, 'V'), - (0xA696, 'M', u'ꚗ'), - (0xA697, 'V'), - (0xA698, 'M', u'ꚙ'), - (0xA699, 'V'), - (0xA69A, 'M', u'ꚛ'), - (0xA69B, 'V'), - (0xA69C, 'M', u'ъ'), - (0xA69D, 'M', u'ь'), - (0xA69E, 'V'), - (0xA6F8, 'X'), - ] - -def _seg_36(): - return [ - (0xA700, 'V'), - (0xA722, 'M', u'ꜣ'), - (0xA723, 'V'), - (0xA724, 'M', u'ꜥ'), - (0xA725, 'V'), - (0xA726, 'M', u'ꜧ'), - (0xA727, 'V'), - (0xA728, 'M', u'ꜩ'), - (0xA729, 'V'), - (0xA72A, 'M', u'ꜫ'), - (0xA72B, 'V'), - (0xA72C, 'M', u'ꜭ'), - (0xA72D, 'V'), - (0xA72E, 'M', u'ꜯ'), - (0xA72F, 'V'), - (0xA732, 'M', u'ꜳ'), - (0xA733, 'V'), - (0xA734, 'M', u'ꜵ'), - (0xA735, 'V'), - (0xA736, 'M', u'ꜷ'), - (0xA737, 'V'), - (0xA738, 'M', u'ꜹ'), - (0xA739, 'V'), - (0xA73A, 'M', u'ꜻ'), - (0xA73B, 'V'), - (0xA73C, 'M', u'ꜽ'), - (0xA73D, 'V'), - (0xA73E, 'M', u'ꜿ'), - (0xA73F, 'V'), - (0xA740, 'M', u'ꝁ'), - (0xA741, 'V'), - (0xA742, 'M', u'ꝃ'), - (0xA743, 'V'), - (0xA744, 'M', u'ꝅ'), - (0xA745, 'V'), - (0xA746, 'M', u'ꝇ'), - (0xA747, 'V'), - (0xA748, 'M', u'ꝉ'), - (0xA749, 'V'), - (0xA74A, 'M', u'ꝋ'), - (0xA74B, 'V'), - (0xA74C, 'M', u'ꝍ'), - (0xA74D, 'V'), - (0xA74E, 'M', u'ꝏ'), - (0xA74F, 'V'), - (0xA750, 'M', u'ꝑ'), - (0xA751, 'V'), - (0xA752, 'M', u'ꝓ'), - (0xA753, 'V'), - (0xA754, 'M', u'ꝕ'), - (0xA755, 'V'), - (0xA756, 'M', u'ꝗ'), - (0xA757, 'V'), - (0xA758, 'M', u'ꝙ'), - (0xA759, 'V'), - (0xA75A, 'M', u'ꝛ'), - (0xA75B, 'V'), - (0xA75C, 'M', u'ꝝ'), - (0xA75D, 'V'), - (0xA75E, 'M', u'ꝟ'), - (0xA75F, 'V'), - (0xA760, 'M', u'ꝡ'), - (0xA761, 'V'), - (0xA762, 'M', u'ꝣ'), - (0xA763, 'V'), - (0xA764, 'M', u'ꝥ'), - (0xA765, 'V'), - (0xA766, 'M', u'ꝧ'), - (0xA767, 'V'), - (0xA768, 'M', u'ꝩ'), - (0xA769, 'V'), - (0xA76A, 'M', u'ꝫ'), - (0xA76B, 'V'), - (0xA76C, 'M', u'ꝭ'), - (0xA76D, 'V'), - (0xA76E, 'M', u'ꝯ'), - (0xA76F, 'V'), - (0xA770, 'M', u'ꝯ'), - (0xA771, 'V'), - (0xA779, 'M', u'ꝺ'), - (0xA77A, 'V'), - (0xA77B, 'M', u'ꝼ'), - (0xA77C, 'V'), - (0xA77D, 'M', u'ᵹ'), - (0xA77E, 'M', u'ꝿ'), - (0xA77F, 'V'), - (0xA780, 'M', u'ꞁ'), - (0xA781, 'V'), - (0xA782, 'M', u'ꞃ'), - (0xA783, 'V'), - (0xA784, 'M', u'ꞅ'), - (0xA785, 'V'), - (0xA786, 'M', u'ꞇ'), - (0xA787, 'V'), - (0xA78B, 'M', u'ꞌ'), - (0xA78C, 'V'), - (0xA78D, 'M', u'ɥ'), - (0xA78E, 'V'), - (0xA790, 'M', u'ꞑ'), - (0xA791, 'V'), - ] - -def _seg_37(): - return [ - (0xA792, 'M', u'ꞓ'), - (0xA793, 'V'), - (0xA796, 'M', u'ꞗ'), - (0xA797, 'V'), - (0xA798, 'M', u'ꞙ'), - (0xA799, 'V'), - (0xA79A, 'M', u'ꞛ'), - (0xA79B, 'V'), - (0xA79C, 'M', u'ꞝ'), - (0xA79D, 'V'), - (0xA79E, 'M', u'ꞟ'), - (0xA79F, 'V'), - (0xA7A0, 'M', u'ꞡ'), - (0xA7A1, 'V'), - (0xA7A2, 'M', u'ꞣ'), - (0xA7A3, 'V'), - (0xA7A4, 'M', u'ꞥ'), - (0xA7A5, 'V'), - (0xA7A6, 'M', u'ꞧ'), - (0xA7A7, 'V'), - (0xA7A8, 'M', u'ꞩ'), - (0xA7A9, 'V'), - (0xA7AA, 'M', u'ɦ'), - (0xA7AB, 'M', u'ɜ'), - (0xA7AC, 'M', u'ɡ'), - (0xA7AD, 'M', u'ɬ'), - (0xA7AE, 'M', u'ɪ'), - (0xA7AF, 'V'), - (0xA7B0, 'M', u'ʞ'), - (0xA7B1, 'M', u'ʇ'), - (0xA7B2, 'M', u'ʝ'), - (0xA7B3, 'M', u'ꭓ'), - (0xA7B4, 'M', u'ꞵ'), - (0xA7B5, 'V'), - (0xA7B6, 'M', u'ꞷ'), - (0xA7B7, 'V'), - (0xA7B8, 'X'), - (0xA7B9, 'V'), - (0xA7BA, 'X'), - (0xA7F7, 'V'), - (0xA7F8, 'M', u'ħ'), - (0xA7F9, 'M', u'œ'), - (0xA7FA, 'V'), - (0xA82C, 'X'), - (0xA830, 'V'), - (0xA83A, 'X'), - (0xA840, 'V'), - (0xA878, 'X'), - (0xA880, 'V'), - (0xA8C6, 'X'), - (0xA8CE, 'V'), - (0xA8DA, 'X'), - (0xA8E0, 'V'), - (0xA954, 'X'), - (0xA95F, 'V'), - (0xA97D, 'X'), - (0xA980, 'V'), - (0xA9CE, 'X'), - (0xA9CF, 'V'), - (0xA9DA, 'X'), - (0xA9DE, 'V'), - (0xA9FF, 'X'), - (0xAA00, 'V'), - (0xAA37, 'X'), - (0xAA40, 'V'), - (0xAA4E, 'X'), - (0xAA50, 'V'), - (0xAA5A, 'X'), - (0xAA5C, 'V'), - (0xAAC3, 'X'), - (0xAADB, 'V'), - (0xAAF7, 'X'), - (0xAB01, 'V'), - (0xAB07, 'X'), - (0xAB09, 'V'), - (0xAB0F, 'X'), - (0xAB11, 'V'), - (0xAB17, 'X'), - (0xAB20, 'V'), - (0xAB27, 'X'), - (0xAB28, 'V'), - (0xAB2F, 'X'), - (0xAB30, 'V'), - (0xAB5C, 'M', u'ꜧ'), - (0xAB5D, 'M', u'ꬷ'), - (0xAB5E, 'M', u'ɫ'), - (0xAB5F, 'M', u'ꭒ'), - (0xAB60, 'V'), - (0xAB66, 'X'), - (0xAB70, 'M', u'Ꭰ'), - (0xAB71, 'M', u'Ꭱ'), - (0xAB72, 'M', u'Ꭲ'), - (0xAB73, 'M', u'Ꭳ'), - (0xAB74, 'M', u'Ꭴ'), - (0xAB75, 'M', u'Ꭵ'), - (0xAB76, 'M', u'Ꭶ'), - (0xAB77, 'M', u'Ꭷ'), - (0xAB78, 'M', u'Ꭸ'), - (0xAB79, 'M', u'Ꭹ'), - (0xAB7A, 'M', u'Ꭺ'), - ] - -def _seg_38(): - return [ - (0xAB7B, 'M', u'Ꭻ'), - (0xAB7C, 'M', u'Ꭼ'), - (0xAB7D, 'M', u'Ꭽ'), - (0xAB7E, 'M', u'Ꭾ'), - (0xAB7F, 'M', u'Ꭿ'), - (0xAB80, 'M', u'Ꮀ'), - (0xAB81, 'M', u'Ꮁ'), - (0xAB82, 'M', u'Ꮂ'), - (0xAB83, 'M', u'Ꮃ'), - (0xAB84, 'M', u'Ꮄ'), - (0xAB85, 'M', u'Ꮅ'), - (0xAB86, 'M', u'Ꮆ'), - (0xAB87, 'M', u'Ꮇ'), - (0xAB88, 'M', u'Ꮈ'), - (0xAB89, 'M', u'Ꮉ'), - (0xAB8A, 'M', u'Ꮊ'), - (0xAB8B, 'M', u'Ꮋ'), - (0xAB8C, 'M', u'Ꮌ'), - (0xAB8D, 'M', u'Ꮍ'), - (0xAB8E, 'M', u'Ꮎ'), - (0xAB8F, 'M', u'Ꮏ'), - (0xAB90, 'M', u'Ꮐ'), - (0xAB91, 'M', u'Ꮑ'), - (0xAB92, 'M', u'Ꮒ'), - (0xAB93, 'M', u'Ꮓ'), - (0xAB94, 'M', u'Ꮔ'), - (0xAB95, 'M', u'Ꮕ'), - (0xAB96, 'M', u'Ꮖ'), - (0xAB97, 'M', u'Ꮗ'), - (0xAB98, 'M', u'Ꮘ'), - (0xAB99, 'M', u'Ꮙ'), - (0xAB9A, 'M', u'Ꮚ'), - (0xAB9B, 'M', u'Ꮛ'), - (0xAB9C, 'M', u'Ꮜ'), - (0xAB9D, 'M', u'Ꮝ'), - (0xAB9E, 'M', u'Ꮞ'), - (0xAB9F, 'M', u'Ꮟ'), - (0xABA0, 'M', u'Ꮠ'), - (0xABA1, 'M', u'Ꮡ'), - (0xABA2, 'M', u'Ꮢ'), - (0xABA3, 'M', u'Ꮣ'), - (0xABA4, 'M', u'Ꮤ'), - (0xABA5, 'M', u'Ꮥ'), - (0xABA6, 'M', u'Ꮦ'), - (0xABA7, 'M', u'Ꮧ'), - (0xABA8, 'M', u'Ꮨ'), - (0xABA9, 'M', u'Ꮩ'), - (0xABAA, 'M', u'Ꮪ'), - (0xABAB, 'M', u'Ꮫ'), - (0xABAC, 'M', u'Ꮬ'), - (0xABAD, 'M', u'Ꮭ'), - (0xABAE, 'M', u'Ꮮ'), - (0xABAF, 'M', u'Ꮯ'), - (0xABB0, 'M', u'Ꮰ'), - (0xABB1, 'M', u'Ꮱ'), - (0xABB2, 'M', u'Ꮲ'), - (0xABB3, 'M', u'Ꮳ'), - (0xABB4, 'M', u'Ꮴ'), - (0xABB5, 'M', u'Ꮵ'), - (0xABB6, 'M', u'Ꮶ'), - (0xABB7, 'M', u'Ꮷ'), - (0xABB8, 'M', u'Ꮸ'), - (0xABB9, 'M', u'Ꮹ'), - (0xABBA, 'M', u'Ꮺ'), - (0xABBB, 'M', u'Ꮻ'), - (0xABBC, 'M', u'Ꮼ'), - (0xABBD, 'M', u'Ꮽ'), - (0xABBE, 'M', u'Ꮾ'), - (0xABBF, 'M', u'Ꮿ'), - (0xABC0, 'V'), - (0xABEE, 'X'), - (0xABF0, 'V'), - (0xABFA, 'X'), - (0xAC00, 'V'), - (0xD7A4, 'X'), - (0xD7B0, 'V'), - (0xD7C7, 'X'), - (0xD7CB, 'V'), - (0xD7FC, 'X'), - (0xF900, 'M', u'豈'), - (0xF901, 'M', u'更'), - (0xF902, 'M', u'車'), - (0xF903, 'M', u'賈'), - (0xF904, 'M', u'滑'), - (0xF905, 'M', u'串'), - (0xF906, 'M', u'句'), - (0xF907, 'M', u'龜'), - (0xF909, 'M', u'契'), - (0xF90A, 'M', u'金'), - (0xF90B, 'M', u'喇'), - (0xF90C, 'M', u'奈'), - (0xF90D, 'M', u'懶'), - (0xF90E, 'M', u'癩'), - (0xF90F, 'M', u'羅'), - (0xF910, 'M', u'蘿'), - (0xF911, 'M', u'螺'), - (0xF912, 'M', u'裸'), - (0xF913, 'M', u'邏'), - (0xF914, 'M', u'樂'), - (0xF915, 'M', u'洛'), - ] - -def _seg_39(): - return [ - (0xF916, 'M', u'烙'), - (0xF917, 'M', u'珞'), - (0xF918, 'M', u'落'), - (0xF919, 'M', u'酪'), - (0xF91A, 'M', u'駱'), - (0xF91B, 'M', u'亂'), - (0xF91C, 'M', u'卵'), - (0xF91D, 'M', u'欄'), - (0xF91E, 'M', u'爛'), - (0xF91F, 'M', u'蘭'), - (0xF920, 'M', u'鸞'), - (0xF921, 'M', u'嵐'), - (0xF922, 'M', u'濫'), - (0xF923, 'M', u'藍'), - (0xF924, 'M', u'襤'), - (0xF925, 'M', u'拉'), - (0xF926, 'M', u'臘'), - (0xF927, 'M', u'蠟'), - (0xF928, 'M', u'廊'), - (0xF929, 'M', u'朗'), - (0xF92A, 'M', u'浪'), - (0xF92B, 'M', u'狼'), - (0xF92C, 'M', u'郎'), - (0xF92D, 'M', u'來'), - (0xF92E, 'M', u'冷'), - (0xF92F, 'M', u'勞'), - (0xF930, 'M', u'擄'), - (0xF931, 'M', u'櫓'), - (0xF932, 'M', u'爐'), - (0xF933, 'M', u'盧'), - (0xF934, 'M', u'老'), - (0xF935, 'M', u'蘆'), - (0xF936, 'M', u'虜'), - (0xF937, 'M', u'路'), - (0xF938, 'M', u'露'), - (0xF939, 'M', u'魯'), - (0xF93A, 'M', u'鷺'), - (0xF93B, 'M', u'碌'), - (0xF93C, 'M', u'祿'), - (0xF93D, 'M', u'綠'), - (0xF93E, 'M', u'菉'), - (0xF93F, 'M', u'錄'), - (0xF940, 'M', u'鹿'), - (0xF941, 'M', u'論'), - (0xF942, 'M', u'壟'), - (0xF943, 'M', u'弄'), - (0xF944, 'M', u'籠'), - (0xF945, 'M', u'聾'), - (0xF946, 'M', u'牢'), - (0xF947, 'M', u'磊'), - (0xF948, 'M', u'賂'), - (0xF949, 'M', u'雷'), - (0xF94A, 'M', u'壘'), - (0xF94B, 'M', u'屢'), - (0xF94C, 'M', u'樓'), - (0xF94D, 'M', u'淚'), - (0xF94E, 'M', u'漏'), - (0xF94F, 'M', u'累'), - (0xF950, 'M', u'縷'), - (0xF951, 'M', u'陋'), - (0xF952, 'M', u'勒'), - (0xF953, 'M', u'肋'), - (0xF954, 'M', u'凜'), - (0xF955, 'M', u'凌'), - (0xF956, 'M', u'稜'), - (0xF957, 'M', u'綾'), - (0xF958, 'M', u'菱'), - (0xF959, 'M', u'陵'), - (0xF95A, 'M', u'讀'), - (0xF95B, 'M', u'拏'), - (0xF95C, 'M', u'樂'), - (0xF95D, 'M', u'諾'), - (0xF95E, 'M', u'丹'), - (0xF95F, 'M', u'寧'), - (0xF960, 'M', u'怒'), - (0xF961, 'M', u'率'), - (0xF962, 'M', u'異'), - (0xF963, 'M', u'北'), - (0xF964, 'M', u'磻'), - (0xF965, 'M', u'便'), - (0xF966, 'M', u'復'), - (0xF967, 'M', u'不'), - (0xF968, 'M', u'泌'), - (0xF969, 'M', u'數'), - (0xF96A, 'M', u'索'), - (0xF96B, 'M', u'參'), - (0xF96C, 'M', u'塞'), - (0xF96D, 'M', u'省'), - (0xF96E, 'M', u'葉'), - (0xF96F, 'M', u'說'), - (0xF970, 'M', u'殺'), - (0xF971, 'M', u'辰'), - (0xF972, 'M', u'沈'), - (0xF973, 'M', u'拾'), - (0xF974, 'M', u'若'), - (0xF975, 'M', u'掠'), - (0xF976, 'M', u'略'), - (0xF977, 'M', u'亮'), - (0xF978, 'M', u'兩'), - (0xF979, 'M', u'凉'), - ] - -def _seg_40(): - return [ - (0xF97A, 'M', u'梁'), - (0xF97B, 'M', u'糧'), - (0xF97C, 'M', u'良'), - (0xF97D, 'M', u'諒'), - (0xF97E, 'M', u'量'), - (0xF97F, 'M', u'勵'), - (0xF980, 'M', u'呂'), - (0xF981, 'M', u'女'), - (0xF982, 'M', u'廬'), - (0xF983, 'M', u'旅'), - (0xF984, 'M', u'濾'), - (0xF985, 'M', u'礪'), - (0xF986, 'M', u'閭'), - (0xF987, 'M', u'驪'), - (0xF988, 'M', u'麗'), - (0xF989, 'M', u'黎'), - (0xF98A, 'M', u'力'), - (0xF98B, 'M', u'曆'), - (0xF98C, 'M', u'歷'), - (0xF98D, 'M', u'轢'), - (0xF98E, 'M', u'年'), - (0xF98F, 'M', u'憐'), - (0xF990, 'M', u'戀'), - (0xF991, 'M', u'撚'), - (0xF992, 'M', u'漣'), - (0xF993, 'M', u'煉'), - (0xF994, 'M', u'璉'), - (0xF995, 'M', u'秊'), - (0xF996, 'M', u'練'), - (0xF997, 'M', u'聯'), - (0xF998, 'M', u'輦'), - (0xF999, 'M', u'蓮'), - (0xF99A, 'M', u'連'), - (0xF99B, 'M', u'鍊'), - (0xF99C, 'M', u'列'), - (0xF99D, 'M', u'劣'), - (0xF99E, 'M', u'咽'), - (0xF99F, 'M', u'烈'), - (0xF9A0, 'M', u'裂'), - (0xF9A1, 'M', u'說'), - (0xF9A2, 'M', u'廉'), - (0xF9A3, 'M', u'念'), - (0xF9A4, 'M', u'捻'), - (0xF9A5, 'M', u'殮'), - (0xF9A6, 'M', u'簾'), - (0xF9A7, 'M', u'獵'), - (0xF9A8, 'M', u'令'), - (0xF9A9, 'M', u'囹'), - (0xF9AA, 'M', u'寧'), - (0xF9AB, 'M', u'嶺'), - (0xF9AC, 'M', u'怜'), - (0xF9AD, 'M', u'玲'), - (0xF9AE, 'M', u'瑩'), - (0xF9AF, 'M', u'羚'), - (0xF9B0, 'M', u'聆'), - (0xF9B1, 'M', u'鈴'), - (0xF9B2, 'M', u'零'), - (0xF9B3, 'M', u'靈'), - (0xF9B4, 'M', u'領'), - (0xF9B5, 'M', u'例'), - (0xF9B6, 'M', u'禮'), - (0xF9B7, 'M', u'醴'), - (0xF9B8, 'M', u'隸'), - (0xF9B9, 'M', u'惡'), - (0xF9BA, 'M', u'了'), - (0xF9BB, 'M', u'僚'), - (0xF9BC, 'M', u'寮'), - (0xF9BD, 'M', u'尿'), - (0xF9BE, 'M', u'料'), - (0xF9BF, 'M', u'樂'), - (0xF9C0, 'M', u'燎'), - (0xF9C1, 'M', u'療'), - (0xF9C2, 'M', u'蓼'), - (0xF9C3, 'M', u'遼'), - (0xF9C4, 'M', u'龍'), - (0xF9C5, 'M', u'暈'), - (0xF9C6, 'M', u'阮'), - (0xF9C7, 'M', u'劉'), - (0xF9C8, 'M', u'杻'), - (0xF9C9, 'M', u'柳'), - (0xF9CA, 'M', u'流'), - (0xF9CB, 'M', u'溜'), - (0xF9CC, 'M', u'琉'), - (0xF9CD, 'M', u'留'), - (0xF9CE, 'M', u'硫'), - (0xF9CF, 'M', u'紐'), - (0xF9D0, 'M', u'類'), - (0xF9D1, 'M', u'六'), - (0xF9D2, 'M', u'戮'), - (0xF9D3, 'M', u'陸'), - (0xF9D4, 'M', u'倫'), - (0xF9D5, 'M', u'崙'), - (0xF9D6, 'M', u'淪'), - (0xF9D7, 'M', u'輪'), - (0xF9D8, 'M', u'律'), - (0xF9D9, 'M', u'慄'), - (0xF9DA, 'M', u'栗'), - (0xF9DB, 'M', u'率'), - (0xF9DC, 'M', u'隆'), - (0xF9DD, 'M', u'利'), - ] - -def _seg_41(): - return [ - (0xF9DE, 'M', u'吏'), - (0xF9DF, 'M', u'履'), - (0xF9E0, 'M', u'易'), - (0xF9E1, 'M', u'李'), - (0xF9E2, 'M', u'梨'), - (0xF9E3, 'M', u'泥'), - (0xF9E4, 'M', u'理'), - (0xF9E5, 'M', u'痢'), - (0xF9E6, 'M', u'罹'), - (0xF9E7, 'M', u'裏'), - (0xF9E8, 'M', u'裡'), - (0xF9E9, 'M', u'里'), - (0xF9EA, 'M', u'離'), - (0xF9EB, 'M', u'匿'), - (0xF9EC, 'M', u'溺'), - (0xF9ED, 'M', u'吝'), - (0xF9EE, 'M', u'燐'), - (0xF9EF, 'M', u'璘'), - (0xF9F0, 'M', u'藺'), - (0xF9F1, 'M', u'隣'), - (0xF9F2, 'M', u'鱗'), - (0xF9F3, 'M', u'麟'), - (0xF9F4, 'M', u'林'), - (0xF9F5, 'M', u'淋'), - (0xF9F6, 'M', u'臨'), - (0xF9F7, 'M', u'立'), - (0xF9F8, 'M', u'笠'), - (0xF9F9, 'M', u'粒'), - (0xF9FA, 'M', u'狀'), - (0xF9FB, 'M', u'炙'), - (0xF9FC, 'M', u'識'), - (0xF9FD, 'M', u'什'), - (0xF9FE, 'M', u'茶'), - (0xF9FF, 'M', u'刺'), - (0xFA00, 'M', u'切'), - (0xFA01, 'M', u'度'), - (0xFA02, 'M', u'拓'), - (0xFA03, 'M', u'糖'), - (0xFA04, 'M', u'宅'), - (0xFA05, 'M', u'洞'), - (0xFA06, 'M', u'暴'), - (0xFA07, 'M', u'輻'), - (0xFA08, 'M', u'行'), - (0xFA09, 'M', u'降'), - (0xFA0A, 'M', u'見'), - (0xFA0B, 'M', u'廓'), - (0xFA0C, 'M', u'兀'), - (0xFA0D, 'M', u'嗀'), - (0xFA0E, 'V'), - (0xFA10, 'M', u'塚'), - (0xFA11, 'V'), - (0xFA12, 'M', u'晴'), - (0xFA13, 'V'), - (0xFA15, 'M', u'凞'), - (0xFA16, 'M', u'猪'), - (0xFA17, 'M', u'益'), - (0xFA18, 'M', u'礼'), - (0xFA19, 'M', u'神'), - (0xFA1A, 'M', u'祥'), - (0xFA1B, 'M', u'福'), - (0xFA1C, 'M', u'靖'), - (0xFA1D, 'M', u'精'), - (0xFA1E, 'M', u'羽'), - (0xFA1F, 'V'), - (0xFA20, 'M', u'蘒'), - (0xFA21, 'V'), - (0xFA22, 'M', u'諸'), - (0xFA23, 'V'), - (0xFA25, 'M', u'逸'), - (0xFA26, 'M', u'都'), - (0xFA27, 'V'), - (0xFA2A, 'M', u'飯'), - (0xFA2B, 'M', u'飼'), - (0xFA2C, 'M', u'館'), - (0xFA2D, 'M', u'鶴'), - (0xFA2E, 'M', u'郞'), - (0xFA2F, 'M', u'隷'), - (0xFA30, 'M', u'侮'), - (0xFA31, 'M', u'僧'), - (0xFA32, 'M', u'免'), - (0xFA33, 'M', u'勉'), - (0xFA34, 'M', u'勤'), - (0xFA35, 'M', u'卑'), - (0xFA36, 'M', u'喝'), - (0xFA37, 'M', u'嘆'), - (0xFA38, 'M', u'器'), - (0xFA39, 'M', u'塀'), - (0xFA3A, 'M', u'墨'), - (0xFA3B, 'M', u'層'), - (0xFA3C, 'M', u'屮'), - (0xFA3D, 'M', u'悔'), - (0xFA3E, 'M', u'慨'), - (0xFA3F, 'M', u'憎'), - (0xFA40, 'M', u'懲'), - (0xFA41, 'M', u'敏'), - (0xFA42, 'M', u'既'), - (0xFA43, 'M', u'暑'), - (0xFA44, 'M', u'梅'), - (0xFA45, 'M', u'海'), - (0xFA46, 'M', u'渚'), - ] - -def _seg_42(): - return [ - (0xFA47, 'M', u'漢'), - (0xFA48, 'M', u'煮'), - (0xFA49, 'M', u'爫'), - (0xFA4A, 'M', u'琢'), - (0xFA4B, 'M', u'碑'), - (0xFA4C, 'M', u'社'), - (0xFA4D, 'M', u'祉'), - (0xFA4E, 'M', u'祈'), - (0xFA4F, 'M', u'祐'), - (0xFA50, 'M', u'祖'), - (0xFA51, 'M', u'祝'), - (0xFA52, 'M', u'禍'), - (0xFA53, 'M', u'禎'), - (0xFA54, 'M', u'穀'), - (0xFA55, 'M', u'突'), - (0xFA56, 'M', u'節'), - (0xFA57, 'M', u'練'), - (0xFA58, 'M', u'縉'), - (0xFA59, 'M', u'繁'), - (0xFA5A, 'M', u'署'), - (0xFA5B, 'M', u'者'), - (0xFA5C, 'M', u'臭'), - (0xFA5D, 'M', u'艹'), - (0xFA5F, 'M', u'著'), - (0xFA60, 'M', u'褐'), - (0xFA61, 'M', u'視'), - (0xFA62, 'M', u'謁'), - (0xFA63, 'M', u'謹'), - (0xFA64, 'M', u'賓'), - (0xFA65, 'M', u'贈'), - (0xFA66, 'M', u'辶'), - (0xFA67, 'M', u'逸'), - (0xFA68, 'M', u'難'), - (0xFA69, 'M', u'響'), - (0xFA6A, 'M', u'頻'), - (0xFA6B, 'M', u'恵'), - (0xFA6C, 'M', u'𤋮'), - (0xFA6D, 'M', u'舘'), - (0xFA6E, 'X'), - (0xFA70, 'M', u'並'), - (0xFA71, 'M', u'况'), - (0xFA72, 'M', u'全'), - (0xFA73, 'M', u'侀'), - (0xFA74, 'M', u'充'), - (0xFA75, 'M', u'冀'), - (0xFA76, 'M', u'勇'), - (0xFA77, 'M', u'勺'), - (0xFA78, 'M', u'喝'), - (0xFA79, 'M', u'啕'), - (0xFA7A, 'M', u'喙'), - (0xFA7B, 'M', u'嗢'), - (0xFA7C, 'M', u'塚'), - (0xFA7D, 'M', u'墳'), - (0xFA7E, 'M', u'奄'), - (0xFA7F, 'M', u'奔'), - (0xFA80, 'M', u'婢'), - (0xFA81, 'M', u'嬨'), - (0xFA82, 'M', u'廒'), - (0xFA83, 'M', u'廙'), - (0xFA84, 'M', u'彩'), - (0xFA85, 'M', u'徭'), - (0xFA86, 'M', u'惘'), - (0xFA87, 'M', u'慎'), - (0xFA88, 'M', u'愈'), - (0xFA89, 'M', u'憎'), - (0xFA8A, 'M', u'慠'), - (0xFA8B, 'M', u'懲'), - (0xFA8C, 'M', u'戴'), - (0xFA8D, 'M', u'揄'), - (0xFA8E, 'M', u'搜'), - (0xFA8F, 'M', u'摒'), - (0xFA90, 'M', u'敖'), - (0xFA91, 'M', u'晴'), - (0xFA92, 'M', u'朗'), - (0xFA93, 'M', u'望'), - (0xFA94, 'M', u'杖'), - (0xFA95, 'M', u'歹'), - (0xFA96, 'M', u'殺'), - (0xFA97, 'M', u'流'), - (0xFA98, 'M', u'滛'), - (0xFA99, 'M', u'滋'), - (0xFA9A, 'M', u'漢'), - (0xFA9B, 'M', u'瀞'), - (0xFA9C, 'M', u'煮'), - (0xFA9D, 'M', u'瞧'), - (0xFA9E, 'M', u'爵'), - (0xFA9F, 'M', u'犯'), - (0xFAA0, 'M', u'猪'), - (0xFAA1, 'M', u'瑱'), - (0xFAA2, 'M', u'甆'), - (0xFAA3, 'M', u'画'), - (0xFAA4, 'M', u'瘝'), - (0xFAA5, 'M', u'瘟'), - (0xFAA6, 'M', u'益'), - (0xFAA7, 'M', u'盛'), - (0xFAA8, 'M', u'直'), - (0xFAA9, 'M', u'睊'), - (0xFAAA, 'M', u'着'), - (0xFAAB, 'M', u'磌'), - (0xFAAC, 'M', u'窱'), - ] - -def _seg_43(): - return [ - (0xFAAD, 'M', u'節'), - (0xFAAE, 'M', u'类'), - (0xFAAF, 'M', u'絛'), - (0xFAB0, 'M', u'練'), - (0xFAB1, 'M', u'缾'), - (0xFAB2, 'M', u'者'), - (0xFAB3, 'M', u'荒'), - (0xFAB4, 'M', u'華'), - (0xFAB5, 'M', u'蝹'), - (0xFAB6, 'M', u'襁'), - (0xFAB7, 'M', u'覆'), - (0xFAB8, 'M', u'視'), - (0xFAB9, 'M', u'調'), - (0xFABA, 'M', u'諸'), - (0xFABB, 'M', u'請'), - (0xFABC, 'M', u'謁'), - (0xFABD, 'M', u'諾'), - (0xFABE, 'M', u'諭'), - (0xFABF, 'M', u'謹'), - (0xFAC0, 'M', u'變'), - (0xFAC1, 'M', u'贈'), - (0xFAC2, 'M', u'輸'), - (0xFAC3, 'M', u'遲'), - (0xFAC4, 'M', u'醙'), - (0xFAC5, 'M', u'鉶'), - (0xFAC6, 'M', u'陼'), - (0xFAC7, 'M', u'難'), - (0xFAC8, 'M', u'靖'), - (0xFAC9, 'M', u'韛'), - (0xFACA, 'M', u'響'), - (0xFACB, 'M', u'頋'), - (0xFACC, 'M', u'頻'), - (0xFACD, 'M', u'鬒'), - (0xFACE, 'M', u'龜'), - (0xFACF, 'M', u'𢡊'), - (0xFAD0, 'M', u'𢡄'), - (0xFAD1, 'M', u'𣏕'), - (0xFAD2, 'M', u'㮝'), - (0xFAD3, 'M', u'䀘'), - (0xFAD4, 'M', u'䀹'), - (0xFAD5, 'M', u'𥉉'), - (0xFAD6, 'M', u'𥳐'), - (0xFAD7, 'M', u'𧻓'), - (0xFAD8, 'M', u'齃'), - (0xFAD9, 'M', u'龎'), - (0xFADA, 'X'), - (0xFB00, 'M', u'ff'), - (0xFB01, 'M', u'fi'), - (0xFB02, 'M', u'fl'), - (0xFB03, 'M', u'ffi'), - (0xFB04, 'M', u'ffl'), - (0xFB05, 'M', u'st'), - (0xFB07, 'X'), - (0xFB13, 'M', u'մն'), - (0xFB14, 'M', u'մե'), - (0xFB15, 'M', u'մի'), - (0xFB16, 'M', u'վն'), - (0xFB17, 'M', u'մխ'), - (0xFB18, 'X'), - (0xFB1D, 'M', u'יִ'), - (0xFB1E, 'V'), - (0xFB1F, 'M', u'ײַ'), - (0xFB20, 'M', u'ע'), - (0xFB21, 'M', u'א'), - (0xFB22, 'M', u'ד'), - (0xFB23, 'M', u'ה'), - (0xFB24, 'M', u'כ'), - (0xFB25, 'M', u'ל'), - (0xFB26, 'M', u'ם'), - (0xFB27, 'M', u'ר'), - (0xFB28, 'M', u'ת'), - (0xFB29, '3', u'+'), - (0xFB2A, 'M', u'שׁ'), - (0xFB2B, 'M', u'שׂ'), - (0xFB2C, 'M', u'שּׁ'), - (0xFB2D, 'M', u'שּׂ'), - (0xFB2E, 'M', u'אַ'), - (0xFB2F, 'M', u'אָ'), - (0xFB30, 'M', u'אּ'), - (0xFB31, 'M', u'בּ'), - (0xFB32, 'M', u'גּ'), - (0xFB33, 'M', u'דּ'), - (0xFB34, 'M', u'הּ'), - (0xFB35, 'M', u'וּ'), - (0xFB36, 'M', u'זּ'), - (0xFB37, 'X'), - (0xFB38, 'M', u'טּ'), - (0xFB39, 'M', u'יּ'), - (0xFB3A, 'M', u'ךּ'), - (0xFB3B, 'M', u'כּ'), - (0xFB3C, 'M', u'לּ'), - (0xFB3D, 'X'), - (0xFB3E, 'M', u'מּ'), - (0xFB3F, 'X'), - (0xFB40, 'M', u'נּ'), - (0xFB41, 'M', u'סּ'), - (0xFB42, 'X'), - (0xFB43, 'M', u'ףּ'), - (0xFB44, 'M', u'פּ'), - (0xFB45, 'X'), - ] - -def _seg_44(): - return [ - (0xFB46, 'M', u'צּ'), - (0xFB47, 'M', u'קּ'), - (0xFB48, 'M', u'רּ'), - (0xFB49, 'M', u'שּ'), - (0xFB4A, 'M', u'תּ'), - (0xFB4B, 'M', u'וֹ'), - (0xFB4C, 'M', u'בֿ'), - (0xFB4D, 'M', u'כֿ'), - (0xFB4E, 'M', u'פֿ'), - (0xFB4F, 'M', u'אל'), - (0xFB50, 'M', u'ٱ'), - (0xFB52, 'M', u'ٻ'), - (0xFB56, 'M', u'پ'), - (0xFB5A, 'M', u'ڀ'), - (0xFB5E, 'M', u'ٺ'), - (0xFB62, 'M', u'ٿ'), - (0xFB66, 'M', u'ٹ'), - (0xFB6A, 'M', u'ڤ'), - (0xFB6E, 'M', u'ڦ'), - (0xFB72, 'M', u'ڄ'), - (0xFB76, 'M', u'ڃ'), - (0xFB7A, 'M', u'چ'), - (0xFB7E, 'M', u'ڇ'), - (0xFB82, 'M', u'ڍ'), - (0xFB84, 'M', u'ڌ'), - (0xFB86, 'M', u'ڎ'), - (0xFB88, 'M', u'ڈ'), - (0xFB8A, 'M', u'ژ'), - (0xFB8C, 'M', u'ڑ'), - (0xFB8E, 'M', u'ک'), - (0xFB92, 'M', u'گ'), - (0xFB96, 'M', u'ڳ'), - (0xFB9A, 'M', u'ڱ'), - (0xFB9E, 'M', u'ں'), - (0xFBA0, 'M', u'ڻ'), - (0xFBA4, 'M', u'ۀ'), - (0xFBA6, 'M', u'ہ'), - (0xFBAA, 'M', u'ھ'), - (0xFBAE, 'M', u'ے'), - (0xFBB0, 'M', u'ۓ'), - (0xFBB2, 'V'), - (0xFBC2, 'X'), - (0xFBD3, 'M', u'ڭ'), - (0xFBD7, 'M', u'ۇ'), - (0xFBD9, 'M', u'ۆ'), - (0xFBDB, 'M', u'ۈ'), - (0xFBDD, 'M', u'ۇٴ'), - (0xFBDE, 'M', u'ۋ'), - (0xFBE0, 'M', u'ۅ'), - (0xFBE2, 'M', u'ۉ'), - (0xFBE4, 'M', u'ې'), - (0xFBE8, 'M', u'ى'), - (0xFBEA, 'M', u'ئا'), - (0xFBEC, 'M', u'ئە'), - (0xFBEE, 'M', u'ئو'), - (0xFBF0, 'M', u'ئۇ'), - (0xFBF2, 'M', u'ئۆ'), - (0xFBF4, 'M', u'ئۈ'), - (0xFBF6, 'M', u'ئې'), - (0xFBF9, 'M', u'ئى'), - (0xFBFC, 'M', u'ی'), - (0xFC00, 'M', u'ئج'), - (0xFC01, 'M', u'ئح'), - (0xFC02, 'M', u'ئم'), - (0xFC03, 'M', u'ئى'), - (0xFC04, 'M', u'ئي'), - (0xFC05, 'M', u'بج'), - (0xFC06, 'M', u'بح'), - (0xFC07, 'M', u'بخ'), - (0xFC08, 'M', u'بم'), - (0xFC09, 'M', u'بى'), - (0xFC0A, 'M', u'بي'), - (0xFC0B, 'M', u'تج'), - (0xFC0C, 'M', u'تح'), - (0xFC0D, 'M', u'تخ'), - (0xFC0E, 'M', u'تم'), - (0xFC0F, 'M', u'تى'), - (0xFC10, 'M', u'تي'), - (0xFC11, 'M', u'ثج'), - (0xFC12, 'M', u'ثم'), - (0xFC13, 'M', u'ثى'), - (0xFC14, 'M', u'ثي'), - (0xFC15, 'M', u'جح'), - (0xFC16, 'M', u'جم'), - (0xFC17, 'M', u'حج'), - (0xFC18, 'M', u'حم'), - (0xFC19, 'M', u'خج'), - (0xFC1A, 'M', u'خح'), - (0xFC1B, 'M', u'خم'), - (0xFC1C, 'M', u'سج'), - (0xFC1D, 'M', u'سح'), - (0xFC1E, 'M', u'سخ'), - (0xFC1F, 'M', u'سم'), - (0xFC20, 'M', u'صح'), - (0xFC21, 'M', u'صم'), - (0xFC22, 'M', u'ضج'), - (0xFC23, 'M', u'ضح'), - (0xFC24, 'M', u'ضخ'), - (0xFC25, 'M', u'ضم'), - (0xFC26, 'M', u'طح'), - ] - -def _seg_45(): - return [ - (0xFC27, 'M', u'طم'), - (0xFC28, 'M', u'ظم'), - (0xFC29, 'M', u'عج'), - (0xFC2A, 'M', u'عم'), - (0xFC2B, 'M', u'غج'), - (0xFC2C, 'M', u'غم'), - (0xFC2D, 'M', u'فج'), - (0xFC2E, 'M', u'فح'), - (0xFC2F, 'M', u'فخ'), - (0xFC30, 'M', u'فم'), - (0xFC31, 'M', u'فى'), - (0xFC32, 'M', u'في'), - (0xFC33, 'M', u'قح'), - (0xFC34, 'M', u'قم'), - (0xFC35, 'M', u'قى'), - (0xFC36, 'M', u'قي'), - (0xFC37, 'M', u'كا'), - (0xFC38, 'M', u'كج'), - (0xFC39, 'M', u'كح'), - (0xFC3A, 'M', u'كخ'), - (0xFC3B, 'M', u'كل'), - (0xFC3C, 'M', u'كم'), - (0xFC3D, 'M', u'كى'), - (0xFC3E, 'M', u'كي'), - (0xFC3F, 'M', u'لج'), - (0xFC40, 'M', u'لح'), - (0xFC41, 'M', u'لخ'), - (0xFC42, 'M', u'لم'), - (0xFC43, 'M', u'لى'), - (0xFC44, 'M', u'لي'), - (0xFC45, 'M', u'مج'), - (0xFC46, 'M', u'مح'), - (0xFC47, 'M', u'مخ'), - (0xFC48, 'M', u'مم'), - (0xFC49, 'M', u'مى'), - (0xFC4A, 'M', u'مي'), - (0xFC4B, 'M', u'نج'), - (0xFC4C, 'M', u'نح'), - (0xFC4D, 'M', u'نخ'), - (0xFC4E, 'M', u'نم'), - (0xFC4F, 'M', u'نى'), - (0xFC50, 'M', u'ني'), - (0xFC51, 'M', u'هج'), - (0xFC52, 'M', u'هم'), - (0xFC53, 'M', u'هى'), - (0xFC54, 'M', u'هي'), - (0xFC55, 'M', u'يج'), - (0xFC56, 'M', u'يح'), - (0xFC57, 'M', u'يخ'), - (0xFC58, 'M', u'يم'), - (0xFC59, 'M', u'يى'), - (0xFC5A, 'M', u'يي'), - (0xFC5B, 'M', u'ذٰ'), - (0xFC5C, 'M', u'رٰ'), - (0xFC5D, 'M', u'ىٰ'), - (0xFC5E, '3', u' ٌّ'), - (0xFC5F, '3', u' ٍّ'), - (0xFC60, '3', u' َّ'), - (0xFC61, '3', u' ُّ'), - (0xFC62, '3', u' ِّ'), - (0xFC63, '3', u' ّٰ'), - (0xFC64, 'M', u'ئر'), - (0xFC65, 'M', u'ئز'), - (0xFC66, 'M', u'ئم'), - (0xFC67, 'M', u'ئن'), - (0xFC68, 'M', u'ئى'), - (0xFC69, 'M', u'ئي'), - (0xFC6A, 'M', u'بر'), - (0xFC6B, 'M', u'بز'), - (0xFC6C, 'M', u'بم'), - (0xFC6D, 'M', u'بن'), - (0xFC6E, 'M', u'بى'), - (0xFC6F, 'M', u'بي'), - (0xFC70, 'M', u'تر'), - (0xFC71, 'M', u'تز'), - (0xFC72, 'M', u'تم'), - (0xFC73, 'M', u'تن'), - (0xFC74, 'M', u'تى'), - (0xFC75, 'M', u'تي'), - (0xFC76, 'M', u'ثر'), - (0xFC77, 'M', u'ثز'), - (0xFC78, 'M', u'ثم'), - (0xFC79, 'M', u'ثن'), - (0xFC7A, 'M', u'ثى'), - (0xFC7B, 'M', u'ثي'), - (0xFC7C, 'M', u'فى'), - (0xFC7D, 'M', u'في'), - (0xFC7E, 'M', u'قى'), - (0xFC7F, 'M', u'قي'), - (0xFC80, 'M', u'كا'), - (0xFC81, 'M', u'كل'), - (0xFC82, 'M', u'كم'), - (0xFC83, 'M', u'كى'), - (0xFC84, 'M', u'كي'), - (0xFC85, 'M', u'لم'), - (0xFC86, 'M', u'لى'), - (0xFC87, 'M', u'لي'), - (0xFC88, 'M', u'ما'), - (0xFC89, 'M', u'مم'), - (0xFC8A, 'M', u'نر'), - ] - -def _seg_46(): - return [ - (0xFC8B, 'M', u'نز'), - (0xFC8C, 'M', u'نم'), - (0xFC8D, 'M', u'نن'), - (0xFC8E, 'M', u'نى'), - (0xFC8F, 'M', u'ني'), - (0xFC90, 'M', u'ىٰ'), - (0xFC91, 'M', u'ير'), - (0xFC92, 'M', u'يز'), - (0xFC93, 'M', u'يم'), - (0xFC94, 'M', u'ين'), - (0xFC95, 'M', u'يى'), - (0xFC96, 'M', u'يي'), - (0xFC97, 'M', u'ئج'), - (0xFC98, 'M', u'ئح'), - (0xFC99, 'M', u'ئخ'), - (0xFC9A, 'M', u'ئم'), - (0xFC9B, 'M', u'ئه'), - (0xFC9C, 'M', u'بج'), - (0xFC9D, 'M', u'بح'), - (0xFC9E, 'M', u'بخ'), - (0xFC9F, 'M', u'بم'), - (0xFCA0, 'M', u'به'), - (0xFCA1, 'M', u'تج'), - (0xFCA2, 'M', u'تح'), - (0xFCA3, 'M', u'تخ'), - (0xFCA4, 'M', u'تم'), - (0xFCA5, 'M', u'ته'), - (0xFCA6, 'M', u'ثم'), - (0xFCA7, 'M', u'جح'), - (0xFCA8, 'M', u'جم'), - (0xFCA9, 'M', u'حج'), - (0xFCAA, 'M', u'حم'), - (0xFCAB, 'M', u'خج'), - (0xFCAC, 'M', u'خم'), - (0xFCAD, 'M', u'سج'), - (0xFCAE, 'M', u'سح'), - (0xFCAF, 'M', u'سخ'), - (0xFCB0, 'M', u'سم'), - (0xFCB1, 'M', u'صح'), - (0xFCB2, 'M', u'صخ'), - (0xFCB3, 'M', u'صم'), - (0xFCB4, 'M', u'ضج'), - (0xFCB5, 'M', u'ضح'), - (0xFCB6, 'M', u'ضخ'), - (0xFCB7, 'M', u'ضم'), - (0xFCB8, 'M', u'طح'), - (0xFCB9, 'M', u'ظم'), - (0xFCBA, 'M', u'عج'), - (0xFCBB, 'M', u'عم'), - (0xFCBC, 'M', u'غج'), - (0xFCBD, 'M', u'غم'), - (0xFCBE, 'M', u'فج'), - (0xFCBF, 'M', u'فح'), - (0xFCC0, 'M', u'فخ'), - (0xFCC1, 'M', u'فم'), - (0xFCC2, 'M', u'قح'), - (0xFCC3, 'M', u'قم'), - (0xFCC4, 'M', u'كج'), - (0xFCC5, 'M', u'كح'), - (0xFCC6, 'M', u'كخ'), - (0xFCC7, 'M', u'كل'), - (0xFCC8, 'M', u'كم'), - (0xFCC9, 'M', u'لج'), - (0xFCCA, 'M', u'لح'), - (0xFCCB, 'M', u'لخ'), - (0xFCCC, 'M', u'لم'), - (0xFCCD, 'M', u'له'), - (0xFCCE, 'M', u'مج'), - (0xFCCF, 'M', u'مح'), - (0xFCD0, 'M', u'مخ'), - (0xFCD1, 'M', u'مم'), - (0xFCD2, 'M', u'نج'), - (0xFCD3, 'M', u'نح'), - (0xFCD4, 'M', u'نخ'), - (0xFCD5, 'M', u'نم'), - (0xFCD6, 'M', u'نه'), - (0xFCD7, 'M', u'هج'), - (0xFCD8, 'M', u'هم'), - (0xFCD9, 'M', u'هٰ'), - (0xFCDA, 'M', u'يج'), - (0xFCDB, 'M', u'يح'), - (0xFCDC, 'M', u'يخ'), - (0xFCDD, 'M', u'يم'), - (0xFCDE, 'M', u'يه'), - (0xFCDF, 'M', u'ئم'), - (0xFCE0, 'M', u'ئه'), - (0xFCE1, 'M', u'بم'), - (0xFCE2, 'M', u'به'), - (0xFCE3, 'M', u'تم'), - (0xFCE4, 'M', u'ته'), - (0xFCE5, 'M', u'ثم'), - (0xFCE6, 'M', u'ثه'), - (0xFCE7, 'M', u'سم'), - (0xFCE8, 'M', u'سه'), - (0xFCE9, 'M', u'شم'), - (0xFCEA, 'M', u'شه'), - (0xFCEB, 'M', u'كل'), - (0xFCEC, 'M', u'كم'), - (0xFCED, 'M', u'لم'), - (0xFCEE, 'M', u'نم'), - ] - -def _seg_47(): - return [ - (0xFCEF, 'M', u'نه'), - (0xFCF0, 'M', u'يم'), - (0xFCF1, 'M', u'يه'), - (0xFCF2, 'M', u'ـَّ'), - (0xFCF3, 'M', u'ـُّ'), - (0xFCF4, 'M', u'ـِّ'), - (0xFCF5, 'M', u'طى'), - (0xFCF6, 'M', u'طي'), - (0xFCF7, 'M', u'عى'), - (0xFCF8, 'M', u'عي'), - (0xFCF9, 'M', u'غى'), - (0xFCFA, 'M', u'غي'), - (0xFCFB, 'M', u'سى'), - (0xFCFC, 'M', u'سي'), - (0xFCFD, 'M', u'شى'), - (0xFCFE, 'M', u'شي'), - (0xFCFF, 'M', u'حى'), - (0xFD00, 'M', u'حي'), - (0xFD01, 'M', u'جى'), - (0xFD02, 'M', u'جي'), - (0xFD03, 'M', u'خى'), - (0xFD04, 'M', u'خي'), - (0xFD05, 'M', u'صى'), - (0xFD06, 'M', u'صي'), - (0xFD07, 'M', u'ضى'), - (0xFD08, 'M', u'ضي'), - (0xFD09, 'M', u'شج'), - (0xFD0A, 'M', u'شح'), - (0xFD0B, 'M', u'شخ'), - (0xFD0C, 'M', u'شم'), - (0xFD0D, 'M', u'شر'), - (0xFD0E, 'M', u'سر'), - (0xFD0F, 'M', u'صر'), - (0xFD10, 'M', u'ضر'), - (0xFD11, 'M', u'طى'), - (0xFD12, 'M', u'طي'), - (0xFD13, 'M', u'عى'), - (0xFD14, 'M', u'عي'), - (0xFD15, 'M', u'غى'), - (0xFD16, 'M', u'غي'), - (0xFD17, 'M', u'سى'), - (0xFD18, 'M', u'سي'), - (0xFD19, 'M', u'شى'), - (0xFD1A, 'M', u'شي'), - (0xFD1B, 'M', u'حى'), - (0xFD1C, 'M', u'حي'), - (0xFD1D, 'M', u'جى'), - (0xFD1E, 'M', u'جي'), - (0xFD1F, 'M', u'خى'), - (0xFD20, 'M', u'خي'), - (0xFD21, 'M', u'صى'), - (0xFD22, 'M', u'صي'), - (0xFD23, 'M', u'ضى'), - (0xFD24, 'M', u'ضي'), - (0xFD25, 'M', u'شج'), - (0xFD26, 'M', u'شح'), - (0xFD27, 'M', u'شخ'), - (0xFD28, 'M', u'شم'), - (0xFD29, 'M', u'شر'), - (0xFD2A, 'M', u'سر'), - (0xFD2B, 'M', u'صر'), - (0xFD2C, 'M', u'ضر'), - (0xFD2D, 'M', u'شج'), - (0xFD2E, 'M', u'شح'), - (0xFD2F, 'M', u'شخ'), - (0xFD30, 'M', u'شم'), - (0xFD31, 'M', u'سه'), - (0xFD32, 'M', u'شه'), - (0xFD33, 'M', u'طم'), - (0xFD34, 'M', u'سج'), - (0xFD35, 'M', u'سح'), - (0xFD36, 'M', u'سخ'), - (0xFD37, 'M', u'شج'), - (0xFD38, 'M', u'شح'), - (0xFD39, 'M', u'شخ'), - (0xFD3A, 'M', u'طم'), - (0xFD3B, 'M', u'ظم'), - (0xFD3C, 'M', u'اً'), - (0xFD3E, 'V'), - (0xFD40, 'X'), - (0xFD50, 'M', u'تجم'), - (0xFD51, 'M', u'تحج'), - (0xFD53, 'M', u'تحم'), - (0xFD54, 'M', u'تخم'), - (0xFD55, 'M', u'تمج'), - (0xFD56, 'M', u'تمح'), - (0xFD57, 'M', u'تمخ'), - (0xFD58, 'M', u'جمح'), - (0xFD5A, 'M', u'حمي'), - (0xFD5B, 'M', u'حمى'), - (0xFD5C, 'M', u'سحج'), - (0xFD5D, 'M', u'سجح'), - (0xFD5E, 'M', u'سجى'), - (0xFD5F, 'M', u'سمح'), - (0xFD61, 'M', u'سمج'), - (0xFD62, 'M', u'سمم'), - (0xFD64, 'M', u'صحح'), - (0xFD66, 'M', u'صمم'), - (0xFD67, 'M', u'شحم'), - (0xFD69, 'M', u'شجي'), - ] - -def _seg_48(): - return [ - (0xFD6A, 'M', u'شمخ'), - (0xFD6C, 'M', u'شمم'), - (0xFD6E, 'M', u'ضحى'), - (0xFD6F, 'M', u'ضخم'), - (0xFD71, 'M', u'طمح'), - (0xFD73, 'M', u'طمم'), - (0xFD74, 'M', u'طمي'), - (0xFD75, 'M', u'عجم'), - (0xFD76, 'M', u'عمم'), - (0xFD78, 'M', u'عمى'), - (0xFD79, 'M', u'غمم'), - (0xFD7A, 'M', u'غمي'), - (0xFD7B, 'M', u'غمى'), - (0xFD7C, 'M', u'فخم'), - (0xFD7E, 'M', u'قمح'), - (0xFD7F, 'M', u'قمم'), - (0xFD80, 'M', u'لحم'), - (0xFD81, 'M', u'لحي'), - (0xFD82, 'M', u'لحى'), - (0xFD83, 'M', u'لجج'), - (0xFD85, 'M', u'لخم'), - (0xFD87, 'M', u'لمح'), - (0xFD89, 'M', u'محج'), - (0xFD8A, 'M', u'محم'), - (0xFD8B, 'M', u'محي'), - (0xFD8C, 'M', u'مجح'), - (0xFD8D, 'M', u'مجم'), - (0xFD8E, 'M', u'مخج'), - (0xFD8F, 'M', u'مخم'), - (0xFD90, 'X'), - (0xFD92, 'M', u'مجخ'), - (0xFD93, 'M', u'همج'), - (0xFD94, 'M', u'همم'), - (0xFD95, 'M', u'نحم'), - (0xFD96, 'M', u'نحى'), - (0xFD97, 'M', u'نجم'), - (0xFD99, 'M', u'نجى'), - (0xFD9A, 'M', u'نمي'), - (0xFD9B, 'M', u'نمى'), - (0xFD9C, 'M', u'يمم'), - (0xFD9E, 'M', u'بخي'), - (0xFD9F, 'M', u'تجي'), - (0xFDA0, 'M', u'تجى'), - (0xFDA1, 'M', u'تخي'), - (0xFDA2, 'M', u'تخى'), - (0xFDA3, 'M', u'تمي'), - (0xFDA4, 'M', u'تمى'), - (0xFDA5, 'M', u'جمي'), - (0xFDA6, 'M', u'جحى'), - (0xFDA7, 'M', u'جمى'), - (0xFDA8, 'M', u'سخى'), - (0xFDA9, 'M', u'صحي'), - (0xFDAA, 'M', u'شحي'), - (0xFDAB, 'M', u'ضحي'), - (0xFDAC, 'M', u'لجي'), - (0xFDAD, 'M', u'لمي'), - (0xFDAE, 'M', u'يحي'), - (0xFDAF, 'M', u'يجي'), - (0xFDB0, 'M', u'يمي'), - (0xFDB1, 'M', u'ممي'), - (0xFDB2, 'M', u'قمي'), - (0xFDB3, 'M', u'نحي'), - (0xFDB4, 'M', u'قمح'), - (0xFDB5, 'M', u'لحم'), - (0xFDB6, 'M', u'عمي'), - (0xFDB7, 'M', u'كمي'), - (0xFDB8, 'M', u'نجح'), - (0xFDB9, 'M', u'مخي'), - (0xFDBA, 'M', u'لجم'), - (0xFDBB, 'M', u'كمم'), - (0xFDBC, 'M', u'لجم'), - (0xFDBD, 'M', u'نجح'), - (0xFDBE, 'M', u'جحي'), - (0xFDBF, 'M', u'حجي'), - (0xFDC0, 'M', u'مجي'), - (0xFDC1, 'M', u'فمي'), - (0xFDC2, 'M', u'بحي'), - (0xFDC3, 'M', u'كمم'), - (0xFDC4, 'M', u'عجم'), - (0xFDC5, 'M', u'صمم'), - (0xFDC6, 'M', u'سخي'), - (0xFDC7, 'M', u'نجي'), - (0xFDC8, 'X'), - (0xFDF0, 'M', u'صلے'), - (0xFDF1, 'M', u'قلے'), - (0xFDF2, 'M', u'الله'), - (0xFDF3, 'M', u'اكبر'), - (0xFDF4, 'M', u'محمد'), - (0xFDF5, 'M', u'صلعم'), - (0xFDF6, 'M', u'رسول'), - (0xFDF7, 'M', u'عليه'), - (0xFDF8, 'M', u'وسلم'), - (0xFDF9, 'M', u'صلى'), - (0xFDFA, '3', u'صلى الله عليه وسلم'), - (0xFDFB, '3', u'جل جلاله'), - (0xFDFC, 'M', u'ریال'), - (0xFDFD, 'V'), - (0xFDFE, 'X'), - (0xFE00, 'I'), - (0xFE10, '3', u','), - ] - -def _seg_49(): - return [ - (0xFE11, 'M', u'、'), - (0xFE12, 'X'), - (0xFE13, '3', u':'), - (0xFE14, '3', u';'), - (0xFE15, '3', u'!'), - (0xFE16, '3', u'?'), - (0xFE17, 'M', u'〖'), - (0xFE18, 'M', u'〗'), - (0xFE19, 'X'), - (0xFE20, 'V'), - (0xFE30, 'X'), - (0xFE31, 'M', u'—'), - (0xFE32, 'M', u'–'), - (0xFE33, '3', u'_'), - (0xFE35, '3', u'('), - (0xFE36, '3', u')'), - (0xFE37, '3', u'{'), - (0xFE38, '3', u'}'), - (0xFE39, 'M', u'〔'), - (0xFE3A, 'M', u'〕'), - (0xFE3B, 'M', u'【'), - (0xFE3C, 'M', u'】'), - (0xFE3D, 'M', u'《'), - (0xFE3E, 'M', u'》'), - (0xFE3F, 'M', u'〈'), - (0xFE40, 'M', u'〉'), - (0xFE41, 'M', u'「'), - (0xFE42, 'M', u'」'), - (0xFE43, 'M', u'『'), - (0xFE44, 'M', u'』'), - (0xFE45, 'V'), - (0xFE47, '3', u'['), - (0xFE48, '3', u']'), - (0xFE49, '3', u' ̅'), - (0xFE4D, '3', u'_'), - (0xFE50, '3', u','), - (0xFE51, 'M', u'、'), - (0xFE52, 'X'), - (0xFE54, '3', u';'), - (0xFE55, '3', u':'), - (0xFE56, '3', u'?'), - (0xFE57, '3', u'!'), - (0xFE58, 'M', u'—'), - (0xFE59, '3', u'('), - (0xFE5A, '3', u')'), - (0xFE5B, '3', u'{'), - (0xFE5C, '3', u'}'), - (0xFE5D, 'M', u'〔'), - (0xFE5E, 'M', u'〕'), - (0xFE5F, '3', u'#'), - (0xFE60, '3', u'&'), - (0xFE61, '3', u'*'), - (0xFE62, '3', u'+'), - (0xFE63, 'M', u'-'), - (0xFE64, '3', u'<'), - (0xFE65, '3', u'>'), - (0xFE66, '3', u'='), - (0xFE67, 'X'), - (0xFE68, '3', u'\\'), - (0xFE69, '3', u'$'), - (0xFE6A, '3', u'%'), - (0xFE6B, '3', u'@'), - (0xFE6C, 'X'), - (0xFE70, '3', u' ً'), - (0xFE71, 'M', u'ـً'), - (0xFE72, '3', u' ٌ'), - (0xFE73, 'V'), - (0xFE74, '3', u' ٍ'), - (0xFE75, 'X'), - (0xFE76, '3', u' َ'), - (0xFE77, 'M', u'ـَ'), - (0xFE78, '3', u' ُ'), - (0xFE79, 'M', u'ـُ'), - (0xFE7A, '3', u' ِ'), - (0xFE7B, 'M', u'ـِ'), - (0xFE7C, '3', u' ّ'), - (0xFE7D, 'M', u'ـّ'), - (0xFE7E, '3', u' ْ'), - (0xFE7F, 'M', u'ـْ'), - (0xFE80, 'M', u'ء'), - (0xFE81, 'M', u'آ'), - (0xFE83, 'M', u'أ'), - (0xFE85, 'M', u'ؤ'), - (0xFE87, 'M', u'إ'), - (0xFE89, 'M', u'ئ'), - (0xFE8D, 'M', u'ا'), - (0xFE8F, 'M', u'ب'), - (0xFE93, 'M', u'ة'), - (0xFE95, 'M', u'ت'), - (0xFE99, 'M', u'ث'), - (0xFE9D, 'M', u'ج'), - (0xFEA1, 'M', u'ح'), - (0xFEA5, 'M', u'خ'), - (0xFEA9, 'M', u'د'), - (0xFEAB, 'M', u'ذ'), - (0xFEAD, 'M', u'ر'), - (0xFEAF, 'M', u'ز'), - (0xFEB1, 'M', u'س'), - (0xFEB5, 'M', u'ش'), - (0xFEB9, 'M', u'ص'), - ] - -def _seg_50(): - return [ - (0xFEBD, 'M', u'ض'), - (0xFEC1, 'M', u'ط'), - (0xFEC5, 'M', u'ظ'), - (0xFEC9, 'M', u'ع'), - (0xFECD, 'M', u'غ'), - (0xFED1, 'M', u'ف'), - (0xFED5, 'M', u'ق'), - (0xFED9, 'M', u'ك'), - (0xFEDD, 'M', u'ل'), - (0xFEE1, 'M', u'م'), - (0xFEE5, 'M', u'ن'), - (0xFEE9, 'M', u'ه'), - (0xFEED, 'M', u'و'), - (0xFEEF, 'M', u'ى'), - (0xFEF1, 'M', u'ي'), - (0xFEF5, 'M', u'لآ'), - (0xFEF7, 'M', u'لأ'), - (0xFEF9, 'M', u'لإ'), - (0xFEFB, 'M', u'لا'), - (0xFEFD, 'X'), - (0xFEFF, 'I'), - (0xFF00, 'X'), - (0xFF01, '3', u'!'), - (0xFF02, '3', u'"'), - (0xFF03, '3', u'#'), - (0xFF04, '3', u'$'), - (0xFF05, '3', u'%'), - (0xFF06, '3', u'&'), - (0xFF07, '3', u'\''), - (0xFF08, '3', u'('), - (0xFF09, '3', u')'), - (0xFF0A, '3', u'*'), - (0xFF0B, '3', u'+'), - (0xFF0C, '3', u','), - (0xFF0D, 'M', u'-'), - (0xFF0E, 'M', u'.'), - (0xFF0F, '3', u'/'), - (0xFF10, 'M', u'0'), - (0xFF11, 'M', u'1'), - (0xFF12, 'M', u'2'), - (0xFF13, 'M', u'3'), - (0xFF14, 'M', u'4'), - (0xFF15, 'M', u'5'), - (0xFF16, 'M', u'6'), - (0xFF17, 'M', u'7'), - (0xFF18, 'M', u'8'), - (0xFF19, 'M', u'9'), - (0xFF1A, '3', u':'), - (0xFF1B, '3', u';'), - (0xFF1C, '3', u'<'), - (0xFF1D, '3', u'='), - (0xFF1E, '3', u'>'), - (0xFF1F, '3', u'?'), - (0xFF20, '3', u'@'), - (0xFF21, 'M', u'a'), - (0xFF22, 'M', u'b'), - (0xFF23, 'M', u'c'), - (0xFF24, 'M', u'd'), - (0xFF25, 'M', u'e'), - (0xFF26, 'M', u'f'), - (0xFF27, 'M', u'g'), - (0xFF28, 'M', u'h'), - (0xFF29, 'M', u'i'), - (0xFF2A, 'M', u'j'), - (0xFF2B, 'M', u'k'), - (0xFF2C, 'M', u'l'), - (0xFF2D, 'M', u'm'), - (0xFF2E, 'M', u'n'), - (0xFF2F, 'M', u'o'), - (0xFF30, 'M', u'p'), - (0xFF31, 'M', u'q'), - (0xFF32, 'M', u'r'), - (0xFF33, 'M', u's'), - (0xFF34, 'M', u't'), - (0xFF35, 'M', u'u'), - (0xFF36, 'M', u'v'), - (0xFF37, 'M', u'w'), - (0xFF38, 'M', u'x'), - (0xFF39, 'M', u'y'), - (0xFF3A, 'M', u'z'), - (0xFF3B, '3', u'['), - (0xFF3C, '3', u'\\'), - (0xFF3D, '3', u']'), - (0xFF3E, '3', u'^'), - (0xFF3F, '3', u'_'), - (0xFF40, '3', u'`'), - (0xFF41, 'M', u'a'), - (0xFF42, 'M', u'b'), - (0xFF43, 'M', u'c'), - (0xFF44, 'M', u'd'), - (0xFF45, 'M', u'e'), - (0xFF46, 'M', u'f'), - (0xFF47, 'M', u'g'), - (0xFF48, 'M', u'h'), - (0xFF49, 'M', u'i'), - (0xFF4A, 'M', u'j'), - (0xFF4B, 'M', u'k'), - (0xFF4C, 'M', u'l'), - (0xFF4D, 'M', u'm'), - (0xFF4E, 'M', u'n'), - ] - -def _seg_51(): - return [ - (0xFF4F, 'M', u'o'), - (0xFF50, 'M', u'p'), - (0xFF51, 'M', u'q'), - (0xFF52, 'M', u'r'), - (0xFF53, 'M', u's'), - (0xFF54, 'M', u't'), - (0xFF55, 'M', u'u'), - (0xFF56, 'M', u'v'), - (0xFF57, 'M', u'w'), - (0xFF58, 'M', u'x'), - (0xFF59, 'M', u'y'), - (0xFF5A, 'M', u'z'), - (0xFF5B, '3', u'{'), - (0xFF5C, '3', u'|'), - (0xFF5D, '3', u'}'), - (0xFF5E, '3', u'~'), - (0xFF5F, 'M', u'⦅'), - (0xFF60, 'M', u'⦆'), - (0xFF61, 'M', u'.'), - (0xFF62, 'M', u'「'), - (0xFF63, 'M', u'」'), - (0xFF64, 'M', u'、'), - (0xFF65, 'M', u'・'), - (0xFF66, 'M', u'ヲ'), - (0xFF67, 'M', u'ァ'), - (0xFF68, 'M', u'ィ'), - (0xFF69, 'M', u'ゥ'), - (0xFF6A, 'M', u'ェ'), - (0xFF6B, 'M', u'ォ'), - (0xFF6C, 'M', u'ャ'), - (0xFF6D, 'M', u'ュ'), - (0xFF6E, 'M', u'ョ'), - (0xFF6F, 'M', u'ッ'), - (0xFF70, 'M', u'ー'), - (0xFF71, 'M', u'ア'), - (0xFF72, 'M', u'イ'), - (0xFF73, 'M', u'ウ'), - (0xFF74, 'M', u'エ'), - (0xFF75, 'M', u'オ'), - (0xFF76, 'M', u'カ'), - (0xFF77, 'M', u'キ'), - (0xFF78, 'M', u'ク'), - (0xFF79, 'M', u'ケ'), - (0xFF7A, 'M', u'コ'), - (0xFF7B, 'M', u'サ'), - (0xFF7C, 'M', u'シ'), - (0xFF7D, 'M', u'ス'), - (0xFF7E, 'M', u'セ'), - (0xFF7F, 'M', u'ソ'), - (0xFF80, 'M', u'タ'), - (0xFF81, 'M', u'チ'), - (0xFF82, 'M', u'ツ'), - (0xFF83, 'M', u'テ'), - (0xFF84, 'M', u'ト'), - (0xFF85, 'M', u'ナ'), - (0xFF86, 'M', u'ニ'), - (0xFF87, 'M', u'ヌ'), - (0xFF88, 'M', u'ネ'), - (0xFF89, 'M', u'ノ'), - (0xFF8A, 'M', u'ハ'), - (0xFF8B, 'M', u'ヒ'), - (0xFF8C, 'M', u'フ'), - (0xFF8D, 'M', u'ヘ'), - (0xFF8E, 'M', u'ホ'), - (0xFF8F, 'M', u'マ'), - (0xFF90, 'M', u'ミ'), - (0xFF91, 'M', u'ム'), - (0xFF92, 'M', u'メ'), - (0xFF93, 'M', u'モ'), - (0xFF94, 'M', u'ヤ'), - (0xFF95, 'M', u'ユ'), - (0xFF96, 'M', u'ヨ'), - (0xFF97, 'M', u'ラ'), - (0xFF98, 'M', u'リ'), - (0xFF99, 'M', u'ル'), - (0xFF9A, 'M', u'レ'), - (0xFF9B, 'M', u'ロ'), - (0xFF9C, 'M', u'ワ'), - (0xFF9D, 'M', u'ン'), - (0xFF9E, 'M', u'゙'), - (0xFF9F, 'M', u'゚'), - (0xFFA0, 'X'), - (0xFFA1, 'M', u'ᄀ'), - (0xFFA2, 'M', u'ᄁ'), - (0xFFA3, 'M', u'ᆪ'), - (0xFFA4, 'M', u'ᄂ'), - (0xFFA5, 'M', u'ᆬ'), - (0xFFA6, 'M', u'ᆭ'), - (0xFFA7, 'M', u'ᄃ'), - (0xFFA8, 'M', u'ᄄ'), - (0xFFA9, 'M', u'ᄅ'), - (0xFFAA, 'M', u'ᆰ'), - (0xFFAB, 'M', u'ᆱ'), - (0xFFAC, 'M', u'ᆲ'), - (0xFFAD, 'M', u'ᆳ'), - (0xFFAE, 'M', u'ᆴ'), - (0xFFAF, 'M', u'ᆵ'), - (0xFFB0, 'M', u'ᄚ'), - (0xFFB1, 'M', u'ᄆ'), - (0xFFB2, 'M', u'ᄇ'), - ] - -def _seg_52(): - return [ - (0xFFB3, 'M', u'ᄈ'), - (0xFFB4, 'M', u'ᄡ'), - (0xFFB5, 'M', u'ᄉ'), - (0xFFB6, 'M', u'ᄊ'), - (0xFFB7, 'M', u'ᄋ'), - (0xFFB8, 'M', u'ᄌ'), - (0xFFB9, 'M', u'ᄍ'), - (0xFFBA, 'M', u'ᄎ'), - (0xFFBB, 'M', u'ᄏ'), - (0xFFBC, 'M', u'ᄐ'), - (0xFFBD, 'M', u'ᄑ'), - (0xFFBE, 'M', u'ᄒ'), - (0xFFBF, 'X'), - (0xFFC2, 'M', u'ᅡ'), - (0xFFC3, 'M', u'ᅢ'), - (0xFFC4, 'M', u'ᅣ'), - (0xFFC5, 'M', u'ᅤ'), - (0xFFC6, 'M', u'ᅥ'), - (0xFFC7, 'M', u'ᅦ'), - (0xFFC8, 'X'), - (0xFFCA, 'M', u'ᅧ'), - (0xFFCB, 'M', u'ᅨ'), - (0xFFCC, 'M', u'ᅩ'), - (0xFFCD, 'M', u'ᅪ'), - (0xFFCE, 'M', u'ᅫ'), - (0xFFCF, 'M', u'ᅬ'), - (0xFFD0, 'X'), - (0xFFD2, 'M', u'ᅭ'), - (0xFFD3, 'M', u'ᅮ'), - (0xFFD4, 'M', u'ᅯ'), - (0xFFD5, 'M', u'ᅰ'), - (0xFFD6, 'M', u'ᅱ'), - (0xFFD7, 'M', u'ᅲ'), - (0xFFD8, 'X'), - (0xFFDA, 'M', u'ᅳ'), - (0xFFDB, 'M', u'ᅴ'), - (0xFFDC, 'M', u'ᅵ'), - (0xFFDD, 'X'), - (0xFFE0, 'M', u'¢'), - (0xFFE1, 'M', u'£'), - (0xFFE2, 'M', u'¬'), - (0xFFE3, '3', u' ̄'), - (0xFFE4, 'M', u'¦'), - (0xFFE5, 'M', u'¥'), - (0xFFE6, 'M', u'₩'), - (0xFFE7, 'X'), - (0xFFE8, 'M', u'│'), - (0xFFE9, 'M', u'←'), - (0xFFEA, 'M', u'↑'), - (0xFFEB, 'M', u'→'), - (0xFFEC, 'M', u'↓'), - (0xFFED, 'M', u'■'), - (0xFFEE, 'M', u'○'), - (0xFFEF, 'X'), - (0x10000, 'V'), - (0x1000C, 'X'), - (0x1000D, 'V'), - (0x10027, 'X'), - (0x10028, 'V'), - (0x1003B, 'X'), - (0x1003C, 'V'), - (0x1003E, 'X'), - (0x1003F, 'V'), - (0x1004E, 'X'), - (0x10050, 'V'), - (0x1005E, 'X'), - (0x10080, 'V'), - (0x100FB, 'X'), - (0x10100, 'V'), - (0x10103, 'X'), - (0x10107, 'V'), - (0x10134, 'X'), - (0x10137, 'V'), - (0x1018F, 'X'), - (0x10190, 'V'), - (0x1019C, 'X'), - (0x101A0, 'V'), - (0x101A1, 'X'), - (0x101D0, 'V'), - (0x101FE, 'X'), - (0x10280, 'V'), - (0x1029D, 'X'), - (0x102A0, 'V'), - (0x102D1, 'X'), - (0x102E0, 'V'), - (0x102FC, 'X'), - (0x10300, 'V'), - (0x10324, 'X'), - (0x1032D, 'V'), - (0x1034B, 'X'), - (0x10350, 'V'), - (0x1037B, 'X'), - (0x10380, 'V'), - (0x1039E, 'X'), - (0x1039F, 'V'), - (0x103C4, 'X'), - (0x103C8, 'V'), - (0x103D6, 'X'), - (0x10400, 'M', u'𐐨'), - (0x10401, 'M', u'𐐩'), - ] - -def _seg_53(): - return [ - (0x10402, 'M', u'𐐪'), - (0x10403, 'M', u'𐐫'), - (0x10404, 'M', u'𐐬'), - (0x10405, 'M', u'𐐭'), - (0x10406, 'M', u'𐐮'), - (0x10407, 'M', u'𐐯'), - (0x10408, 'M', u'𐐰'), - (0x10409, 'M', u'𐐱'), - (0x1040A, 'M', u'𐐲'), - (0x1040B, 'M', u'𐐳'), - (0x1040C, 'M', u'𐐴'), - (0x1040D, 'M', u'𐐵'), - (0x1040E, 'M', u'𐐶'), - (0x1040F, 'M', u'𐐷'), - (0x10410, 'M', u'𐐸'), - (0x10411, 'M', u'𐐹'), - (0x10412, 'M', u'𐐺'), - (0x10413, 'M', u'𐐻'), - (0x10414, 'M', u'𐐼'), - (0x10415, 'M', u'𐐽'), - (0x10416, 'M', u'𐐾'), - (0x10417, 'M', u'𐐿'), - (0x10418, 'M', u'𐑀'), - (0x10419, 'M', u'𐑁'), - (0x1041A, 'M', u'𐑂'), - (0x1041B, 'M', u'𐑃'), - (0x1041C, 'M', u'𐑄'), - (0x1041D, 'M', u'𐑅'), - (0x1041E, 'M', u'𐑆'), - (0x1041F, 'M', u'𐑇'), - (0x10420, 'M', u'𐑈'), - (0x10421, 'M', u'𐑉'), - (0x10422, 'M', u'𐑊'), - (0x10423, 'M', u'𐑋'), - (0x10424, 'M', u'𐑌'), - (0x10425, 'M', u'𐑍'), - (0x10426, 'M', u'𐑎'), - (0x10427, 'M', u'𐑏'), - (0x10428, 'V'), - (0x1049E, 'X'), - (0x104A0, 'V'), - (0x104AA, 'X'), - (0x104B0, 'M', u'𐓘'), - (0x104B1, 'M', u'𐓙'), - (0x104B2, 'M', u'𐓚'), - (0x104B3, 'M', u'𐓛'), - (0x104B4, 'M', u'𐓜'), - (0x104B5, 'M', u'𐓝'), - (0x104B6, 'M', u'𐓞'), - (0x104B7, 'M', u'𐓟'), - (0x104B8, 'M', u'𐓠'), - (0x104B9, 'M', u'𐓡'), - (0x104BA, 'M', u'𐓢'), - (0x104BB, 'M', u'𐓣'), - (0x104BC, 'M', u'𐓤'), - (0x104BD, 'M', u'𐓥'), - (0x104BE, 'M', u'𐓦'), - (0x104BF, 'M', u'𐓧'), - (0x104C0, 'M', u'𐓨'), - (0x104C1, 'M', u'𐓩'), - (0x104C2, 'M', u'𐓪'), - (0x104C3, 'M', u'𐓫'), - (0x104C4, 'M', u'𐓬'), - (0x104C5, 'M', u'𐓭'), - (0x104C6, 'M', u'𐓮'), - (0x104C7, 'M', u'𐓯'), - (0x104C8, 'M', u'𐓰'), - (0x104C9, 'M', u'𐓱'), - (0x104CA, 'M', u'𐓲'), - (0x104CB, 'M', u'𐓳'), - (0x104CC, 'M', u'𐓴'), - (0x104CD, 'M', u'𐓵'), - (0x104CE, 'M', u'𐓶'), - (0x104CF, 'M', u'𐓷'), - (0x104D0, 'M', u'𐓸'), - (0x104D1, 'M', u'𐓹'), - (0x104D2, 'M', u'𐓺'), - (0x104D3, 'M', u'𐓻'), - (0x104D4, 'X'), - (0x104D8, 'V'), - (0x104FC, 'X'), - (0x10500, 'V'), - (0x10528, 'X'), - (0x10530, 'V'), - (0x10564, 'X'), - (0x1056F, 'V'), - (0x10570, 'X'), - (0x10600, 'V'), - (0x10737, 'X'), - (0x10740, 'V'), - (0x10756, 'X'), - (0x10760, 'V'), - (0x10768, 'X'), - (0x10800, 'V'), - (0x10806, 'X'), - (0x10808, 'V'), - (0x10809, 'X'), - (0x1080A, 'V'), - (0x10836, 'X'), - (0x10837, 'V'), - ] - -def _seg_54(): - return [ - (0x10839, 'X'), - (0x1083C, 'V'), - (0x1083D, 'X'), - (0x1083F, 'V'), - (0x10856, 'X'), - (0x10857, 'V'), - (0x1089F, 'X'), - (0x108A7, 'V'), - (0x108B0, 'X'), - (0x108E0, 'V'), - (0x108F3, 'X'), - (0x108F4, 'V'), - (0x108F6, 'X'), - (0x108FB, 'V'), - (0x1091C, 'X'), - (0x1091F, 'V'), - (0x1093A, 'X'), - (0x1093F, 'V'), - (0x10940, 'X'), - (0x10980, 'V'), - (0x109B8, 'X'), - (0x109BC, 'V'), - (0x109D0, 'X'), - (0x109D2, 'V'), - (0x10A04, 'X'), - (0x10A05, 'V'), - (0x10A07, 'X'), - (0x10A0C, 'V'), - (0x10A14, 'X'), - (0x10A15, 'V'), - (0x10A18, 'X'), - (0x10A19, 'V'), - (0x10A36, 'X'), - (0x10A38, 'V'), - (0x10A3B, 'X'), - (0x10A3F, 'V'), - (0x10A49, 'X'), - (0x10A50, 'V'), - (0x10A59, 'X'), - (0x10A60, 'V'), - (0x10AA0, 'X'), - (0x10AC0, 'V'), - (0x10AE7, 'X'), - (0x10AEB, 'V'), - (0x10AF7, 'X'), - (0x10B00, 'V'), - (0x10B36, 'X'), - (0x10B39, 'V'), - (0x10B56, 'X'), - (0x10B58, 'V'), - (0x10B73, 'X'), - (0x10B78, 'V'), - (0x10B92, 'X'), - (0x10B99, 'V'), - (0x10B9D, 'X'), - (0x10BA9, 'V'), - (0x10BB0, 'X'), - (0x10C00, 'V'), - (0x10C49, 'X'), - (0x10C80, 'M', u'𐳀'), - (0x10C81, 'M', u'𐳁'), - (0x10C82, 'M', u'𐳂'), - (0x10C83, 'M', u'𐳃'), - (0x10C84, 'M', u'𐳄'), - (0x10C85, 'M', u'𐳅'), - (0x10C86, 'M', u'𐳆'), - (0x10C87, 'M', u'𐳇'), - (0x10C88, 'M', u'𐳈'), - (0x10C89, 'M', u'𐳉'), - (0x10C8A, 'M', u'𐳊'), - (0x10C8B, 'M', u'𐳋'), - (0x10C8C, 'M', u'𐳌'), - (0x10C8D, 'M', u'𐳍'), - (0x10C8E, 'M', u'𐳎'), - (0x10C8F, 'M', u'𐳏'), - (0x10C90, 'M', u'𐳐'), - (0x10C91, 'M', u'𐳑'), - (0x10C92, 'M', u'𐳒'), - (0x10C93, 'M', u'𐳓'), - (0x10C94, 'M', u'𐳔'), - (0x10C95, 'M', u'𐳕'), - (0x10C96, 'M', u'𐳖'), - (0x10C97, 'M', u'𐳗'), - (0x10C98, 'M', u'𐳘'), - (0x10C99, 'M', u'𐳙'), - (0x10C9A, 'M', u'𐳚'), - (0x10C9B, 'M', u'𐳛'), - (0x10C9C, 'M', u'𐳜'), - (0x10C9D, 'M', u'𐳝'), - (0x10C9E, 'M', u'𐳞'), - (0x10C9F, 'M', u'𐳟'), - (0x10CA0, 'M', u'𐳠'), - (0x10CA1, 'M', u'𐳡'), - (0x10CA2, 'M', u'𐳢'), - (0x10CA3, 'M', u'𐳣'), - (0x10CA4, 'M', u'𐳤'), - (0x10CA5, 'M', u'𐳥'), - (0x10CA6, 'M', u'𐳦'), - (0x10CA7, 'M', u'𐳧'), - (0x10CA8, 'M', u'𐳨'), - ] - -def _seg_55(): - return [ - (0x10CA9, 'M', u'𐳩'), - (0x10CAA, 'M', u'𐳪'), - (0x10CAB, 'M', u'𐳫'), - (0x10CAC, 'M', u'𐳬'), - (0x10CAD, 'M', u'𐳭'), - (0x10CAE, 'M', u'𐳮'), - (0x10CAF, 'M', u'𐳯'), - (0x10CB0, 'M', u'𐳰'), - (0x10CB1, 'M', u'𐳱'), - (0x10CB2, 'M', u'𐳲'), - (0x10CB3, 'X'), - (0x10CC0, 'V'), - (0x10CF3, 'X'), - (0x10CFA, 'V'), - (0x10D28, 'X'), - (0x10D30, 'V'), - (0x10D3A, 'X'), - (0x10E60, 'V'), - (0x10E7F, 'X'), - (0x10F00, 'V'), - (0x10F28, 'X'), - (0x10F30, 'V'), - (0x10F5A, 'X'), - (0x11000, 'V'), - (0x1104E, 'X'), - (0x11052, 'V'), - (0x11070, 'X'), - (0x1107F, 'V'), - (0x110BD, 'X'), - (0x110BE, 'V'), - (0x110C2, 'X'), - (0x110D0, 'V'), - (0x110E9, 'X'), - (0x110F0, 'V'), - (0x110FA, 'X'), - (0x11100, 'V'), - (0x11135, 'X'), - (0x11136, 'V'), - (0x11147, 'X'), - (0x11150, 'V'), - (0x11177, 'X'), - (0x11180, 'V'), - (0x111CE, 'X'), - (0x111D0, 'V'), - (0x111E0, 'X'), - (0x111E1, 'V'), - (0x111F5, 'X'), - (0x11200, 'V'), - (0x11212, 'X'), - (0x11213, 'V'), - (0x1123F, 'X'), - (0x11280, 'V'), - (0x11287, 'X'), - (0x11288, 'V'), - (0x11289, 'X'), - (0x1128A, 'V'), - (0x1128E, 'X'), - (0x1128F, 'V'), - (0x1129E, 'X'), - (0x1129F, 'V'), - (0x112AA, 'X'), - (0x112B0, 'V'), - (0x112EB, 'X'), - (0x112F0, 'V'), - (0x112FA, 'X'), - (0x11300, 'V'), - (0x11304, 'X'), - (0x11305, 'V'), - (0x1130D, 'X'), - (0x1130F, 'V'), - (0x11311, 'X'), - (0x11313, 'V'), - (0x11329, 'X'), - (0x1132A, 'V'), - (0x11331, 'X'), - (0x11332, 'V'), - (0x11334, 'X'), - (0x11335, 'V'), - (0x1133A, 'X'), - (0x1133B, 'V'), - (0x11345, 'X'), - (0x11347, 'V'), - (0x11349, 'X'), - (0x1134B, 'V'), - (0x1134E, 'X'), - (0x11350, 'V'), - (0x11351, 'X'), - (0x11357, 'V'), - (0x11358, 'X'), - (0x1135D, 'V'), - (0x11364, 'X'), - (0x11366, 'V'), - (0x1136D, 'X'), - (0x11370, 'V'), - (0x11375, 'X'), - (0x11400, 'V'), - (0x1145A, 'X'), - (0x1145B, 'V'), - (0x1145C, 'X'), - (0x1145D, 'V'), - ] - -def _seg_56(): - return [ - (0x1145F, 'X'), - (0x11480, 'V'), - (0x114C8, 'X'), - (0x114D0, 'V'), - (0x114DA, 'X'), - (0x11580, 'V'), - (0x115B6, 'X'), - (0x115B8, 'V'), - (0x115DE, 'X'), - (0x11600, 'V'), - (0x11645, 'X'), - (0x11650, 'V'), - (0x1165A, 'X'), - (0x11660, 'V'), - (0x1166D, 'X'), - (0x11680, 'V'), - (0x116B8, 'X'), - (0x116C0, 'V'), - (0x116CA, 'X'), - (0x11700, 'V'), - (0x1171B, 'X'), - (0x1171D, 'V'), - (0x1172C, 'X'), - (0x11730, 'V'), - (0x11740, 'X'), - (0x11800, 'V'), - (0x1183C, 'X'), - (0x118A0, 'M', u'𑣀'), - (0x118A1, 'M', u'𑣁'), - (0x118A2, 'M', u'𑣂'), - (0x118A3, 'M', u'𑣃'), - (0x118A4, 'M', u'𑣄'), - (0x118A5, 'M', u'𑣅'), - (0x118A6, 'M', u'𑣆'), - (0x118A7, 'M', u'𑣇'), - (0x118A8, 'M', u'𑣈'), - (0x118A9, 'M', u'𑣉'), - (0x118AA, 'M', u'𑣊'), - (0x118AB, 'M', u'𑣋'), - (0x118AC, 'M', u'𑣌'), - (0x118AD, 'M', u'𑣍'), - (0x118AE, 'M', u'𑣎'), - (0x118AF, 'M', u'𑣏'), - (0x118B0, 'M', u'𑣐'), - (0x118B1, 'M', u'𑣑'), - (0x118B2, 'M', u'𑣒'), - (0x118B3, 'M', u'𑣓'), - (0x118B4, 'M', u'𑣔'), - (0x118B5, 'M', u'𑣕'), - (0x118B6, 'M', u'𑣖'), - (0x118B7, 'M', u'𑣗'), - (0x118B8, 'M', u'𑣘'), - (0x118B9, 'M', u'𑣙'), - (0x118BA, 'M', u'𑣚'), - (0x118BB, 'M', u'𑣛'), - (0x118BC, 'M', u'𑣜'), - (0x118BD, 'M', u'𑣝'), - (0x118BE, 'M', u'𑣞'), - (0x118BF, 'M', u'𑣟'), - (0x118C0, 'V'), - (0x118F3, 'X'), - (0x118FF, 'V'), - (0x11900, 'X'), - (0x11A00, 'V'), - (0x11A48, 'X'), - (0x11A50, 'V'), - (0x11A84, 'X'), - (0x11A86, 'V'), - (0x11AA3, 'X'), - (0x11AC0, 'V'), - (0x11AF9, 'X'), - (0x11C00, 'V'), - (0x11C09, 'X'), - (0x11C0A, 'V'), - (0x11C37, 'X'), - (0x11C38, 'V'), - (0x11C46, 'X'), - (0x11C50, 'V'), - (0x11C6D, 'X'), - (0x11C70, 'V'), - (0x11C90, 'X'), - (0x11C92, 'V'), - (0x11CA8, 'X'), - (0x11CA9, 'V'), - (0x11CB7, 'X'), - (0x11D00, 'V'), - (0x11D07, 'X'), - (0x11D08, 'V'), - (0x11D0A, 'X'), - (0x11D0B, 'V'), - (0x11D37, 'X'), - (0x11D3A, 'V'), - (0x11D3B, 'X'), - (0x11D3C, 'V'), - (0x11D3E, 'X'), - (0x11D3F, 'V'), - (0x11D48, 'X'), - (0x11D50, 'V'), - (0x11D5A, 'X'), - (0x11D60, 'V'), - ] - -def _seg_57(): - return [ - (0x11D66, 'X'), - (0x11D67, 'V'), - (0x11D69, 'X'), - (0x11D6A, 'V'), - (0x11D8F, 'X'), - (0x11D90, 'V'), - (0x11D92, 'X'), - (0x11D93, 'V'), - (0x11D99, 'X'), - (0x11DA0, 'V'), - (0x11DAA, 'X'), - (0x11EE0, 'V'), - (0x11EF9, 'X'), - (0x12000, 'V'), - (0x1239A, 'X'), - (0x12400, 'V'), - (0x1246F, 'X'), - (0x12470, 'V'), - (0x12475, 'X'), - (0x12480, 'V'), - (0x12544, 'X'), - (0x13000, 'V'), - (0x1342F, 'X'), - (0x14400, 'V'), - (0x14647, 'X'), - (0x16800, 'V'), - (0x16A39, 'X'), - (0x16A40, 'V'), - (0x16A5F, 'X'), - (0x16A60, 'V'), - (0x16A6A, 'X'), - (0x16A6E, 'V'), - (0x16A70, 'X'), - (0x16AD0, 'V'), - (0x16AEE, 'X'), - (0x16AF0, 'V'), - (0x16AF6, 'X'), - (0x16B00, 'V'), - (0x16B46, 'X'), - (0x16B50, 'V'), - (0x16B5A, 'X'), - (0x16B5B, 'V'), - (0x16B62, 'X'), - (0x16B63, 'V'), - (0x16B78, 'X'), - (0x16B7D, 'V'), - (0x16B90, 'X'), - (0x16E60, 'V'), - (0x16E9B, 'X'), - (0x16F00, 'V'), - (0x16F45, 'X'), - (0x16F50, 'V'), - (0x16F7F, 'X'), - (0x16F8F, 'V'), - (0x16FA0, 'X'), - (0x16FE0, 'V'), - (0x16FE2, 'X'), - (0x17000, 'V'), - (0x187F2, 'X'), - (0x18800, 'V'), - (0x18AF3, 'X'), - (0x1B000, 'V'), - (0x1B11F, 'X'), - (0x1B170, 'V'), - (0x1B2FC, 'X'), - (0x1BC00, 'V'), - (0x1BC6B, 'X'), - (0x1BC70, 'V'), - (0x1BC7D, 'X'), - (0x1BC80, 'V'), - (0x1BC89, 'X'), - (0x1BC90, 'V'), - (0x1BC9A, 'X'), - (0x1BC9C, 'V'), - (0x1BCA0, 'I'), - (0x1BCA4, 'X'), - (0x1D000, 'V'), - (0x1D0F6, 'X'), - (0x1D100, 'V'), - (0x1D127, 'X'), - (0x1D129, 'V'), - (0x1D15E, 'M', u'𝅗𝅥'), - (0x1D15F, 'M', u'𝅘𝅥'), - (0x1D160, 'M', u'𝅘𝅥𝅮'), - (0x1D161, 'M', u'𝅘𝅥𝅯'), - (0x1D162, 'M', u'𝅘𝅥𝅰'), - (0x1D163, 'M', u'𝅘𝅥𝅱'), - (0x1D164, 'M', u'𝅘𝅥𝅲'), - (0x1D165, 'V'), - (0x1D173, 'X'), - (0x1D17B, 'V'), - (0x1D1BB, 'M', u'𝆹𝅥'), - (0x1D1BC, 'M', u'𝆺𝅥'), - (0x1D1BD, 'M', u'𝆹𝅥𝅮'), - (0x1D1BE, 'M', u'𝆺𝅥𝅮'), - (0x1D1BF, 'M', u'𝆹𝅥𝅯'), - (0x1D1C0, 'M', u'𝆺𝅥𝅯'), - (0x1D1C1, 'V'), - (0x1D1E9, 'X'), - (0x1D200, 'V'), - ] - -def _seg_58(): - return [ - (0x1D246, 'X'), - (0x1D2E0, 'V'), - (0x1D2F4, 'X'), - (0x1D300, 'V'), - (0x1D357, 'X'), - (0x1D360, 'V'), - (0x1D379, 'X'), - (0x1D400, 'M', u'a'), - (0x1D401, 'M', u'b'), - (0x1D402, 'M', u'c'), - (0x1D403, 'M', u'd'), - (0x1D404, 'M', u'e'), - (0x1D405, 'M', u'f'), - (0x1D406, 'M', u'g'), - (0x1D407, 'M', u'h'), - (0x1D408, 'M', u'i'), - (0x1D409, 'M', u'j'), - (0x1D40A, 'M', u'k'), - (0x1D40B, 'M', u'l'), - (0x1D40C, 'M', u'm'), - (0x1D40D, 'M', u'n'), - (0x1D40E, 'M', u'o'), - (0x1D40F, 'M', u'p'), - (0x1D410, 'M', u'q'), - (0x1D411, 'M', u'r'), - (0x1D412, 'M', u's'), - (0x1D413, 'M', u't'), - (0x1D414, 'M', u'u'), - (0x1D415, 'M', u'v'), - (0x1D416, 'M', u'w'), - (0x1D417, 'M', u'x'), - (0x1D418, 'M', u'y'), - (0x1D419, 'M', u'z'), - (0x1D41A, 'M', u'a'), - (0x1D41B, 'M', u'b'), - (0x1D41C, 'M', u'c'), - (0x1D41D, 'M', u'd'), - (0x1D41E, 'M', u'e'), - (0x1D41F, 'M', u'f'), - (0x1D420, 'M', u'g'), - (0x1D421, 'M', u'h'), - (0x1D422, 'M', u'i'), - (0x1D423, 'M', u'j'), - (0x1D424, 'M', u'k'), - (0x1D425, 'M', u'l'), - (0x1D426, 'M', u'm'), - (0x1D427, 'M', u'n'), - (0x1D428, 'M', u'o'), - (0x1D429, 'M', u'p'), - (0x1D42A, 'M', u'q'), - (0x1D42B, 'M', u'r'), - (0x1D42C, 'M', u's'), - (0x1D42D, 'M', u't'), - (0x1D42E, 'M', u'u'), - (0x1D42F, 'M', u'v'), - (0x1D430, 'M', u'w'), - (0x1D431, 'M', u'x'), - (0x1D432, 'M', u'y'), - (0x1D433, 'M', u'z'), - (0x1D434, 'M', u'a'), - (0x1D435, 'M', u'b'), - (0x1D436, 'M', u'c'), - (0x1D437, 'M', u'd'), - (0x1D438, 'M', u'e'), - (0x1D439, 'M', u'f'), - (0x1D43A, 'M', u'g'), - (0x1D43B, 'M', u'h'), - (0x1D43C, 'M', u'i'), - (0x1D43D, 'M', u'j'), - (0x1D43E, 'M', u'k'), - (0x1D43F, 'M', u'l'), - (0x1D440, 'M', u'm'), - (0x1D441, 'M', u'n'), - (0x1D442, 'M', u'o'), - (0x1D443, 'M', u'p'), - (0x1D444, 'M', u'q'), - (0x1D445, 'M', u'r'), - (0x1D446, 'M', u's'), - (0x1D447, 'M', u't'), - (0x1D448, 'M', u'u'), - (0x1D449, 'M', u'v'), - (0x1D44A, 'M', u'w'), - (0x1D44B, 'M', u'x'), - (0x1D44C, 'M', u'y'), - (0x1D44D, 'M', u'z'), - (0x1D44E, 'M', u'a'), - (0x1D44F, 'M', u'b'), - (0x1D450, 'M', u'c'), - (0x1D451, 'M', u'd'), - (0x1D452, 'M', u'e'), - (0x1D453, 'M', u'f'), - (0x1D454, 'M', u'g'), - (0x1D455, 'X'), - (0x1D456, 'M', u'i'), - (0x1D457, 'M', u'j'), - (0x1D458, 'M', u'k'), - (0x1D459, 'M', u'l'), - (0x1D45A, 'M', u'm'), - (0x1D45B, 'M', u'n'), - (0x1D45C, 'M', u'o'), - ] - -def _seg_59(): - return [ - (0x1D45D, 'M', u'p'), - (0x1D45E, 'M', u'q'), - (0x1D45F, 'M', u'r'), - (0x1D460, 'M', u's'), - (0x1D461, 'M', u't'), - (0x1D462, 'M', u'u'), - (0x1D463, 'M', u'v'), - (0x1D464, 'M', u'w'), - (0x1D465, 'M', u'x'), - (0x1D466, 'M', u'y'), - (0x1D467, 'M', u'z'), - (0x1D468, 'M', u'a'), - (0x1D469, 'M', u'b'), - (0x1D46A, 'M', u'c'), - (0x1D46B, 'M', u'd'), - (0x1D46C, 'M', u'e'), - (0x1D46D, 'M', u'f'), - (0x1D46E, 'M', u'g'), - (0x1D46F, 'M', u'h'), - (0x1D470, 'M', u'i'), - (0x1D471, 'M', u'j'), - (0x1D472, 'M', u'k'), - (0x1D473, 'M', u'l'), - (0x1D474, 'M', u'm'), - (0x1D475, 'M', u'n'), - (0x1D476, 'M', u'o'), - (0x1D477, 'M', u'p'), - (0x1D478, 'M', u'q'), - (0x1D479, 'M', u'r'), - (0x1D47A, 'M', u's'), - (0x1D47B, 'M', u't'), - (0x1D47C, 'M', u'u'), - (0x1D47D, 'M', u'v'), - (0x1D47E, 'M', u'w'), - (0x1D47F, 'M', u'x'), - (0x1D480, 'M', u'y'), - (0x1D481, 'M', u'z'), - (0x1D482, 'M', u'a'), - (0x1D483, 'M', u'b'), - (0x1D484, 'M', u'c'), - (0x1D485, 'M', u'd'), - (0x1D486, 'M', u'e'), - (0x1D487, 'M', u'f'), - (0x1D488, 'M', u'g'), - (0x1D489, 'M', u'h'), - (0x1D48A, 'M', u'i'), - (0x1D48B, 'M', u'j'), - (0x1D48C, 'M', u'k'), - (0x1D48D, 'M', u'l'), - (0x1D48E, 'M', u'm'), - (0x1D48F, 'M', u'n'), - (0x1D490, 'M', u'o'), - (0x1D491, 'M', u'p'), - (0x1D492, 'M', u'q'), - (0x1D493, 'M', u'r'), - (0x1D494, 'M', u's'), - (0x1D495, 'M', u't'), - (0x1D496, 'M', u'u'), - (0x1D497, 'M', u'v'), - (0x1D498, 'M', u'w'), - (0x1D499, 'M', u'x'), - (0x1D49A, 'M', u'y'), - (0x1D49B, 'M', u'z'), - (0x1D49C, 'M', u'a'), - (0x1D49D, 'X'), - (0x1D49E, 'M', u'c'), - (0x1D49F, 'M', u'd'), - (0x1D4A0, 'X'), - (0x1D4A2, 'M', u'g'), - (0x1D4A3, 'X'), - (0x1D4A5, 'M', u'j'), - (0x1D4A6, 'M', u'k'), - (0x1D4A7, 'X'), - (0x1D4A9, 'M', u'n'), - (0x1D4AA, 'M', u'o'), - (0x1D4AB, 'M', u'p'), - (0x1D4AC, 'M', u'q'), - (0x1D4AD, 'X'), - (0x1D4AE, 'M', u's'), - (0x1D4AF, 'M', u't'), - (0x1D4B0, 'M', u'u'), - (0x1D4B1, 'M', u'v'), - (0x1D4B2, 'M', u'w'), - (0x1D4B3, 'M', u'x'), - (0x1D4B4, 'M', u'y'), - (0x1D4B5, 'M', u'z'), - (0x1D4B6, 'M', u'a'), - (0x1D4B7, 'M', u'b'), - (0x1D4B8, 'M', u'c'), - (0x1D4B9, 'M', u'd'), - (0x1D4BA, 'X'), - (0x1D4BB, 'M', u'f'), - (0x1D4BC, 'X'), - (0x1D4BD, 'M', u'h'), - (0x1D4BE, 'M', u'i'), - (0x1D4BF, 'M', u'j'), - (0x1D4C0, 'M', u'k'), - (0x1D4C1, 'M', u'l'), - (0x1D4C2, 'M', u'm'), - (0x1D4C3, 'M', u'n'), - ] - -def _seg_60(): - return [ - (0x1D4C4, 'X'), - (0x1D4C5, 'M', u'p'), - (0x1D4C6, 'M', u'q'), - (0x1D4C7, 'M', u'r'), - (0x1D4C8, 'M', u's'), - (0x1D4C9, 'M', u't'), - (0x1D4CA, 'M', u'u'), - (0x1D4CB, 'M', u'v'), - (0x1D4CC, 'M', u'w'), - (0x1D4CD, 'M', u'x'), - (0x1D4CE, 'M', u'y'), - (0x1D4CF, 'M', u'z'), - (0x1D4D0, 'M', u'a'), - (0x1D4D1, 'M', u'b'), - (0x1D4D2, 'M', u'c'), - (0x1D4D3, 'M', u'd'), - (0x1D4D4, 'M', u'e'), - (0x1D4D5, 'M', u'f'), - (0x1D4D6, 'M', u'g'), - (0x1D4D7, 'M', u'h'), - (0x1D4D8, 'M', u'i'), - (0x1D4D9, 'M', u'j'), - (0x1D4DA, 'M', u'k'), - (0x1D4DB, 'M', u'l'), - (0x1D4DC, 'M', u'm'), - (0x1D4DD, 'M', u'n'), - (0x1D4DE, 'M', u'o'), - (0x1D4DF, 'M', u'p'), - (0x1D4E0, 'M', u'q'), - (0x1D4E1, 'M', u'r'), - (0x1D4E2, 'M', u's'), - (0x1D4E3, 'M', u't'), - (0x1D4E4, 'M', u'u'), - (0x1D4E5, 'M', u'v'), - (0x1D4E6, 'M', u'w'), - (0x1D4E7, 'M', u'x'), - (0x1D4E8, 'M', u'y'), - (0x1D4E9, 'M', u'z'), - (0x1D4EA, 'M', u'a'), - (0x1D4EB, 'M', u'b'), - (0x1D4EC, 'M', u'c'), - (0x1D4ED, 'M', u'd'), - (0x1D4EE, 'M', u'e'), - (0x1D4EF, 'M', u'f'), - (0x1D4F0, 'M', u'g'), - (0x1D4F1, 'M', u'h'), - (0x1D4F2, 'M', u'i'), - (0x1D4F3, 'M', u'j'), - (0x1D4F4, 'M', u'k'), - (0x1D4F5, 'M', u'l'), - (0x1D4F6, 'M', u'm'), - (0x1D4F7, 'M', u'n'), - (0x1D4F8, 'M', u'o'), - (0x1D4F9, 'M', u'p'), - (0x1D4FA, 'M', u'q'), - (0x1D4FB, 'M', u'r'), - (0x1D4FC, 'M', u's'), - (0x1D4FD, 'M', u't'), - (0x1D4FE, 'M', u'u'), - (0x1D4FF, 'M', u'v'), - (0x1D500, 'M', u'w'), - (0x1D501, 'M', u'x'), - (0x1D502, 'M', u'y'), - (0x1D503, 'M', u'z'), - (0x1D504, 'M', u'a'), - (0x1D505, 'M', u'b'), - (0x1D506, 'X'), - (0x1D507, 'M', u'd'), - (0x1D508, 'M', u'e'), - (0x1D509, 'M', u'f'), - (0x1D50A, 'M', u'g'), - (0x1D50B, 'X'), - (0x1D50D, 'M', u'j'), - (0x1D50E, 'M', u'k'), - (0x1D50F, 'M', u'l'), - (0x1D510, 'M', u'm'), - (0x1D511, 'M', u'n'), - (0x1D512, 'M', u'o'), - (0x1D513, 'M', u'p'), - (0x1D514, 'M', u'q'), - (0x1D515, 'X'), - (0x1D516, 'M', u's'), - (0x1D517, 'M', u't'), - (0x1D518, 'M', u'u'), - (0x1D519, 'M', u'v'), - (0x1D51A, 'M', u'w'), - (0x1D51B, 'M', u'x'), - (0x1D51C, 'M', u'y'), - (0x1D51D, 'X'), - (0x1D51E, 'M', u'a'), - (0x1D51F, 'M', u'b'), - (0x1D520, 'M', u'c'), - (0x1D521, 'M', u'd'), - (0x1D522, 'M', u'e'), - (0x1D523, 'M', u'f'), - (0x1D524, 'M', u'g'), - (0x1D525, 'M', u'h'), - (0x1D526, 'M', u'i'), - (0x1D527, 'M', u'j'), - (0x1D528, 'M', u'k'), - ] - -def _seg_61(): - return [ - (0x1D529, 'M', u'l'), - (0x1D52A, 'M', u'm'), - (0x1D52B, 'M', u'n'), - (0x1D52C, 'M', u'o'), - (0x1D52D, 'M', u'p'), - (0x1D52E, 'M', u'q'), - (0x1D52F, 'M', u'r'), - (0x1D530, 'M', u's'), - (0x1D531, 'M', u't'), - (0x1D532, 'M', u'u'), - (0x1D533, 'M', u'v'), - (0x1D534, 'M', u'w'), - (0x1D535, 'M', u'x'), - (0x1D536, 'M', u'y'), - (0x1D537, 'M', u'z'), - (0x1D538, 'M', u'a'), - (0x1D539, 'M', u'b'), - (0x1D53A, 'X'), - (0x1D53B, 'M', u'd'), - (0x1D53C, 'M', u'e'), - (0x1D53D, 'M', u'f'), - (0x1D53E, 'M', u'g'), - (0x1D53F, 'X'), - (0x1D540, 'M', u'i'), - (0x1D541, 'M', u'j'), - (0x1D542, 'M', u'k'), - (0x1D543, 'M', u'l'), - (0x1D544, 'M', u'm'), - (0x1D545, 'X'), - (0x1D546, 'M', u'o'), - (0x1D547, 'X'), - (0x1D54A, 'M', u's'), - (0x1D54B, 'M', u't'), - (0x1D54C, 'M', u'u'), - (0x1D54D, 'M', u'v'), - (0x1D54E, 'M', u'w'), - (0x1D54F, 'M', u'x'), - (0x1D550, 'M', u'y'), - (0x1D551, 'X'), - (0x1D552, 'M', u'a'), - (0x1D553, 'M', u'b'), - (0x1D554, 'M', u'c'), - (0x1D555, 'M', u'd'), - (0x1D556, 'M', u'e'), - (0x1D557, 'M', u'f'), - (0x1D558, 'M', u'g'), - (0x1D559, 'M', u'h'), - (0x1D55A, 'M', u'i'), - (0x1D55B, 'M', u'j'), - (0x1D55C, 'M', u'k'), - (0x1D55D, 'M', u'l'), - (0x1D55E, 'M', u'm'), - (0x1D55F, 'M', u'n'), - (0x1D560, 'M', u'o'), - (0x1D561, 'M', u'p'), - (0x1D562, 'M', u'q'), - (0x1D563, 'M', u'r'), - (0x1D564, 'M', u's'), - (0x1D565, 'M', u't'), - (0x1D566, 'M', u'u'), - (0x1D567, 'M', u'v'), - (0x1D568, 'M', u'w'), - (0x1D569, 'M', u'x'), - (0x1D56A, 'M', u'y'), - (0x1D56B, 'M', u'z'), - (0x1D56C, 'M', u'a'), - (0x1D56D, 'M', u'b'), - (0x1D56E, 'M', u'c'), - (0x1D56F, 'M', u'd'), - (0x1D570, 'M', u'e'), - (0x1D571, 'M', u'f'), - (0x1D572, 'M', u'g'), - (0x1D573, 'M', u'h'), - (0x1D574, 'M', u'i'), - (0x1D575, 'M', u'j'), - (0x1D576, 'M', u'k'), - (0x1D577, 'M', u'l'), - (0x1D578, 'M', u'm'), - (0x1D579, 'M', u'n'), - (0x1D57A, 'M', u'o'), - (0x1D57B, 'M', u'p'), - (0x1D57C, 'M', u'q'), - (0x1D57D, 'M', u'r'), - (0x1D57E, 'M', u's'), - (0x1D57F, 'M', u't'), - (0x1D580, 'M', u'u'), - (0x1D581, 'M', u'v'), - (0x1D582, 'M', u'w'), - (0x1D583, 'M', u'x'), - (0x1D584, 'M', u'y'), - (0x1D585, 'M', u'z'), - (0x1D586, 'M', u'a'), - (0x1D587, 'M', u'b'), - (0x1D588, 'M', u'c'), - (0x1D589, 'M', u'd'), - (0x1D58A, 'M', u'e'), - (0x1D58B, 'M', u'f'), - (0x1D58C, 'M', u'g'), - (0x1D58D, 'M', u'h'), - (0x1D58E, 'M', u'i'), - ] - -def _seg_62(): - return [ - (0x1D58F, 'M', u'j'), - (0x1D590, 'M', u'k'), - (0x1D591, 'M', u'l'), - (0x1D592, 'M', u'm'), - (0x1D593, 'M', u'n'), - (0x1D594, 'M', u'o'), - (0x1D595, 'M', u'p'), - (0x1D596, 'M', u'q'), - (0x1D597, 'M', u'r'), - (0x1D598, 'M', u's'), - (0x1D599, 'M', u't'), - (0x1D59A, 'M', u'u'), - (0x1D59B, 'M', u'v'), - (0x1D59C, 'M', u'w'), - (0x1D59D, 'M', u'x'), - (0x1D59E, 'M', u'y'), - (0x1D59F, 'M', u'z'), - (0x1D5A0, 'M', u'a'), - (0x1D5A1, 'M', u'b'), - (0x1D5A2, 'M', u'c'), - (0x1D5A3, 'M', u'd'), - (0x1D5A4, 'M', u'e'), - (0x1D5A5, 'M', u'f'), - (0x1D5A6, 'M', u'g'), - (0x1D5A7, 'M', u'h'), - (0x1D5A8, 'M', u'i'), - (0x1D5A9, 'M', u'j'), - (0x1D5AA, 'M', u'k'), - (0x1D5AB, 'M', u'l'), - (0x1D5AC, 'M', u'm'), - (0x1D5AD, 'M', u'n'), - (0x1D5AE, 'M', u'o'), - (0x1D5AF, 'M', u'p'), - (0x1D5B0, 'M', u'q'), - (0x1D5B1, 'M', u'r'), - (0x1D5B2, 'M', u's'), - (0x1D5B3, 'M', u't'), - (0x1D5B4, 'M', u'u'), - (0x1D5B5, 'M', u'v'), - (0x1D5B6, 'M', u'w'), - (0x1D5B7, 'M', u'x'), - (0x1D5B8, 'M', u'y'), - (0x1D5B9, 'M', u'z'), - (0x1D5BA, 'M', u'a'), - (0x1D5BB, 'M', u'b'), - (0x1D5BC, 'M', u'c'), - (0x1D5BD, 'M', u'd'), - (0x1D5BE, 'M', u'e'), - (0x1D5BF, 'M', u'f'), - (0x1D5C0, 'M', u'g'), - (0x1D5C1, 'M', u'h'), - (0x1D5C2, 'M', u'i'), - (0x1D5C3, 'M', u'j'), - (0x1D5C4, 'M', u'k'), - (0x1D5C5, 'M', u'l'), - (0x1D5C6, 'M', u'm'), - (0x1D5C7, 'M', u'n'), - (0x1D5C8, 'M', u'o'), - (0x1D5C9, 'M', u'p'), - (0x1D5CA, 'M', u'q'), - (0x1D5CB, 'M', u'r'), - (0x1D5CC, 'M', u's'), - (0x1D5CD, 'M', u't'), - (0x1D5CE, 'M', u'u'), - (0x1D5CF, 'M', u'v'), - (0x1D5D0, 'M', u'w'), - (0x1D5D1, 'M', u'x'), - (0x1D5D2, 'M', u'y'), - (0x1D5D3, 'M', u'z'), - (0x1D5D4, 'M', u'a'), - (0x1D5D5, 'M', u'b'), - (0x1D5D6, 'M', u'c'), - (0x1D5D7, 'M', u'd'), - (0x1D5D8, 'M', u'e'), - (0x1D5D9, 'M', u'f'), - (0x1D5DA, 'M', u'g'), - (0x1D5DB, 'M', u'h'), - (0x1D5DC, 'M', u'i'), - (0x1D5DD, 'M', u'j'), - (0x1D5DE, 'M', u'k'), - (0x1D5DF, 'M', u'l'), - (0x1D5E0, 'M', u'm'), - (0x1D5E1, 'M', u'n'), - (0x1D5E2, 'M', u'o'), - (0x1D5E3, 'M', u'p'), - (0x1D5E4, 'M', u'q'), - (0x1D5E5, 'M', u'r'), - (0x1D5E6, 'M', u's'), - (0x1D5E7, 'M', u't'), - (0x1D5E8, 'M', u'u'), - (0x1D5E9, 'M', u'v'), - (0x1D5EA, 'M', u'w'), - (0x1D5EB, 'M', u'x'), - (0x1D5EC, 'M', u'y'), - (0x1D5ED, 'M', u'z'), - (0x1D5EE, 'M', u'a'), - (0x1D5EF, 'M', u'b'), - (0x1D5F0, 'M', u'c'), - (0x1D5F1, 'M', u'd'), - (0x1D5F2, 'M', u'e'), - ] - -def _seg_63(): - return [ - (0x1D5F3, 'M', u'f'), - (0x1D5F4, 'M', u'g'), - (0x1D5F5, 'M', u'h'), - (0x1D5F6, 'M', u'i'), - (0x1D5F7, 'M', u'j'), - (0x1D5F8, 'M', u'k'), - (0x1D5F9, 'M', u'l'), - (0x1D5FA, 'M', u'm'), - (0x1D5FB, 'M', u'n'), - (0x1D5FC, 'M', u'o'), - (0x1D5FD, 'M', u'p'), - (0x1D5FE, 'M', u'q'), - (0x1D5FF, 'M', u'r'), - (0x1D600, 'M', u's'), - (0x1D601, 'M', u't'), - (0x1D602, 'M', u'u'), - (0x1D603, 'M', u'v'), - (0x1D604, 'M', u'w'), - (0x1D605, 'M', u'x'), - (0x1D606, 'M', u'y'), - (0x1D607, 'M', u'z'), - (0x1D608, 'M', u'a'), - (0x1D609, 'M', u'b'), - (0x1D60A, 'M', u'c'), - (0x1D60B, 'M', u'd'), - (0x1D60C, 'M', u'e'), - (0x1D60D, 'M', u'f'), - (0x1D60E, 'M', u'g'), - (0x1D60F, 'M', u'h'), - (0x1D610, 'M', u'i'), - (0x1D611, 'M', u'j'), - (0x1D612, 'M', u'k'), - (0x1D613, 'M', u'l'), - (0x1D614, 'M', u'm'), - (0x1D615, 'M', u'n'), - (0x1D616, 'M', u'o'), - (0x1D617, 'M', u'p'), - (0x1D618, 'M', u'q'), - (0x1D619, 'M', u'r'), - (0x1D61A, 'M', u's'), - (0x1D61B, 'M', u't'), - (0x1D61C, 'M', u'u'), - (0x1D61D, 'M', u'v'), - (0x1D61E, 'M', u'w'), - (0x1D61F, 'M', u'x'), - (0x1D620, 'M', u'y'), - (0x1D621, 'M', u'z'), - (0x1D622, 'M', u'a'), - (0x1D623, 'M', u'b'), - (0x1D624, 'M', u'c'), - (0x1D625, 'M', u'd'), - (0x1D626, 'M', u'e'), - (0x1D627, 'M', u'f'), - (0x1D628, 'M', u'g'), - (0x1D629, 'M', u'h'), - (0x1D62A, 'M', u'i'), - (0x1D62B, 'M', u'j'), - (0x1D62C, 'M', u'k'), - (0x1D62D, 'M', u'l'), - (0x1D62E, 'M', u'm'), - (0x1D62F, 'M', u'n'), - (0x1D630, 'M', u'o'), - (0x1D631, 'M', u'p'), - (0x1D632, 'M', u'q'), - (0x1D633, 'M', u'r'), - (0x1D634, 'M', u's'), - (0x1D635, 'M', u't'), - (0x1D636, 'M', u'u'), - (0x1D637, 'M', u'v'), - (0x1D638, 'M', u'w'), - (0x1D639, 'M', u'x'), - (0x1D63A, 'M', u'y'), - (0x1D63B, 'M', u'z'), - (0x1D63C, 'M', u'a'), - (0x1D63D, 'M', u'b'), - (0x1D63E, 'M', u'c'), - (0x1D63F, 'M', u'd'), - (0x1D640, 'M', u'e'), - (0x1D641, 'M', u'f'), - (0x1D642, 'M', u'g'), - (0x1D643, 'M', u'h'), - (0x1D644, 'M', u'i'), - (0x1D645, 'M', u'j'), - (0x1D646, 'M', u'k'), - (0x1D647, 'M', u'l'), - (0x1D648, 'M', u'm'), - (0x1D649, 'M', u'n'), - (0x1D64A, 'M', u'o'), - (0x1D64B, 'M', u'p'), - (0x1D64C, 'M', u'q'), - (0x1D64D, 'M', u'r'), - (0x1D64E, 'M', u's'), - (0x1D64F, 'M', u't'), - (0x1D650, 'M', u'u'), - (0x1D651, 'M', u'v'), - (0x1D652, 'M', u'w'), - (0x1D653, 'M', u'x'), - (0x1D654, 'M', u'y'), - (0x1D655, 'M', u'z'), - (0x1D656, 'M', u'a'), - ] - -def _seg_64(): - return [ - (0x1D657, 'M', u'b'), - (0x1D658, 'M', u'c'), - (0x1D659, 'M', u'd'), - (0x1D65A, 'M', u'e'), - (0x1D65B, 'M', u'f'), - (0x1D65C, 'M', u'g'), - (0x1D65D, 'M', u'h'), - (0x1D65E, 'M', u'i'), - (0x1D65F, 'M', u'j'), - (0x1D660, 'M', u'k'), - (0x1D661, 'M', u'l'), - (0x1D662, 'M', u'm'), - (0x1D663, 'M', u'n'), - (0x1D664, 'M', u'o'), - (0x1D665, 'M', u'p'), - (0x1D666, 'M', u'q'), - (0x1D667, 'M', u'r'), - (0x1D668, 'M', u's'), - (0x1D669, 'M', u't'), - (0x1D66A, 'M', u'u'), - (0x1D66B, 'M', u'v'), - (0x1D66C, 'M', u'w'), - (0x1D66D, 'M', u'x'), - (0x1D66E, 'M', u'y'), - (0x1D66F, 'M', u'z'), - (0x1D670, 'M', u'a'), - (0x1D671, 'M', u'b'), - (0x1D672, 'M', u'c'), - (0x1D673, 'M', u'd'), - (0x1D674, 'M', u'e'), - (0x1D675, 'M', u'f'), - (0x1D676, 'M', u'g'), - (0x1D677, 'M', u'h'), - (0x1D678, 'M', u'i'), - (0x1D679, 'M', u'j'), - (0x1D67A, 'M', u'k'), - (0x1D67B, 'M', u'l'), - (0x1D67C, 'M', u'm'), - (0x1D67D, 'M', u'n'), - (0x1D67E, 'M', u'o'), - (0x1D67F, 'M', u'p'), - (0x1D680, 'M', u'q'), - (0x1D681, 'M', u'r'), - (0x1D682, 'M', u's'), - (0x1D683, 'M', u't'), - (0x1D684, 'M', u'u'), - (0x1D685, 'M', u'v'), - (0x1D686, 'M', u'w'), - (0x1D687, 'M', u'x'), - (0x1D688, 'M', u'y'), - (0x1D689, 'M', u'z'), - (0x1D68A, 'M', u'a'), - (0x1D68B, 'M', u'b'), - (0x1D68C, 'M', u'c'), - (0x1D68D, 'M', u'd'), - (0x1D68E, 'M', u'e'), - (0x1D68F, 'M', u'f'), - (0x1D690, 'M', u'g'), - (0x1D691, 'M', u'h'), - (0x1D692, 'M', u'i'), - (0x1D693, 'M', u'j'), - (0x1D694, 'M', u'k'), - (0x1D695, 'M', u'l'), - (0x1D696, 'M', u'm'), - (0x1D697, 'M', u'n'), - (0x1D698, 'M', u'o'), - (0x1D699, 'M', u'p'), - (0x1D69A, 'M', u'q'), - (0x1D69B, 'M', u'r'), - (0x1D69C, 'M', u's'), - (0x1D69D, 'M', u't'), - (0x1D69E, 'M', u'u'), - (0x1D69F, 'M', u'v'), - (0x1D6A0, 'M', u'w'), - (0x1D6A1, 'M', u'x'), - (0x1D6A2, 'M', u'y'), - (0x1D6A3, 'M', u'z'), - (0x1D6A4, 'M', u'ı'), - (0x1D6A5, 'M', u'ȷ'), - (0x1D6A6, 'X'), - (0x1D6A8, 'M', u'α'), - (0x1D6A9, 'M', u'β'), - (0x1D6AA, 'M', u'γ'), - (0x1D6AB, 'M', u'δ'), - (0x1D6AC, 'M', u'ε'), - (0x1D6AD, 'M', u'ζ'), - (0x1D6AE, 'M', u'η'), - (0x1D6AF, 'M', u'θ'), - (0x1D6B0, 'M', u'ι'), - (0x1D6B1, 'M', u'κ'), - (0x1D6B2, 'M', u'λ'), - (0x1D6B3, 'M', u'μ'), - (0x1D6B4, 'M', u'ν'), - (0x1D6B5, 'M', u'ξ'), - (0x1D6B6, 'M', u'ο'), - (0x1D6B7, 'M', u'π'), - (0x1D6B8, 'M', u'ρ'), - (0x1D6B9, 'M', u'θ'), - (0x1D6BA, 'M', u'σ'), - (0x1D6BB, 'M', u'τ'), - ] - -def _seg_65(): - return [ - (0x1D6BC, 'M', u'υ'), - (0x1D6BD, 'M', u'φ'), - (0x1D6BE, 'M', u'χ'), - (0x1D6BF, 'M', u'ψ'), - (0x1D6C0, 'M', u'ω'), - (0x1D6C1, 'M', u'∇'), - (0x1D6C2, 'M', u'α'), - (0x1D6C3, 'M', u'β'), - (0x1D6C4, 'M', u'γ'), - (0x1D6C5, 'M', u'δ'), - (0x1D6C6, 'M', u'ε'), - (0x1D6C7, 'M', u'ζ'), - (0x1D6C8, 'M', u'η'), - (0x1D6C9, 'M', u'θ'), - (0x1D6CA, 'M', u'ι'), - (0x1D6CB, 'M', u'κ'), - (0x1D6CC, 'M', u'λ'), - (0x1D6CD, 'M', u'μ'), - (0x1D6CE, 'M', u'ν'), - (0x1D6CF, 'M', u'ξ'), - (0x1D6D0, 'M', u'ο'), - (0x1D6D1, 'M', u'π'), - (0x1D6D2, 'M', u'ρ'), - (0x1D6D3, 'M', u'σ'), - (0x1D6D5, 'M', u'τ'), - (0x1D6D6, 'M', u'υ'), - (0x1D6D7, 'M', u'φ'), - (0x1D6D8, 'M', u'χ'), - (0x1D6D9, 'M', u'ψ'), - (0x1D6DA, 'M', u'ω'), - (0x1D6DB, 'M', u'∂'), - (0x1D6DC, 'M', u'ε'), - (0x1D6DD, 'M', u'θ'), - (0x1D6DE, 'M', u'κ'), - (0x1D6DF, 'M', u'φ'), - (0x1D6E0, 'M', u'ρ'), - (0x1D6E1, 'M', u'π'), - (0x1D6E2, 'M', u'α'), - (0x1D6E3, 'M', u'β'), - (0x1D6E4, 'M', u'γ'), - (0x1D6E5, 'M', u'δ'), - (0x1D6E6, 'M', u'ε'), - (0x1D6E7, 'M', u'ζ'), - (0x1D6E8, 'M', u'η'), - (0x1D6E9, 'M', u'θ'), - (0x1D6EA, 'M', u'ι'), - (0x1D6EB, 'M', u'κ'), - (0x1D6EC, 'M', u'λ'), - (0x1D6ED, 'M', u'μ'), - (0x1D6EE, 'M', u'ν'), - (0x1D6EF, 'M', u'ξ'), - (0x1D6F0, 'M', u'ο'), - (0x1D6F1, 'M', u'π'), - (0x1D6F2, 'M', u'ρ'), - (0x1D6F3, 'M', u'θ'), - (0x1D6F4, 'M', u'σ'), - (0x1D6F5, 'M', u'τ'), - (0x1D6F6, 'M', u'υ'), - (0x1D6F7, 'M', u'φ'), - (0x1D6F8, 'M', u'χ'), - (0x1D6F9, 'M', u'ψ'), - (0x1D6FA, 'M', u'ω'), - (0x1D6FB, 'M', u'∇'), - (0x1D6FC, 'M', u'α'), - (0x1D6FD, 'M', u'β'), - (0x1D6FE, 'M', u'γ'), - (0x1D6FF, 'M', u'δ'), - (0x1D700, 'M', u'ε'), - (0x1D701, 'M', u'ζ'), - (0x1D702, 'M', u'η'), - (0x1D703, 'M', u'θ'), - (0x1D704, 'M', u'ι'), - (0x1D705, 'M', u'κ'), - (0x1D706, 'M', u'λ'), - (0x1D707, 'M', u'μ'), - (0x1D708, 'M', u'ν'), - (0x1D709, 'M', u'ξ'), - (0x1D70A, 'M', u'ο'), - (0x1D70B, 'M', u'π'), - (0x1D70C, 'M', u'ρ'), - (0x1D70D, 'M', u'σ'), - (0x1D70F, 'M', u'τ'), - (0x1D710, 'M', u'υ'), - (0x1D711, 'M', u'φ'), - (0x1D712, 'M', u'χ'), - (0x1D713, 'M', u'ψ'), - (0x1D714, 'M', u'ω'), - (0x1D715, 'M', u'∂'), - (0x1D716, 'M', u'ε'), - (0x1D717, 'M', u'θ'), - (0x1D718, 'M', u'κ'), - (0x1D719, 'M', u'φ'), - (0x1D71A, 'M', u'ρ'), - (0x1D71B, 'M', u'π'), - (0x1D71C, 'M', u'α'), - (0x1D71D, 'M', u'β'), - (0x1D71E, 'M', u'γ'), - (0x1D71F, 'M', u'δ'), - (0x1D720, 'M', u'ε'), - (0x1D721, 'M', u'ζ'), - ] - -def _seg_66(): - return [ - (0x1D722, 'M', u'η'), - (0x1D723, 'M', u'θ'), - (0x1D724, 'M', u'ι'), - (0x1D725, 'M', u'κ'), - (0x1D726, 'M', u'λ'), - (0x1D727, 'M', u'μ'), - (0x1D728, 'M', u'ν'), - (0x1D729, 'M', u'ξ'), - (0x1D72A, 'M', u'ο'), - (0x1D72B, 'M', u'π'), - (0x1D72C, 'M', u'ρ'), - (0x1D72D, 'M', u'θ'), - (0x1D72E, 'M', u'σ'), - (0x1D72F, 'M', u'τ'), - (0x1D730, 'M', u'υ'), - (0x1D731, 'M', u'φ'), - (0x1D732, 'M', u'χ'), - (0x1D733, 'M', u'ψ'), - (0x1D734, 'M', u'ω'), - (0x1D735, 'M', u'∇'), - (0x1D736, 'M', u'α'), - (0x1D737, 'M', u'β'), - (0x1D738, 'M', u'γ'), - (0x1D739, 'M', u'δ'), - (0x1D73A, 'M', u'ε'), - (0x1D73B, 'M', u'ζ'), - (0x1D73C, 'M', u'η'), - (0x1D73D, 'M', u'θ'), - (0x1D73E, 'M', u'ι'), - (0x1D73F, 'M', u'κ'), - (0x1D740, 'M', u'λ'), - (0x1D741, 'M', u'μ'), - (0x1D742, 'M', u'ν'), - (0x1D743, 'M', u'ξ'), - (0x1D744, 'M', u'ο'), - (0x1D745, 'M', u'π'), - (0x1D746, 'M', u'ρ'), - (0x1D747, 'M', u'σ'), - (0x1D749, 'M', u'τ'), - (0x1D74A, 'M', u'υ'), - (0x1D74B, 'M', u'φ'), - (0x1D74C, 'M', u'χ'), - (0x1D74D, 'M', u'ψ'), - (0x1D74E, 'M', u'ω'), - (0x1D74F, 'M', u'∂'), - (0x1D750, 'M', u'ε'), - (0x1D751, 'M', u'θ'), - (0x1D752, 'M', u'κ'), - (0x1D753, 'M', u'φ'), - (0x1D754, 'M', u'ρ'), - (0x1D755, 'M', u'π'), - (0x1D756, 'M', u'α'), - (0x1D757, 'M', u'β'), - (0x1D758, 'M', u'γ'), - (0x1D759, 'M', u'δ'), - (0x1D75A, 'M', u'ε'), - (0x1D75B, 'M', u'ζ'), - (0x1D75C, 'M', u'η'), - (0x1D75D, 'M', u'θ'), - (0x1D75E, 'M', u'ι'), - (0x1D75F, 'M', u'κ'), - (0x1D760, 'M', u'λ'), - (0x1D761, 'M', u'μ'), - (0x1D762, 'M', u'ν'), - (0x1D763, 'M', u'ξ'), - (0x1D764, 'M', u'ο'), - (0x1D765, 'M', u'π'), - (0x1D766, 'M', u'ρ'), - (0x1D767, 'M', u'θ'), - (0x1D768, 'M', u'σ'), - (0x1D769, 'M', u'τ'), - (0x1D76A, 'M', u'υ'), - (0x1D76B, 'M', u'φ'), - (0x1D76C, 'M', u'χ'), - (0x1D76D, 'M', u'ψ'), - (0x1D76E, 'M', u'ω'), - (0x1D76F, 'M', u'∇'), - (0x1D770, 'M', u'α'), - (0x1D771, 'M', u'β'), - (0x1D772, 'M', u'γ'), - (0x1D773, 'M', u'δ'), - (0x1D774, 'M', u'ε'), - (0x1D775, 'M', u'ζ'), - (0x1D776, 'M', u'η'), - (0x1D777, 'M', u'θ'), - (0x1D778, 'M', u'ι'), - (0x1D779, 'M', u'κ'), - (0x1D77A, 'M', u'λ'), - (0x1D77B, 'M', u'μ'), - (0x1D77C, 'M', u'ν'), - (0x1D77D, 'M', u'ξ'), - (0x1D77E, 'M', u'ο'), - (0x1D77F, 'M', u'π'), - (0x1D780, 'M', u'ρ'), - (0x1D781, 'M', u'σ'), - (0x1D783, 'M', u'τ'), - (0x1D784, 'M', u'υ'), - (0x1D785, 'M', u'φ'), - (0x1D786, 'M', u'χ'), - (0x1D787, 'M', u'ψ'), - ] - -def _seg_67(): - return [ - (0x1D788, 'M', u'ω'), - (0x1D789, 'M', u'∂'), - (0x1D78A, 'M', u'ε'), - (0x1D78B, 'M', u'θ'), - (0x1D78C, 'M', u'κ'), - (0x1D78D, 'M', u'φ'), - (0x1D78E, 'M', u'ρ'), - (0x1D78F, 'M', u'π'), - (0x1D790, 'M', u'α'), - (0x1D791, 'M', u'β'), - (0x1D792, 'M', u'γ'), - (0x1D793, 'M', u'δ'), - (0x1D794, 'M', u'ε'), - (0x1D795, 'M', u'ζ'), - (0x1D796, 'M', u'η'), - (0x1D797, 'M', u'θ'), - (0x1D798, 'M', u'ι'), - (0x1D799, 'M', u'κ'), - (0x1D79A, 'M', u'λ'), - (0x1D79B, 'M', u'μ'), - (0x1D79C, 'M', u'ν'), - (0x1D79D, 'M', u'ξ'), - (0x1D79E, 'M', u'ο'), - (0x1D79F, 'M', u'π'), - (0x1D7A0, 'M', u'ρ'), - (0x1D7A1, 'M', u'θ'), - (0x1D7A2, 'M', u'σ'), - (0x1D7A3, 'M', u'τ'), - (0x1D7A4, 'M', u'υ'), - (0x1D7A5, 'M', u'φ'), - (0x1D7A6, 'M', u'χ'), - (0x1D7A7, 'M', u'ψ'), - (0x1D7A8, 'M', u'ω'), - (0x1D7A9, 'M', u'∇'), - (0x1D7AA, 'M', u'α'), - (0x1D7AB, 'M', u'β'), - (0x1D7AC, 'M', u'γ'), - (0x1D7AD, 'M', u'δ'), - (0x1D7AE, 'M', u'ε'), - (0x1D7AF, 'M', u'ζ'), - (0x1D7B0, 'M', u'η'), - (0x1D7B1, 'M', u'θ'), - (0x1D7B2, 'M', u'ι'), - (0x1D7B3, 'M', u'κ'), - (0x1D7B4, 'M', u'λ'), - (0x1D7B5, 'M', u'μ'), - (0x1D7B6, 'M', u'ν'), - (0x1D7B7, 'M', u'ξ'), - (0x1D7B8, 'M', u'ο'), - (0x1D7B9, 'M', u'π'), - (0x1D7BA, 'M', u'ρ'), - (0x1D7BB, 'M', u'σ'), - (0x1D7BD, 'M', u'τ'), - (0x1D7BE, 'M', u'υ'), - (0x1D7BF, 'M', u'φ'), - (0x1D7C0, 'M', u'χ'), - (0x1D7C1, 'M', u'ψ'), - (0x1D7C2, 'M', u'ω'), - (0x1D7C3, 'M', u'∂'), - (0x1D7C4, 'M', u'ε'), - (0x1D7C5, 'M', u'θ'), - (0x1D7C6, 'M', u'κ'), - (0x1D7C7, 'M', u'φ'), - (0x1D7C8, 'M', u'ρ'), - (0x1D7C9, 'M', u'π'), - (0x1D7CA, 'M', u'ϝ'), - (0x1D7CC, 'X'), - (0x1D7CE, 'M', u'0'), - (0x1D7CF, 'M', u'1'), - (0x1D7D0, 'M', u'2'), - (0x1D7D1, 'M', u'3'), - (0x1D7D2, 'M', u'4'), - (0x1D7D3, 'M', u'5'), - (0x1D7D4, 'M', u'6'), - (0x1D7D5, 'M', u'7'), - (0x1D7D6, 'M', u'8'), - (0x1D7D7, 'M', u'9'), - (0x1D7D8, 'M', u'0'), - (0x1D7D9, 'M', u'1'), - (0x1D7DA, 'M', u'2'), - (0x1D7DB, 'M', u'3'), - (0x1D7DC, 'M', u'4'), - (0x1D7DD, 'M', u'5'), - (0x1D7DE, 'M', u'6'), - (0x1D7DF, 'M', u'7'), - (0x1D7E0, 'M', u'8'), - (0x1D7E1, 'M', u'9'), - (0x1D7E2, 'M', u'0'), - (0x1D7E3, 'M', u'1'), - (0x1D7E4, 'M', u'2'), - (0x1D7E5, 'M', u'3'), - (0x1D7E6, 'M', u'4'), - (0x1D7E7, 'M', u'5'), - (0x1D7E8, 'M', u'6'), - (0x1D7E9, 'M', u'7'), - (0x1D7EA, 'M', u'8'), - (0x1D7EB, 'M', u'9'), - (0x1D7EC, 'M', u'0'), - (0x1D7ED, 'M', u'1'), - (0x1D7EE, 'M', u'2'), - ] - -def _seg_68(): - return [ - (0x1D7EF, 'M', u'3'), - (0x1D7F0, 'M', u'4'), - (0x1D7F1, 'M', u'5'), - (0x1D7F2, 'M', u'6'), - (0x1D7F3, 'M', u'7'), - (0x1D7F4, 'M', u'8'), - (0x1D7F5, 'M', u'9'), - (0x1D7F6, 'M', u'0'), - (0x1D7F7, 'M', u'1'), - (0x1D7F8, 'M', u'2'), - (0x1D7F9, 'M', u'3'), - (0x1D7FA, 'M', u'4'), - (0x1D7FB, 'M', u'5'), - (0x1D7FC, 'M', u'6'), - (0x1D7FD, 'M', u'7'), - (0x1D7FE, 'M', u'8'), - (0x1D7FF, 'M', u'9'), - (0x1D800, 'V'), - (0x1DA8C, 'X'), - (0x1DA9B, 'V'), - (0x1DAA0, 'X'), - (0x1DAA1, 'V'), - (0x1DAB0, 'X'), - (0x1E000, 'V'), - (0x1E007, 'X'), - (0x1E008, 'V'), - (0x1E019, 'X'), - (0x1E01B, 'V'), - (0x1E022, 'X'), - (0x1E023, 'V'), - (0x1E025, 'X'), - (0x1E026, 'V'), - (0x1E02B, 'X'), - (0x1E800, 'V'), - (0x1E8C5, 'X'), - (0x1E8C7, 'V'), - (0x1E8D7, 'X'), - (0x1E900, 'M', u'𞤢'), - (0x1E901, 'M', u'𞤣'), - (0x1E902, 'M', u'𞤤'), - (0x1E903, 'M', u'𞤥'), - (0x1E904, 'M', u'𞤦'), - (0x1E905, 'M', u'𞤧'), - (0x1E906, 'M', u'𞤨'), - (0x1E907, 'M', u'𞤩'), - (0x1E908, 'M', u'𞤪'), - (0x1E909, 'M', u'𞤫'), - (0x1E90A, 'M', u'𞤬'), - (0x1E90B, 'M', u'𞤭'), - (0x1E90C, 'M', u'𞤮'), - (0x1E90D, 'M', u'𞤯'), - (0x1E90E, 'M', u'𞤰'), - (0x1E90F, 'M', u'𞤱'), - (0x1E910, 'M', u'𞤲'), - (0x1E911, 'M', u'𞤳'), - (0x1E912, 'M', u'𞤴'), - (0x1E913, 'M', u'𞤵'), - (0x1E914, 'M', u'𞤶'), - (0x1E915, 'M', u'𞤷'), - (0x1E916, 'M', u'𞤸'), - (0x1E917, 'M', u'𞤹'), - (0x1E918, 'M', u'𞤺'), - (0x1E919, 'M', u'𞤻'), - (0x1E91A, 'M', u'𞤼'), - (0x1E91B, 'M', u'𞤽'), - (0x1E91C, 'M', u'𞤾'), - (0x1E91D, 'M', u'𞤿'), - (0x1E91E, 'M', u'𞥀'), - (0x1E91F, 'M', u'𞥁'), - (0x1E920, 'M', u'𞥂'), - (0x1E921, 'M', u'𞥃'), - (0x1E922, 'V'), - (0x1E94B, 'X'), - (0x1E950, 'V'), - (0x1E95A, 'X'), - (0x1E95E, 'V'), - (0x1E960, 'X'), - (0x1EC71, 'V'), - (0x1ECB5, 'X'), - (0x1EE00, 'M', u'ا'), - (0x1EE01, 'M', u'ب'), - (0x1EE02, 'M', u'ج'), - (0x1EE03, 'M', u'د'), - (0x1EE04, 'X'), - (0x1EE05, 'M', u'و'), - (0x1EE06, 'M', u'ز'), - (0x1EE07, 'M', u'ح'), - (0x1EE08, 'M', u'ط'), - (0x1EE09, 'M', u'ي'), - (0x1EE0A, 'M', u'ك'), - (0x1EE0B, 'M', u'ل'), - (0x1EE0C, 'M', u'م'), - (0x1EE0D, 'M', u'ن'), - (0x1EE0E, 'M', u'س'), - (0x1EE0F, 'M', u'ع'), - (0x1EE10, 'M', u'ف'), - (0x1EE11, 'M', u'ص'), - (0x1EE12, 'M', u'ق'), - (0x1EE13, 'M', u'ر'), - (0x1EE14, 'M', u'ش'), - ] - -def _seg_69(): - return [ - (0x1EE15, 'M', u'ت'), - (0x1EE16, 'M', u'ث'), - (0x1EE17, 'M', u'خ'), - (0x1EE18, 'M', u'ذ'), - (0x1EE19, 'M', u'ض'), - (0x1EE1A, 'M', u'ظ'), - (0x1EE1B, 'M', u'غ'), - (0x1EE1C, 'M', u'ٮ'), - (0x1EE1D, 'M', u'ں'), - (0x1EE1E, 'M', u'ڡ'), - (0x1EE1F, 'M', u'ٯ'), - (0x1EE20, 'X'), - (0x1EE21, 'M', u'ب'), - (0x1EE22, 'M', u'ج'), - (0x1EE23, 'X'), - (0x1EE24, 'M', u'ه'), - (0x1EE25, 'X'), - (0x1EE27, 'M', u'ح'), - (0x1EE28, 'X'), - (0x1EE29, 'M', u'ي'), - (0x1EE2A, 'M', u'ك'), - (0x1EE2B, 'M', u'ل'), - (0x1EE2C, 'M', u'م'), - (0x1EE2D, 'M', u'ن'), - (0x1EE2E, 'M', u'س'), - (0x1EE2F, 'M', u'ع'), - (0x1EE30, 'M', u'ف'), - (0x1EE31, 'M', u'ص'), - (0x1EE32, 'M', u'ق'), - (0x1EE33, 'X'), - (0x1EE34, 'M', u'ش'), - (0x1EE35, 'M', u'ت'), - (0x1EE36, 'M', u'ث'), - (0x1EE37, 'M', u'خ'), - (0x1EE38, 'X'), - (0x1EE39, 'M', u'ض'), - (0x1EE3A, 'X'), - (0x1EE3B, 'M', u'غ'), - (0x1EE3C, 'X'), - (0x1EE42, 'M', u'ج'), - (0x1EE43, 'X'), - (0x1EE47, 'M', u'ح'), - (0x1EE48, 'X'), - (0x1EE49, 'M', u'ي'), - (0x1EE4A, 'X'), - (0x1EE4B, 'M', u'ل'), - (0x1EE4C, 'X'), - (0x1EE4D, 'M', u'ن'), - (0x1EE4E, 'M', u'س'), - (0x1EE4F, 'M', u'ع'), - (0x1EE50, 'X'), - (0x1EE51, 'M', u'ص'), - (0x1EE52, 'M', u'ق'), - (0x1EE53, 'X'), - (0x1EE54, 'M', u'ش'), - (0x1EE55, 'X'), - (0x1EE57, 'M', u'خ'), - (0x1EE58, 'X'), - (0x1EE59, 'M', u'ض'), - (0x1EE5A, 'X'), - (0x1EE5B, 'M', u'غ'), - (0x1EE5C, 'X'), - (0x1EE5D, 'M', u'ں'), - (0x1EE5E, 'X'), - (0x1EE5F, 'M', u'ٯ'), - (0x1EE60, 'X'), - (0x1EE61, 'M', u'ب'), - (0x1EE62, 'M', u'ج'), - (0x1EE63, 'X'), - (0x1EE64, 'M', u'ه'), - (0x1EE65, 'X'), - (0x1EE67, 'M', u'ح'), - (0x1EE68, 'M', u'ط'), - (0x1EE69, 'M', u'ي'), - (0x1EE6A, 'M', u'ك'), - (0x1EE6B, 'X'), - (0x1EE6C, 'M', u'م'), - (0x1EE6D, 'M', u'ن'), - (0x1EE6E, 'M', u'س'), - (0x1EE6F, 'M', u'ع'), - (0x1EE70, 'M', u'ف'), - (0x1EE71, 'M', u'ص'), - (0x1EE72, 'M', u'ق'), - (0x1EE73, 'X'), - (0x1EE74, 'M', u'ش'), - (0x1EE75, 'M', u'ت'), - (0x1EE76, 'M', u'ث'), - (0x1EE77, 'M', u'خ'), - (0x1EE78, 'X'), - (0x1EE79, 'M', u'ض'), - (0x1EE7A, 'M', u'ظ'), - (0x1EE7B, 'M', u'غ'), - (0x1EE7C, 'M', u'ٮ'), - (0x1EE7D, 'X'), - (0x1EE7E, 'M', u'ڡ'), - (0x1EE7F, 'X'), - (0x1EE80, 'M', u'ا'), - (0x1EE81, 'M', u'ب'), - (0x1EE82, 'M', u'ج'), - (0x1EE83, 'M', u'د'), - ] - -def _seg_70(): - return [ - (0x1EE84, 'M', u'ه'), - (0x1EE85, 'M', u'و'), - (0x1EE86, 'M', u'ز'), - (0x1EE87, 'M', u'ح'), - (0x1EE88, 'M', u'ط'), - (0x1EE89, 'M', u'ي'), - (0x1EE8A, 'X'), - (0x1EE8B, 'M', u'ل'), - (0x1EE8C, 'M', u'م'), - (0x1EE8D, 'M', u'ن'), - (0x1EE8E, 'M', u'س'), - (0x1EE8F, 'M', u'ع'), - (0x1EE90, 'M', u'ف'), - (0x1EE91, 'M', u'ص'), - (0x1EE92, 'M', u'ق'), - (0x1EE93, 'M', u'ر'), - (0x1EE94, 'M', u'ش'), - (0x1EE95, 'M', u'ت'), - (0x1EE96, 'M', u'ث'), - (0x1EE97, 'M', u'خ'), - (0x1EE98, 'M', u'ذ'), - (0x1EE99, 'M', u'ض'), - (0x1EE9A, 'M', u'ظ'), - (0x1EE9B, 'M', u'غ'), - (0x1EE9C, 'X'), - (0x1EEA1, 'M', u'ب'), - (0x1EEA2, 'M', u'ج'), - (0x1EEA3, 'M', u'د'), - (0x1EEA4, 'X'), - (0x1EEA5, 'M', u'و'), - (0x1EEA6, 'M', u'ز'), - (0x1EEA7, 'M', u'ح'), - (0x1EEA8, 'M', u'ط'), - (0x1EEA9, 'M', u'ي'), - (0x1EEAA, 'X'), - (0x1EEAB, 'M', u'ل'), - (0x1EEAC, 'M', u'م'), - (0x1EEAD, 'M', u'ن'), - (0x1EEAE, 'M', u'س'), - (0x1EEAF, 'M', u'ع'), - (0x1EEB0, 'M', u'ف'), - (0x1EEB1, 'M', u'ص'), - (0x1EEB2, 'M', u'ق'), - (0x1EEB3, 'M', u'ر'), - (0x1EEB4, 'M', u'ش'), - (0x1EEB5, 'M', u'ت'), - (0x1EEB6, 'M', u'ث'), - (0x1EEB7, 'M', u'خ'), - (0x1EEB8, 'M', u'ذ'), - (0x1EEB9, 'M', u'ض'), - (0x1EEBA, 'M', u'ظ'), - (0x1EEBB, 'M', u'غ'), - (0x1EEBC, 'X'), - (0x1EEF0, 'V'), - (0x1EEF2, 'X'), - (0x1F000, 'V'), - (0x1F02C, 'X'), - (0x1F030, 'V'), - (0x1F094, 'X'), - (0x1F0A0, 'V'), - (0x1F0AF, 'X'), - (0x1F0B1, 'V'), - (0x1F0C0, 'X'), - (0x1F0C1, 'V'), - (0x1F0D0, 'X'), - (0x1F0D1, 'V'), - (0x1F0F6, 'X'), - (0x1F101, '3', u'0,'), - (0x1F102, '3', u'1,'), - (0x1F103, '3', u'2,'), - (0x1F104, '3', u'3,'), - (0x1F105, '3', u'4,'), - (0x1F106, '3', u'5,'), - (0x1F107, '3', u'6,'), - (0x1F108, '3', u'7,'), - (0x1F109, '3', u'8,'), - (0x1F10A, '3', u'9,'), - (0x1F10B, 'V'), - (0x1F10D, 'X'), - (0x1F110, '3', u'(a)'), - (0x1F111, '3', u'(b)'), - (0x1F112, '3', u'(c)'), - (0x1F113, '3', u'(d)'), - (0x1F114, '3', u'(e)'), - (0x1F115, '3', u'(f)'), - (0x1F116, '3', u'(g)'), - (0x1F117, '3', u'(h)'), - (0x1F118, '3', u'(i)'), - (0x1F119, '3', u'(j)'), - (0x1F11A, '3', u'(k)'), - (0x1F11B, '3', u'(l)'), - (0x1F11C, '3', u'(m)'), - (0x1F11D, '3', u'(n)'), - (0x1F11E, '3', u'(o)'), - (0x1F11F, '3', u'(p)'), - (0x1F120, '3', u'(q)'), - (0x1F121, '3', u'(r)'), - (0x1F122, '3', u'(s)'), - (0x1F123, '3', u'(t)'), - (0x1F124, '3', u'(u)'), - ] - -def _seg_71(): - return [ - (0x1F125, '3', u'(v)'), - (0x1F126, '3', u'(w)'), - (0x1F127, '3', u'(x)'), - (0x1F128, '3', u'(y)'), - (0x1F129, '3', u'(z)'), - (0x1F12A, 'M', u'〔s〕'), - (0x1F12B, 'M', u'c'), - (0x1F12C, 'M', u'r'), - (0x1F12D, 'M', u'cd'), - (0x1F12E, 'M', u'wz'), - (0x1F12F, 'V'), - (0x1F130, 'M', u'a'), - (0x1F131, 'M', u'b'), - (0x1F132, 'M', u'c'), - (0x1F133, 'M', u'd'), - (0x1F134, 'M', u'e'), - (0x1F135, 'M', u'f'), - (0x1F136, 'M', u'g'), - (0x1F137, 'M', u'h'), - (0x1F138, 'M', u'i'), - (0x1F139, 'M', u'j'), - (0x1F13A, 'M', u'k'), - (0x1F13B, 'M', u'l'), - (0x1F13C, 'M', u'm'), - (0x1F13D, 'M', u'n'), - (0x1F13E, 'M', u'o'), - (0x1F13F, 'M', u'p'), - (0x1F140, 'M', u'q'), - (0x1F141, 'M', u'r'), - (0x1F142, 'M', u's'), - (0x1F143, 'M', u't'), - (0x1F144, 'M', u'u'), - (0x1F145, 'M', u'v'), - (0x1F146, 'M', u'w'), - (0x1F147, 'M', u'x'), - (0x1F148, 'M', u'y'), - (0x1F149, 'M', u'z'), - (0x1F14A, 'M', u'hv'), - (0x1F14B, 'M', u'mv'), - (0x1F14C, 'M', u'sd'), - (0x1F14D, 'M', u'ss'), - (0x1F14E, 'M', u'ppv'), - (0x1F14F, 'M', u'wc'), - (0x1F150, 'V'), - (0x1F16A, 'M', u'mc'), - (0x1F16B, 'M', u'md'), - (0x1F16C, 'X'), - (0x1F170, 'V'), - (0x1F190, 'M', u'dj'), - (0x1F191, 'V'), - (0x1F1AD, 'X'), - (0x1F1E6, 'V'), - (0x1F200, 'M', u'ほか'), - (0x1F201, 'M', u'ココ'), - (0x1F202, 'M', u'サ'), - (0x1F203, 'X'), - (0x1F210, 'M', u'手'), - (0x1F211, 'M', u'字'), - (0x1F212, 'M', u'双'), - (0x1F213, 'M', u'デ'), - (0x1F214, 'M', u'二'), - (0x1F215, 'M', u'多'), - (0x1F216, 'M', u'解'), - (0x1F217, 'M', u'天'), - (0x1F218, 'M', u'交'), - (0x1F219, 'M', u'映'), - (0x1F21A, 'M', u'無'), - (0x1F21B, 'M', u'料'), - (0x1F21C, 'M', u'前'), - (0x1F21D, 'M', u'後'), - (0x1F21E, 'M', u'再'), - (0x1F21F, 'M', u'新'), - (0x1F220, 'M', u'初'), - (0x1F221, 'M', u'終'), - (0x1F222, 'M', u'生'), - (0x1F223, 'M', u'販'), - (0x1F224, 'M', u'声'), - (0x1F225, 'M', u'吹'), - (0x1F226, 'M', u'演'), - (0x1F227, 'M', u'投'), - (0x1F228, 'M', u'捕'), - (0x1F229, 'M', u'一'), - (0x1F22A, 'M', u'三'), - (0x1F22B, 'M', u'遊'), - (0x1F22C, 'M', u'左'), - (0x1F22D, 'M', u'中'), - (0x1F22E, 'M', u'右'), - (0x1F22F, 'M', u'指'), - (0x1F230, 'M', u'走'), - (0x1F231, 'M', u'打'), - (0x1F232, 'M', u'禁'), - (0x1F233, 'M', u'空'), - (0x1F234, 'M', u'合'), - (0x1F235, 'M', u'満'), - (0x1F236, 'M', u'有'), - (0x1F237, 'M', u'月'), - (0x1F238, 'M', u'申'), - (0x1F239, 'M', u'割'), - (0x1F23A, 'M', u'営'), - (0x1F23B, 'M', u'配'), - ] - -def _seg_72(): - return [ - (0x1F23C, 'X'), - (0x1F240, 'M', u'〔本〕'), - (0x1F241, 'M', u'〔三〕'), - (0x1F242, 'M', u'〔二〕'), - (0x1F243, 'M', u'〔安〕'), - (0x1F244, 'M', u'〔点〕'), - (0x1F245, 'M', u'〔打〕'), - (0x1F246, 'M', u'〔盗〕'), - (0x1F247, 'M', u'〔勝〕'), - (0x1F248, 'M', u'〔敗〕'), - (0x1F249, 'X'), - (0x1F250, 'M', u'得'), - (0x1F251, 'M', u'可'), - (0x1F252, 'X'), - (0x1F260, 'V'), - (0x1F266, 'X'), - (0x1F300, 'V'), - (0x1F6D5, 'X'), - (0x1F6E0, 'V'), - (0x1F6ED, 'X'), - (0x1F6F0, 'V'), - (0x1F6FA, 'X'), - (0x1F700, 'V'), - (0x1F774, 'X'), - (0x1F780, 'V'), - (0x1F7D9, 'X'), - (0x1F800, 'V'), - (0x1F80C, 'X'), - (0x1F810, 'V'), - (0x1F848, 'X'), - (0x1F850, 'V'), - (0x1F85A, 'X'), - (0x1F860, 'V'), - (0x1F888, 'X'), - (0x1F890, 'V'), - (0x1F8AE, 'X'), - (0x1F900, 'V'), - (0x1F90C, 'X'), - (0x1F910, 'V'), - (0x1F93F, 'X'), - (0x1F940, 'V'), - (0x1F971, 'X'), - (0x1F973, 'V'), - (0x1F977, 'X'), - (0x1F97A, 'V'), - (0x1F97B, 'X'), - (0x1F97C, 'V'), - (0x1F9A3, 'X'), - (0x1F9B0, 'V'), - (0x1F9BA, 'X'), - (0x1F9C0, 'V'), - (0x1F9C3, 'X'), - (0x1F9D0, 'V'), - (0x1FA00, 'X'), - (0x1FA60, 'V'), - (0x1FA6E, 'X'), - (0x20000, 'V'), - (0x2A6D7, 'X'), - (0x2A700, 'V'), - (0x2B735, 'X'), - (0x2B740, 'V'), - (0x2B81E, 'X'), - (0x2B820, 'V'), - (0x2CEA2, 'X'), - (0x2CEB0, 'V'), - (0x2EBE1, 'X'), - (0x2F800, 'M', u'丽'), - (0x2F801, 'M', u'丸'), - (0x2F802, 'M', u'乁'), - (0x2F803, 'M', u'𠄢'), - (0x2F804, 'M', u'你'), - (0x2F805, 'M', u'侮'), - (0x2F806, 'M', u'侻'), - (0x2F807, 'M', u'倂'), - (0x2F808, 'M', u'偺'), - (0x2F809, 'M', u'備'), - (0x2F80A, 'M', u'僧'), - (0x2F80B, 'M', u'像'), - (0x2F80C, 'M', u'㒞'), - (0x2F80D, 'M', u'𠘺'), - (0x2F80E, 'M', u'免'), - (0x2F80F, 'M', u'兔'), - (0x2F810, 'M', u'兤'), - (0x2F811, 'M', u'具'), - (0x2F812, 'M', u'𠔜'), - (0x2F813, 'M', u'㒹'), - (0x2F814, 'M', u'內'), - (0x2F815, 'M', u'再'), - (0x2F816, 'M', u'𠕋'), - (0x2F817, 'M', u'冗'), - (0x2F818, 'M', u'冤'), - (0x2F819, 'M', u'仌'), - (0x2F81A, 'M', u'冬'), - (0x2F81B, 'M', u'况'), - (0x2F81C, 'M', u'𩇟'), - (0x2F81D, 'M', u'凵'), - (0x2F81E, 'M', u'刃'), - (0x2F81F, 'M', u'㓟'), - (0x2F820, 'M', u'刻'), - (0x2F821, 'M', u'剆'), - ] - -def _seg_73(): - return [ - (0x2F822, 'M', u'割'), - (0x2F823, 'M', u'剷'), - (0x2F824, 'M', u'㔕'), - (0x2F825, 'M', u'勇'), - (0x2F826, 'M', u'勉'), - (0x2F827, 'M', u'勤'), - (0x2F828, 'M', u'勺'), - (0x2F829, 'M', u'包'), - (0x2F82A, 'M', u'匆'), - (0x2F82B, 'M', u'北'), - (0x2F82C, 'M', u'卉'), - (0x2F82D, 'M', u'卑'), - (0x2F82E, 'M', u'博'), - (0x2F82F, 'M', u'即'), - (0x2F830, 'M', u'卽'), - (0x2F831, 'M', u'卿'), - (0x2F834, 'M', u'𠨬'), - (0x2F835, 'M', u'灰'), - (0x2F836, 'M', u'及'), - (0x2F837, 'M', u'叟'), - (0x2F838, 'M', u'𠭣'), - (0x2F839, 'M', u'叫'), - (0x2F83A, 'M', u'叱'), - (0x2F83B, 'M', u'吆'), - (0x2F83C, 'M', u'咞'), - (0x2F83D, 'M', u'吸'), - (0x2F83E, 'M', u'呈'), - (0x2F83F, 'M', u'周'), - (0x2F840, 'M', u'咢'), - (0x2F841, 'M', u'哶'), - (0x2F842, 'M', u'唐'), - (0x2F843, 'M', u'啓'), - (0x2F844, 'M', u'啣'), - (0x2F845, 'M', u'善'), - (0x2F847, 'M', u'喙'), - (0x2F848, 'M', u'喫'), - (0x2F849, 'M', u'喳'), - (0x2F84A, 'M', u'嗂'), - (0x2F84B, 'M', u'圖'), - (0x2F84C, 'M', u'嘆'), - (0x2F84D, 'M', u'圗'), - (0x2F84E, 'M', u'噑'), - (0x2F84F, 'M', u'噴'), - (0x2F850, 'M', u'切'), - (0x2F851, 'M', u'壮'), - (0x2F852, 'M', u'城'), - (0x2F853, 'M', u'埴'), - (0x2F854, 'M', u'堍'), - (0x2F855, 'M', u'型'), - (0x2F856, 'M', u'堲'), - (0x2F857, 'M', u'報'), - (0x2F858, 'M', u'墬'), - (0x2F859, 'M', u'𡓤'), - (0x2F85A, 'M', u'売'), - (0x2F85B, 'M', u'壷'), - (0x2F85C, 'M', u'夆'), - (0x2F85D, 'M', u'多'), - (0x2F85E, 'M', u'夢'), - (0x2F85F, 'M', u'奢'), - (0x2F860, 'M', u'𡚨'), - (0x2F861, 'M', u'𡛪'), - (0x2F862, 'M', u'姬'), - (0x2F863, 'M', u'娛'), - (0x2F864, 'M', u'娧'), - (0x2F865, 'M', u'姘'), - (0x2F866, 'M', u'婦'), - (0x2F867, 'M', u'㛮'), - (0x2F868, 'X'), - (0x2F869, 'M', u'嬈'), - (0x2F86A, 'M', u'嬾'), - (0x2F86C, 'M', u'𡧈'), - (0x2F86D, 'M', u'寃'), - (0x2F86E, 'M', u'寘'), - (0x2F86F, 'M', u'寧'), - (0x2F870, 'M', u'寳'), - (0x2F871, 'M', u'𡬘'), - (0x2F872, 'M', u'寿'), - (0x2F873, 'M', u'将'), - (0x2F874, 'X'), - (0x2F875, 'M', u'尢'), - (0x2F876, 'M', u'㞁'), - (0x2F877, 'M', u'屠'), - (0x2F878, 'M', u'屮'), - (0x2F879, 'M', u'峀'), - (0x2F87A, 'M', u'岍'), - (0x2F87B, 'M', u'𡷤'), - (0x2F87C, 'M', u'嵃'), - (0x2F87D, 'M', u'𡷦'), - (0x2F87E, 'M', u'嵮'), - (0x2F87F, 'M', u'嵫'), - (0x2F880, 'M', u'嵼'), - (0x2F881, 'M', u'巡'), - (0x2F882, 'M', u'巢'), - (0x2F883, 'M', u'㠯'), - (0x2F884, 'M', u'巽'), - (0x2F885, 'M', u'帨'), - (0x2F886, 'M', u'帽'), - (0x2F887, 'M', u'幩'), - (0x2F888, 'M', u'㡢'), - (0x2F889, 'M', u'𢆃'), - ] - -def _seg_74(): - return [ - (0x2F88A, 'M', u'㡼'), - (0x2F88B, 'M', u'庰'), - (0x2F88C, 'M', u'庳'), - (0x2F88D, 'M', u'庶'), - (0x2F88E, 'M', u'廊'), - (0x2F88F, 'M', u'𪎒'), - (0x2F890, 'M', u'廾'), - (0x2F891, 'M', u'𢌱'), - (0x2F893, 'M', u'舁'), - (0x2F894, 'M', u'弢'), - (0x2F896, 'M', u'㣇'), - (0x2F897, 'M', u'𣊸'), - (0x2F898, 'M', u'𦇚'), - (0x2F899, 'M', u'形'), - (0x2F89A, 'M', u'彫'), - (0x2F89B, 'M', u'㣣'), - (0x2F89C, 'M', u'徚'), - (0x2F89D, 'M', u'忍'), - (0x2F89E, 'M', u'志'), - (0x2F89F, 'M', u'忹'), - (0x2F8A0, 'M', u'悁'), - (0x2F8A1, 'M', u'㤺'), - (0x2F8A2, 'M', u'㤜'), - (0x2F8A3, 'M', u'悔'), - (0x2F8A4, 'M', u'𢛔'), - (0x2F8A5, 'M', u'惇'), - (0x2F8A6, 'M', u'慈'), - (0x2F8A7, 'M', u'慌'), - (0x2F8A8, 'M', u'慎'), - (0x2F8A9, 'M', u'慌'), - (0x2F8AA, 'M', u'慺'), - (0x2F8AB, 'M', u'憎'), - (0x2F8AC, 'M', u'憲'), - (0x2F8AD, 'M', u'憤'), - (0x2F8AE, 'M', u'憯'), - (0x2F8AF, 'M', u'懞'), - (0x2F8B0, 'M', u'懲'), - (0x2F8B1, 'M', u'懶'), - (0x2F8B2, 'M', u'成'), - (0x2F8B3, 'M', u'戛'), - (0x2F8B4, 'M', u'扝'), - (0x2F8B5, 'M', u'抱'), - (0x2F8B6, 'M', u'拔'), - (0x2F8B7, 'M', u'捐'), - (0x2F8B8, 'M', u'𢬌'), - (0x2F8B9, 'M', u'挽'), - (0x2F8BA, 'M', u'拼'), - (0x2F8BB, 'M', u'捨'), - (0x2F8BC, 'M', u'掃'), - (0x2F8BD, 'M', u'揤'), - (0x2F8BE, 'M', u'𢯱'), - (0x2F8BF, 'M', u'搢'), - (0x2F8C0, 'M', u'揅'), - (0x2F8C1, 'M', u'掩'), - (0x2F8C2, 'M', u'㨮'), - (0x2F8C3, 'M', u'摩'), - (0x2F8C4, 'M', u'摾'), - (0x2F8C5, 'M', u'撝'), - (0x2F8C6, 'M', u'摷'), - (0x2F8C7, 'M', u'㩬'), - (0x2F8C8, 'M', u'敏'), - (0x2F8C9, 'M', u'敬'), - (0x2F8CA, 'M', u'𣀊'), - (0x2F8CB, 'M', u'旣'), - (0x2F8CC, 'M', u'書'), - (0x2F8CD, 'M', u'晉'), - (0x2F8CE, 'M', u'㬙'), - (0x2F8CF, 'M', u'暑'), - (0x2F8D0, 'M', u'㬈'), - (0x2F8D1, 'M', u'㫤'), - (0x2F8D2, 'M', u'冒'), - (0x2F8D3, 'M', u'冕'), - (0x2F8D4, 'M', u'最'), - (0x2F8D5, 'M', u'暜'), - (0x2F8D6, 'M', u'肭'), - (0x2F8D7, 'M', u'䏙'), - (0x2F8D8, 'M', u'朗'), - (0x2F8D9, 'M', u'望'), - (0x2F8DA, 'M', u'朡'), - (0x2F8DB, 'M', u'杞'), - (0x2F8DC, 'M', u'杓'), - (0x2F8DD, 'M', u'𣏃'), - (0x2F8DE, 'M', u'㭉'), - (0x2F8DF, 'M', u'柺'), - (0x2F8E0, 'M', u'枅'), - (0x2F8E1, 'M', u'桒'), - (0x2F8E2, 'M', u'梅'), - (0x2F8E3, 'M', u'𣑭'), - (0x2F8E4, 'M', u'梎'), - (0x2F8E5, 'M', u'栟'), - (0x2F8E6, 'M', u'椔'), - (0x2F8E7, 'M', u'㮝'), - (0x2F8E8, 'M', u'楂'), - (0x2F8E9, 'M', u'榣'), - (0x2F8EA, 'M', u'槪'), - (0x2F8EB, 'M', u'檨'), - (0x2F8EC, 'M', u'𣚣'), - (0x2F8ED, 'M', u'櫛'), - (0x2F8EE, 'M', u'㰘'), - (0x2F8EF, 'M', u'次'), - ] - -def _seg_75(): - return [ - (0x2F8F0, 'M', u'𣢧'), - (0x2F8F1, 'M', u'歔'), - (0x2F8F2, 'M', u'㱎'), - (0x2F8F3, 'M', u'歲'), - (0x2F8F4, 'M', u'殟'), - (0x2F8F5, 'M', u'殺'), - (0x2F8F6, 'M', u'殻'), - (0x2F8F7, 'M', u'𣪍'), - (0x2F8F8, 'M', u'𡴋'), - (0x2F8F9, 'M', u'𣫺'), - (0x2F8FA, 'M', u'汎'), - (0x2F8FB, 'M', u'𣲼'), - (0x2F8FC, 'M', u'沿'), - (0x2F8FD, 'M', u'泍'), - (0x2F8FE, 'M', u'汧'), - (0x2F8FF, 'M', u'洖'), - (0x2F900, 'M', u'派'), - (0x2F901, 'M', u'海'), - (0x2F902, 'M', u'流'), - (0x2F903, 'M', u'浩'), - (0x2F904, 'M', u'浸'), - (0x2F905, 'M', u'涅'), - (0x2F906, 'M', u'𣴞'), - (0x2F907, 'M', u'洴'), - (0x2F908, 'M', u'港'), - (0x2F909, 'M', u'湮'), - (0x2F90A, 'M', u'㴳'), - (0x2F90B, 'M', u'滋'), - (0x2F90C, 'M', u'滇'), - (0x2F90D, 'M', u'𣻑'), - (0x2F90E, 'M', u'淹'), - (0x2F90F, 'M', u'潮'), - (0x2F910, 'M', u'𣽞'), - (0x2F911, 'M', u'𣾎'), - (0x2F912, 'M', u'濆'), - (0x2F913, 'M', u'瀹'), - (0x2F914, 'M', u'瀞'), - (0x2F915, 'M', u'瀛'), - (0x2F916, 'M', u'㶖'), - (0x2F917, 'M', u'灊'), - (0x2F918, 'M', u'災'), - (0x2F919, 'M', u'灷'), - (0x2F91A, 'M', u'炭'), - (0x2F91B, 'M', u'𠔥'), - (0x2F91C, 'M', u'煅'), - (0x2F91D, 'M', u'𤉣'), - (0x2F91E, 'M', u'熜'), - (0x2F91F, 'X'), - (0x2F920, 'M', u'爨'), - (0x2F921, 'M', u'爵'), - (0x2F922, 'M', u'牐'), - (0x2F923, 'M', u'𤘈'), - (0x2F924, 'M', u'犀'), - (0x2F925, 'M', u'犕'), - (0x2F926, 'M', u'𤜵'), - (0x2F927, 'M', u'𤠔'), - (0x2F928, 'M', u'獺'), - (0x2F929, 'M', u'王'), - (0x2F92A, 'M', u'㺬'), - (0x2F92B, 'M', u'玥'), - (0x2F92C, 'M', u'㺸'), - (0x2F92E, 'M', u'瑇'), - (0x2F92F, 'M', u'瑜'), - (0x2F930, 'M', u'瑱'), - (0x2F931, 'M', u'璅'), - (0x2F932, 'M', u'瓊'), - (0x2F933, 'M', u'㼛'), - (0x2F934, 'M', u'甤'), - (0x2F935, 'M', u'𤰶'), - (0x2F936, 'M', u'甾'), - (0x2F937, 'M', u'𤲒'), - (0x2F938, 'M', u'異'), - (0x2F939, 'M', u'𢆟'), - (0x2F93A, 'M', u'瘐'), - (0x2F93B, 'M', u'𤾡'), - (0x2F93C, 'M', u'𤾸'), - (0x2F93D, 'M', u'𥁄'), - (0x2F93E, 'M', u'㿼'), - (0x2F93F, 'M', u'䀈'), - (0x2F940, 'M', u'直'), - (0x2F941, 'M', u'𥃳'), - (0x2F942, 'M', u'𥃲'), - (0x2F943, 'M', u'𥄙'), - (0x2F944, 'M', u'𥄳'), - (0x2F945, 'M', u'眞'), - (0x2F946, 'M', u'真'), - (0x2F948, 'M', u'睊'), - (0x2F949, 'M', u'䀹'), - (0x2F94A, 'M', u'瞋'), - (0x2F94B, 'M', u'䁆'), - (0x2F94C, 'M', u'䂖'), - (0x2F94D, 'M', u'𥐝'), - (0x2F94E, 'M', u'硎'), - (0x2F94F, 'M', u'碌'), - (0x2F950, 'M', u'磌'), - (0x2F951, 'M', u'䃣'), - (0x2F952, 'M', u'𥘦'), - (0x2F953, 'M', u'祖'), - (0x2F954, 'M', u'𥚚'), - (0x2F955, 'M', u'𥛅'), - ] - -def _seg_76(): - return [ - (0x2F956, 'M', u'福'), - (0x2F957, 'M', u'秫'), - (0x2F958, 'M', u'䄯'), - (0x2F959, 'M', u'穀'), - (0x2F95A, 'M', u'穊'), - (0x2F95B, 'M', u'穏'), - (0x2F95C, 'M', u'𥥼'), - (0x2F95D, 'M', u'𥪧'), - (0x2F95F, 'X'), - (0x2F960, 'M', u'䈂'), - (0x2F961, 'M', u'𥮫'), - (0x2F962, 'M', u'篆'), - (0x2F963, 'M', u'築'), - (0x2F964, 'M', u'䈧'), - (0x2F965, 'M', u'𥲀'), - (0x2F966, 'M', u'糒'), - (0x2F967, 'M', u'䊠'), - (0x2F968, 'M', u'糨'), - (0x2F969, 'M', u'糣'), - (0x2F96A, 'M', u'紀'), - (0x2F96B, 'M', u'𥾆'), - (0x2F96C, 'M', u'絣'), - (0x2F96D, 'M', u'䌁'), - (0x2F96E, 'M', u'緇'), - (0x2F96F, 'M', u'縂'), - (0x2F970, 'M', u'繅'), - (0x2F971, 'M', u'䌴'), - (0x2F972, 'M', u'𦈨'), - (0x2F973, 'M', u'𦉇'), - (0x2F974, 'M', u'䍙'), - (0x2F975, 'M', u'𦋙'), - (0x2F976, 'M', u'罺'), - (0x2F977, 'M', u'𦌾'), - (0x2F978, 'M', u'羕'), - (0x2F979, 'M', u'翺'), - (0x2F97A, 'M', u'者'), - (0x2F97B, 'M', u'𦓚'), - (0x2F97C, 'M', u'𦔣'), - (0x2F97D, 'M', u'聠'), - (0x2F97E, 'M', u'𦖨'), - (0x2F97F, 'M', u'聰'), - (0x2F980, 'M', u'𣍟'), - (0x2F981, 'M', u'䏕'), - (0x2F982, 'M', u'育'), - (0x2F983, 'M', u'脃'), - (0x2F984, 'M', u'䐋'), - (0x2F985, 'M', u'脾'), - (0x2F986, 'M', u'媵'), - (0x2F987, 'M', u'𦞧'), - (0x2F988, 'M', u'𦞵'), - (0x2F989, 'M', u'𣎓'), - (0x2F98A, 'M', u'𣎜'), - (0x2F98B, 'M', u'舁'), - (0x2F98C, 'M', u'舄'), - (0x2F98D, 'M', u'辞'), - (0x2F98E, 'M', u'䑫'), - (0x2F98F, 'M', u'芑'), - (0x2F990, 'M', u'芋'), - (0x2F991, 'M', u'芝'), - (0x2F992, 'M', u'劳'), - (0x2F993, 'M', u'花'), - (0x2F994, 'M', u'芳'), - (0x2F995, 'M', u'芽'), - (0x2F996, 'M', u'苦'), - (0x2F997, 'M', u'𦬼'), - (0x2F998, 'M', u'若'), - (0x2F999, 'M', u'茝'), - (0x2F99A, 'M', u'荣'), - (0x2F99B, 'M', u'莭'), - (0x2F99C, 'M', u'茣'), - (0x2F99D, 'M', u'莽'), - (0x2F99E, 'M', u'菧'), - (0x2F99F, 'M', u'著'), - (0x2F9A0, 'M', u'荓'), - (0x2F9A1, 'M', u'菊'), - (0x2F9A2, 'M', u'菌'), - (0x2F9A3, 'M', u'菜'), - (0x2F9A4, 'M', u'𦰶'), - (0x2F9A5, 'M', u'𦵫'), - (0x2F9A6, 'M', u'𦳕'), - (0x2F9A7, 'M', u'䔫'), - (0x2F9A8, 'M', u'蓱'), - (0x2F9A9, 'M', u'蓳'), - (0x2F9AA, 'M', u'蔖'), - (0x2F9AB, 'M', u'𧏊'), - (0x2F9AC, 'M', u'蕤'), - (0x2F9AD, 'M', u'𦼬'), - (0x2F9AE, 'M', u'䕝'), - (0x2F9AF, 'M', u'䕡'), - (0x2F9B0, 'M', u'𦾱'), - (0x2F9B1, 'M', u'𧃒'), - (0x2F9B2, 'M', u'䕫'), - (0x2F9B3, 'M', u'虐'), - (0x2F9B4, 'M', u'虜'), - (0x2F9B5, 'M', u'虧'), - (0x2F9B6, 'M', u'虩'), - (0x2F9B7, 'M', u'蚩'), - (0x2F9B8, 'M', u'蚈'), - (0x2F9B9, 'M', u'蜎'), - (0x2F9BA, 'M', u'蛢'), - ] - -def _seg_77(): - return [ - (0x2F9BB, 'M', u'蝹'), - (0x2F9BC, 'M', u'蜨'), - (0x2F9BD, 'M', u'蝫'), - (0x2F9BE, 'M', u'螆'), - (0x2F9BF, 'X'), - (0x2F9C0, 'M', u'蟡'), - (0x2F9C1, 'M', u'蠁'), - (0x2F9C2, 'M', u'䗹'), - (0x2F9C3, 'M', u'衠'), - (0x2F9C4, 'M', u'衣'), - (0x2F9C5, 'M', u'𧙧'), - (0x2F9C6, 'M', u'裗'), - (0x2F9C7, 'M', u'裞'), - (0x2F9C8, 'M', u'䘵'), - (0x2F9C9, 'M', u'裺'), - (0x2F9CA, 'M', u'㒻'), - (0x2F9CB, 'M', u'𧢮'), - (0x2F9CC, 'M', u'𧥦'), - (0x2F9CD, 'M', u'䚾'), - (0x2F9CE, 'M', u'䛇'), - (0x2F9CF, 'M', u'誠'), - (0x2F9D0, 'M', u'諭'), - (0x2F9D1, 'M', u'變'), - (0x2F9D2, 'M', u'豕'), - (0x2F9D3, 'M', u'𧲨'), - (0x2F9D4, 'M', u'貫'), - (0x2F9D5, 'M', u'賁'), - (0x2F9D6, 'M', u'贛'), - (0x2F9D7, 'M', u'起'), - (0x2F9D8, 'M', u'𧼯'), - (0x2F9D9, 'M', u'𠠄'), - (0x2F9DA, 'M', u'跋'), - (0x2F9DB, 'M', u'趼'), - (0x2F9DC, 'M', u'跰'), - (0x2F9DD, 'M', u'𠣞'), - (0x2F9DE, 'M', u'軔'), - (0x2F9DF, 'M', u'輸'), - (0x2F9E0, 'M', u'𨗒'), - (0x2F9E1, 'M', u'𨗭'), - (0x2F9E2, 'M', u'邔'), - (0x2F9E3, 'M', u'郱'), - (0x2F9E4, 'M', u'鄑'), - (0x2F9E5, 'M', u'𨜮'), - (0x2F9E6, 'M', u'鄛'), - (0x2F9E7, 'M', u'鈸'), - (0x2F9E8, 'M', u'鋗'), - (0x2F9E9, 'M', u'鋘'), - (0x2F9EA, 'M', u'鉼'), - (0x2F9EB, 'M', u'鏹'), - (0x2F9EC, 'M', u'鐕'), - (0x2F9ED, 'M', u'𨯺'), - (0x2F9EE, 'M', u'開'), - (0x2F9EF, 'M', u'䦕'), - (0x2F9F0, 'M', u'閷'), - (0x2F9F1, 'M', u'𨵷'), - (0x2F9F2, 'M', u'䧦'), - (0x2F9F3, 'M', u'雃'), - (0x2F9F4, 'M', u'嶲'), - (0x2F9F5, 'M', u'霣'), - (0x2F9F6, 'M', u'𩅅'), - (0x2F9F7, 'M', u'𩈚'), - (0x2F9F8, 'M', u'䩮'), - (0x2F9F9, 'M', u'䩶'), - (0x2F9FA, 'M', u'韠'), - (0x2F9FB, 'M', u'𩐊'), - (0x2F9FC, 'M', u'䪲'), - (0x2F9FD, 'M', u'𩒖'), - (0x2F9FE, 'M', u'頋'), - (0x2FA00, 'M', u'頩'), - (0x2FA01, 'M', u'𩖶'), - (0x2FA02, 'M', u'飢'), - (0x2FA03, 'M', u'䬳'), - (0x2FA04, 'M', u'餩'), - (0x2FA05, 'M', u'馧'), - (0x2FA06, 'M', u'駂'), - (0x2FA07, 'M', u'駾'), - (0x2FA08, 'M', u'䯎'), - (0x2FA09, 'M', u'𩬰'), - (0x2FA0A, 'M', u'鬒'), - (0x2FA0B, 'M', u'鱀'), - (0x2FA0C, 'M', u'鳽'), - (0x2FA0D, 'M', u'䳎'), - (0x2FA0E, 'M', u'䳭'), - (0x2FA0F, 'M', u'鵧'), - (0x2FA10, 'M', u'𪃎'), - (0x2FA11, 'M', u'䳸'), - (0x2FA12, 'M', u'𪄅'), - (0x2FA13, 'M', u'𪈎'), - (0x2FA14, 'M', u'𪊑'), - (0x2FA15, 'M', u'麻'), - (0x2FA16, 'M', u'䵖'), - (0x2FA17, 'M', u'黹'), - (0x2FA18, 'M', u'黾'), - (0x2FA19, 'M', u'鼅'), - (0x2FA1A, 'M', u'鼏'), - (0x2FA1B, 'M', u'鼖'), - (0x2FA1C, 'M', u'鼻'), - (0x2FA1D, 'M', u'𪘀'), - (0x2FA1E, 'X'), - (0xE0100, 'I'), - ] - -def _seg_78(): - return [ - (0xE01F0, 'X'), - ] - -uts46data = tuple( - _seg_0() - + _seg_1() - + _seg_2() - + _seg_3() - + _seg_4() - + _seg_5() - + _seg_6() - + _seg_7() - + _seg_8() - + _seg_9() - + _seg_10() - + _seg_11() - + _seg_12() - + _seg_13() - + _seg_14() - + _seg_15() - + _seg_16() - + _seg_17() - + _seg_18() - + _seg_19() - + _seg_20() - + _seg_21() - + _seg_22() - + _seg_23() - + _seg_24() - + _seg_25() - + _seg_26() - + _seg_27() - + _seg_28() - + _seg_29() - + _seg_30() - + _seg_31() - + _seg_32() - + _seg_33() - + _seg_34() - + _seg_35() - + _seg_36() - + _seg_37() - + _seg_38() - + _seg_39() - + _seg_40() - + _seg_41() - + _seg_42() - + _seg_43() - + _seg_44() - + _seg_45() - + _seg_46() - + _seg_47() - + _seg_48() - + _seg_49() - + _seg_50() - + _seg_51() - + _seg_52() - + _seg_53() - + _seg_54() - + _seg_55() - + _seg_56() - + _seg_57() - + _seg_58() - + _seg_59() - + _seg_60() - + _seg_61() - + _seg_62() - + _seg_63() - + _seg_64() - + _seg_65() - + _seg_66() - + _seg_67() - + _seg_68() - + _seg_69() - + _seg_70() - + _seg_71() - + _seg_72() - + _seg_73() - + _seg_74() - + _seg_75() - + _seg_76() - + _seg_77() - + _seg_78() -) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/ipaddress.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/ipaddress.py deleted file mode 100644 index f2d0766..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/ipaddress.py +++ /dev/null @@ -1,2419 +0,0 @@ -# Copyright 2007 Google Inc. -# Licensed to PSF under a Contributor Agreement. - -"""A fast, lightweight IPv4/IPv6 manipulation library in Python. - -This library is used to create/poke/manipulate IPv4 and IPv6 addresses -and networks. - -""" - -from __future__ import unicode_literals - - -import itertools -import struct - -__version__ = '1.0.22' - -# Compatibility functions -_compat_int_types = (int,) -try: - _compat_int_types = (int, long) -except NameError: - pass -try: - _compat_str = unicode -except NameError: - _compat_str = str - assert bytes != str -if b'\0'[0] == 0: # Python 3 semantics - def _compat_bytes_to_byte_vals(byt): - return byt -else: - def _compat_bytes_to_byte_vals(byt): - return [struct.unpack(b'!B', b)[0] for b in byt] -try: - _compat_int_from_byte_vals = int.from_bytes -except AttributeError: - def _compat_int_from_byte_vals(bytvals, endianess): - assert endianess == 'big' - res = 0 - for bv in bytvals: - assert isinstance(bv, _compat_int_types) - res = (res << 8) + bv - return res - - -def _compat_to_bytes(intval, length, endianess): - assert isinstance(intval, _compat_int_types) - assert endianess == 'big' - if length == 4: - if intval < 0 or intval >= 2 ** 32: - raise struct.error("integer out of range for 'I' format code") - return struct.pack(b'!I', intval) - elif length == 16: - if intval < 0 or intval >= 2 ** 128: - raise struct.error("integer out of range for 'QQ' format code") - return struct.pack(b'!QQ', intval >> 64, intval & 0xffffffffffffffff) - else: - raise NotImplementedError() - - -if hasattr(int, 'bit_length'): - # Not int.bit_length , since that won't work in 2.7 where long exists - def _compat_bit_length(i): - return i.bit_length() -else: - def _compat_bit_length(i): - for res in itertools.count(): - if i >> res == 0: - return res - - -def _compat_range(start, end, step=1): - assert step > 0 - i = start - while i < end: - yield i - i += step - - -class _TotalOrderingMixin(object): - __slots__ = () - - # Helper that derives the other comparison operations from - # __lt__ and __eq__ - # We avoid functools.total_ordering because it doesn't handle - # NotImplemented correctly yet (http://bugs.python.org/issue10042) - def __eq__(self, other): - raise NotImplementedError - - def __ne__(self, other): - equal = self.__eq__(other) - if equal is NotImplemented: - return NotImplemented - return not equal - - def __lt__(self, other): - raise NotImplementedError - - def __le__(self, other): - less = self.__lt__(other) - if less is NotImplemented or not less: - return self.__eq__(other) - return less - - def __gt__(self, other): - less = self.__lt__(other) - if less is NotImplemented: - return NotImplemented - equal = self.__eq__(other) - if equal is NotImplemented: - return NotImplemented - return not (less or equal) - - def __ge__(self, other): - less = self.__lt__(other) - if less is NotImplemented: - return NotImplemented - return not less - - -IPV4LENGTH = 32 -IPV6LENGTH = 128 - - -class AddressValueError(ValueError): - """A Value Error related to the address.""" - - -class NetmaskValueError(ValueError): - """A Value Error related to the netmask.""" - - -def ip_address(address): - """Take an IP string/int and return an object of the correct type. - - Args: - address: A string or integer, the IP address. Either IPv4 or - IPv6 addresses may be supplied; integers less than 2**32 will - be considered to be IPv4 by default. - - Returns: - An IPv4Address or IPv6Address object. - - Raises: - ValueError: if the *address* passed isn't either a v4 or a v6 - address - - """ - try: - return IPv4Address(address) - except (AddressValueError, NetmaskValueError): - pass - - try: - return IPv6Address(address) - except (AddressValueError, NetmaskValueError): - pass - - if isinstance(address, bytes): - raise AddressValueError( - '%r does not appear to be an IPv4 or IPv6 address. ' - 'Did you pass in a bytes (str in Python 2) instead of' - ' a unicode object?' % address) - - raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % - address) - - -def ip_network(address, strict=True): - """Take an IP string/int and return an object of the correct type. - - Args: - address: A string or integer, the IP network. Either IPv4 or - IPv6 networks may be supplied; integers less than 2**32 will - be considered to be IPv4 by default. - - Returns: - An IPv4Network or IPv6Network object. - - Raises: - ValueError: if the string passed isn't either a v4 or a v6 - address. Or if the network has host bits set. - - """ - try: - return IPv4Network(address, strict) - except (AddressValueError, NetmaskValueError): - pass - - try: - return IPv6Network(address, strict) - except (AddressValueError, NetmaskValueError): - pass - - if isinstance(address, bytes): - raise AddressValueError( - '%r does not appear to be an IPv4 or IPv6 network. ' - 'Did you pass in a bytes (str in Python 2) instead of' - ' a unicode object?' % address) - - raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % - address) - - -def ip_interface(address): - """Take an IP string/int and return an object of the correct type. - - Args: - address: A string or integer, the IP address. Either IPv4 or - IPv6 addresses may be supplied; integers less than 2**32 will - be considered to be IPv4 by default. - - Returns: - An IPv4Interface or IPv6Interface object. - - Raises: - ValueError: if the string passed isn't either a v4 or a v6 - address. - - Notes: - The IPv?Interface classes describe an Address on a particular - Network, so they're basically a combination of both the Address - and Network classes. - - """ - try: - return IPv4Interface(address) - except (AddressValueError, NetmaskValueError): - pass - - try: - return IPv6Interface(address) - except (AddressValueError, NetmaskValueError): - pass - - raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % - address) - - -def v4_int_to_packed(address): - """Represent an address as 4 packed bytes in network (big-endian) order. - - Args: - address: An integer representation of an IPv4 IP address. - - Returns: - The integer address packed as 4 bytes in network (big-endian) order. - - Raises: - ValueError: If the integer is negative or too large to be an - IPv4 IP address. - - """ - try: - return _compat_to_bytes(address, 4, 'big') - except (struct.error, OverflowError): - raise ValueError("Address negative or too large for IPv4") - - -def v6_int_to_packed(address): - """Represent an address as 16 packed bytes in network (big-endian) order. - - Args: - address: An integer representation of an IPv6 IP address. - - Returns: - The integer address packed as 16 bytes in network (big-endian) order. - - """ - try: - return _compat_to_bytes(address, 16, 'big') - except (struct.error, OverflowError): - raise ValueError("Address negative or too large for IPv6") - - -def _split_optional_netmask(address): - """Helper to split the netmask and raise AddressValueError if needed""" - addr = _compat_str(address).split('/') - if len(addr) > 2: - raise AddressValueError("Only one '/' permitted in %r" % address) - return addr - - -def _find_address_range(addresses): - """Find a sequence of sorted deduplicated IPv#Address. - - Args: - addresses: a list of IPv#Address objects. - - Yields: - A tuple containing the first and last IP addresses in the sequence. - - """ - it = iter(addresses) - first = last = next(it) - for ip in it: - if ip._ip != last._ip + 1: - yield first, last - first = ip - last = ip - yield first, last - - -def _count_righthand_zero_bits(number, bits): - """Count the number of zero bits on the right hand side. - - Args: - number: an integer. - bits: maximum number of bits to count. - - Returns: - The number of zero bits on the right hand side of the number. - - """ - if number == 0: - return bits - return min(bits, _compat_bit_length(~number & (number - 1))) - - -def summarize_address_range(first, last): - """Summarize a network range given the first and last IP addresses. - - Example: - >>> list(summarize_address_range(IPv4Address('192.0.2.0'), - ... IPv4Address('192.0.2.130'))) - ... #doctest: +NORMALIZE_WHITESPACE - [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), - IPv4Network('192.0.2.130/32')] - - Args: - first: the first IPv4Address or IPv6Address in the range. - last: the last IPv4Address or IPv6Address in the range. - - Returns: - An iterator of the summarized IPv(4|6) network objects. - - Raise: - TypeError: - If the first and last objects are not IP addresses. - If the first and last objects are not the same version. - ValueError: - If the last object is not greater than the first. - If the version of the first address is not 4 or 6. - - """ - if (not (isinstance(first, _BaseAddress) and - isinstance(last, _BaseAddress))): - raise TypeError('first and last must be IP addresses, not networks') - if first.version != last.version: - raise TypeError("%s and %s are not of the same version" % ( - first, last)) - if first > last: - raise ValueError('last IP address must be greater than first') - - if first.version == 4: - ip = IPv4Network - elif first.version == 6: - ip = IPv6Network - else: - raise ValueError('unknown IP version') - - ip_bits = first._max_prefixlen - first_int = first._ip - last_int = last._ip - while first_int <= last_int: - nbits = min(_count_righthand_zero_bits(first_int, ip_bits), - _compat_bit_length(last_int - first_int + 1) - 1) - net = ip((first_int, ip_bits - nbits)) - yield net - first_int += 1 << nbits - if first_int - 1 == ip._ALL_ONES: - break - - -def _collapse_addresses_internal(addresses): - """Loops through the addresses, collapsing concurrent netblocks. - - Example: - - ip1 = IPv4Network('192.0.2.0/26') - ip2 = IPv4Network('192.0.2.64/26') - ip3 = IPv4Network('192.0.2.128/26') - ip4 = IPv4Network('192.0.2.192/26') - - _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> - [IPv4Network('192.0.2.0/24')] - - This shouldn't be called directly; it is called via - collapse_addresses([]). - - Args: - addresses: A list of IPv4Network's or IPv6Network's - - Returns: - A list of IPv4Network's or IPv6Network's depending on what we were - passed. - - """ - # First merge - to_merge = list(addresses) - subnets = {} - while to_merge: - net = to_merge.pop() - supernet = net.supernet() - existing = subnets.get(supernet) - if existing is None: - subnets[supernet] = net - elif existing != net: - # Merge consecutive subnets - del subnets[supernet] - to_merge.append(supernet) - # Then iterate over resulting networks, skipping subsumed subnets - last = None - for net in sorted(subnets.values()): - if last is not None: - # Since they are sorted, - # last.network_address <= net.network_address is a given. - if last.broadcast_address >= net.broadcast_address: - continue - yield net - last = net - - -def collapse_addresses(addresses): - """Collapse a list of IP objects. - - Example: - collapse_addresses([IPv4Network('192.0.2.0/25'), - IPv4Network('192.0.2.128/25')]) -> - [IPv4Network('192.0.2.0/24')] - - Args: - addresses: An iterator of IPv4Network or IPv6Network objects. - - Returns: - An iterator of the collapsed IPv(4|6)Network objects. - - Raises: - TypeError: If passed a list of mixed version objects. - - """ - addrs = [] - ips = [] - nets = [] - - # split IP addresses and networks - for ip in addresses: - if isinstance(ip, _BaseAddress): - if ips and ips[-1]._version != ip._version: - raise TypeError("%s and %s are not of the same version" % ( - ip, ips[-1])) - ips.append(ip) - elif ip._prefixlen == ip._max_prefixlen: - if ips and ips[-1]._version != ip._version: - raise TypeError("%s and %s are not of the same version" % ( - ip, ips[-1])) - try: - ips.append(ip.ip) - except AttributeError: - ips.append(ip.network_address) - else: - if nets and nets[-1]._version != ip._version: - raise TypeError("%s and %s are not of the same version" % ( - ip, nets[-1])) - nets.append(ip) - - # sort and dedup - ips = sorted(set(ips)) - - # find consecutive address ranges in the sorted sequence and summarize them - if ips: - for first, last in _find_address_range(ips): - addrs.extend(summarize_address_range(first, last)) - - return _collapse_addresses_internal(addrs + nets) - - -def get_mixed_type_key(obj): - """Return a key suitable for sorting between networks and addresses. - - Address and Network objects are not sortable by default; they're - fundamentally different so the expression - - IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') - - doesn't make any sense. There are some times however, where you may wish - to have ipaddress sort these for you anyway. If you need to do this, you - can use this function as the key= argument to sorted(). - - Args: - obj: either a Network or Address object. - Returns: - appropriate key. - - """ - if isinstance(obj, _BaseNetwork): - return obj._get_networks_key() - elif isinstance(obj, _BaseAddress): - return obj._get_address_key() - return NotImplemented - - -class _IPAddressBase(_TotalOrderingMixin): - - """The mother class.""" - - __slots__ = () - - @property - def exploded(self): - """Return the longhand version of the IP address as a string.""" - return self._explode_shorthand_ip_string() - - @property - def compressed(self): - """Return the shorthand version of the IP address as a string.""" - return _compat_str(self) - - @property - def reverse_pointer(self): - """The name of the reverse DNS pointer for the IP address, e.g.: - >>> ipaddress.ip_address("127.0.0.1").reverse_pointer - '1.0.0.127.in-addr.arpa' - >>> ipaddress.ip_address("2001:db8::1").reverse_pointer - '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' - - """ - return self._reverse_pointer() - - @property - def version(self): - msg = '%200s has no version specified' % (type(self),) - raise NotImplementedError(msg) - - def _check_int_address(self, address): - if address < 0: - msg = "%d (< 0) is not permitted as an IPv%d address" - raise AddressValueError(msg % (address, self._version)) - if address > self._ALL_ONES: - msg = "%d (>= 2**%d) is not permitted as an IPv%d address" - raise AddressValueError(msg % (address, self._max_prefixlen, - self._version)) - - def _check_packed_address(self, address, expected_len): - address_len = len(address) - if address_len != expected_len: - msg = ( - '%r (len %d != %d) is not permitted as an IPv%d address. ' - 'Did you pass in a bytes (str in Python 2) instead of' - ' a unicode object?') - raise AddressValueError(msg % (address, address_len, - expected_len, self._version)) - - @classmethod - def _ip_int_from_prefix(cls, prefixlen): - """Turn the prefix length into a bitwise netmask - - Args: - prefixlen: An integer, the prefix length. - - Returns: - An integer. - - """ - return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) - - @classmethod - def _prefix_from_ip_int(cls, ip_int): - """Return prefix length from the bitwise netmask. - - Args: - ip_int: An integer, the netmask in expanded bitwise format - - Returns: - An integer, the prefix length. - - Raises: - ValueError: If the input intermingles zeroes & ones - """ - trailing_zeroes = _count_righthand_zero_bits(ip_int, - cls._max_prefixlen) - prefixlen = cls._max_prefixlen - trailing_zeroes - leading_ones = ip_int >> trailing_zeroes - all_ones = (1 << prefixlen) - 1 - if leading_ones != all_ones: - byteslen = cls._max_prefixlen // 8 - details = _compat_to_bytes(ip_int, byteslen, 'big') - msg = 'Netmask pattern %r mixes zeroes & ones' - raise ValueError(msg % details) - return prefixlen - - @classmethod - def _report_invalid_netmask(cls, netmask_str): - msg = '%r is not a valid netmask' % netmask_str - raise NetmaskValueError(msg) - - @classmethod - def _prefix_from_prefix_string(cls, prefixlen_str): - """Return prefix length from a numeric string - - Args: - prefixlen_str: The string to be converted - - Returns: - An integer, the prefix length. - - Raises: - NetmaskValueError: If the input is not a valid netmask - """ - # int allows a leading +/- as well as surrounding whitespace, - # so we ensure that isn't the case - if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): - cls._report_invalid_netmask(prefixlen_str) - try: - prefixlen = int(prefixlen_str) - except ValueError: - cls._report_invalid_netmask(prefixlen_str) - if not (0 <= prefixlen <= cls._max_prefixlen): - cls._report_invalid_netmask(prefixlen_str) - return prefixlen - - @classmethod - def _prefix_from_ip_string(cls, ip_str): - """Turn a netmask/hostmask string into a prefix length - - Args: - ip_str: The netmask/hostmask to be converted - - Returns: - An integer, the prefix length. - - Raises: - NetmaskValueError: If the input is not a valid netmask/hostmask - """ - # Parse the netmask/hostmask like an IP address. - try: - ip_int = cls._ip_int_from_string(ip_str) - except AddressValueError: - cls._report_invalid_netmask(ip_str) - - # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). - # Note that the two ambiguous cases (all-ones and all-zeroes) are - # treated as netmasks. - try: - return cls._prefix_from_ip_int(ip_int) - except ValueError: - pass - - # Invert the bits, and try matching a /0+1+/ hostmask instead. - ip_int ^= cls._ALL_ONES - try: - return cls._prefix_from_ip_int(ip_int) - except ValueError: - cls._report_invalid_netmask(ip_str) - - def __reduce__(self): - return self.__class__, (_compat_str(self),) - - -class _BaseAddress(_IPAddressBase): - - """A generic IP object. - - This IP class contains the version independent methods which are - used by single IP addresses. - """ - - __slots__ = () - - def __int__(self): - return self._ip - - def __eq__(self, other): - try: - return (self._ip == other._ip and - self._version == other._version) - except AttributeError: - return NotImplemented - - def __lt__(self, other): - if not isinstance(other, _IPAddressBase): - return NotImplemented - if not isinstance(other, _BaseAddress): - raise TypeError('%s and %s are not of the same type' % ( - self, other)) - if self._version != other._version: - raise TypeError('%s and %s are not of the same version' % ( - self, other)) - if self._ip != other._ip: - return self._ip < other._ip - return False - - # Shorthand for Integer addition and subtraction. This is not - # meant to ever support addition/subtraction of addresses. - def __add__(self, other): - if not isinstance(other, _compat_int_types): - return NotImplemented - return self.__class__(int(self) + other) - - def __sub__(self, other): - if not isinstance(other, _compat_int_types): - return NotImplemented - return self.__class__(int(self) - other) - - def __repr__(self): - return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) - - def __str__(self): - return _compat_str(self._string_from_ip_int(self._ip)) - - def __hash__(self): - return hash(hex(int(self._ip))) - - def _get_address_key(self): - return (self._version, self) - - def __reduce__(self): - return self.__class__, (self._ip,) - - -class _BaseNetwork(_IPAddressBase): - - """A generic IP network object. - - This IP class contains the version independent methods which are - used by networks. - - """ - def __init__(self, address): - self._cache = {} - - def __repr__(self): - return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) - - def __str__(self): - return '%s/%d' % (self.network_address, self.prefixlen) - - def hosts(self): - """Generate Iterator over usable hosts in a network. - - This is like __iter__ except it doesn't return the network - or broadcast addresses. - - """ - network = int(self.network_address) - broadcast = int(self.broadcast_address) - for x in _compat_range(network + 1, broadcast): - yield self._address_class(x) - - def __iter__(self): - network = int(self.network_address) - broadcast = int(self.broadcast_address) - for x in _compat_range(network, broadcast + 1): - yield self._address_class(x) - - def __getitem__(self, n): - network = int(self.network_address) - broadcast = int(self.broadcast_address) - if n >= 0: - if network + n > broadcast: - raise IndexError('address out of range') - return self._address_class(network + n) - else: - n += 1 - if broadcast + n < network: - raise IndexError('address out of range') - return self._address_class(broadcast + n) - - def __lt__(self, other): - if not isinstance(other, _IPAddressBase): - return NotImplemented - if not isinstance(other, _BaseNetwork): - raise TypeError('%s and %s are not of the same type' % ( - self, other)) - if self._version != other._version: - raise TypeError('%s and %s are not of the same version' % ( - self, other)) - if self.network_address != other.network_address: - return self.network_address < other.network_address - if self.netmask != other.netmask: - return self.netmask < other.netmask - return False - - def __eq__(self, other): - try: - return (self._version == other._version and - self.network_address == other.network_address and - int(self.netmask) == int(other.netmask)) - except AttributeError: - return NotImplemented - - def __hash__(self): - return hash(int(self.network_address) ^ int(self.netmask)) - - def __contains__(self, other): - # always false if one is v4 and the other is v6. - if self._version != other._version: - return False - # dealing with another network. - if isinstance(other, _BaseNetwork): - return False - # dealing with another address - else: - # address - return (int(self.network_address) <= int(other._ip) <= - int(self.broadcast_address)) - - def overlaps(self, other): - """Tell if self is partly contained in other.""" - return self.network_address in other or ( - self.broadcast_address in other or ( - other.network_address in self or ( - other.broadcast_address in self))) - - @property - def broadcast_address(self): - x = self._cache.get('broadcast_address') - if x is None: - x = self._address_class(int(self.network_address) | - int(self.hostmask)) - self._cache['broadcast_address'] = x - return x - - @property - def hostmask(self): - x = self._cache.get('hostmask') - if x is None: - x = self._address_class(int(self.netmask) ^ self._ALL_ONES) - self._cache['hostmask'] = x - return x - - @property - def with_prefixlen(self): - return '%s/%d' % (self.network_address, self._prefixlen) - - @property - def with_netmask(self): - return '%s/%s' % (self.network_address, self.netmask) - - @property - def with_hostmask(self): - return '%s/%s' % (self.network_address, self.hostmask) - - @property - def num_addresses(self): - """Number of hosts in the current subnet.""" - return int(self.broadcast_address) - int(self.network_address) + 1 - - @property - def _address_class(self): - # Returning bare address objects (rather than interfaces) allows for - # more consistent behaviour across the network address, broadcast - # address and individual host addresses. - msg = '%200s has no associated address class' % (type(self),) - raise NotImplementedError(msg) - - @property - def prefixlen(self): - return self._prefixlen - - def address_exclude(self, other): - """Remove an address from a larger block. - - For example: - - addr1 = ip_network('192.0.2.0/28') - addr2 = ip_network('192.0.2.1/32') - list(addr1.address_exclude(addr2)) = - [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), - IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] - - or IPv6: - - addr1 = ip_network('2001:db8::1/32') - addr2 = ip_network('2001:db8::1/128') - list(addr1.address_exclude(addr2)) = - [ip_network('2001:db8::1/128'), - ip_network('2001:db8::2/127'), - ip_network('2001:db8::4/126'), - ip_network('2001:db8::8/125'), - ... - ip_network('2001:db8:8000::/33')] - - Args: - other: An IPv4Network or IPv6Network object of the same type. - - Returns: - An iterator of the IPv(4|6)Network objects which is self - minus other. - - Raises: - TypeError: If self and other are of differing address - versions, or if other is not a network object. - ValueError: If other is not completely contained by self. - - """ - if not self._version == other._version: - raise TypeError("%s and %s are not of the same version" % ( - self, other)) - - if not isinstance(other, _BaseNetwork): - raise TypeError("%s is not a network object" % other) - - if not other.subnet_of(self): - raise ValueError('%s not contained in %s' % (other, self)) - if other == self: - return - - # Make sure we're comparing the network of other. - other = other.__class__('%s/%s' % (other.network_address, - other.prefixlen)) - - s1, s2 = self.subnets() - while s1 != other and s2 != other: - if other.subnet_of(s1): - yield s2 - s1, s2 = s1.subnets() - elif other.subnet_of(s2): - yield s1 - s1, s2 = s2.subnets() - else: - # If we got here, there's a bug somewhere. - raise AssertionError('Error performing exclusion: ' - 's1: %s s2: %s other: %s' % - (s1, s2, other)) - if s1 == other: - yield s2 - elif s2 == other: - yield s1 - else: - # If we got here, there's a bug somewhere. - raise AssertionError('Error performing exclusion: ' - 's1: %s s2: %s other: %s' % - (s1, s2, other)) - - def compare_networks(self, other): - """Compare two IP objects. - - This is only concerned about the comparison of the integer - representation of the network addresses. This means that the - host bits aren't considered at all in this method. If you want - to compare host bits, you can easily enough do a - 'HostA._ip < HostB._ip' - - Args: - other: An IP object. - - Returns: - If the IP versions of self and other are the same, returns: - - -1 if self < other: - eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') - IPv6Network('2001:db8::1000/124') < - IPv6Network('2001:db8::2000/124') - 0 if self == other - eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') - IPv6Network('2001:db8::1000/124') == - IPv6Network('2001:db8::1000/124') - 1 if self > other - eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') - IPv6Network('2001:db8::2000/124') > - IPv6Network('2001:db8::1000/124') - - Raises: - TypeError if the IP versions are different. - - """ - # does this need to raise a ValueError? - if self._version != other._version: - raise TypeError('%s and %s are not of the same type' % ( - self, other)) - # self._version == other._version below here: - if self.network_address < other.network_address: - return -1 - if self.network_address > other.network_address: - return 1 - # self.network_address == other.network_address below here: - if self.netmask < other.netmask: - return -1 - if self.netmask > other.netmask: - return 1 - return 0 - - def _get_networks_key(self): - """Network-only key function. - - Returns an object that identifies this address' network and - netmask. This function is a suitable "key" argument for sorted() - and list.sort(). - - """ - return (self._version, self.network_address, self.netmask) - - def subnets(self, prefixlen_diff=1, new_prefix=None): - """The subnets which join to make the current subnet. - - In the case that self contains only one IP - (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 - for IPv6), yield an iterator with just ourself. - - Args: - prefixlen_diff: An integer, the amount the prefix length - should be increased by. This should not be set if - new_prefix is also set. - new_prefix: The desired new prefix length. This must be a - larger number (smaller prefix) than the existing prefix. - This should not be set if prefixlen_diff is also set. - - Returns: - An iterator of IPv(4|6) objects. - - Raises: - ValueError: The prefixlen_diff is too small or too large. - OR - prefixlen_diff and new_prefix are both set or new_prefix - is a smaller number than the current prefix (smaller - number means a larger network) - - """ - if self._prefixlen == self._max_prefixlen: - yield self - return - - if new_prefix is not None: - if new_prefix < self._prefixlen: - raise ValueError('new prefix must be longer') - if prefixlen_diff != 1: - raise ValueError('cannot set prefixlen_diff and new_prefix') - prefixlen_diff = new_prefix - self._prefixlen - - if prefixlen_diff < 0: - raise ValueError('prefix length diff must be > 0') - new_prefixlen = self._prefixlen + prefixlen_diff - - if new_prefixlen > self._max_prefixlen: - raise ValueError( - 'prefix length diff %d is invalid for netblock %s' % ( - new_prefixlen, self)) - - start = int(self.network_address) - end = int(self.broadcast_address) + 1 - step = (int(self.hostmask) + 1) >> prefixlen_diff - for new_addr in _compat_range(start, end, step): - current = self.__class__((new_addr, new_prefixlen)) - yield current - - def supernet(self, prefixlen_diff=1, new_prefix=None): - """The supernet containing the current network. - - Args: - prefixlen_diff: An integer, the amount the prefix length of - the network should be decreased by. For example, given a - /24 network and a prefixlen_diff of 3, a supernet with a - /21 netmask is returned. - - Returns: - An IPv4 network object. - - Raises: - ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have - a negative prefix length. - OR - If prefixlen_diff and new_prefix are both set or new_prefix is a - larger number than the current prefix (larger number means a - smaller network) - - """ - if self._prefixlen == 0: - return self - - if new_prefix is not None: - if new_prefix > self._prefixlen: - raise ValueError('new prefix must be shorter') - if prefixlen_diff != 1: - raise ValueError('cannot set prefixlen_diff and new_prefix') - prefixlen_diff = self._prefixlen - new_prefix - - new_prefixlen = self.prefixlen - prefixlen_diff - if new_prefixlen < 0: - raise ValueError( - 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % - (self.prefixlen, prefixlen_diff)) - return self.__class__(( - int(self.network_address) & (int(self.netmask) << prefixlen_diff), - new_prefixlen)) - - @property - def is_multicast(self): - """Test if the address is reserved for multicast use. - - Returns: - A boolean, True if the address is a multicast address. - See RFC 2373 2.7 for details. - - """ - return (self.network_address.is_multicast and - self.broadcast_address.is_multicast) - - @staticmethod - def _is_subnet_of(a, b): - try: - # Always false if one is v4 and the other is v6. - if a._version != b._version: - raise TypeError("%s and %s are not of the same version" (a, b)) - return (b.network_address <= a.network_address and - b.broadcast_address >= a.broadcast_address) - except AttributeError: - raise TypeError("Unable to test subnet containment " - "between %s and %s" % (a, b)) - - def subnet_of(self, other): - """Return True if this network is a subnet of other.""" - return self._is_subnet_of(self, other) - - def supernet_of(self, other): - """Return True if this network is a supernet of other.""" - return self._is_subnet_of(other, self) - - @property - def is_reserved(self): - """Test if the address is otherwise IETF reserved. - - Returns: - A boolean, True if the address is within one of the - reserved IPv6 Network ranges. - - """ - return (self.network_address.is_reserved and - self.broadcast_address.is_reserved) - - @property - def is_link_local(self): - """Test if the address is reserved for link-local. - - Returns: - A boolean, True if the address is reserved per RFC 4291. - - """ - return (self.network_address.is_link_local and - self.broadcast_address.is_link_local) - - @property - def is_private(self): - """Test if this address is allocated for private networks. - - Returns: - A boolean, True if the address is reserved per - iana-ipv4-special-registry or iana-ipv6-special-registry. - - """ - return (self.network_address.is_private and - self.broadcast_address.is_private) - - @property - def is_global(self): - """Test if this address is allocated for public networks. - - Returns: - A boolean, True if the address is not reserved per - iana-ipv4-special-registry or iana-ipv6-special-registry. - - """ - return not self.is_private - - @property - def is_unspecified(self): - """Test if the address is unspecified. - - Returns: - A boolean, True if this is the unspecified address as defined in - RFC 2373 2.5.2. - - """ - return (self.network_address.is_unspecified and - self.broadcast_address.is_unspecified) - - @property - def is_loopback(self): - """Test if the address is a loopback address. - - Returns: - A boolean, True if the address is a loopback address as defined in - RFC 2373 2.5.3. - - """ - return (self.network_address.is_loopback and - self.broadcast_address.is_loopback) - - -class _BaseV4(object): - - """Base IPv4 object. - - The following methods are used by IPv4 objects in both single IP - addresses and networks. - - """ - - __slots__ = () - _version = 4 - # Equivalent to 255.255.255.255 or 32 bits of 1's. - _ALL_ONES = (2 ** IPV4LENGTH) - 1 - _DECIMAL_DIGITS = frozenset('0123456789') - - # the valid octets for host and netmasks. only useful for IPv4. - _valid_mask_octets = frozenset([255, 254, 252, 248, 240, 224, 192, 128, 0]) - - _max_prefixlen = IPV4LENGTH - # There are only a handful of valid v4 netmasks, so we cache them all - # when constructed (see _make_netmask()). - _netmask_cache = {} - - def _explode_shorthand_ip_string(self): - return _compat_str(self) - - @classmethod - def _make_netmask(cls, arg): - """Make a (netmask, prefix_len) tuple from the given argument. - - Argument can be: - - an integer (the prefix length) - - a string representing the prefix length (e.g. "24") - - a string representing the prefix netmask (e.g. "255.255.255.0") - """ - if arg not in cls._netmask_cache: - if isinstance(arg, _compat_int_types): - prefixlen = arg - else: - try: - # Check for a netmask in prefix length form - prefixlen = cls._prefix_from_prefix_string(arg) - except NetmaskValueError: - # Check for a netmask or hostmask in dotted-quad form. - # This may raise NetmaskValueError. - prefixlen = cls._prefix_from_ip_string(arg) - netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) - cls._netmask_cache[arg] = netmask, prefixlen - return cls._netmask_cache[arg] - - @classmethod - def _ip_int_from_string(cls, ip_str): - """Turn the given IP string into an integer for comparison. - - Args: - ip_str: A string, the IP ip_str. - - Returns: - The IP ip_str as an integer. - - Raises: - AddressValueError: if ip_str isn't a valid IPv4 Address. - - """ - if not ip_str: - raise AddressValueError('Address cannot be empty') - - octets = ip_str.split('.') - if len(octets) != 4: - raise AddressValueError("Expected 4 octets in %r" % ip_str) - - try: - return _compat_int_from_byte_vals( - map(cls._parse_octet, octets), 'big') - except ValueError as exc: - raise AddressValueError("%s in %r" % (exc, ip_str)) - - @classmethod - def _parse_octet(cls, octet_str): - """Convert a decimal octet into an integer. - - Args: - octet_str: A string, the number to parse. - - Returns: - The octet as an integer. - - Raises: - ValueError: if the octet isn't strictly a decimal from [0..255]. - - """ - if not octet_str: - raise ValueError("Empty octet not permitted") - # Whitelist the characters, since int() allows a lot of bizarre stuff. - if not cls._DECIMAL_DIGITS.issuperset(octet_str): - msg = "Only decimal digits permitted in %r" - raise ValueError(msg % octet_str) - # We do the length check second, since the invalid character error - # is likely to be more informative for the user - if len(octet_str) > 3: - msg = "At most 3 characters permitted in %r" - raise ValueError(msg % octet_str) - # Convert to integer (we know digits are legal) - octet_int = int(octet_str, 10) - # Any octets that look like they *might* be written in octal, - # and which don't look exactly the same in both octal and - # decimal are rejected as ambiguous - if octet_int > 7 and octet_str[0] == '0': - msg = "Ambiguous (octal/decimal) value in %r not permitted" - raise ValueError(msg % octet_str) - if octet_int > 255: - raise ValueError("Octet %d (> 255) not permitted" % octet_int) - return octet_int - - @classmethod - def _string_from_ip_int(cls, ip_int): - """Turns a 32-bit integer into dotted decimal notation. - - Args: - ip_int: An integer, the IP address. - - Returns: - The IP address as a string in dotted decimal notation. - - """ - return '.'.join(_compat_str(struct.unpack(b'!B', b)[0] - if isinstance(b, bytes) - else b) - for b in _compat_to_bytes(ip_int, 4, 'big')) - - def _is_hostmask(self, ip_str): - """Test if the IP string is a hostmask (rather than a netmask). - - Args: - ip_str: A string, the potential hostmask. - - Returns: - A boolean, True if the IP string is a hostmask. - - """ - bits = ip_str.split('.') - try: - parts = [x for x in map(int, bits) if x in self._valid_mask_octets] - except ValueError: - return False - if len(parts) != len(bits): - return False - if parts[0] < parts[-1]: - return True - return False - - def _reverse_pointer(self): - """Return the reverse DNS pointer name for the IPv4 address. - - This implements the method described in RFC1035 3.5. - - """ - reverse_octets = _compat_str(self).split('.')[::-1] - return '.'.join(reverse_octets) + '.in-addr.arpa' - - @property - def max_prefixlen(self): - return self._max_prefixlen - - @property - def version(self): - return self._version - - -class IPv4Address(_BaseV4, _BaseAddress): - - """Represent and manipulate single IPv4 Addresses.""" - - __slots__ = ('_ip', '__weakref__') - - def __init__(self, address): - - """ - Args: - address: A string or integer representing the IP - - Additionally, an integer can be passed, so - IPv4Address('192.0.2.1') == IPv4Address(3221225985). - or, more generally - IPv4Address(int(IPv4Address('192.0.2.1'))) == - IPv4Address('192.0.2.1') - - Raises: - AddressValueError: If ipaddress isn't a valid IPv4 address. - - """ - # Efficient constructor from integer. - if isinstance(address, _compat_int_types): - self._check_int_address(address) - self._ip = address - return - - # Constructing from a packed address - if isinstance(address, bytes): - self._check_packed_address(address, 4) - bvs = _compat_bytes_to_byte_vals(address) - self._ip = _compat_int_from_byte_vals(bvs, 'big') - return - - # Assume input argument to be string or any object representation - # which converts into a formatted IP string. - addr_str = _compat_str(address) - if '/' in addr_str: - raise AddressValueError("Unexpected '/' in %r" % address) - self._ip = self._ip_int_from_string(addr_str) - - @property - def packed(self): - """The binary representation of this address.""" - return v4_int_to_packed(self._ip) - - @property - def is_reserved(self): - """Test if the address is otherwise IETF reserved. - - Returns: - A boolean, True if the address is within the - reserved IPv4 Network range. - - """ - return self in self._constants._reserved_network - - @property - def is_private(self): - """Test if this address is allocated for private networks. - - Returns: - A boolean, True if the address is reserved per - iana-ipv4-special-registry. - - """ - return any(self in net for net in self._constants._private_networks) - - @property - def is_global(self): - return ( - self not in self._constants._public_network and - not self.is_private) - - @property - def is_multicast(self): - """Test if the address is reserved for multicast use. - - Returns: - A boolean, True if the address is multicast. - See RFC 3171 for details. - - """ - return self in self._constants._multicast_network - - @property - def is_unspecified(self): - """Test if the address is unspecified. - - Returns: - A boolean, True if this is the unspecified address as defined in - RFC 5735 3. - - """ - return self == self._constants._unspecified_address - - @property - def is_loopback(self): - """Test if the address is a loopback address. - - Returns: - A boolean, True if the address is a loopback per RFC 3330. - - """ - return self in self._constants._loopback_network - - @property - def is_link_local(self): - """Test if the address is reserved for link-local. - - Returns: - A boolean, True if the address is link-local per RFC 3927. - - """ - return self in self._constants._linklocal_network - - -class IPv4Interface(IPv4Address): - - def __init__(self, address): - if isinstance(address, (bytes, _compat_int_types)): - IPv4Address.__init__(self, address) - self.network = IPv4Network(self._ip) - self._prefixlen = self._max_prefixlen - return - - if isinstance(address, tuple): - IPv4Address.__init__(self, address[0]) - if len(address) > 1: - self._prefixlen = int(address[1]) - else: - self._prefixlen = self._max_prefixlen - - self.network = IPv4Network(address, strict=False) - self.netmask = self.network.netmask - self.hostmask = self.network.hostmask - return - - addr = _split_optional_netmask(address) - IPv4Address.__init__(self, addr[0]) - - self.network = IPv4Network(address, strict=False) - self._prefixlen = self.network._prefixlen - - self.netmask = self.network.netmask - self.hostmask = self.network.hostmask - - def __str__(self): - return '%s/%d' % (self._string_from_ip_int(self._ip), - self.network.prefixlen) - - def __eq__(self, other): - address_equal = IPv4Address.__eq__(self, other) - if not address_equal or address_equal is NotImplemented: - return address_equal - try: - return self.network == other.network - except AttributeError: - # An interface with an associated network is NOT the - # same as an unassociated address. That's why the hash - # takes the extra info into account. - return False - - def __lt__(self, other): - address_less = IPv4Address.__lt__(self, other) - if address_less is NotImplemented: - return NotImplemented - try: - return (self.network < other.network or - self.network == other.network and address_less) - except AttributeError: - # We *do* allow addresses and interfaces to be sorted. The - # unassociated address is considered less than all interfaces. - return False - - def __hash__(self): - return self._ip ^ self._prefixlen ^ int(self.network.network_address) - - __reduce__ = _IPAddressBase.__reduce__ - - @property - def ip(self): - return IPv4Address(self._ip) - - @property - def with_prefixlen(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self._prefixlen) - - @property - def with_netmask(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self.netmask) - - @property - def with_hostmask(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self.hostmask) - - -class IPv4Network(_BaseV4, _BaseNetwork): - - """This class represents and manipulates 32-bit IPv4 network + addresses.. - - Attributes: [examples for IPv4Network('192.0.2.0/27')] - .network_address: IPv4Address('192.0.2.0') - .hostmask: IPv4Address('0.0.0.31') - .broadcast_address: IPv4Address('192.0.2.32') - .netmask: IPv4Address('255.255.255.224') - .prefixlen: 27 - - """ - # Class to use when creating address objects - _address_class = IPv4Address - - def __init__(self, address, strict=True): - - """Instantiate a new IPv4 network object. - - Args: - address: A string or integer representing the IP [& network]. - '192.0.2.0/24' - '192.0.2.0/255.255.255.0' - '192.0.0.2/0.0.0.255' - are all functionally the same in IPv4. Similarly, - '192.0.2.1' - '192.0.2.1/255.255.255.255' - '192.0.2.1/32' - are also functionally equivalent. That is to say, failing to - provide a subnetmask will create an object with a mask of /32. - - If the mask (portion after the / in the argument) is given in - dotted quad form, it is treated as a netmask if it starts with a - non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it - starts with a zero field (e.g. 0.255.255.255 == /8), with the - single exception of an all-zero mask which is treated as a - netmask == /0. If no mask is given, a default of /32 is used. - - Additionally, an integer can be passed, so - IPv4Network('192.0.2.1') == IPv4Network(3221225985) - or, more generally - IPv4Interface(int(IPv4Interface('192.0.2.1'))) == - IPv4Interface('192.0.2.1') - - Raises: - AddressValueError: If ipaddress isn't a valid IPv4 address. - NetmaskValueError: If the netmask isn't valid for - an IPv4 address. - ValueError: If strict is True and a network address is not - supplied. - - """ - _BaseNetwork.__init__(self, address) - - # Constructing from a packed address or integer - if isinstance(address, (_compat_int_types, bytes)): - self.network_address = IPv4Address(address) - self.netmask, self._prefixlen = self._make_netmask( - self._max_prefixlen) - # fixme: address/network test here. - return - - if isinstance(address, tuple): - if len(address) > 1: - arg = address[1] - else: - # We weren't given an address[1] - arg = self._max_prefixlen - self.network_address = IPv4Address(address[0]) - self.netmask, self._prefixlen = self._make_netmask(arg) - packed = int(self.network_address) - if packed & int(self.netmask) != packed: - if strict: - raise ValueError('%s has host bits set' % self) - else: - self.network_address = IPv4Address(packed & - int(self.netmask)) - return - - # Assume input argument to be string or any object representation - # which converts into a formatted IP prefix string. - addr = _split_optional_netmask(address) - self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) - - if len(addr) == 2: - arg = addr[1] - else: - arg = self._max_prefixlen - self.netmask, self._prefixlen = self._make_netmask(arg) - - if strict: - if (IPv4Address(int(self.network_address) & int(self.netmask)) != - self.network_address): - raise ValueError('%s has host bits set' % self) - self.network_address = IPv4Address(int(self.network_address) & - int(self.netmask)) - - if self._prefixlen == (self._max_prefixlen - 1): - self.hosts = self.__iter__ - - @property - def is_global(self): - """Test if this address is allocated for public networks. - - Returns: - A boolean, True if the address is not reserved per - iana-ipv4-special-registry. - - """ - return (not (self.network_address in IPv4Network('100.64.0.0/10') and - self.broadcast_address in IPv4Network('100.64.0.0/10')) and - not self.is_private) - - -class _IPv4Constants(object): - - _linklocal_network = IPv4Network('169.254.0.0/16') - - _loopback_network = IPv4Network('127.0.0.0/8') - - _multicast_network = IPv4Network('224.0.0.0/4') - - _public_network = IPv4Network('100.64.0.0/10') - - _private_networks = [ - IPv4Network('0.0.0.0/8'), - IPv4Network('10.0.0.0/8'), - IPv4Network('127.0.0.0/8'), - IPv4Network('169.254.0.0/16'), - IPv4Network('172.16.0.0/12'), - IPv4Network('192.0.0.0/29'), - IPv4Network('192.0.0.170/31'), - IPv4Network('192.0.2.0/24'), - IPv4Network('192.168.0.0/16'), - IPv4Network('198.18.0.0/15'), - IPv4Network('198.51.100.0/24'), - IPv4Network('203.0.113.0/24'), - IPv4Network('240.0.0.0/4'), - IPv4Network('255.255.255.255/32'), - ] - - _reserved_network = IPv4Network('240.0.0.0/4') - - _unspecified_address = IPv4Address('0.0.0.0') - - -IPv4Address._constants = _IPv4Constants - - -class _BaseV6(object): - - """Base IPv6 object. - - The following methods are used by IPv6 objects in both single IP - addresses and networks. - - """ - - __slots__ = () - _version = 6 - _ALL_ONES = (2 ** IPV6LENGTH) - 1 - _HEXTET_COUNT = 8 - _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') - _max_prefixlen = IPV6LENGTH - - # There are only a bunch of valid v6 netmasks, so we cache them all - # when constructed (see _make_netmask()). - _netmask_cache = {} - - @classmethod - def _make_netmask(cls, arg): - """Make a (netmask, prefix_len) tuple from the given argument. - - Argument can be: - - an integer (the prefix length) - - a string representing the prefix length (e.g. "24") - - a string representing the prefix netmask (e.g. "255.255.255.0") - """ - if arg not in cls._netmask_cache: - if isinstance(arg, _compat_int_types): - prefixlen = arg - else: - prefixlen = cls._prefix_from_prefix_string(arg) - netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) - cls._netmask_cache[arg] = netmask, prefixlen - return cls._netmask_cache[arg] - - @classmethod - def _ip_int_from_string(cls, ip_str): - """Turn an IPv6 ip_str into an integer. - - Args: - ip_str: A string, the IPv6 ip_str. - - Returns: - An int, the IPv6 address - - Raises: - AddressValueError: if ip_str isn't a valid IPv6 Address. - - """ - if not ip_str: - raise AddressValueError('Address cannot be empty') - - parts = ip_str.split(':') - - # An IPv6 address needs at least 2 colons (3 parts). - _min_parts = 3 - if len(parts) < _min_parts: - msg = "At least %d parts expected in %r" % (_min_parts, ip_str) - raise AddressValueError(msg) - - # If the address has an IPv4-style suffix, convert it to hexadecimal. - if '.' in parts[-1]: - try: - ipv4_int = IPv4Address(parts.pop())._ip - except AddressValueError as exc: - raise AddressValueError("%s in %r" % (exc, ip_str)) - parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) - parts.append('%x' % (ipv4_int & 0xFFFF)) - - # An IPv6 address can't have more than 8 colons (9 parts). - # The extra colon comes from using the "::" notation for a single - # leading or trailing zero part. - _max_parts = cls._HEXTET_COUNT + 1 - if len(parts) > _max_parts: - msg = "At most %d colons permitted in %r" % ( - _max_parts - 1, ip_str) - raise AddressValueError(msg) - - # Disregarding the endpoints, find '::' with nothing in between. - # This indicates that a run of zeroes has been skipped. - skip_index = None - for i in _compat_range(1, len(parts) - 1): - if not parts[i]: - if skip_index is not None: - # Can't have more than one '::' - msg = "At most one '::' permitted in %r" % ip_str - raise AddressValueError(msg) - skip_index = i - - # parts_hi is the number of parts to copy from above/before the '::' - # parts_lo is the number of parts to copy from below/after the '::' - if skip_index is not None: - # If we found a '::', then check if it also covers the endpoints. - parts_hi = skip_index - parts_lo = len(parts) - skip_index - 1 - if not parts[0]: - parts_hi -= 1 - if parts_hi: - msg = "Leading ':' only permitted as part of '::' in %r" - raise AddressValueError(msg % ip_str) # ^: requires ^:: - if not parts[-1]: - parts_lo -= 1 - if parts_lo: - msg = "Trailing ':' only permitted as part of '::' in %r" - raise AddressValueError(msg % ip_str) # :$ requires ::$ - parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) - if parts_skipped < 1: - msg = "Expected at most %d other parts with '::' in %r" - raise AddressValueError(msg % (cls._HEXTET_COUNT - 1, ip_str)) - else: - # Otherwise, allocate the entire address to parts_hi. The - # endpoints could still be empty, but _parse_hextet() will check - # for that. - if len(parts) != cls._HEXTET_COUNT: - msg = "Exactly %d parts expected without '::' in %r" - raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) - if not parts[0]: - msg = "Leading ':' only permitted as part of '::' in %r" - raise AddressValueError(msg % ip_str) # ^: requires ^:: - if not parts[-1]: - msg = "Trailing ':' only permitted as part of '::' in %r" - raise AddressValueError(msg % ip_str) # :$ requires ::$ - parts_hi = len(parts) - parts_lo = 0 - parts_skipped = 0 - - try: - # Now, parse the hextets into a 128-bit integer. - ip_int = 0 - for i in range(parts_hi): - ip_int <<= 16 - ip_int |= cls._parse_hextet(parts[i]) - ip_int <<= 16 * parts_skipped - for i in range(-parts_lo, 0): - ip_int <<= 16 - ip_int |= cls._parse_hextet(parts[i]) - return ip_int - except ValueError as exc: - raise AddressValueError("%s in %r" % (exc, ip_str)) - - @classmethod - def _parse_hextet(cls, hextet_str): - """Convert an IPv6 hextet string into an integer. - - Args: - hextet_str: A string, the number to parse. - - Returns: - The hextet as an integer. - - Raises: - ValueError: if the input isn't strictly a hex number from - [0..FFFF]. - - """ - # Whitelist the characters, since int() allows a lot of bizarre stuff. - if not cls._HEX_DIGITS.issuperset(hextet_str): - raise ValueError("Only hex digits permitted in %r" % hextet_str) - # We do the length check second, since the invalid character error - # is likely to be more informative for the user - if len(hextet_str) > 4: - msg = "At most 4 characters permitted in %r" - raise ValueError(msg % hextet_str) - # Length check means we can skip checking the integer value - return int(hextet_str, 16) - - @classmethod - def _compress_hextets(cls, hextets): - """Compresses a list of hextets. - - Compresses a list of strings, replacing the longest continuous - sequence of "0" in the list with "" and adding empty strings at - the beginning or at the end of the string such that subsequently - calling ":".join(hextets) will produce the compressed version of - the IPv6 address. - - Args: - hextets: A list of strings, the hextets to compress. - - Returns: - A list of strings. - - """ - best_doublecolon_start = -1 - best_doublecolon_len = 0 - doublecolon_start = -1 - doublecolon_len = 0 - for index, hextet in enumerate(hextets): - if hextet == '0': - doublecolon_len += 1 - if doublecolon_start == -1: - # Start of a sequence of zeros. - doublecolon_start = index - if doublecolon_len > best_doublecolon_len: - # This is the longest sequence of zeros so far. - best_doublecolon_len = doublecolon_len - best_doublecolon_start = doublecolon_start - else: - doublecolon_len = 0 - doublecolon_start = -1 - - if best_doublecolon_len > 1: - best_doublecolon_end = (best_doublecolon_start + - best_doublecolon_len) - # For zeros at the end of the address. - if best_doublecolon_end == len(hextets): - hextets += [''] - hextets[best_doublecolon_start:best_doublecolon_end] = [''] - # For zeros at the beginning of the address. - if best_doublecolon_start == 0: - hextets = [''] + hextets - - return hextets - - @classmethod - def _string_from_ip_int(cls, ip_int=None): - """Turns a 128-bit integer into hexadecimal notation. - - Args: - ip_int: An integer, the IP address. - - Returns: - A string, the hexadecimal representation of the address. - - Raises: - ValueError: The address is bigger than 128 bits of all ones. - - """ - if ip_int is None: - ip_int = int(cls._ip) - - if ip_int > cls._ALL_ONES: - raise ValueError('IPv6 address is too large') - - hex_str = '%032x' % ip_int - hextets = ['%x' % int(hex_str[x:x + 4], 16) for x in range(0, 32, 4)] - - hextets = cls._compress_hextets(hextets) - return ':'.join(hextets) - - def _explode_shorthand_ip_string(self): - """Expand a shortened IPv6 address. - - Args: - ip_str: A string, the IPv6 address. - - Returns: - A string, the expanded IPv6 address. - - """ - if isinstance(self, IPv6Network): - ip_str = _compat_str(self.network_address) - elif isinstance(self, IPv6Interface): - ip_str = _compat_str(self.ip) - else: - ip_str = _compat_str(self) - - ip_int = self._ip_int_from_string(ip_str) - hex_str = '%032x' % ip_int - parts = [hex_str[x:x + 4] for x in range(0, 32, 4)] - if isinstance(self, (_BaseNetwork, IPv6Interface)): - return '%s/%d' % (':'.join(parts), self._prefixlen) - return ':'.join(parts) - - def _reverse_pointer(self): - """Return the reverse DNS pointer name for the IPv6 address. - - This implements the method described in RFC3596 2.5. - - """ - reverse_chars = self.exploded[::-1].replace(':', '') - return '.'.join(reverse_chars) + '.ip6.arpa' - - @property - def max_prefixlen(self): - return self._max_prefixlen - - @property - def version(self): - return self._version - - -class IPv6Address(_BaseV6, _BaseAddress): - - """Represent and manipulate single IPv6 Addresses.""" - - __slots__ = ('_ip', '__weakref__') - - def __init__(self, address): - """Instantiate a new IPv6 address object. - - Args: - address: A string or integer representing the IP - - Additionally, an integer can be passed, so - IPv6Address('2001:db8::') == - IPv6Address(42540766411282592856903984951653826560) - or, more generally - IPv6Address(int(IPv6Address('2001:db8::'))) == - IPv6Address('2001:db8::') - - Raises: - AddressValueError: If address isn't a valid IPv6 address. - - """ - # Efficient constructor from integer. - if isinstance(address, _compat_int_types): - self._check_int_address(address) - self._ip = address - return - - # Constructing from a packed address - if isinstance(address, bytes): - self._check_packed_address(address, 16) - bvs = _compat_bytes_to_byte_vals(address) - self._ip = _compat_int_from_byte_vals(bvs, 'big') - return - - # Assume input argument to be string or any object representation - # which converts into a formatted IP string. - addr_str = _compat_str(address) - if '/' in addr_str: - raise AddressValueError("Unexpected '/' in %r" % address) - self._ip = self._ip_int_from_string(addr_str) - - @property - def packed(self): - """The binary representation of this address.""" - return v6_int_to_packed(self._ip) - - @property - def is_multicast(self): - """Test if the address is reserved for multicast use. - - Returns: - A boolean, True if the address is a multicast address. - See RFC 2373 2.7 for details. - - """ - return self in self._constants._multicast_network - - @property - def is_reserved(self): - """Test if the address is otherwise IETF reserved. - - Returns: - A boolean, True if the address is within one of the - reserved IPv6 Network ranges. - - """ - return any(self in x for x in self._constants._reserved_networks) - - @property - def is_link_local(self): - """Test if the address is reserved for link-local. - - Returns: - A boolean, True if the address is reserved per RFC 4291. - - """ - return self in self._constants._linklocal_network - - @property - def is_site_local(self): - """Test if the address is reserved for site-local. - - Note that the site-local address space has been deprecated by RFC 3879. - Use is_private to test if this address is in the space of unique local - addresses as defined by RFC 4193. - - Returns: - A boolean, True if the address is reserved per RFC 3513 2.5.6. - - """ - return self in self._constants._sitelocal_network - - @property - def is_private(self): - """Test if this address is allocated for private networks. - - Returns: - A boolean, True if the address is reserved per - iana-ipv6-special-registry. - - """ - return any(self in net for net in self._constants._private_networks) - - @property - def is_global(self): - """Test if this address is allocated for public networks. - - Returns: - A boolean, true if the address is not reserved per - iana-ipv6-special-registry. - - """ - return not self.is_private - - @property - def is_unspecified(self): - """Test if the address is unspecified. - - Returns: - A boolean, True if this is the unspecified address as defined in - RFC 2373 2.5.2. - - """ - return self._ip == 0 - - @property - def is_loopback(self): - """Test if the address is a loopback address. - - Returns: - A boolean, True if the address is a loopback address as defined in - RFC 2373 2.5.3. - - """ - return self._ip == 1 - - @property - def ipv4_mapped(self): - """Return the IPv4 mapped address. - - Returns: - If the IPv6 address is a v4 mapped address, return the - IPv4 mapped address. Return None otherwise. - - """ - if (self._ip >> 32) != 0xFFFF: - return None - return IPv4Address(self._ip & 0xFFFFFFFF) - - @property - def teredo(self): - """Tuple of embedded teredo IPs. - - Returns: - Tuple of the (server, client) IPs or None if the address - doesn't appear to be a teredo address (doesn't start with - 2001::/32) - - """ - if (self._ip >> 96) != 0x20010000: - return None - return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), - IPv4Address(~self._ip & 0xFFFFFFFF)) - - @property - def sixtofour(self): - """Return the IPv4 6to4 embedded address. - - Returns: - The IPv4 6to4-embedded address if present or None if the - address doesn't appear to contain a 6to4 embedded address. - - """ - if (self._ip >> 112) != 0x2002: - return None - return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) - - -class IPv6Interface(IPv6Address): - - def __init__(self, address): - if isinstance(address, (bytes, _compat_int_types)): - IPv6Address.__init__(self, address) - self.network = IPv6Network(self._ip) - self._prefixlen = self._max_prefixlen - return - if isinstance(address, tuple): - IPv6Address.__init__(self, address[0]) - if len(address) > 1: - self._prefixlen = int(address[1]) - else: - self._prefixlen = self._max_prefixlen - self.network = IPv6Network(address, strict=False) - self.netmask = self.network.netmask - self.hostmask = self.network.hostmask - return - - addr = _split_optional_netmask(address) - IPv6Address.__init__(self, addr[0]) - self.network = IPv6Network(address, strict=False) - self.netmask = self.network.netmask - self._prefixlen = self.network._prefixlen - self.hostmask = self.network.hostmask - - def __str__(self): - return '%s/%d' % (self._string_from_ip_int(self._ip), - self.network.prefixlen) - - def __eq__(self, other): - address_equal = IPv6Address.__eq__(self, other) - if not address_equal or address_equal is NotImplemented: - return address_equal - try: - return self.network == other.network - except AttributeError: - # An interface with an associated network is NOT the - # same as an unassociated address. That's why the hash - # takes the extra info into account. - return False - - def __lt__(self, other): - address_less = IPv6Address.__lt__(self, other) - if address_less is NotImplemented: - return NotImplemented - try: - return (self.network < other.network or - self.network == other.network and address_less) - except AttributeError: - # We *do* allow addresses and interfaces to be sorted. The - # unassociated address is considered less than all interfaces. - return False - - def __hash__(self): - return self._ip ^ self._prefixlen ^ int(self.network.network_address) - - __reduce__ = _IPAddressBase.__reduce__ - - @property - def ip(self): - return IPv6Address(self._ip) - - @property - def with_prefixlen(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self._prefixlen) - - @property - def with_netmask(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self.netmask) - - @property - def with_hostmask(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self.hostmask) - - @property - def is_unspecified(self): - return self._ip == 0 and self.network.is_unspecified - - @property - def is_loopback(self): - return self._ip == 1 and self.network.is_loopback - - -class IPv6Network(_BaseV6, _BaseNetwork): - - """This class represents and manipulates 128-bit IPv6 networks. - - Attributes: [examples for IPv6('2001:db8::1000/124')] - .network_address: IPv6Address('2001:db8::1000') - .hostmask: IPv6Address('::f') - .broadcast_address: IPv6Address('2001:db8::100f') - .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') - .prefixlen: 124 - - """ - - # Class to use when creating address objects - _address_class = IPv6Address - - def __init__(self, address, strict=True): - """Instantiate a new IPv6 Network object. - - Args: - address: A string or integer representing the IPv6 network or the - IP and prefix/netmask. - '2001:db8::/128' - '2001:db8:0000:0000:0000:0000:0000:0000/128' - '2001:db8::' - are all functionally the same in IPv6. That is to say, - failing to provide a subnetmask will create an object with - a mask of /128. - - Additionally, an integer can be passed, so - IPv6Network('2001:db8::') == - IPv6Network(42540766411282592856903984951653826560) - or, more generally - IPv6Network(int(IPv6Network('2001:db8::'))) == - IPv6Network('2001:db8::') - - strict: A boolean. If true, ensure that we have been passed - A true network address, eg, 2001:db8::1000/124 and not an - IP address on a network, eg, 2001:db8::1/124. - - Raises: - AddressValueError: If address isn't a valid IPv6 address. - NetmaskValueError: If the netmask isn't valid for - an IPv6 address. - ValueError: If strict was True and a network address was not - supplied. - - """ - _BaseNetwork.__init__(self, address) - - # Efficient constructor from integer or packed address - if isinstance(address, (bytes, _compat_int_types)): - self.network_address = IPv6Address(address) - self.netmask, self._prefixlen = self._make_netmask( - self._max_prefixlen) - return - - if isinstance(address, tuple): - if len(address) > 1: - arg = address[1] - else: - arg = self._max_prefixlen - self.netmask, self._prefixlen = self._make_netmask(arg) - self.network_address = IPv6Address(address[0]) - packed = int(self.network_address) - if packed & int(self.netmask) != packed: - if strict: - raise ValueError('%s has host bits set' % self) - else: - self.network_address = IPv6Address(packed & - int(self.netmask)) - return - - # Assume input argument to be string or any object representation - # which converts into a formatted IP prefix string. - addr = _split_optional_netmask(address) - - self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) - - if len(addr) == 2: - arg = addr[1] - else: - arg = self._max_prefixlen - self.netmask, self._prefixlen = self._make_netmask(arg) - - if strict: - if (IPv6Address(int(self.network_address) & int(self.netmask)) != - self.network_address): - raise ValueError('%s has host bits set' % self) - self.network_address = IPv6Address(int(self.network_address) & - int(self.netmask)) - - if self._prefixlen == (self._max_prefixlen - 1): - self.hosts = self.__iter__ - - def hosts(self): - """Generate Iterator over usable hosts in a network. - - This is like __iter__ except it doesn't return the - Subnet-Router anycast address. - - """ - network = int(self.network_address) - broadcast = int(self.broadcast_address) - for x in _compat_range(network + 1, broadcast + 1): - yield self._address_class(x) - - @property - def is_site_local(self): - """Test if the address is reserved for site-local. - - Note that the site-local address space has been deprecated by RFC 3879. - Use is_private to test if this address is in the space of unique local - addresses as defined by RFC 4193. - - Returns: - A boolean, True if the address is reserved per RFC 3513 2.5.6. - - """ - return (self.network_address.is_site_local and - self.broadcast_address.is_site_local) - - -class _IPv6Constants(object): - - _linklocal_network = IPv6Network('fe80::/10') - - _multicast_network = IPv6Network('ff00::/8') - - _private_networks = [ - IPv6Network('::1/128'), - IPv6Network('::/128'), - IPv6Network('::ffff:0:0/96'), - IPv6Network('100::/64'), - IPv6Network('2001::/23'), - IPv6Network('2001:2::/48'), - IPv6Network('2001:db8::/32'), - IPv6Network('2001:10::/28'), - IPv6Network('fc00::/7'), - IPv6Network('fe80::/10'), - ] - - _reserved_networks = [ - IPv6Network('::/8'), IPv6Network('100::/8'), - IPv6Network('200::/7'), IPv6Network('400::/6'), - IPv6Network('800::/5'), IPv6Network('1000::/4'), - IPv6Network('4000::/3'), IPv6Network('6000::/3'), - IPv6Network('8000::/3'), IPv6Network('A000::/3'), - IPv6Network('C000::/3'), IPv6Network('E000::/4'), - IPv6Network('F000::/5'), IPv6Network('F800::/6'), - IPv6Network('FE00::/9'), - ] - - _sitelocal_network = IPv6Network('fec0::/10') - - -IPv6Address._constants = _IPv6Constants diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/__init__.py deleted file mode 100644 index a6f44a5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/__init__.py +++ /dev/null @@ -1,347 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -lockfile.py - Platform-independent advisory file locks. - -Requires Python 2.5 unless you apply 2.4.diff -Locking is done on a per-thread basis instead of a per-process basis. - -Usage: - ->>> lock = LockFile('somefile') ->>> try: -... lock.acquire() -... except AlreadyLocked: -... print 'somefile', 'is locked already.' -... except LockFailed: -... print 'somefile', 'can\\'t be locked.' -... else: -... print 'got lock' -got lock ->>> print lock.is_locked() -True ->>> lock.release() - ->>> lock = LockFile('somefile') ->>> print lock.is_locked() -False ->>> with lock: -... print lock.is_locked() -True ->>> print lock.is_locked() -False - ->>> lock = LockFile('somefile') ->>> # It is okay to lock twice from the same thread... ->>> with lock: -... lock.acquire() -... ->>> # Though no counter is kept, so you can't unlock multiple times... ->>> print lock.is_locked() -False - -Exceptions: - - Error - base class for other exceptions - LockError - base class for all locking exceptions - AlreadyLocked - Another thread or process already holds the lock - LockFailed - Lock failed for some other reason - UnlockError - base class for all unlocking exceptions - AlreadyUnlocked - File was not locked. - NotMyLock - File was locked but not by the current thread/process -""" - -from __future__ import absolute_import - -import functools -import os -import socket -import threading -import warnings - -# Work with PEP8 and non-PEP8 versions of threading module. -if not hasattr(threading, "current_thread"): - threading.current_thread = threading.currentThread -if not hasattr(threading.Thread, "get_name"): - threading.Thread.get_name = threading.Thread.getName - -__all__ = ['Error', 'LockError', 'LockTimeout', 'AlreadyLocked', - 'LockFailed', 'UnlockError', 'NotLocked', 'NotMyLock', - 'LinkFileLock', 'MkdirFileLock', 'SQLiteFileLock', - 'LockBase', 'locked'] - - -class Error(Exception): - """ - Base class for other exceptions. - - >>> try: - ... raise Error - ... except Exception: - ... pass - """ - pass - - -class LockError(Error): - """ - Base class for error arising from attempts to acquire the lock. - - >>> try: - ... raise LockError - ... except Error: - ... pass - """ - pass - - -class LockTimeout(LockError): - """Raised when lock creation fails within a user-defined period of time. - - >>> try: - ... raise LockTimeout - ... except LockError: - ... pass - """ - pass - - -class AlreadyLocked(LockError): - """Some other thread/process is locking the file. - - >>> try: - ... raise AlreadyLocked - ... except LockError: - ... pass - """ - pass - - -class LockFailed(LockError): - """Lock file creation failed for some other reason. - - >>> try: - ... raise LockFailed - ... except LockError: - ... pass - """ - pass - - -class UnlockError(Error): - """ - Base class for errors arising from attempts to release the lock. - - >>> try: - ... raise UnlockError - ... except Error: - ... pass - """ - pass - - -class NotLocked(UnlockError): - """Raised when an attempt is made to unlock an unlocked file. - - >>> try: - ... raise NotLocked - ... except UnlockError: - ... pass - """ - pass - - -class NotMyLock(UnlockError): - """Raised when an attempt is made to unlock a file someone else locked. - - >>> try: - ... raise NotMyLock - ... except UnlockError: - ... pass - """ - pass - - -class _SharedBase(object): - def __init__(self, path): - self.path = path - - def acquire(self, timeout=None): - """ - Acquire the lock. - - * If timeout is omitted (or None), wait forever trying to lock the - file. - - * If timeout > 0, try to acquire the lock for that many seconds. If - the lock period expires and the file is still locked, raise - LockTimeout. - - * If timeout <= 0, raise AlreadyLocked immediately if the file is - already locked. - """ - raise NotImplemented("implement in subclass") - - def release(self): - """ - Release the lock. - - If the file is not locked, raise NotLocked. - """ - raise NotImplemented("implement in subclass") - - def __enter__(self): - """ - Context manager support. - """ - self.acquire() - return self - - def __exit__(self, *_exc): - """ - Context manager support. - """ - self.release() - - def __repr__(self): - return "<%s: %r>" % (self.__class__.__name__, self.path) - - -class LockBase(_SharedBase): - """Base class for platform-specific lock classes.""" - def __init__(self, path, threaded=True, timeout=None): - """ - >>> lock = LockBase('somefile') - >>> lock = LockBase('somefile', threaded=False) - """ - super(LockBase, self).__init__(path) - self.lock_file = os.path.abspath(path) + ".lock" - self.hostname = socket.gethostname() - self.pid = os.getpid() - if threaded: - t = threading.current_thread() - # Thread objects in Python 2.4 and earlier do not have ident - # attrs. Worm around that. - ident = getattr(t, "ident", hash(t)) - self.tname = "-%x" % (ident & 0xffffffff) - else: - self.tname = "" - dirname = os.path.dirname(self.lock_file) - - # unique name is mostly about the current process, but must - # also contain the path -- otherwise, two adjacent locked - # files conflict (one file gets locked, creating lock-file and - # unique file, the other one gets locked, creating lock-file - # and overwriting the already existing lock-file, then one - # gets unlocked, deleting both lock-file and unique file, - # finally the last lock errors out upon releasing. - self.unique_name = os.path.join(dirname, - "%s%s.%s%s" % (self.hostname, - self.tname, - self.pid, - hash(self.path))) - self.timeout = timeout - - def is_locked(self): - """ - Tell whether or not the file is locked. - """ - raise NotImplemented("implement in subclass") - - def i_am_locking(self): - """ - Return True if this object is locking the file. - """ - raise NotImplemented("implement in subclass") - - def break_lock(self): - """ - Remove a lock. Useful if a locking thread failed to unlock. - """ - raise NotImplemented("implement in subclass") - - def __repr__(self): - return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name, - self.path) - - -def _fl_helper(cls, mod, *args, **kwds): - warnings.warn("Import from %s module instead of lockfile package" % mod, - DeprecationWarning, stacklevel=2) - # This is a bit funky, but it's only for awhile. The way the unit tests - # are constructed this function winds up as an unbound method, so it - # actually takes three args, not two. We want to toss out self. - if not isinstance(args[0], str): - # We are testing, avoid the first arg - args = args[1:] - if len(args) == 1 and not kwds: - kwds["threaded"] = True - return cls(*args, **kwds) - - -def LinkFileLock(*args, **kwds): - """Factory function provided for backwards compatibility. - - Do not use in new code. Instead, import LinkLockFile from the - lockfile.linklockfile module. - """ - from . import linklockfile - return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile", - *args, **kwds) - - -def MkdirFileLock(*args, **kwds): - """Factory function provided for backwards compatibility. - - Do not use in new code. Instead, import MkdirLockFile from the - lockfile.mkdirlockfile module. - """ - from . import mkdirlockfile - return _fl_helper(mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile", - *args, **kwds) - - -def SQLiteFileLock(*args, **kwds): - """Factory function provided for backwards compatibility. - - Do not use in new code. Instead, import SQLiteLockFile from the - lockfile.mkdirlockfile module. - """ - from . import sqlitelockfile - return _fl_helper(sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile", - *args, **kwds) - - -def locked(path, timeout=None): - """Decorator which enables locks for decorated function. - - Arguments: - - path: path for lockfile. - - timeout (optional): Timeout for acquiring lock. - - Usage: - @locked('/var/run/myname', timeout=0) - def myname(...): - ... - """ - def decor(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - lock = FileLock(path, timeout=timeout) - lock.acquire() - try: - return func(*args, **kwargs) - finally: - lock.release() - return wrapper - return decor - - -if hasattr(os, "link"): - from . import linklockfile as _llf - LockFile = _llf.LinkLockFile -else: - from . import mkdirlockfile as _mlf - LockFile = _mlf.MkdirLockFile - -FileLock = LockFile diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/linklockfile.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/linklockfile.py deleted file mode 100644 index 2ca9be0..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/linklockfile.py +++ /dev/null @@ -1,73 +0,0 @@ -from __future__ import absolute_import - -import time -import os - -from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, - AlreadyLocked) - - -class LinkLockFile(LockBase): - """Lock access to a file using atomic property of link(2). - - >>> lock = LinkLockFile('somefile') - >>> lock = LinkLockFile('somefile', threaded=False) - """ - - def acquire(self, timeout=None): - try: - open(self.unique_name, "wb").close() - except IOError: - raise LockFailed("failed to create %s" % self.unique_name) - - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - while True: - # Try and create a hard link to it. - try: - os.link(self.unique_name, self.lock_file) - except OSError: - # Link creation failed. Maybe we've double-locked? - nlinks = os.stat(self.unique_name).st_nlink - if nlinks == 2: - # The original link plus the one I created == 2. We're - # good to go. - return - else: - # Otherwise the lock creation failed. - if timeout is not None and time.time() > end_time: - os.unlink(self.unique_name) - if timeout > 0: - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - raise AlreadyLocked("%s is already locked" % - self.path) - time.sleep(timeout is not None and timeout / 10 or 0.1) - else: - # Link creation succeeded. We're good to go. - return - - def release(self): - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - elif not os.path.exists(self.unique_name): - raise NotMyLock("%s is locked, but not by me" % self.path) - os.unlink(self.unique_name) - os.unlink(self.lock_file) - - def is_locked(self): - return os.path.exists(self.lock_file) - - def i_am_locking(self): - return (self.is_locked() and - os.path.exists(self.unique_name) and - os.stat(self.unique_name).st_nlink == 2) - - def break_lock(self): - if os.path.exists(self.lock_file): - os.unlink(self.lock_file) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/mkdirlockfile.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/mkdirlockfile.py deleted file mode 100644 index 05a8c96..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/mkdirlockfile.py +++ /dev/null @@ -1,84 +0,0 @@ -from __future__ import absolute_import, division - -import time -import os -import sys -import errno - -from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, - AlreadyLocked) - - -class MkdirLockFile(LockBase): - """Lock file by creating a directory.""" - def __init__(self, path, threaded=True, timeout=None): - """ - >>> lock = MkdirLockFile('somefile') - >>> lock = MkdirLockFile('somefile', threaded=False) - """ - LockBase.__init__(self, path, threaded, timeout) - # Lock file itself is a directory. Place the unique file name into - # it. - self.unique_name = os.path.join(self.lock_file, - "%s.%s%s" % (self.hostname, - self.tname, - self.pid)) - - def acquire(self, timeout=None): - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - if timeout is None: - wait = 0.1 - else: - wait = max(0, timeout / 10) - - while True: - try: - os.mkdir(self.lock_file) - except OSError: - err = sys.exc_info()[1] - if err.errno == errno.EEXIST: - # Already locked. - if os.path.exists(self.unique_name): - # Already locked by me. - return - if timeout is not None and time.time() > end_time: - if timeout > 0: - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - # Someone else has the lock. - raise AlreadyLocked("%s is already locked" % - self.path) - time.sleep(wait) - else: - # Couldn't create the lock for some other reason - raise LockFailed("failed to create %s" % self.lock_file) - else: - open(self.unique_name, "wb").close() - return - - def release(self): - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - elif not os.path.exists(self.unique_name): - raise NotMyLock("%s is locked, but not by me" % self.path) - os.unlink(self.unique_name) - os.rmdir(self.lock_file) - - def is_locked(self): - return os.path.exists(self.lock_file) - - def i_am_locking(self): - return (self.is_locked() and - os.path.exists(self.unique_name)) - - def break_lock(self): - if os.path.exists(self.lock_file): - for name in os.listdir(self.lock_file): - os.unlink(os.path.join(self.lock_file, name)) - os.rmdir(self.lock_file) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/pidlockfile.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/pidlockfile.py deleted file mode 100644 index 069e85b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/pidlockfile.py +++ /dev/null @@ -1,190 +0,0 @@ -# -*- coding: utf-8 -*- - -# pidlockfile.py -# -# Copyright © 2008–2009 Ben Finney <ben+python@benfinney.id.au> -# -# This is free software: you may copy, modify, and/or distribute this work -# under the terms of the Python Software Foundation License, version 2 or -# later as published by the Python Software Foundation. -# No warranty expressed or implied. See the file LICENSE.PSF-2 for details. - -""" Lockfile behaviour implemented via Unix PID files. - """ - -from __future__ import absolute_import - -import errno -import os -import time - -from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, - LockTimeout) - - -class PIDLockFile(LockBase): - """ Lockfile implemented as a Unix PID file. - - The lock file is a normal file named by the attribute `path`. - A lock's PID file contains a single line of text, containing - the process ID (PID) of the process that acquired the lock. - - >>> lock = PIDLockFile('somefile') - >>> lock = PIDLockFile('somefile') - """ - - def __init__(self, path, threaded=False, timeout=None): - # pid lockfiles don't support threaded operation, so always force - # False as the threaded arg. - LockBase.__init__(self, path, False, timeout) - self.unique_name = self.path - - def read_pid(self): - """ Get the PID from the lock file. - """ - return read_pid_from_pidfile(self.path) - - def is_locked(self): - """ Test if the lock is currently held. - - The lock is held if the PID file for this lock exists. - - """ - return os.path.exists(self.path) - - def i_am_locking(self): - """ Test if the lock is held by the current process. - - Returns ``True`` if the current process ID matches the - number stored in the PID file. - """ - return self.is_locked() and os.getpid() == self.read_pid() - - def acquire(self, timeout=None): - """ Acquire the lock. - - Creates the PID file for this lock, or raises an error if - the lock could not be acquired. - """ - - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - while True: - try: - write_pid_to_pidfile(self.path) - except OSError as exc: - if exc.errno == errno.EEXIST: - # The lock creation failed. Maybe sleep a bit. - if time.time() > end_time: - if timeout is not None and timeout > 0: - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - raise AlreadyLocked("%s is already locked" % - self.path) - time.sleep(timeout is not None and timeout / 10 or 0.1) - else: - raise LockFailed("failed to create %s" % self.path) - else: - return - - def release(self): - """ Release the lock. - - Removes the PID file to release the lock, or raises an - error if the current process does not hold the lock. - - """ - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - if not self.i_am_locking(): - raise NotMyLock("%s is locked, but not by me" % self.path) - remove_existing_pidfile(self.path) - - def break_lock(self): - """ Break an existing lock. - - Removes the PID file if it already exists, otherwise does - nothing. - - """ - remove_existing_pidfile(self.path) - - -def read_pid_from_pidfile(pidfile_path): - """ Read the PID recorded in the named PID file. - - Read and return the numeric PID recorded as text in the named - PID file. If the PID file cannot be read, or if the content is - not a valid PID, return ``None``. - - """ - pid = None - try: - pidfile = open(pidfile_path, 'r') - except IOError: - pass - else: - # According to the FHS 2.3 section on PID files in /var/run: - # - # The file must consist of the process identifier in - # ASCII-encoded decimal, followed by a newline character. - # - # Programs that read PID files should be somewhat flexible - # in what they accept; i.e., they should ignore extra - # whitespace, leading zeroes, absence of the trailing - # newline, or additional lines in the PID file. - - line = pidfile.readline().strip() - try: - pid = int(line) - except ValueError: - pass - pidfile.close() - - return pid - - -def write_pid_to_pidfile(pidfile_path): - """ Write the PID in the named PID file. - - Get the numeric process ID (“PID”) of the current process - and write it to the named file as a line of text. - - """ - open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY) - open_mode = 0o644 - pidfile_fd = os.open(pidfile_path, open_flags, open_mode) - pidfile = os.fdopen(pidfile_fd, 'w') - - # According to the FHS 2.3 section on PID files in /var/run: - # - # The file must consist of the process identifier in - # ASCII-encoded decimal, followed by a newline character. For - # example, if crond was process number 25, /var/run/crond.pid - # would contain three characters: two, five, and newline. - - pid = os.getpid() - pidfile.write("%s\n" % pid) - pidfile.close() - - -def remove_existing_pidfile(pidfile_path): - """ Remove the named PID file if it exists. - - Removing a PID file that doesn't already exist puts us in the - desired state, so we ignore the condition if the file does not - exist. - - """ - try: - os.remove(pidfile_path) - except OSError as exc: - if exc.errno == errno.ENOENT: - pass - else: - raise diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/sqlitelockfile.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/sqlitelockfile.py deleted file mode 100644 index f997e24..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/sqlitelockfile.py +++ /dev/null @@ -1,156 +0,0 @@ -from __future__ import absolute_import, division - -import time -import os - -try: - unicode -except NameError: - unicode = str - -from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked - - -class SQLiteLockFile(LockBase): - "Demonstrate SQL-based locking." - - testdb = None - - def __init__(self, path, threaded=True, timeout=None): - """ - >>> lock = SQLiteLockFile('somefile') - >>> lock = SQLiteLockFile('somefile', threaded=False) - """ - LockBase.__init__(self, path, threaded, timeout) - self.lock_file = unicode(self.lock_file) - self.unique_name = unicode(self.unique_name) - - if SQLiteLockFile.testdb is None: - import tempfile - _fd, testdb = tempfile.mkstemp() - os.close(_fd) - os.unlink(testdb) - del _fd, tempfile - SQLiteLockFile.testdb = testdb - - import sqlite3 - self.connection = sqlite3.connect(SQLiteLockFile.testdb) - - c = self.connection.cursor() - try: - c.execute("create table locks" - "(" - " lock_file varchar(32)," - " unique_name varchar(32)" - ")") - except sqlite3.OperationalError: - pass - else: - self.connection.commit() - import atexit - atexit.register(os.unlink, SQLiteLockFile.testdb) - - def acquire(self, timeout=None): - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - if timeout is None: - wait = 0.1 - elif timeout <= 0: - wait = 0 - else: - wait = timeout / 10 - - cursor = self.connection.cursor() - - while True: - if not self.is_locked(): - # Not locked. Try to lock it. - cursor.execute("insert into locks" - " (lock_file, unique_name)" - " values" - " (?, ?)", - (self.lock_file, self.unique_name)) - self.connection.commit() - - # Check to see if we are the only lock holder. - cursor.execute("select * from locks" - " where unique_name = ?", - (self.unique_name,)) - rows = cursor.fetchall() - if len(rows) > 1: - # Nope. Someone else got there. Remove our lock. - cursor.execute("delete from locks" - " where unique_name = ?", - (self.unique_name,)) - self.connection.commit() - else: - # Yup. We're done, so go home. - return - else: - # Check to see if we are the only lock holder. - cursor.execute("select * from locks" - " where unique_name = ?", - (self.unique_name,)) - rows = cursor.fetchall() - if len(rows) == 1: - # We're the locker, so go home. - return - - # Maybe we should wait a bit longer. - if timeout is not None and time.time() > end_time: - if timeout > 0: - # No more waiting. - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - # Someone else has the lock and we are impatient.. - raise AlreadyLocked("%s is already locked" % self.path) - - # Well, okay. We'll give it a bit longer. - time.sleep(wait) - - def release(self): - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - if not self.i_am_locking(): - raise NotMyLock("%s is locked, but not by me (by %s)" % - (self.unique_name, self._who_is_locking())) - cursor = self.connection.cursor() - cursor.execute("delete from locks" - " where unique_name = ?", - (self.unique_name,)) - self.connection.commit() - - def _who_is_locking(self): - cursor = self.connection.cursor() - cursor.execute("select unique_name from locks" - " where lock_file = ?", - (self.lock_file,)) - return cursor.fetchone()[0] - - def is_locked(self): - cursor = self.connection.cursor() - cursor.execute("select * from locks" - " where lock_file = ?", - (self.lock_file,)) - rows = cursor.fetchall() - return not not rows - - def i_am_locking(self): - cursor = self.connection.cursor() - cursor.execute("select * from locks" - " where lock_file = ?" - " and unique_name = ?", - (self.lock_file, self.unique_name)) - return not not cursor.fetchall() - - def break_lock(self): - cursor = self.connection.cursor() - cursor.execute("delete from locks" - " where lock_file = ?", - (self.lock_file,)) - self.connection.commit() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/symlinklockfile.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/symlinklockfile.py deleted file mode 100644 index 23b41f5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/lockfile/symlinklockfile.py +++ /dev/null @@ -1,70 +0,0 @@ -from __future__ import absolute_import - -import os -import time - -from . import (LockBase, NotLocked, NotMyLock, LockTimeout, - AlreadyLocked) - - -class SymlinkLockFile(LockBase): - """Lock access to a file using symlink(2).""" - - def __init__(self, path, threaded=True, timeout=None): - # super(SymlinkLockFile).__init(...) - LockBase.__init__(self, path, threaded, timeout) - # split it back! - self.unique_name = os.path.split(self.unique_name)[1] - - def acquire(self, timeout=None): - # Hopefully unnecessary for symlink. - # try: - # open(self.unique_name, "wb").close() - # except IOError: - # raise LockFailed("failed to create %s" % self.unique_name) - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - while True: - # Try and create a symbolic link to it. - try: - os.symlink(self.unique_name, self.lock_file) - except OSError: - # Link creation failed. Maybe we've double-locked? - if self.i_am_locking(): - # Linked to out unique name. Proceed. - return - else: - # Otherwise the lock creation failed. - if timeout is not None and time.time() > end_time: - if timeout > 0: - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - raise AlreadyLocked("%s is already locked" % - self.path) - time.sleep(timeout / 10 if timeout is not None else 0.1) - else: - # Link creation succeeded. We're good to go. - return - - def release(self): - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - elif not self.i_am_locking(): - raise NotMyLock("%s is locked, but not by me" % self.path) - os.unlink(self.lock_file) - - def is_locked(self): - return os.path.islink(self.lock_file) - - def i_am_locking(self): - return (os.path.islink(self.lock_file) - and os.readlink(self.lock_file) == self.unique_name) - - def break_lock(self): - if os.path.islink(self.lock_file): # exists && link - os.unlink(self.lock_file) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/__init__.py deleted file mode 100644 index 2afca5a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/__init__.py +++ /dev/null @@ -1,66 +0,0 @@ -# coding: utf-8 -from pip._vendor.msgpack._version import version -from pip._vendor.msgpack.exceptions import * - -from collections import namedtuple - - -class ExtType(namedtuple('ExtType', 'code data')): - """ExtType represents ext type in msgpack.""" - def __new__(cls, code, data): - if not isinstance(code, int): - raise TypeError("code must be int") - if not isinstance(data, bytes): - raise TypeError("data must be bytes") - if not 0 <= code <= 127: - raise ValueError("code must be 0~127") - return super(ExtType, cls).__new__(cls, code, data) - - -import os -if os.environ.get('MSGPACK_PUREPYTHON'): - from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker -else: - try: - from pip._vendor.msgpack._packer import Packer - from pip._vendor.msgpack._unpacker import unpackb, Unpacker - except ImportError: - from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker - - -def pack(o, stream, **kwargs): - """ - Pack object `o` and write it to `stream` - - See :class:`Packer` for options. - """ - packer = Packer(**kwargs) - stream.write(packer.pack(o)) - - -def packb(o, **kwargs): - """ - Pack object `o` and return packed bytes - - See :class:`Packer` for options. - """ - return Packer(**kwargs).pack(o) - - -def unpack(stream, **kwargs): - """ - Unpack an object from `stream`. - - Raises `ExtraData` when `stream` contains extra bytes. - See :class:`Unpacker` for options. - """ - data = stream.read() - return unpackb(data, **kwargs) - - -# alias for compatibility to simplejson/marshal/pickle. -load = unpack -loads = unpackb - -dump = pack -dumps = packb diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/_version.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/_version.py deleted file mode 100644 index d28f0de..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/_version.py +++ /dev/null @@ -1 +0,0 @@ -version = (0, 5, 6) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/exceptions.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/exceptions.py deleted file mode 100644 index 9766881..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/exceptions.py +++ /dev/null @@ -1,41 +0,0 @@ -class UnpackException(Exception): - """Deprecated. Use Exception instead to catch all exception during unpacking.""" - - -class BufferFull(UnpackException): - pass - - -class OutOfData(UnpackException): - pass - - -class UnpackValueError(UnpackException, ValueError): - """Deprecated. Use ValueError instead.""" - - -class ExtraData(UnpackValueError): - def __init__(self, unpacked, extra): - self.unpacked = unpacked - self.extra = extra - - def __str__(self): - return "unpack(b) received extra data." - - -class PackException(Exception): - """Deprecated. Use Exception instead to catch all exception during packing.""" - - -class PackValueError(PackException, ValueError): - """PackValueError is raised when type of input data is supported but it's value is unsupported. - - Deprecated. Use ValueError instead. - """ - - -class PackOverflowError(PackValueError, OverflowError): - """PackOverflowError is raised when integer value is out of range of msgpack support [-2**31, 2**32). - - Deprecated. Use ValueError instead. - """ diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/fallback.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/fallback.py deleted file mode 100644 index 9418421..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/msgpack/fallback.py +++ /dev/null @@ -1,977 +0,0 @@ -"""Fallback pure Python implementation of msgpack""" - -import sys -import struct -import warnings - -if sys.version_info[0] == 3: - PY3 = True - int_types = int - Unicode = str - xrange = range - def dict_iteritems(d): - return d.items() -else: - PY3 = False - int_types = (int, long) - Unicode = unicode - def dict_iteritems(d): - return d.iteritems() - - -if hasattr(sys, 'pypy_version_info'): - # cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own - # StringBuilder is fastest. - from __pypy__ import newlist_hint - try: - from __pypy__.builders import BytesBuilder as StringBuilder - except ImportError: - from __pypy__.builders import StringBuilder - USING_STRINGBUILDER = True - class StringIO(object): - def __init__(self, s=b''): - if s: - self.builder = StringBuilder(len(s)) - self.builder.append(s) - else: - self.builder = StringBuilder() - def write(self, s): - if isinstance(s, memoryview): - s = s.tobytes() - elif isinstance(s, bytearray): - s = bytes(s) - self.builder.append(s) - def getvalue(self): - return self.builder.build() -else: - USING_STRINGBUILDER = False - from io import BytesIO as StringIO - newlist_hint = lambda size: [] - - -from pip._vendor.msgpack.exceptions import ( - BufferFull, - OutOfData, - UnpackValueError, - PackValueError, - PackOverflowError, - ExtraData) - -from pip._vendor.msgpack import ExtType - - -EX_SKIP = 0 -EX_CONSTRUCT = 1 -EX_READ_ARRAY_HEADER = 2 -EX_READ_MAP_HEADER = 3 - -TYPE_IMMEDIATE = 0 -TYPE_ARRAY = 1 -TYPE_MAP = 2 -TYPE_RAW = 3 -TYPE_BIN = 4 -TYPE_EXT = 5 - -DEFAULT_RECURSE_LIMIT = 511 - - -def _check_type_strict(obj, t, type=type, tuple=tuple): - if type(t) is tuple: - return type(obj) in t - else: - return type(obj) is t - - -def _get_data_from_buffer(obj): - try: - view = memoryview(obj) - except TypeError: - # try to use legacy buffer protocol if 2.7, otherwise re-raise - if not PY3: - view = memoryview(buffer(obj)) - warnings.warn("using old buffer interface to unpack %s; " - "this leads to unpacking errors if slicing is used and " - "will be removed in a future version" % type(obj), - RuntimeWarning) - else: - raise - if view.itemsize != 1: - raise ValueError("cannot unpack from multi-byte object") - return view - - -def unpack(stream, **kwargs): - warnings.warn( - "Direct calling implementation's unpack() is deprecated, Use msgpack.unpack() or unpackb() instead.", - PendingDeprecationWarning) - data = stream.read() - return unpackb(data, **kwargs) - - -def unpackb(packed, **kwargs): - """ - Unpack an object from `packed`. - - Raises `ExtraData` when `packed` contains extra bytes. - See :class:`Unpacker` for options. - """ - unpacker = Unpacker(None, **kwargs) - unpacker.feed(packed) - try: - ret = unpacker._unpack() - except OutOfData: - raise UnpackValueError("Data is not enough.") - if unpacker._got_extradata(): - raise ExtraData(ret, unpacker._get_extradata()) - return ret - - -class Unpacker(object): - """Streaming unpacker. - - arguments: - - :param file_like: - File-like object having `.read(n)` method. - If specified, unpacker reads serialized data from it and :meth:`feed()` is not usable. - - :param int read_size: - Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`) - - :param bool use_list: - If true, unpack msgpack array to Python list. - Otherwise, unpack to Python tuple. (default: True) - - :param bool raw: - If true, unpack msgpack raw to Python bytes (default). - Otherwise, unpack to Python str (or unicode on Python 2) by decoding - with UTF-8 encoding (recommended). - Currently, the default is true, but it will be changed to false in - near future. So you must specify it explicitly for keeping backward - compatibility. - - *encoding* option which is deprecated overrides this option. - - :param callable object_hook: - When specified, it should be callable. - Unpacker calls it with a dict argument after unpacking msgpack map. - (See also simplejson) - - :param callable object_pairs_hook: - When specified, it should be callable. - Unpacker calls it with a list of key-value pairs after unpacking msgpack map. - (See also simplejson) - - :param str encoding: - Encoding used for decoding msgpack raw. - If it is None (default), msgpack raw is deserialized to Python bytes. - - :param str unicode_errors: - (deprecated) Used for decoding msgpack raw with *encoding*. - (default: `'strict'`) - - :param int max_buffer_size: - Limits size of data waiting unpacked. 0 means system's INT_MAX (default). - Raises `BufferFull` exception when it is insufficient. - You should set this parameter when unpacking data from untrusted source. - - :param int max_str_len: - Limits max length of str. (default: 2**31-1) - - :param int max_bin_len: - Limits max length of bin. (default: 2**31-1) - - :param int max_array_len: - Limits max length of array. (default: 2**31-1) - - :param int max_map_len: - Limits max length of map. (default: 2**31-1) - - - example of streaming deserialize from file-like object:: - - unpacker = Unpacker(file_like, raw=False) - for o in unpacker: - process(o) - - example of streaming deserialize from socket:: - - unpacker = Unpacker(raw=False) - while True: - buf = sock.recv(1024**2) - if not buf: - break - unpacker.feed(buf) - for o in unpacker: - process(o) - """ - - def __init__(self, file_like=None, read_size=0, use_list=True, raw=True, - object_hook=None, object_pairs_hook=None, list_hook=None, - encoding=None, unicode_errors=None, max_buffer_size=0, - ext_hook=ExtType, - max_str_len=2147483647, # 2**32-1 - max_bin_len=2147483647, - max_array_len=2147483647, - max_map_len=2147483647, - max_ext_len=2147483647): - - if encoding is not None: - warnings.warn( - "encoding is deprecated, Use raw=False instead.", - PendingDeprecationWarning) - - if unicode_errors is None: - unicode_errors = 'strict' - - if file_like is None: - self._feeding = True - else: - if not callable(file_like.read): - raise TypeError("`file_like.read` must be callable") - self.file_like = file_like - self._feeding = False - - #: array of bytes fed. - self._buffer = bytearray() - # Some very old pythons don't support `struct.unpack_from()` with a - # `bytearray`. So we wrap it in a `buffer()` there. - if sys.version_info < (2, 7, 6): - self._buffer_view = buffer(self._buffer) - else: - self._buffer_view = self._buffer - #: Which position we currently reads - self._buff_i = 0 - - # When Unpacker is used as an iterable, between the calls to next(), - # the buffer is not "consumed" completely, for efficiency sake. - # Instead, it is done sloppily. To make sure we raise BufferFull at - # the correct moments, we have to keep track of how sloppy we were. - # Furthermore, when the buffer is incomplete (that is: in the case - # we raise an OutOfData) we need to rollback the buffer to the correct - # state, which _buf_checkpoint records. - self._buf_checkpoint = 0 - - self._max_buffer_size = max_buffer_size or 2**31-1 - if read_size > self._max_buffer_size: - raise ValueError("read_size must be smaller than max_buffer_size") - self._read_size = read_size or min(self._max_buffer_size, 16*1024) - self._raw = bool(raw) - self._encoding = encoding - self._unicode_errors = unicode_errors - self._use_list = use_list - self._list_hook = list_hook - self._object_hook = object_hook - self._object_pairs_hook = object_pairs_hook - self._ext_hook = ext_hook - self._max_str_len = max_str_len - self._max_bin_len = max_bin_len - self._max_array_len = max_array_len - self._max_map_len = max_map_len - self._max_ext_len = max_ext_len - self._stream_offset = 0 - - if list_hook is not None and not callable(list_hook): - raise TypeError('`list_hook` is not callable') - if object_hook is not None and not callable(object_hook): - raise TypeError('`object_hook` is not callable') - if object_pairs_hook is not None and not callable(object_pairs_hook): - raise TypeError('`object_pairs_hook` is not callable') - if object_hook is not None and object_pairs_hook is not None: - raise TypeError("object_pairs_hook and object_hook are mutually " - "exclusive") - if not callable(ext_hook): - raise TypeError("`ext_hook` is not callable") - - def feed(self, next_bytes): - assert self._feeding - view = _get_data_from_buffer(next_bytes) - if (len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size): - raise BufferFull - - # Strip buffer before checkpoint before reading file. - if self._buf_checkpoint > 0: - del self._buffer[:self._buf_checkpoint] - self._buff_i -= self._buf_checkpoint - self._buf_checkpoint = 0 - - self._buffer += view - - def _consume(self): - """ Gets rid of the used parts of the buffer. """ - self._stream_offset += self._buff_i - self._buf_checkpoint - self._buf_checkpoint = self._buff_i - - def _got_extradata(self): - return self._buff_i < len(self._buffer) - - def _get_extradata(self): - return self._buffer[self._buff_i:] - - def read_bytes(self, n): - return self._read(n) - - def _read(self, n): - # (int) -> bytearray - self._reserve(n) - i = self._buff_i - self._buff_i = i+n - return self._buffer[i:i+n] - - def _reserve(self, n): - remain_bytes = len(self._buffer) - self._buff_i - n - - # Fast path: buffer has n bytes already - if remain_bytes >= 0: - return - - if self._feeding: - self._buff_i = self._buf_checkpoint - raise OutOfData - - # Strip buffer before checkpoint before reading file. - if self._buf_checkpoint > 0: - del self._buffer[:self._buf_checkpoint] - self._buff_i -= self._buf_checkpoint - self._buf_checkpoint = 0 - - # Read from file - remain_bytes = -remain_bytes - while remain_bytes > 0: - to_read_bytes = max(self._read_size, remain_bytes) - read_data = self.file_like.read(to_read_bytes) - if not read_data: - break - assert isinstance(read_data, bytes) - self._buffer += read_data - remain_bytes -= len(read_data) - - if len(self._buffer) < n + self._buff_i: - self._buff_i = 0 # rollback - raise OutOfData - - def _read_header(self, execute=EX_CONSTRUCT): - typ = TYPE_IMMEDIATE - n = 0 - obj = None - self._reserve(1) - b = self._buffer[self._buff_i] - self._buff_i += 1 - if b & 0b10000000 == 0: - obj = b - elif b & 0b11100000 == 0b11100000: - obj = -1 - (b ^ 0xff) - elif b & 0b11100000 == 0b10100000: - n = b & 0b00011111 - typ = TYPE_RAW - if n > self._max_str_len: - raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) - obj = self._read(n) - elif b & 0b11110000 == 0b10010000: - n = b & 0b00001111 - typ = TYPE_ARRAY - if n > self._max_array_len: - raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) - elif b & 0b11110000 == 0b10000000: - n = b & 0b00001111 - typ = TYPE_MAP - if n > self._max_map_len: - raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) - elif b == 0xc0: - obj = None - elif b == 0xc2: - obj = False - elif b == 0xc3: - obj = True - elif b == 0xc4: - typ = TYPE_BIN - self._reserve(1) - n = self._buffer[self._buff_i] - self._buff_i += 1 - if n > self._max_bin_len: - raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) - obj = self._read(n) - elif b == 0xc5: - typ = TYPE_BIN - self._reserve(2) - n = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] - self._buff_i += 2 - if n > self._max_bin_len: - raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) - obj = self._read(n) - elif b == 0xc6: - typ = TYPE_BIN - self._reserve(4) - n = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] - self._buff_i += 4 - if n > self._max_bin_len: - raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) - obj = self._read(n) - elif b == 0xc7: # ext 8 - typ = TYPE_EXT - self._reserve(2) - L, n = struct.unpack_from('Bb', self._buffer_view, self._buff_i) - self._buff_i += 2 - if L > self._max_ext_len: - raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) - obj = self._read(L) - elif b == 0xc8: # ext 16 - typ = TYPE_EXT - self._reserve(3) - L, n = struct.unpack_from('>Hb', self._buffer_view, self._buff_i) - self._buff_i += 3 - if L > self._max_ext_len: - raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) - obj = self._read(L) - elif b == 0xc9: # ext 32 - typ = TYPE_EXT - self._reserve(5) - L, n = struct.unpack_from('>Ib', self._buffer_view, self._buff_i) - self._buff_i += 5 - if L > self._max_ext_len: - raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) - obj = self._read(L) - elif b == 0xca: - self._reserve(4) - obj = struct.unpack_from(">f", self._buffer_view, self._buff_i)[0] - self._buff_i += 4 - elif b == 0xcb: - self._reserve(8) - obj = struct.unpack_from(">d", self._buffer_view, self._buff_i)[0] - self._buff_i += 8 - elif b == 0xcc: - self._reserve(1) - obj = self._buffer[self._buff_i] - self._buff_i += 1 - elif b == 0xcd: - self._reserve(2) - obj = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] - self._buff_i += 2 - elif b == 0xce: - self._reserve(4) - obj = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] - self._buff_i += 4 - elif b == 0xcf: - self._reserve(8) - obj = struct.unpack_from(">Q", self._buffer_view, self._buff_i)[0] - self._buff_i += 8 - elif b == 0xd0: - self._reserve(1) - obj = struct.unpack_from("b", self._buffer_view, self._buff_i)[0] - self._buff_i += 1 - elif b == 0xd1: - self._reserve(2) - obj = struct.unpack_from(">h", self._buffer_view, self._buff_i)[0] - self._buff_i += 2 - elif b == 0xd2: - self._reserve(4) - obj = struct.unpack_from(">i", self._buffer_view, self._buff_i)[0] - self._buff_i += 4 - elif b == 0xd3: - self._reserve(8) - obj = struct.unpack_from(">q", self._buffer_view, self._buff_i)[0] - self._buff_i += 8 - elif b == 0xd4: # fixext 1 - typ = TYPE_EXT - if self._max_ext_len < 1: - raise UnpackValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) - self._reserve(2) - n, obj = struct.unpack_from("b1s", self._buffer_view, self._buff_i) - self._buff_i += 2 - elif b == 0xd5: # fixext 2 - typ = TYPE_EXT - if self._max_ext_len < 2: - raise UnpackValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) - self._reserve(3) - n, obj = struct.unpack_from("b2s", self._buffer_view, self._buff_i) - self._buff_i += 3 - elif b == 0xd6: # fixext 4 - typ = TYPE_EXT - if self._max_ext_len < 4: - raise UnpackValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) - self._reserve(5) - n, obj = struct.unpack_from("b4s", self._buffer_view, self._buff_i) - self._buff_i += 5 - elif b == 0xd7: # fixext 8 - typ = TYPE_EXT - if self._max_ext_len < 8: - raise UnpackValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) - self._reserve(9) - n, obj = struct.unpack_from("b8s", self._buffer_view, self._buff_i) - self._buff_i += 9 - elif b == 0xd8: # fixext 16 - typ = TYPE_EXT - if self._max_ext_len < 16: - raise UnpackValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) - self._reserve(17) - n, obj = struct.unpack_from("b16s", self._buffer_view, self._buff_i) - self._buff_i += 17 - elif b == 0xd9: - typ = TYPE_RAW - self._reserve(1) - n = self._buffer[self._buff_i] - self._buff_i += 1 - if n > self._max_str_len: - raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) - obj = self._read(n) - elif b == 0xda: - typ = TYPE_RAW - self._reserve(2) - n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) - self._buff_i += 2 - if n > self._max_str_len: - raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) - obj = self._read(n) - elif b == 0xdb: - typ = TYPE_RAW - self._reserve(4) - n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) - self._buff_i += 4 - if n > self._max_str_len: - raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) - obj = self._read(n) - elif b == 0xdc: - typ = TYPE_ARRAY - self._reserve(2) - n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) - self._buff_i += 2 - if n > self._max_array_len: - raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) - elif b == 0xdd: - typ = TYPE_ARRAY - self._reserve(4) - n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) - self._buff_i += 4 - if n > self._max_array_len: - raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) - elif b == 0xde: - self._reserve(2) - n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) - self._buff_i += 2 - if n > self._max_map_len: - raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) - typ = TYPE_MAP - elif b == 0xdf: - self._reserve(4) - n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) - self._buff_i += 4 - if n > self._max_map_len: - raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) - typ = TYPE_MAP - else: - raise UnpackValueError("Unknown header: 0x%x" % b) - return typ, n, obj - - def _unpack(self, execute=EX_CONSTRUCT): - typ, n, obj = self._read_header(execute) - - if execute == EX_READ_ARRAY_HEADER: - if typ != TYPE_ARRAY: - raise UnpackValueError("Expected array") - return n - if execute == EX_READ_MAP_HEADER: - if typ != TYPE_MAP: - raise UnpackValueError("Expected map") - return n - # TODO should we eliminate the recursion? - if typ == TYPE_ARRAY: - if execute == EX_SKIP: - for i in xrange(n): - # TODO check whether we need to call `list_hook` - self._unpack(EX_SKIP) - return - ret = newlist_hint(n) - for i in xrange(n): - ret.append(self._unpack(EX_CONSTRUCT)) - if self._list_hook is not None: - ret = self._list_hook(ret) - # TODO is the interaction between `list_hook` and `use_list` ok? - return ret if self._use_list else tuple(ret) - if typ == TYPE_MAP: - if execute == EX_SKIP: - for i in xrange(n): - # TODO check whether we need to call hooks - self._unpack(EX_SKIP) - self._unpack(EX_SKIP) - return - if self._object_pairs_hook is not None: - ret = self._object_pairs_hook( - (self._unpack(EX_CONSTRUCT), - self._unpack(EX_CONSTRUCT)) - for _ in xrange(n)) - else: - ret = {} - for _ in xrange(n): - key = self._unpack(EX_CONSTRUCT) - ret[key] = self._unpack(EX_CONSTRUCT) - if self._object_hook is not None: - ret = self._object_hook(ret) - return ret - if execute == EX_SKIP: - return - if typ == TYPE_RAW: - if self._encoding is not None: - obj = obj.decode(self._encoding, self._unicode_errors) - elif self._raw: - obj = bytes(obj) - else: - obj = obj.decode('utf_8') - return obj - if typ == TYPE_EXT: - return self._ext_hook(n, bytes(obj)) - if typ == TYPE_BIN: - return bytes(obj) - assert typ == TYPE_IMMEDIATE - return obj - - def __iter__(self): - return self - - def __next__(self): - try: - ret = self._unpack(EX_CONSTRUCT) - self._consume() - return ret - except OutOfData: - self._consume() - raise StopIteration - - next = __next__ - - def skip(self, write_bytes=None): - self._unpack(EX_SKIP) - if write_bytes is not None: - warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) - write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) - self._consume() - - def unpack(self, write_bytes=None): - ret = self._unpack(EX_CONSTRUCT) - if write_bytes is not None: - warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) - write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) - self._consume() - return ret - - def read_array_header(self, write_bytes=None): - ret = self._unpack(EX_READ_ARRAY_HEADER) - if write_bytes is not None: - warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) - write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) - self._consume() - return ret - - def read_map_header(self, write_bytes=None): - ret = self._unpack(EX_READ_MAP_HEADER) - if write_bytes is not None: - warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) - write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) - self._consume() - return ret - - def tell(self): - return self._stream_offset - - -class Packer(object): - """ - MessagePack Packer - - usage: - - packer = Packer() - astream.write(packer.pack(a)) - astream.write(packer.pack(b)) - - Packer's constructor has some keyword arguments: - - :param callable default: - Convert user type to builtin type that Packer supports. - See also simplejson's document. - - :param bool use_single_float: - Use single precision float type for float. (default: False) - - :param bool autoreset: - Reset buffer after each pack and return its content as `bytes`. (default: True). - If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. - - :param bool use_bin_type: - Use bin type introduced in msgpack spec 2.0 for bytes. - It also enables str8 type for unicode. - - :param bool strict_types: - If set to true, types will be checked to be exact. Derived classes - from serializeable types will not be serialized and will be - treated as unsupported type and forwarded to default. - Additionally tuples will not be serialized as lists. - This is useful when trying to implement accurate serialization - for python types. - - :param str encoding: - (deprecated) Convert unicode to bytes with this encoding. (default: 'utf-8') - - :param str unicode_errors: - Error handler for encoding unicode. (default: 'strict') - """ - def __init__(self, default=None, encoding=None, unicode_errors=None, - use_single_float=False, autoreset=True, use_bin_type=False, - strict_types=False): - if encoding is None: - encoding = 'utf_8' - else: - warnings.warn( - "encoding is deprecated, Use raw=False instead.", - PendingDeprecationWarning) - - if unicode_errors is None: - unicode_errors = 'strict' - - self._strict_types = strict_types - self._use_float = use_single_float - self._autoreset = autoreset - self._use_bin_type = use_bin_type - self._encoding = encoding - self._unicode_errors = unicode_errors - self._buffer = StringIO() - if default is not None: - if not callable(default): - raise TypeError("default must be callable") - self._default = default - - def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, - check=isinstance, check_type_strict=_check_type_strict): - default_used = False - if self._strict_types: - check = check_type_strict - list_types = list - else: - list_types = (list, tuple) - while True: - if nest_limit < 0: - raise PackValueError("recursion limit exceeded") - if obj is None: - return self._buffer.write(b"\xc0") - if check(obj, bool): - if obj: - return self._buffer.write(b"\xc3") - return self._buffer.write(b"\xc2") - if check(obj, int_types): - if 0 <= obj < 0x80: - return self._buffer.write(struct.pack("B", obj)) - if -0x20 <= obj < 0: - return self._buffer.write(struct.pack("b", obj)) - if 0x80 <= obj <= 0xff: - return self._buffer.write(struct.pack("BB", 0xcc, obj)) - if -0x80 <= obj < 0: - return self._buffer.write(struct.pack(">Bb", 0xd0, obj)) - if 0xff < obj <= 0xffff: - return self._buffer.write(struct.pack(">BH", 0xcd, obj)) - if -0x8000 <= obj < -0x80: - return self._buffer.write(struct.pack(">Bh", 0xd1, obj)) - if 0xffff < obj <= 0xffffffff: - return self._buffer.write(struct.pack(">BI", 0xce, obj)) - if -0x80000000 <= obj < -0x8000: - return self._buffer.write(struct.pack(">Bi", 0xd2, obj)) - if 0xffffffff < obj <= 0xffffffffffffffff: - return self._buffer.write(struct.pack(">BQ", 0xcf, obj)) - if -0x8000000000000000 <= obj < -0x80000000: - return self._buffer.write(struct.pack(">Bq", 0xd3, obj)) - if not default_used and self._default is not None: - obj = self._default(obj) - default_used = True - continue - raise PackOverflowError("Integer value out of range") - if check(obj, (bytes, bytearray)): - n = len(obj) - if n >= 2**32: - raise PackValueError("%s is too large" % type(obj).__name__) - self._pack_bin_header(n) - return self._buffer.write(obj) - if check(obj, Unicode): - if self._encoding is None: - raise TypeError( - "Can't encode unicode string: " - "no encoding is specified") - obj = obj.encode(self._encoding, self._unicode_errors) - n = len(obj) - if n >= 2**32: - raise PackValueError("String is too large") - self._pack_raw_header(n) - return self._buffer.write(obj) - if check(obj, memoryview): - n = len(obj) * obj.itemsize - if n >= 2**32: - raise PackValueError("Memoryview is too large") - self._pack_bin_header(n) - return self._buffer.write(obj) - if check(obj, float): - if self._use_float: - return self._buffer.write(struct.pack(">Bf", 0xca, obj)) - return self._buffer.write(struct.pack(">Bd", 0xcb, obj)) - if check(obj, ExtType): - code = obj.code - data = obj.data - assert isinstance(code, int) - assert isinstance(data, bytes) - L = len(data) - if L == 1: - self._buffer.write(b'\xd4') - elif L == 2: - self._buffer.write(b'\xd5') - elif L == 4: - self._buffer.write(b'\xd6') - elif L == 8: - self._buffer.write(b'\xd7') - elif L == 16: - self._buffer.write(b'\xd8') - elif L <= 0xff: - self._buffer.write(struct.pack(">BB", 0xc7, L)) - elif L <= 0xffff: - self._buffer.write(struct.pack(">BH", 0xc8, L)) - else: - self._buffer.write(struct.pack(">BI", 0xc9, L)) - self._buffer.write(struct.pack("b", code)) - self._buffer.write(data) - return - if check(obj, list_types): - n = len(obj) - self._pack_array_header(n) - for i in xrange(n): - self._pack(obj[i], nest_limit - 1) - return - if check(obj, dict): - return self._pack_map_pairs(len(obj), dict_iteritems(obj), - nest_limit - 1) - if not default_used and self._default is not None: - obj = self._default(obj) - default_used = 1 - continue - raise TypeError("Cannot serialize %r" % (obj, )) - - def pack(self, obj): - try: - self._pack(obj) - except: - self._buffer = StringIO() # force reset - raise - ret = self._buffer.getvalue() - if self._autoreset: - self._buffer = StringIO() - elif USING_STRINGBUILDER: - self._buffer = StringIO(ret) - return ret - - def pack_map_pairs(self, pairs): - self._pack_map_pairs(len(pairs), pairs) - ret = self._buffer.getvalue() - if self._autoreset: - self._buffer = StringIO() - elif USING_STRINGBUILDER: - self._buffer = StringIO(ret) - return ret - - def pack_array_header(self, n): - if n >= 2**32: - raise PackValueError - self._pack_array_header(n) - ret = self._buffer.getvalue() - if self._autoreset: - self._buffer = StringIO() - elif USING_STRINGBUILDER: - self._buffer = StringIO(ret) - return ret - - def pack_map_header(self, n): - if n >= 2**32: - raise PackValueError - self._pack_map_header(n) - ret = self._buffer.getvalue() - if self._autoreset: - self._buffer = StringIO() - elif USING_STRINGBUILDER: - self._buffer = StringIO(ret) - return ret - - def pack_ext_type(self, typecode, data): - if not isinstance(typecode, int): - raise TypeError("typecode must have int type.") - if not 0 <= typecode <= 127: - raise ValueError("typecode should be 0-127") - if not isinstance(data, bytes): - raise TypeError("data must have bytes type") - L = len(data) - if L > 0xffffffff: - raise PackValueError("Too large data") - if L == 1: - self._buffer.write(b'\xd4') - elif L == 2: - self._buffer.write(b'\xd5') - elif L == 4: - self._buffer.write(b'\xd6') - elif L == 8: - self._buffer.write(b'\xd7') - elif L == 16: - self._buffer.write(b'\xd8') - elif L <= 0xff: - self._buffer.write(b'\xc7' + struct.pack('B', L)) - elif L <= 0xffff: - self._buffer.write(b'\xc8' + struct.pack('>H', L)) - else: - self._buffer.write(b'\xc9' + struct.pack('>I', L)) - self._buffer.write(struct.pack('B', typecode)) - self._buffer.write(data) - - def _pack_array_header(self, n): - if n <= 0x0f: - return self._buffer.write(struct.pack('B', 0x90 + n)) - if n <= 0xffff: - return self._buffer.write(struct.pack(">BH", 0xdc, n)) - if n <= 0xffffffff: - return self._buffer.write(struct.pack(">BI", 0xdd, n)) - raise PackValueError("Array is too large") - - def _pack_map_header(self, n): - if n <= 0x0f: - return self._buffer.write(struct.pack('B', 0x80 + n)) - if n <= 0xffff: - return self._buffer.write(struct.pack(">BH", 0xde, n)) - if n <= 0xffffffff: - return self._buffer.write(struct.pack(">BI", 0xdf, n)) - raise PackValueError("Dict is too large") - - def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT): - self._pack_map_header(n) - for (k, v) in pairs: - self._pack(k, nest_limit - 1) - self._pack(v, nest_limit - 1) - - def _pack_raw_header(self, n): - if n <= 0x1f: - self._buffer.write(struct.pack('B', 0xa0 + n)) - elif self._use_bin_type and n <= 0xff: - self._buffer.write(struct.pack('>BB', 0xd9, n)) - elif n <= 0xffff: - self._buffer.write(struct.pack(">BH", 0xda, n)) - elif n <= 0xffffffff: - self._buffer.write(struct.pack(">BI", 0xdb, n)) - else: - raise PackValueError('Raw is too large') - - def _pack_bin_header(self, n): - if not self._use_bin_type: - return self._pack_raw_header(n) - elif n <= 0xff: - return self._buffer.write(struct.pack('>BB', 0xc4, n)) - elif n <= 0xffff: - return self._buffer.write(struct.pack(">BH", 0xc5, n)) - elif n <= 0xffffffff: - return self._buffer.write(struct.pack(">BI", 0xc6, n)) - else: - raise PackValueError('Bin is too large') - - def bytes(self): - return self._buffer.getvalue() - - def reset(self): - self._buffer = StringIO() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/__about__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/__about__.py deleted file mode 100644 index 7481c9e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/__about__.py +++ /dev/null @@ -1,27 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -__all__ = [ - "__title__", - "__summary__", - "__uri__", - "__version__", - "__author__", - "__email__", - "__license__", - "__copyright__", -] - -__title__ = "packaging" -__summary__ = "Core utilities for Python packages" -__uri__ = "https://github.com/pypa/packaging" - -__version__ = "19.0" - -__author__ = "Donald Stufft and individual contributors" -__email__ = "donald@stufft.io" - -__license__ = "BSD or Apache License, Version 2.0" -__copyright__ = "Copyright 2014-2019 %s" % __author__ diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/__init__.py deleted file mode 100644 index a0cf67d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -from .__about__ import ( - __author__, - __copyright__, - __email__, - __license__, - __summary__, - __title__, - __uri__, - __version__, -) - -__all__ = [ - "__title__", - "__summary__", - "__uri__", - "__version__", - "__author__", - "__email__", - "__license__", - "__copyright__", -] diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/_compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/_compat.py deleted file mode 100644 index 25da473..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/_compat.py +++ /dev/null @@ -1,31 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import sys - - -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 - -# flake8: noqa - -if PY3: - string_types = (str,) -else: - string_types = (basestring,) - - -def with_metaclass(meta, *bases): - """ - Create a base class with a metaclass. - """ - # This requires a bit of explanation: the basic idea is to make a dummy - # metaclass for one level of class instantiation that replaces itself with - # the actual metaclass. - class metaclass(meta): - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - - return type.__new__(metaclass, "temporary_class", (), {}) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/_structures.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/_structures.py deleted file mode 100644 index 68dcca6..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/_structures.py +++ /dev/null @@ -1,68 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - - -class Infinity(object): - def __repr__(self): - return "Infinity" - - def __hash__(self): - return hash(repr(self)) - - def __lt__(self, other): - return False - - def __le__(self, other): - return False - - def __eq__(self, other): - return isinstance(other, self.__class__) - - def __ne__(self, other): - return not isinstance(other, self.__class__) - - def __gt__(self, other): - return True - - def __ge__(self, other): - return True - - def __neg__(self): - return NegativeInfinity - - -Infinity = Infinity() - - -class NegativeInfinity(object): - def __repr__(self): - return "-Infinity" - - def __hash__(self): - return hash(repr(self)) - - def __lt__(self, other): - return True - - def __le__(self, other): - return True - - def __eq__(self, other): - return isinstance(other, self.__class__) - - def __ne__(self, other): - return not isinstance(other, self.__class__) - - def __gt__(self, other): - return False - - def __ge__(self, other): - return False - - def __neg__(self): - return Infinity - - -NegativeInfinity = NegativeInfinity() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/markers.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/markers.py deleted file mode 100644 index 5482476..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/markers.py +++ /dev/null @@ -1,296 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import operator -import os -import platform -import sys - -from pip._vendor.pyparsing import ParseException, ParseResults, stringStart, stringEnd -from pip._vendor.pyparsing import ZeroOrMore, Group, Forward, QuotedString -from pip._vendor.pyparsing import Literal as L # noqa - -from ._compat import string_types -from .specifiers import Specifier, InvalidSpecifier - - -__all__ = [ - "InvalidMarker", - "UndefinedComparison", - "UndefinedEnvironmentName", - "Marker", - "default_environment", -] - - -class InvalidMarker(ValueError): - """ - An invalid marker was found, users should refer to PEP 508. - """ - - -class UndefinedComparison(ValueError): - """ - An invalid operation was attempted on a value that doesn't support it. - """ - - -class UndefinedEnvironmentName(ValueError): - """ - A name was attempted to be used that does not exist inside of the - environment. - """ - - -class Node(object): - def __init__(self, value): - self.value = value - - def __str__(self): - return str(self.value) - - def __repr__(self): - return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) - - def serialize(self): - raise NotImplementedError - - -class Variable(Node): - def serialize(self): - return str(self) - - -class Value(Node): - def serialize(self): - return '"{0}"'.format(self) - - -class Op(Node): - def serialize(self): - return str(self) - - -VARIABLE = ( - L("implementation_version") - | L("platform_python_implementation") - | L("implementation_name") - | L("python_full_version") - | L("platform_release") - | L("platform_version") - | L("platform_machine") - | L("platform_system") - | L("python_version") - | L("sys_platform") - | L("os_name") - | L("os.name") - | L("sys.platform") # PEP-345 - | L("platform.version") # PEP-345 - | L("platform.machine") # PEP-345 - | L("platform.python_implementation") # PEP-345 - | L("python_implementation") # PEP-345 - | L("extra") # undocumented setuptools legacy -) -ALIASES = { - "os.name": "os_name", - "sys.platform": "sys_platform", - "platform.version": "platform_version", - "platform.machine": "platform_machine", - "platform.python_implementation": "platform_python_implementation", - "python_implementation": "platform_python_implementation", -} -VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) - -VERSION_CMP = ( - L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<") -) - -MARKER_OP = VERSION_CMP | L("not in") | L("in") -MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) - -MARKER_VALUE = QuotedString("'") | QuotedString('"') -MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) - -BOOLOP = L("and") | L("or") - -MARKER_VAR = VARIABLE | MARKER_VALUE - -MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) -MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) - -LPAREN = L("(").suppress() -RPAREN = L(")").suppress() - -MARKER_EXPR = Forward() -MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) -MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) - -MARKER = stringStart + MARKER_EXPR + stringEnd - - -def _coerce_parse_result(results): - if isinstance(results, ParseResults): - return [_coerce_parse_result(i) for i in results] - else: - return results - - -def _format_marker(marker, first=True): - assert isinstance(marker, (list, tuple, string_types)) - - # Sometimes we have a structure like [[...]] which is a single item list - # where the single item is itself it's own list. In that case we want skip - # the rest of this function so that we don't get extraneous () on the - # outside. - if ( - isinstance(marker, list) - and len(marker) == 1 - and isinstance(marker[0], (list, tuple)) - ): - return _format_marker(marker[0]) - - if isinstance(marker, list): - inner = (_format_marker(m, first=False) for m in marker) - if first: - return " ".join(inner) - else: - return "(" + " ".join(inner) + ")" - elif isinstance(marker, tuple): - return " ".join([m.serialize() for m in marker]) - else: - return marker - - -_operators = { - "in": lambda lhs, rhs: lhs in rhs, - "not in": lambda lhs, rhs: lhs not in rhs, - "<": operator.lt, - "<=": operator.le, - "==": operator.eq, - "!=": operator.ne, - ">=": operator.ge, - ">": operator.gt, -} - - -def _eval_op(lhs, op, rhs): - try: - spec = Specifier("".join([op.serialize(), rhs])) - except InvalidSpecifier: - pass - else: - return spec.contains(lhs) - - oper = _operators.get(op.serialize()) - if oper is None: - raise UndefinedComparison( - "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) - ) - - return oper(lhs, rhs) - - -_undefined = object() - - -def _get_env(environment, name): - value = environment.get(name, _undefined) - - if value is _undefined: - raise UndefinedEnvironmentName( - "{0!r} does not exist in evaluation environment.".format(name) - ) - - return value - - -def _evaluate_markers(markers, environment): - groups = [[]] - - for marker in markers: - assert isinstance(marker, (list, tuple, string_types)) - - if isinstance(marker, list): - groups[-1].append(_evaluate_markers(marker, environment)) - elif isinstance(marker, tuple): - lhs, op, rhs = marker - - if isinstance(lhs, Variable): - lhs_value = _get_env(environment, lhs.value) - rhs_value = rhs.value - else: - lhs_value = lhs.value - rhs_value = _get_env(environment, rhs.value) - - groups[-1].append(_eval_op(lhs_value, op, rhs_value)) - else: - assert marker in ["and", "or"] - if marker == "or": - groups.append([]) - - return any(all(item) for item in groups) - - -def format_full_version(info): - version = "{0.major}.{0.minor}.{0.micro}".format(info) - kind = info.releaselevel - if kind != "final": - version += kind[0] + str(info.serial) - return version - - -def default_environment(): - if hasattr(sys, "implementation"): - iver = format_full_version(sys.implementation.version) - implementation_name = sys.implementation.name - else: - iver = "0" - implementation_name = "" - - return { - "implementation_name": implementation_name, - "implementation_version": iver, - "os_name": os.name, - "platform_machine": platform.machine(), - "platform_release": platform.release(), - "platform_system": platform.system(), - "platform_version": platform.version(), - "python_full_version": platform.python_version(), - "platform_python_implementation": platform.python_implementation(), - "python_version": platform.python_version()[:3], - "sys_platform": sys.platform, - } - - -class Marker(object): - def __init__(self, marker): - try: - self._markers = _coerce_parse_result(MARKER.parseString(marker)) - except ParseException as e: - err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( - marker, marker[e.loc : e.loc + 8] - ) - raise InvalidMarker(err_str) - - def __str__(self): - return _format_marker(self._markers) - - def __repr__(self): - return "<Marker({0!r})>".format(str(self)) - - def evaluate(self, environment=None): - """Evaluate a marker. - - Return the boolean from evaluating the given marker against the - environment. environment is an optional argument to override all or - part of the determined environment. - - The environment is determined from the current Python process. - """ - current_environment = default_environment() - if environment is not None: - current_environment.update(environment) - - return _evaluate_markers(self._markers, current_environment) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/requirements.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/requirements.py deleted file mode 100644 index dbc5f11..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/requirements.py +++ /dev/null @@ -1,138 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import string -import re - -from pip._vendor.pyparsing import stringStart, stringEnd, originalTextFor, ParseException -from pip._vendor.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine -from pip._vendor.pyparsing import Literal as L # noqa -from pip._vendor.six.moves.urllib import parse as urlparse - -from .markers import MARKER_EXPR, Marker -from .specifiers import LegacySpecifier, Specifier, SpecifierSet - - -class InvalidRequirement(ValueError): - """ - An invalid requirement was found, users should refer to PEP 508. - """ - - -ALPHANUM = Word(string.ascii_letters + string.digits) - -LBRACKET = L("[").suppress() -RBRACKET = L("]").suppress() -LPAREN = L("(").suppress() -RPAREN = L(")").suppress() -COMMA = L(",").suppress() -SEMICOLON = L(";").suppress() -AT = L("@").suppress() - -PUNCTUATION = Word("-_.") -IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) -IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) - -NAME = IDENTIFIER("name") -EXTRA = IDENTIFIER - -URI = Regex(r"[^ ]+")("url") -URL = AT + URI - -EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) -EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") - -VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) -VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) - -VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY -VERSION_MANY = Combine( - VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False -)("_raw_spec") -_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) -_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "") - -VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") -VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) - -MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") -MARKER_EXPR.setParseAction( - lambda s, l, t: Marker(s[t._original_start : t._original_end]) -) -MARKER_SEPARATOR = SEMICOLON -MARKER = MARKER_SEPARATOR + MARKER_EXPR - -VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) -URL_AND_MARKER = URL + Optional(MARKER) - -NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) - -REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd -# pyparsing isn't thread safe during initialization, so we do it eagerly, see -# issue #104 -REQUIREMENT.parseString("x[]") - - -class Requirement(object): - """Parse a requirement. - - Parse a given requirement string into its parts, such as name, specifier, - URL, and extras. Raises InvalidRequirement on a badly-formed requirement - string. - """ - - # TODO: Can we test whether something is contained within a requirement? - # If so how do we do that? Do we need to test against the _name_ of - # the thing as well as the version? What about the markers? - # TODO: Can we normalize the name and extra name? - - def __init__(self, requirement_string): - try: - req = REQUIREMENT.parseString(requirement_string) - except ParseException as e: - raise InvalidRequirement( - 'Parse error at "{0!r}": {1}'.format( - requirement_string[e.loc : e.loc + 8], e.msg - ) - ) - - self.name = req.name - if req.url: - parsed_url = urlparse.urlparse(req.url) - if parsed_url.scheme == "file": - if urlparse.urlunparse(parsed_url) != req.url: - raise InvalidRequirement("Invalid URL given") - elif not (parsed_url.scheme and parsed_url.netloc) or ( - not parsed_url.scheme and not parsed_url.netloc - ): - raise InvalidRequirement("Invalid URL: {0}".format(req.url)) - self.url = req.url - else: - self.url = None - self.extras = set(req.extras.asList() if req.extras else []) - self.specifier = SpecifierSet(req.specifier) - self.marker = req.marker if req.marker else None - - def __str__(self): - parts = [self.name] - - if self.extras: - parts.append("[{0}]".format(",".join(sorted(self.extras)))) - - if self.specifier: - parts.append(str(self.specifier)) - - if self.url: - parts.append("@ {0}".format(self.url)) - if self.marker: - parts.append(" ") - - if self.marker: - parts.append("; {0}".format(self.marker)) - - return "".join(parts) - - def __repr__(self): - return "<Requirement({0!r})>".format(str(self)) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/specifiers.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/specifiers.py deleted file mode 100644 index 743576a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/specifiers.py +++ /dev/null @@ -1,749 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import abc -import functools -import itertools -import re - -from ._compat import string_types, with_metaclass -from .version import Version, LegacyVersion, parse - - -class InvalidSpecifier(ValueError): - """ - An invalid specifier was found, users should refer to PEP 440. - """ - - -class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): - @abc.abstractmethod - def __str__(self): - """ - Returns the str representation of this Specifier like object. This - should be representative of the Specifier itself. - """ - - @abc.abstractmethod - def __hash__(self): - """ - Returns a hash value for this Specifier like object. - """ - - @abc.abstractmethod - def __eq__(self, other): - """ - Returns a boolean representing whether or not the two Specifier like - objects are equal. - """ - - @abc.abstractmethod - def __ne__(self, other): - """ - Returns a boolean representing whether or not the two Specifier like - objects are not equal. - """ - - @abc.abstractproperty - def prereleases(self): - """ - Returns whether or not pre-releases as a whole are allowed by this - specifier. - """ - - @prereleases.setter - def prereleases(self, value): - """ - Sets whether or not pre-releases as a whole are allowed by this - specifier. - """ - - @abc.abstractmethod - def contains(self, item, prereleases=None): - """ - Determines if the given item is contained within this specifier. - """ - - @abc.abstractmethod - def filter(self, iterable, prereleases=None): - """ - Takes an iterable of items and filters them so that only items which - are contained within this specifier are allowed in it. - """ - - -class _IndividualSpecifier(BaseSpecifier): - - _operators = {} - - def __init__(self, spec="", prereleases=None): - match = self._regex.search(spec) - if not match: - raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) - - self._spec = (match.group("operator").strip(), match.group("version").strip()) - - # Store whether or not this Specifier should accept prereleases - self._prereleases = prereleases - - def __repr__(self): - pre = ( - ", prereleases={0!r}".format(self.prereleases) - if self._prereleases is not None - else "" - ) - - return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre) - - def __str__(self): - return "{0}{1}".format(*self._spec) - - def __hash__(self): - return hash(self._spec) - - def __eq__(self, other): - if isinstance(other, string_types): - try: - other = self.__class__(other) - except InvalidSpecifier: - return NotImplemented - elif not isinstance(other, self.__class__): - return NotImplemented - - return self._spec == other._spec - - def __ne__(self, other): - if isinstance(other, string_types): - try: - other = self.__class__(other) - except InvalidSpecifier: - return NotImplemented - elif not isinstance(other, self.__class__): - return NotImplemented - - return self._spec != other._spec - - def _get_operator(self, op): - return getattr(self, "_compare_{0}".format(self._operators[op])) - - def _coerce_version(self, version): - if not isinstance(version, (LegacyVersion, Version)): - version = parse(version) - return version - - @property - def operator(self): - return self._spec[0] - - @property - def version(self): - return self._spec[1] - - @property - def prereleases(self): - return self._prereleases - - @prereleases.setter - def prereleases(self, value): - self._prereleases = value - - def __contains__(self, item): - return self.contains(item) - - def contains(self, item, prereleases=None): - # Determine if prereleases are to be allowed or not. - if prereleases is None: - prereleases = self.prereleases - - # Normalize item to a Version or LegacyVersion, this allows us to have - # a shortcut for ``"2.0" in Specifier(">=2") - item = self._coerce_version(item) - - # Determine if we should be supporting prereleases in this specifier - # or not, if we do not support prereleases than we can short circuit - # logic if this version is a prereleases. - if item.is_prerelease and not prereleases: - return False - - # Actually do the comparison to determine if this item is contained - # within this Specifier or not. - return self._get_operator(self.operator)(item, self.version) - - def filter(self, iterable, prereleases=None): - yielded = False - found_prereleases = [] - - kw = {"prereleases": prereleases if prereleases is not None else True} - - # Attempt to iterate over all the values in the iterable and if any of - # them match, yield them. - for version in iterable: - parsed_version = self._coerce_version(version) - - if self.contains(parsed_version, **kw): - # If our version is a prerelease, and we were not set to allow - # prereleases, then we'll store it for later incase nothing - # else matches this specifier. - if parsed_version.is_prerelease and not ( - prereleases or self.prereleases - ): - found_prereleases.append(version) - # Either this is not a prerelease, or we should have been - # accepting prereleases from the beginning. - else: - yielded = True - yield version - - # Now that we've iterated over everything, determine if we've yielded - # any values, and if we have not and we have any prereleases stored up - # then we will go ahead and yield the prereleases. - if not yielded and found_prereleases: - for version in found_prereleases: - yield version - - -class LegacySpecifier(_IndividualSpecifier): - - _regex_str = r""" - (?P<operator>(==|!=|<=|>=|<|>)) - \s* - (?P<version> - [^,;\s)]* # Since this is a "legacy" specifier, and the version - # string can be just about anything, we match everything - # except for whitespace, a semi-colon for marker support, - # a closing paren since versions can be enclosed in - # them, and a comma since it's a version separator. - ) - """ - - _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) - - _operators = { - "==": "equal", - "!=": "not_equal", - "<=": "less_than_equal", - ">=": "greater_than_equal", - "<": "less_than", - ">": "greater_than", - } - - def _coerce_version(self, version): - if not isinstance(version, LegacyVersion): - version = LegacyVersion(str(version)) - return version - - def _compare_equal(self, prospective, spec): - return prospective == self._coerce_version(spec) - - def _compare_not_equal(self, prospective, spec): - return prospective != self._coerce_version(spec) - - def _compare_less_than_equal(self, prospective, spec): - return prospective <= self._coerce_version(spec) - - def _compare_greater_than_equal(self, prospective, spec): - return prospective >= self._coerce_version(spec) - - def _compare_less_than(self, prospective, spec): - return prospective < self._coerce_version(spec) - - def _compare_greater_than(self, prospective, spec): - return prospective > self._coerce_version(spec) - - -def _require_version_compare(fn): - @functools.wraps(fn) - def wrapped(self, prospective, spec): - if not isinstance(prospective, Version): - return False - return fn(self, prospective, spec) - - return wrapped - - -class Specifier(_IndividualSpecifier): - - _regex_str = r""" - (?P<operator>(~=|==|!=|<=|>=|<|>|===)) - (?P<version> - (?: - # The identity operators allow for an escape hatch that will - # do an exact string match of the version you wish to install. - # This will not be parsed by PEP 440 and we cannot determine - # any semantic meaning from it. This operator is discouraged - # but included entirely as an escape hatch. - (?<====) # Only match for the identity operator - \s* - [^\s]* # We just match everything, except for whitespace - # since we are only testing for strict identity. - ) - | - (?: - # The (non)equality operators allow for wild card and local - # versions to be specified so we have to define these two - # operators separately to enable that. - (?<===|!=) # Only match for equals and not equals - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)* # release - (?: # pre release - [-_\.]? - (a|b|c|rc|alpha|beta|pre|preview) - [-_\.]? - [0-9]* - )? - (?: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - - # You cannot use a wild card and a dev or local version - # together so group them with a | and make them optional. - (?: - (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local - | - \.\* # Wild card syntax of .* - )? - ) - | - (?: - # The compatible operator requires at least two digits in the - # release segment. - (?<=~=) # Only match for the compatible operator - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) - (?: # pre release - [-_\.]? - (a|b|c|rc|alpha|beta|pre|preview) - [-_\.]? - [0-9]* - )? - (?: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - ) - | - (?: - # All other operators only allow a sub set of what the - # (non)equality operators do. Specifically they do not allow - # local versions to be specified nor do they allow the prefix - # matching wild cards. - (?<!==|!=|~=) # We have special cases for these - # operators so we want to make sure they - # don't match here. - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)* # release - (?: # pre release - [-_\.]? - (a|b|c|rc|alpha|beta|pre|preview) - [-_\.]? - [0-9]* - )? - (?: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - ) - ) - """ - - _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) - - _operators = { - "~=": "compatible", - "==": "equal", - "!=": "not_equal", - "<=": "less_than_equal", - ">=": "greater_than_equal", - "<": "less_than", - ">": "greater_than", - "===": "arbitrary", - } - - @_require_version_compare - def _compare_compatible(self, prospective, spec): - # Compatible releases have an equivalent combination of >= and ==. That - # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to - # implement this in terms of the other specifiers instead of - # implementing it ourselves. The only thing we need to do is construct - # the other specifiers. - - # We want everything but the last item in the version, but we want to - # ignore post and dev releases and we want to treat the pre-release as - # it's own separate segment. - prefix = ".".join( - list( - itertools.takewhile( - lambda x: (not x.startswith("post") and not x.startswith("dev")), - _version_split(spec), - ) - )[:-1] - ) - - # Add the prefix notation to the end of our string - prefix += ".*" - - return self._get_operator(">=")(prospective, spec) and self._get_operator("==")( - prospective, prefix - ) - - @_require_version_compare - def _compare_equal(self, prospective, spec): - # We need special logic to handle prefix matching - if spec.endswith(".*"): - # In the case of prefix matching we want to ignore local segment. - prospective = Version(prospective.public) - # Split the spec out by dots, and pretend that there is an implicit - # dot in between a release segment and a pre-release segment. - spec = _version_split(spec[:-2]) # Remove the trailing .* - - # Split the prospective version out by dots, and pretend that there - # is an implicit dot in between a release segment and a pre-release - # segment. - prospective = _version_split(str(prospective)) - - # Shorten the prospective version to be the same length as the spec - # so that we can determine if the specifier is a prefix of the - # prospective version or not. - prospective = prospective[: len(spec)] - - # Pad out our two sides with zeros so that they both equal the same - # length. - spec, prospective = _pad_version(spec, prospective) - else: - # Convert our spec string into a Version - spec = Version(spec) - - # If the specifier does not have a local segment, then we want to - # act as if the prospective version also does not have a local - # segment. - if not spec.local: - prospective = Version(prospective.public) - - return prospective == spec - - @_require_version_compare - def _compare_not_equal(self, prospective, spec): - return not self._compare_equal(prospective, spec) - - @_require_version_compare - def _compare_less_than_equal(self, prospective, spec): - return prospective <= Version(spec) - - @_require_version_compare - def _compare_greater_than_equal(self, prospective, spec): - return prospective >= Version(spec) - - @_require_version_compare - def _compare_less_than(self, prospective, spec): - # Convert our spec to a Version instance, since we'll want to work with - # it as a version. - spec = Version(spec) - - # Check to see if the prospective version is less than the spec - # version. If it's not we can short circuit and just return False now - # instead of doing extra unneeded work. - if not prospective < spec: - return False - - # This special case is here so that, unless the specifier itself - # includes is a pre-release version, that we do not accept pre-release - # versions for the version mentioned in the specifier (e.g. <3.1 should - # not match 3.1.dev0, but should match 3.0.dev0). - if not spec.is_prerelease and prospective.is_prerelease: - if Version(prospective.base_version) == Version(spec.base_version): - return False - - # If we've gotten to here, it means that prospective version is both - # less than the spec version *and* it's not a pre-release of the same - # version in the spec. - return True - - @_require_version_compare - def _compare_greater_than(self, prospective, spec): - # Convert our spec to a Version instance, since we'll want to work with - # it as a version. - spec = Version(spec) - - # Check to see if the prospective version is greater than the spec - # version. If it's not we can short circuit and just return False now - # instead of doing extra unneeded work. - if not prospective > spec: - return False - - # This special case is here so that, unless the specifier itself - # includes is a post-release version, that we do not accept - # post-release versions for the version mentioned in the specifier - # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). - if not spec.is_postrelease and prospective.is_postrelease: - if Version(prospective.base_version) == Version(spec.base_version): - return False - - # Ensure that we do not allow a local version of the version mentioned - # in the specifier, which is technically greater than, to match. - if prospective.local is not None: - if Version(prospective.base_version) == Version(spec.base_version): - return False - - # If we've gotten to here, it means that prospective version is both - # greater than the spec version *and* it's not a pre-release of the - # same version in the spec. - return True - - def _compare_arbitrary(self, prospective, spec): - return str(prospective).lower() == str(spec).lower() - - @property - def prereleases(self): - # If there is an explicit prereleases set for this, then we'll just - # blindly use that. - if self._prereleases is not None: - return self._prereleases - - # Look at all of our specifiers and determine if they are inclusive - # operators, and if they are if they are including an explicit - # prerelease. - operator, version = self._spec - if operator in ["==", ">=", "<=", "~=", "==="]: - # The == specifier can include a trailing .*, if it does we - # want to remove before parsing. - if operator == "==" and version.endswith(".*"): - version = version[:-2] - - # Parse the version, and if it is a pre-release than this - # specifier allows pre-releases. - if parse(version).is_prerelease: - return True - - return False - - @prereleases.setter - def prereleases(self, value): - self._prereleases = value - - -_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") - - -def _version_split(version): - result = [] - for item in version.split("."): - match = _prefix_regex.search(item) - if match: - result.extend(match.groups()) - else: - result.append(item) - return result - - -def _pad_version(left, right): - left_split, right_split = [], [] - - # Get the release segment of our versions - left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) - right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) - - # Get the rest of our versions - left_split.append(left[len(left_split[0]) :]) - right_split.append(right[len(right_split[0]) :]) - - # Insert our padding - left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0]))) - right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0]))) - - return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split))) - - -class SpecifierSet(BaseSpecifier): - def __init__(self, specifiers="", prereleases=None): - # Split on , to break each indidivual specifier into it's own item, and - # strip each item to remove leading/trailing whitespace. - specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] - - # Parsed each individual specifier, attempting first to make it a - # Specifier and falling back to a LegacySpecifier. - parsed = set() - for specifier in specifiers: - try: - parsed.add(Specifier(specifier)) - except InvalidSpecifier: - parsed.add(LegacySpecifier(specifier)) - - # Turn our parsed specifiers into a frozen set and save them for later. - self._specs = frozenset(parsed) - - # Store our prereleases value so we can use it later to determine if - # we accept prereleases or not. - self._prereleases = prereleases - - def __repr__(self): - pre = ( - ", prereleases={0!r}".format(self.prereleases) - if self._prereleases is not None - else "" - ) - - return "<SpecifierSet({0!r}{1})>".format(str(self), pre) - - def __str__(self): - return ",".join(sorted(str(s) for s in self._specs)) - - def __hash__(self): - return hash(self._specs) - - def __and__(self, other): - if isinstance(other, string_types): - other = SpecifierSet(other) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - specifier = SpecifierSet() - specifier._specs = frozenset(self._specs | other._specs) - - if self._prereleases is None and other._prereleases is not None: - specifier._prereleases = other._prereleases - elif self._prereleases is not None and other._prereleases is None: - specifier._prereleases = self._prereleases - elif self._prereleases == other._prereleases: - specifier._prereleases = self._prereleases - else: - raise ValueError( - "Cannot combine SpecifierSets with True and False prerelease " - "overrides." - ) - - return specifier - - def __eq__(self, other): - if isinstance(other, string_types): - other = SpecifierSet(other) - elif isinstance(other, _IndividualSpecifier): - other = SpecifierSet(str(other)) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - return self._specs == other._specs - - def __ne__(self, other): - if isinstance(other, string_types): - other = SpecifierSet(other) - elif isinstance(other, _IndividualSpecifier): - other = SpecifierSet(str(other)) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - return self._specs != other._specs - - def __len__(self): - return len(self._specs) - - def __iter__(self): - return iter(self._specs) - - @property - def prereleases(self): - # If we have been given an explicit prerelease modifier, then we'll - # pass that through here. - if self._prereleases is not None: - return self._prereleases - - # If we don't have any specifiers, and we don't have a forced value, - # then we'll just return None since we don't know if this should have - # pre-releases or not. - if not self._specs: - return None - - # Otherwise we'll see if any of the given specifiers accept - # prereleases, if any of them do we'll return True, otherwise False. - return any(s.prereleases for s in self._specs) - - @prereleases.setter - def prereleases(self, value): - self._prereleases = value - - def __contains__(self, item): - return self.contains(item) - - def contains(self, item, prereleases=None): - # Ensure that our item is a Version or LegacyVersion instance. - if not isinstance(item, (LegacyVersion, Version)): - item = parse(item) - - # Determine if we're forcing a prerelease or not, if we're not forcing - # one for this particular filter call, then we'll use whatever the - # SpecifierSet thinks for whether or not we should support prereleases. - if prereleases is None: - prereleases = self.prereleases - - # We can determine if we're going to allow pre-releases by looking to - # see if any of the underlying items supports them. If none of them do - # and this item is a pre-release then we do not allow it and we can - # short circuit that here. - # Note: This means that 1.0.dev1 would not be contained in something - # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 - if not prereleases and item.is_prerelease: - return False - - # We simply dispatch to the underlying specs here to make sure that the - # given version is contained within all of them. - # Note: This use of all() here means that an empty set of specifiers - # will always return True, this is an explicit design decision. - return all(s.contains(item, prereleases=prereleases) for s in self._specs) - - def filter(self, iterable, prereleases=None): - # Determine if we're forcing a prerelease or not, if we're not forcing - # one for this particular filter call, then we'll use whatever the - # SpecifierSet thinks for whether or not we should support prereleases. - if prereleases is None: - prereleases = self.prereleases - - # If we have any specifiers, then we want to wrap our iterable in the - # filter method for each one, this will act as a logical AND amongst - # each specifier. - if self._specs: - for spec in self._specs: - iterable = spec.filter(iterable, prereleases=bool(prereleases)) - return iterable - # If we do not have any specifiers, then we need to have a rough filter - # which will filter out any pre-releases, unless there are no final - # releases, and which will filter out LegacyVersion in general. - else: - filtered = [] - found_prereleases = [] - - for item in iterable: - # Ensure that we some kind of Version class for this item. - if not isinstance(item, (LegacyVersion, Version)): - parsed_version = parse(item) - else: - parsed_version = item - - # Filter out any item which is parsed as a LegacyVersion - if isinstance(parsed_version, LegacyVersion): - continue - - # Store any item which is a pre-release for later unless we've - # already found a final version or we are accepting prereleases - if parsed_version.is_prerelease and not prereleases: - if not filtered: - found_prereleases.append(item) - else: - filtered.append(item) - - # If we've found no items except for pre-releases, then we'll go - # ahead and use the pre-releases - if not filtered and found_prereleases and prereleases is None: - return found_prereleases - - return filtered diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/utils.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/utils.py deleted file mode 100644 index 8841878..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/utils.py +++ /dev/null @@ -1,57 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import re - -from .version import InvalidVersion, Version - - -_canonicalize_regex = re.compile(r"[-_.]+") - - -def canonicalize_name(name): - # This is taken from PEP 503. - return _canonicalize_regex.sub("-", name).lower() - - -def canonicalize_version(version): - """ - This is very similar to Version.__str__, but has one subtle differences - with the way it handles the release segment. - """ - - try: - version = Version(version) - except InvalidVersion: - # Legacy versions cannot be normalized - return version - - parts = [] - - # Epoch - if version.epoch != 0: - parts.append("{0}!".format(version.epoch)) - - # Release segment - # NB: This strips trailing '.0's to normalize - parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release))) - - # Pre-release - if version.pre is not None: - parts.append("".join(str(x) for x in version.pre)) - - # Post-release - if version.post is not None: - parts.append(".post{0}".format(version.post)) - - # Development release - if version.dev is not None: - parts.append(".dev{0}".format(version.dev)) - - # Local version segment - if version.local is not None: - parts.append("+{0}".format(version.local)) - - return "".join(parts) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/version.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/version.py deleted file mode 100644 index 95157a1..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/packaging/version.py +++ /dev/null @@ -1,420 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import collections -import itertools -import re - -from ._structures import Infinity - - -__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"] - - -_Version = collections.namedtuple( - "_Version", ["epoch", "release", "dev", "pre", "post", "local"] -) - - -def parse(version): - """ - Parse the given version string and return either a :class:`Version` object - or a :class:`LegacyVersion` object depending on if the given version is - a valid PEP 440 version or a legacy version. - """ - try: - return Version(version) - except InvalidVersion: - return LegacyVersion(version) - - -class InvalidVersion(ValueError): - """ - An invalid version was found, users should refer to PEP 440. - """ - - -class _BaseVersion(object): - def __hash__(self): - return hash(self._key) - - def __lt__(self, other): - return self._compare(other, lambda s, o: s < o) - - def __le__(self, other): - return self._compare(other, lambda s, o: s <= o) - - def __eq__(self, other): - return self._compare(other, lambda s, o: s == o) - - def __ge__(self, other): - return self._compare(other, lambda s, o: s >= o) - - def __gt__(self, other): - return self._compare(other, lambda s, o: s > o) - - def __ne__(self, other): - return self._compare(other, lambda s, o: s != o) - - def _compare(self, other, method): - if not isinstance(other, _BaseVersion): - return NotImplemented - - return method(self._key, other._key) - - -class LegacyVersion(_BaseVersion): - def __init__(self, version): - self._version = str(version) - self._key = _legacy_cmpkey(self._version) - - def __str__(self): - return self._version - - def __repr__(self): - return "<LegacyVersion({0})>".format(repr(str(self))) - - @property - def public(self): - return self._version - - @property - def base_version(self): - return self._version - - @property - def epoch(self): - return -1 - - @property - def release(self): - return None - - @property - def pre(self): - return None - - @property - def post(self): - return None - - @property - def dev(self): - return None - - @property - def local(self): - return None - - @property - def is_prerelease(self): - return False - - @property - def is_postrelease(self): - return False - - @property - def is_devrelease(self): - return False - - -_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE) - -_legacy_version_replacement_map = { - "pre": "c", - "preview": "c", - "-": "final-", - "rc": "c", - "dev": "@", -} - - -def _parse_version_parts(s): - for part in _legacy_version_component_re.split(s): - part = _legacy_version_replacement_map.get(part, part) - - if not part or part == ".": - continue - - if part[:1] in "0123456789": - # pad for numeric comparison - yield part.zfill(8) - else: - yield "*" + part - - # ensure that alpha/beta/candidate are before final - yield "*final" - - -def _legacy_cmpkey(version): - # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch - # greater than or equal to 0. This will effectively put the LegacyVersion, - # which uses the defacto standard originally implemented by setuptools, - # as before all PEP 440 versions. - epoch = -1 - - # This scheme is taken from pkg_resources.parse_version setuptools prior to - # it's adoption of the packaging library. - parts = [] - for part in _parse_version_parts(version.lower()): - if part.startswith("*"): - # remove "-" before a prerelease tag - if part < "*final": - while parts and parts[-1] == "*final-": - parts.pop() - - # remove trailing zeros from each series of numeric parts - while parts and parts[-1] == "00000000": - parts.pop() - - parts.append(part) - parts = tuple(parts) - - return epoch, parts - - -# Deliberately not anchored to the start and end of the string, to make it -# easier for 3rd party code to reuse -VERSION_PATTERN = r""" - v? - (?: - (?:(?P<epoch>[0-9]+)!)? # epoch - (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment - (?P<pre> # pre-release - [-_\.]? - (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) - [-_\.]? - (?P<pre_n>[0-9]+)? - )? - (?P<post> # post release - (?:-(?P<post_n1>[0-9]+)) - | - (?: - [-_\.]? - (?P<post_l>post|rev|r) - [-_\.]? - (?P<post_n2>[0-9]+)? - ) - )? - (?P<dev> # dev release - [-_\.]? - (?P<dev_l>dev) - [-_\.]? - (?P<dev_n>[0-9]+)? - )? - ) - (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version -""" - - -class Version(_BaseVersion): - - _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE) - - def __init__(self, version): - # Validate the version and parse it into pieces - match = self._regex.search(version) - if not match: - raise InvalidVersion("Invalid version: '{0}'".format(version)) - - # Store the parsed out pieces of the version - self._version = _Version( - epoch=int(match.group("epoch")) if match.group("epoch") else 0, - release=tuple(int(i) for i in match.group("release").split(".")), - pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")), - post=_parse_letter_version( - match.group("post_l"), match.group("post_n1") or match.group("post_n2") - ), - dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")), - local=_parse_local_version(match.group("local")), - ) - - # Generate a key which will be used for sorting - self._key = _cmpkey( - self._version.epoch, - self._version.release, - self._version.pre, - self._version.post, - self._version.dev, - self._version.local, - ) - - def __repr__(self): - return "<Version({0})>".format(repr(str(self))) - - def __str__(self): - parts = [] - - # Epoch - if self.epoch != 0: - parts.append("{0}!".format(self.epoch)) - - # Release segment - parts.append(".".join(str(x) for x in self.release)) - - # Pre-release - if self.pre is not None: - parts.append("".join(str(x) for x in self.pre)) - - # Post-release - if self.post is not None: - parts.append(".post{0}".format(self.post)) - - # Development release - if self.dev is not None: - parts.append(".dev{0}".format(self.dev)) - - # Local version segment - if self.local is not None: - parts.append("+{0}".format(self.local)) - - return "".join(parts) - - @property - def epoch(self): - return self._version.epoch - - @property - def release(self): - return self._version.release - - @property - def pre(self): - return self._version.pre - - @property - def post(self): - return self._version.post[1] if self._version.post else None - - @property - def dev(self): - return self._version.dev[1] if self._version.dev else None - - @property - def local(self): - if self._version.local: - return ".".join(str(x) for x in self._version.local) - else: - return None - - @property - def public(self): - return str(self).split("+", 1)[0] - - @property - def base_version(self): - parts = [] - - # Epoch - if self.epoch != 0: - parts.append("{0}!".format(self.epoch)) - - # Release segment - parts.append(".".join(str(x) for x in self.release)) - - return "".join(parts) - - @property - def is_prerelease(self): - return self.dev is not None or self.pre is not None - - @property - def is_postrelease(self): - return self.post is not None - - @property - def is_devrelease(self): - return self.dev is not None - - -def _parse_letter_version(letter, number): - if letter: - # We consider there to be an implicit 0 in a pre-release if there is - # not a numeral associated with it. - if number is None: - number = 0 - - # We normalize any letters to their lower case form - letter = letter.lower() - - # We consider some words to be alternate spellings of other words and - # in those cases we want to normalize the spellings to our preferred - # spelling. - if letter == "alpha": - letter = "a" - elif letter == "beta": - letter = "b" - elif letter in ["c", "pre", "preview"]: - letter = "rc" - elif letter in ["rev", "r"]: - letter = "post" - - return letter, int(number) - if not letter and number: - # We assume if we are given a number, but we are not given a letter - # then this is using the implicit post release syntax (e.g. 1.0-1) - letter = "post" - - return letter, int(number) - - -_local_version_separators = re.compile(r"[\._-]") - - -def _parse_local_version(local): - """ - Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). - """ - if local is not None: - return tuple( - part.lower() if not part.isdigit() else int(part) - for part in _local_version_separators.split(local) - ) - - -def _cmpkey(epoch, release, pre, post, dev, local): - # When we compare a release version, we want to compare it with all of the - # trailing zeros removed. So we'll use a reverse the list, drop all the now - # leading zeros until we come to something non zero, then take the rest - # re-reverse it back into the correct order and make it a tuple and use - # that for our sorting key. - release = tuple( - reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release)))) - ) - - # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. - # We'll do this by abusing the pre segment, but we _only_ want to do this - # if there is not a pre or a post segment. If we have one of those then - # the normal sorting rules will handle this case correctly. - if pre is None and post is None and dev is not None: - pre = -Infinity - # Versions without a pre-release (except as noted above) should sort after - # those with one. - elif pre is None: - pre = Infinity - - # Versions without a post segment should sort before those with one. - if post is None: - post = -Infinity - - # Versions without a development segment should sort after those with one. - if dev is None: - dev = Infinity - - if local is None: - # Versions without a local segment should sort before those with one. - local = -Infinity - else: - # Versions with a local segment need that segment parsed to implement - # the sorting rules in PEP440. - # - Alpha numeric segments sort before numeric segments - # - Alpha numeric segments sort lexicographically - # - Numeric segments sort numerically - # - Shorter versions sort before longer versions when the prefixes - # match exactly - local = tuple((i, "") if isinstance(i, int) else (-Infinity, i) for i in local) - - return epoch, release, pre, post, dev, local diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/__init__.py deleted file mode 100644 index 9c1a098..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Wrappers to build Python packages using PEP 517 hooks -""" - -__version__ = '0.5.0' diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/_in_process.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/_in_process.py deleted file mode 100644 index d6524b6..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/_in_process.py +++ /dev/null @@ -1,207 +0,0 @@ -"""This is invoked in a subprocess to call the build backend hooks. - -It expects: -- Command line args: hook_name, control_dir -- Environment variable: PEP517_BUILD_BACKEND=entry.point:spec -- control_dir/input.json: - - {"kwargs": {...}} - -Results: -- control_dir/output.json - - {"return_val": ...} -""" -from glob import glob -from importlib import import_module -import os -from os.path import join as pjoin -import re -import shutil -import sys - -# This is run as a script, not a module, so it can't do a relative import -import compat - - -class BackendUnavailable(Exception): - """Raised if we cannot import the backend""" - - -def _build_backend(): - """Find and load the build backend""" - ep = os.environ['PEP517_BUILD_BACKEND'] - mod_path, _, obj_path = ep.partition(':') - try: - obj = import_module(mod_path) - except ImportError: - raise BackendUnavailable - if obj_path: - for path_part in obj_path.split('.'): - obj = getattr(obj, path_part) - return obj - - -def get_requires_for_build_wheel(config_settings): - """Invoke the optional get_requires_for_build_wheel hook - - Returns [] if the hook is not defined. - """ - backend = _build_backend() - try: - hook = backend.get_requires_for_build_wheel - except AttributeError: - return [] - else: - return hook(config_settings) - - -def prepare_metadata_for_build_wheel(metadata_directory, config_settings): - """Invoke optional prepare_metadata_for_build_wheel - - Implements a fallback by building a wheel if the hook isn't defined. - """ - backend = _build_backend() - try: - hook = backend.prepare_metadata_for_build_wheel - except AttributeError: - return _get_wheel_metadata_from_wheel(backend, metadata_directory, - config_settings) - else: - return hook(metadata_directory, config_settings) - - -WHEEL_BUILT_MARKER = 'PEP517_ALREADY_BUILT_WHEEL' - - -def _dist_info_files(whl_zip): - """Identify the .dist-info folder inside a wheel ZipFile.""" - res = [] - for path in whl_zip.namelist(): - m = re.match(r'[^/\\]+-[^/\\]+\.dist-info/', path) - if m: - res.append(path) - if res: - return res - raise Exception("No .dist-info folder found in wheel") - - -def _get_wheel_metadata_from_wheel( - backend, metadata_directory, config_settings): - """Build a wheel and extract the metadata from it. - - Fallback for when the build backend does not - define the 'get_wheel_metadata' hook. - """ - from zipfile import ZipFile - whl_basename = backend.build_wheel(metadata_directory, config_settings) - with open(os.path.join(metadata_directory, WHEEL_BUILT_MARKER), 'wb'): - pass # Touch marker file - - whl_file = os.path.join(metadata_directory, whl_basename) - with ZipFile(whl_file) as zipf: - dist_info = _dist_info_files(zipf) - zipf.extractall(path=metadata_directory, members=dist_info) - return dist_info[0].split('/')[0] - - -def _find_already_built_wheel(metadata_directory): - """Check for a wheel already built during the get_wheel_metadata hook. - """ - if not metadata_directory: - return None - metadata_parent = os.path.dirname(metadata_directory) - if not os.path.isfile(pjoin(metadata_parent, WHEEL_BUILT_MARKER)): - return None - - whl_files = glob(os.path.join(metadata_parent, '*.whl')) - if not whl_files: - print('Found wheel built marker, but no .whl files') - return None - if len(whl_files) > 1: - print('Found multiple .whl files; unspecified behaviour. ' - 'Will call build_wheel.') - return None - - # Exactly one .whl file - return whl_files[0] - - -def build_wheel(wheel_directory, config_settings, metadata_directory=None): - """Invoke the mandatory build_wheel hook. - - If a wheel was already built in the - prepare_metadata_for_build_wheel fallback, this - will copy it rather than rebuilding the wheel. - """ - prebuilt_whl = _find_already_built_wheel(metadata_directory) - if prebuilt_whl: - shutil.copy2(prebuilt_whl, wheel_directory) - return os.path.basename(prebuilt_whl) - - return _build_backend().build_wheel(wheel_directory, config_settings, - metadata_directory) - - -def get_requires_for_build_sdist(config_settings): - """Invoke the optional get_requires_for_build_wheel hook - - Returns [] if the hook is not defined. - """ - backend = _build_backend() - try: - hook = backend.get_requires_for_build_sdist - except AttributeError: - return [] - else: - return hook(config_settings) - - -class _DummyException(Exception): - """Nothing should ever raise this exception""" - - -class GotUnsupportedOperation(Exception): - """For internal use when backend raises UnsupportedOperation""" - - -def build_sdist(sdist_directory, config_settings): - """Invoke the mandatory build_sdist hook.""" - backend = _build_backend() - try: - return backend.build_sdist(sdist_directory, config_settings) - except getattr(backend, 'UnsupportedOperation', _DummyException): - raise GotUnsupportedOperation - - -HOOK_NAMES = { - 'get_requires_for_build_wheel', - 'prepare_metadata_for_build_wheel', - 'build_wheel', - 'get_requires_for_build_sdist', - 'build_sdist', -} - - -def main(): - if len(sys.argv) < 3: - sys.exit("Needs args: hook_name, control_dir") - hook_name = sys.argv[1] - control_dir = sys.argv[2] - if hook_name not in HOOK_NAMES: - sys.exit("Unknown hook: %s" % hook_name) - hook = globals()[hook_name] - - hook_input = compat.read_json(pjoin(control_dir, 'input.json')) - - json_out = {'unsupported': False, 'return_val': None} - try: - json_out['return_val'] = hook(**hook_input['kwargs']) - except BackendUnavailable: - json_out['no_backend'] = True - except GotUnsupportedOperation: - json_out['unsupported'] = True - - compat.write_json(json_out, pjoin(control_dir, 'output.json'), indent=2) - - -if __name__ == '__main__': - main() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/build.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/build.py deleted file mode 100644 index ac6c949..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/build.py +++ /dev/null @@ -1,108 +0,0 @@ -"""Build a project using PEP 517 hooks. -""" -import argparse -import logging -import os -import contextlib -from pip._vendor import pytoml -import shutil -import errno -import tempfile - -from .envbuild import BuildEnvironment -from .wrappers import Pep517HookCaller - -log = logging.getLogger(__name__) - - -@contextlib.contextmanager -def tempdir(): - td = tempfile.mkdtemp() - try: - yield td - finally: - shutil.rmtree(td) - - -def _do_build(hooks, env, dist, dest): - get_requires_name = 'get_requires_for_build_{dist}'.format(**locals()) - get_requires = getattr(hooks, get_requires_name) - reqs = get_requires({}) - log.info('Got build requires: %s', reqs) - - env.pip_install(reqs) - log.info('Installed dynamic build dependencies') - - with tempdir() as td: - log.info('Trying to build %s in %s', dist, td) - build_name = 'build_{dist}'.format(**locals()) - build = getattr(hooks, build_name) - filename = build(td, {}) - source = os.path.join(td, filename) - shutil.move(source, os.path.join(dest, os.path.basename(filename))) - - -def mkdir_p(*args, **kwargs): - """Like `mkdir`, but does not raise an exception if the - directory already exists. - """ - try: - return os.mkdir(*args, **kwargs) - except OSError as exc: - if exc.errno != errno.EEXIST: - raise - - -def build(source_dir, dist, dest=None): - pyproject = os.path.join(source_dir, 'pyproject.toml') - dest = os.path.join(source_dir, dest or 'dist') - mkdir_p(dest) - - with open(pyproject) as f: - pyproject_data = pytoml.load(f) - # Ensure the mandatory data can be loaded - buildsys = pyproject_data['build-system'] - requires = buildsys['requires'] - backend = buildsys['build-backend'] - - hooks = Pep517HookCaller(source_dir, backend) - - with BuildEnvironment() as env: - env.pip_install(requires) - _do_build(hooks, env, dist, dest) - - -parser = argparse.ArgumentParser() -parser.add_argument( - 'source_dir', - help="A directory containing pyproject.toml", -) -parser.add_argument( - '--binary', '-b', - action='store_true', - default=False, -) -parser.add_argument( - '--source', '-s', - action='store_true', - default=False, -) -parser.add_argument( - '--out-dir', '-o', - help="Destination in which to save the builds relative to source dir", -) - - -def main(args): - # determine which dists to build - dists = list(filter(None, ( - 'sdist' if args.source or not args.binary else None, - 'wheel' if args.binary or not args.source else None, - ))) - - for dist in dists: - build(args.source_dir, dist, args.out_dir) - - -if __name__ == '__main__': - main(parser.parse_args()) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/check.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/check.py deleted file mode 100644 index f4cdc6b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/check.py +++ /dev/null @@ -1,202 +0,0 @@ -"""Check a project and backend by attempting to build using PEP 517 hooks. -""" -import argparse -import logging -import os -from os.path import isfile, join as pjoin -from pip._vendor.pytoml import TomlError, load as toml_load -import shutil -from subprocess import CalledProcessError -import sys -import tarfile -from tempfile import mkdtemp -import zipfile - -from .colorlog import enable_colourful_output -from .envbuild import BuildEnvironment -from .wrappers import Pep517HookCaller - -log = logging.getLogger(__name__) - - -def check_build_sdist(hooks, build_sys_requires): - with BuildEnvironment() as env: - try: - env.pip_install(build_sys_requires) - log.info('Installed static build dependencies') - except CalledProcessError: - log.error('Failed to install static build dependencies') - return False - - try: - reqs = hooks.get_requires_for_build_sdist({}) - log.info('Got build requires: %s', reqs) - except Exception: - log.error('Failure in get_requires_for_build_sdist', exc_info=True) - return False - - try: - env.pip_install(reqs) - log.info('Installed dynamic build dependencies') - except CalledProcessError: - log.error('Failed to install dynamic build dependencies') - return False - - td = mkdtemp() - log.info('Trying to build sdist in %s', td) - try: - try: - filename = hooks.build_sdist(td, {}) - log.info('build_sdist returned %r', filename) - except Exception: - log.info('Failure in build_sdist', exc_info=True) - return False - - if not filename.endswith('.tar.gz'): - log.error( - "Filename %s doesn't have .tar.gz extension", filename) - return False - - path = pjoin(td, filename) - if isfile(path): - log.info("Output file %s exists", path) - else: - log.error("Output file %s does not exist", path) - return False - - if tarfile.is_tarfile(path): - log.info("Output file is a tar file") - else: - log.error("Output file is not a tar file") - return False - - finally: - shutil.rmtree(td) - - return True - - -def check_build_wheel(hooks, build_sys_requires): - with BuildEnvironment() as env: - try: - env.pip_install(build_sys_requires) - log.info('Installed static build dependencies') - except CalledProcessError: - log.error('Failed to install static build dependencies') - return False - - try: - reqs = hooks.get_requires_for_build_wheel({}) - log.info('Got build requires: %s', reqs) - except Exception: - log.error('Failure in get_requires_for_build_sdist', exc_info=True) - return False - - try: - env.pip_install(reqs) - log.info('Installed dynamic build dependencies') - except CalledProcessError: - log.error('Failed to install dynamic build dependencies') - return False - - td = mkdtemp() - log.info('Trying to build wheel in %s', td) - try: - try: - filename = hooks.build_wheel(td, {}) - log.info('build_wheel returned %r', filename) - except Exception: - log.info('Failure in build_wheel', exc_info=True) - return False - - if not filename.endswith('.whl'): - log.error("Filename %s doesn't have .whl extension", filename) - return False - - path = pjoin(td, filename) - if isfile(path): - log.info("Output file %s exists", path) - else: - log.error("Output file %s does not exist", path) - return False - - if zipfile.is_zipfile(path): - log.info("Output file is a zip file") - else: - log.error("Output file is not a zip file") - return False - - finally: - shutil.rmtree(td) - - return True - - -def check(source_dir): - pyproject = pjoin(source_dir, 'pyproject.toml') - if isfile(pyproject): - log.info('Found pyproject.toml') - else: - log.error('Missing pyproject.toml') - return False - - try: - with open(pyproject) as f: - pyproject_data = toml_load(f) - # Ensure the mandatory data can be loaded - buildsys = pyproject_data['build-system'] - requires = buildsys['requires'] - backend = buildsys['build-backend'] - log.info('Loaded pyproject.toml') - except (TomlError, KeyError): - log.error("Invalid pyproject.toml", exc_info=True) - return False - - hooks = Pep517HookCaller(source_dir, backend) - - sdist_ok = check_build_sdist(hooks, requires) - wheel_ok = check_build_wheel(hooks, requires) - - if not sdist_ok: - log.warning('Sdist checks failed; scroll up to see') - if not wheel_ok: - log.warning('Wheel checks failed') - - return sdist_ok - - -def main(argv=None): - ap = argparse.ArgumentParser() - ap.add_argument( - 'source_dir', - help="A directory containing pyproject.toml") - args = ap.parse_args(argv) - - enable_colourful_output() - - ok = check(args.source_dir) - - if ok: - print(ansi('Checks passed', 'green')) - else: - print(ansi('Checks failed', 'red')) - sys.exit(1) - - -ansi_codes = { - 'reset': '\x1b[0m', - 'bold': '\x1b[1m', - 'red': '\x1b[31m', - 'green': '\x1b[32m', -} - - -def ansi(s, attr): - if os.name != 'nt' and sys.stdout.isatty(): - return ansi_codes[attr] + str(s) + ansi_codes['reset'] - else: - return str(s) - - -if __name__ == '__main__': - main() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/colorlog.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/colorlog.py deleted file mode 100644 index 69c8a59..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/colorlog.py +++ /dev/null @@ -1,115 +0,0 @@ -"""Nicer log formatting with colours. - -Code copied from Tornado, Apache licensed. -""" -# Copyright 2012 Facebook -# -# 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 logging -import sys - -try: - import curses -except ImportError: - curses = None - - -def _stderr_supports_color(): - color = False - if curses and hasattr(sys.stderr, 'isatty') and sys.stderr.isatty(): - try: - curses.setupterm() - if curses.tigetnum("colors") > 0: - color = True - except Exception: - pass - return color - - -class LogFormatter(logging.Formatter): - """Log formatter with colour support - """ - DEFAULT_COLORS = { - logging.INFO: 2, # Green - logging.WARNING: 3, # Yellow - logging.ERROR: 1, # Red - logging.CRITICAL: 1, - } - - def __init__(self, color=True, datefmt=None): - r""" - :arg bool color: Enables color support. - :arg string fmt: Log message format. - It will be applied to the attributes dict of log records. The - text between ``%(color)s`` and ``%(end_color)s`` will be colored - depending on the level if color support is on. - :arg dict colors: color mappings from logging level to terminal color - code - :arg string datefmt: Datetime format. - Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``. - .. versionchanged:: 3.2 - Added ``fmt`` and ``datefmt`` arguments. - """ - logging.Formatter.__init__(self, datefmt=datefmt) - self._colors = {} - if color and _stderr_supports_color(): - # The curses module has some str/bytes confusion in - # python3. Until version 3.2.3, most methods return - # bytes, but only accept strings. In addition, we want to - # output these strings with the logging module, which - # works with unicode strings. The explicit calls to - # unicode() below are harmless in python2 but will do the - # right conversion in python 3. - fg_color = (curses.tigetstr("setaf") or - curses.tigetstr("setf") or "") - if (3, 0) < sys.version_info < (3, 2, 3): - fg_color = str(fg_color, "ascii") - - for levelno, code in self.DEFAULT_COLORS.items(): - self._colors[levelno] = str( - curses.tparm(fg_color, code), "ascii") - self._normal = str(curses.tigetstr("sgr0"), "ascii") - - scr = curses.initscr() - self.termwidth = scr.getmaxyx()[1] - curses.endwin() - else: - self._normal = '' - # Default width is usually 80, but too wide is - # worse than too narrow - self.termwidth = 70 - - def formatMessage(self, record): - mlen = len(record.message) - right_text = '{initial}-{name}'.format(initial=record.levelname[0], - name=record.name) - if mlen + len(right_text) < self.termwidth: - space = ' ' * (self.termwidth - (mlen + len(right_text))) - else: - space = ' ' - - if record.levelno in self._colors: - start_color = self._colors[record.levelno] - end_color = self._normal - else: - start_color = end_color = '' - - return record.message + space + start_color + right_text + end_color - - -def enable_colourful_output(level=logging.INFO): - handler = logging.StreamHandler() - handler.setFormatter(LogFormatter()) - logging.root.addHandler(handler) - logging.root.setLevel(level) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/compat.py deleted file mode 100644 index 01c66fc..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/compat.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Handle reading and writing JSON in UTF-8, on Python 3 and 2.""" -import json -import sys - -if sys.version_info[0] >= 3: - # Python 3 - def write_json(obj, path, **kwargs): - with open(path, 'w', encoding='utf-8') as f: - json.dump(obj, f, **kwargs) - - def read_json(path): - with open(path, 'r', encoding='utf-8') as f: - return json.load(f) - -else: - # Python 2 - def write_json(obj, path, **kwargs): - with open(path, 'wb') as f: - json.dump(obj, f, encoding='utf-8', **kwargs) - - def read_json(path): - with open(path, 'rb') as f: - return json.load(f) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/envbuild.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/envbuild.py deleted file mode 100644 index f7ac5f4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/envbuild.py +++ /dev/null @@ -1,158 +0,0 @@ -"""Build wheels/sdists by installing build deps to a temporary environment. -""" - -import os -import logging -from pip._vendor import pytoml -import shutil -from subprocess import check_call -import sys -from sysconfig import get_paths -from tempfile import mkdtemp - -from .wrappers import Pep517HookCaller - -log = logging.getLogger(__name__) - - -def _load_pyproject(source_dir): - with open(os.path.join(source_dir, 'pyproject.toml')) as f: - pyproject_data = pytoml.load(f) - buildsys = pyproject_data['build-system'] - return buildsys['requires'], buildsys['build-backend'] - - -class BuildEnvironment(object): - """Context manager to install build deps in a simple temporary environment - - Based on code I wrote for pip, which is MIT licensed. - """ - # Copyright (c) 2008-2016 The pip developers (see AUTHORS.txt file) - # - # 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. - - path = None - - def __init__(self, cleanup=True): - self._cleanup = cleanup - - def __enter__(self): - self.path = mkdtemp(prefix='pep517-build-env-') - log.info('Temporary build environment: %s', self.path) - - self.save_path = os.environ.get('PATH', None) - self.save_pythonpath = os.environ.get('PYTHONPATH', None) - - install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' - install_dirs = get_paths(install_scheme, vars={ - 'base': self.path, - 'platbase': self.path, - }) - - scripts = install_dirs['scripts'] - if self.save_path: - os.environ['PATH'] = scripts + os.pathsep + self.save_path - else: - os.environ['PATH'] = scripts + os.pathsep + os.defpath - - if install_dirs['purelib'] == install_dirs['platlib']: - lib_dirs = install_dirs['purelib'] - else: - lib_dirs = install_dirs['purelib'] + os.pathsep + \ - install_dirs['platlib'] - if self.save_pythonpath: - os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ - self.save_pythonpath - else: - os.environ['PYTHONPATH'] = lib_dirs - - return self - - def pip_install(self, reqs): - """Install dependencies into this env by calling pip in a subprocess""" - if not reqs: - return - log.info('Calling pip to install %s', reqs) - check_call([ - sys.executable, '-m', 'pip', 'install', '--ignore-installed', - '--prefix', self.path] + list(reqs)) - - def __exit__(self, exc_type, exc_val, exc_tb): - needs_cleanup = ( - self._cleanup and - self.path is not None and - os.path.isdir(self.path) - ) - if needs_cleanup: - shutil.rmtree(self.path) - - if self.save_path is None: - os.environ.pop('PATH', None) - else: - os.environ['PATH'] = self.save_path - - if self.save_pythonpath is None: - os.environ.pop('PYTHONPATH', None) - else: - os.environ['PYTHONPATH'] = self.save_pythonpath - - -def build_wheel(source_dir, wheel_dir, config_settings=None): - """Build a wheel from a source directory using PEP 517 hooks. - - :param str source_dir: Source directory containing pyproject.toml - :param str wheel_dir: Target directory to create wheel in - :param dict config_settings: Options to pass to build backend - - This is a blocking function which will run pip in a subprocess to install - build requirements. - """ - if config_settings is None: - config_settings = {} - requires, backend = _load_pyproject(source_dir) - hooks = Pep517HookCaller(source_dir, backend) - - with BuildEnvironment() as env: - env.pip_install(requires) - reqs = hooks.get_requires_for_build_wheel(config_settings) - env.pip_install(reqs) - return hooks.build_wheel(wheel_dir, config_settings) - - -def build_sdist(source_dir, sdist_dir, config_settings=None): - """Build an sdist from a source directory using PEP 517 hooks. - - :param str source_dir: Source directory containing pyproject.toml - :param str sdist_dir: Target directory to place sdist in - :param dict config_settings: Options to pass to build backend - - This is a blocking function which will run pip in a subprocess to install - build requirements. - """ - if config_settings is None: - config_settings = {} - requires, backend = _load_pyproject(source_dir) - hooks = Pep517HookCaller(source_dir, backend) - - with BuildEnvironment() as env: - env.pip_install(requires) - reqs = hooks.get_requires_for_build_sdist(config_settings) - env.pip_install(reqs) - return hooks.build_sdist(sdist_dir, config_settings) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/wrappers.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/wrappers.py deleted file mode 100644 index b14b899..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pep517/wrappers.py +++ /dev/null @@ -1,163 +0,0 @@ -from contextlib import contextmanager -import os -from os.path import dirname, abspath, join as pjoin -import shutil -from subprocess import check_call -import sys -from tempfile import mkdtemp - -from . import compat - -_in_proc_script = pjoin(dirname(abspath(__file__)), '_in_process.py') - - -@contextmanager -def tempdir(): - td = mkdtemp() - try: - yield td - finally: - shutil.rmtree(td) - - -class BackendUnavailable(Exception): - """Will be raised if the backend cannot be imported in the hook process.""" - - -class UnsupportedOperation(Exception): - """May be raised by build_sdist if the backend indicates that it can't.""" - - -def default_subprocess_runner(cmd, cwd=None, extra_environ=None): - """The default method of calling the wrapper subprocess.""" - env = os.environ.copy() - if extra_environ: - env.update(extra_environ) - - check_call(cmd, cwd=cwd, env=env) - - -class Pep517HookCaller(object): - """A wrapper around a source directory to be built with a PEP 517 backend. - - source_dir : The path to the source directory, containing pyproject.toml. - backend : The build backend spec, as per PEP 517, from pyproject.toml. - """ - def __init__(self, source_dir, build_backend): - self.source_dir = abspath(source_dir) - self.build_backend = build_backend - self._subprocess_runner = default_subprocess_runner - - # TODO: Is this over-engineered? Maybe frontends only need to - # set this when creating the wrapper, not on every call. - @contextmanager - def subprocess_runner(self, runner): - prev = self._subprocess_runner - self._subprocess_runner = runner - yield - self._subprocess_runner = prev - - def get_requires_for_build_wheel(self, config_settings=None): - """Identify packages required for building a wheel - - Returns a list of dependency specifications, e.g.: - ["wheel >= 0.25", "setuptools"] - - This does not include requirements specified in pyproject.toml. - It returns the result of calling the equivalently named hook in a - subprocess. - """ - return self._call_hook('get_requires_for_build_wheel', { - 'config_settings': config_settings - }) - - def prepare_metadata_for_build_wheel( - self, metadata_directory, config_settings=None): - """Prepare a *.dist-info folder with metadata for this project. - - Returns the name of the newly created folder. - - If the build backend defines a hook with this name, it will be called - in a subprocess. If not, the backend will be asked to build a wheel, - and the dist-info extracted from that. - """ - return self._call_hook('prepare_metadata_for_build_wheel', { - 'metadata_directory': abspath(metadata_directory), - 'config_settings': config_settings, - }) - - def build_wheel( - self, wheel_directory, config_settings=None, - metadata_directory=None): - """Build a wheel from this project. - - Returns the name of the newly created file. - - In general, this will call the 'build_wheel' hook in the backend. - However, if that was previously called by - 'prepare_metadata_for_build_wheel', and the same metadata_directory is - used, the previously built wheel will be copied to wheel_directory. - """ - if metadata_directory is not None: - metadata_directory = abspath(metadata_directory) - return self._call_hook('build_wheel', { - 'wheel_directory': abspath(wheel_directory), - 'config_settings': config_settings, - 'metadata_directory': metadata_directory, - }) - - def get_requires_for_build_sdist(self, config_settings=None): - """Identify packages required for building a wheel - - Returns a list of dependency specifications, e.g.: - ["setuptools >= 26"] - - This does not include requirements specified in pyproject.toml. - It returns the result of calling the equivalently named hook in a - subprocess. - """ - return self._call_hook('get_requires_for_build_sdist', { - 'config_settings': config_settings - }) - - def build_sdist(self, sdist_directory, config_settings=None): - """Build an sdist from this project. - - Returns the name of the newly created file. - - This calls the 'build_sdist' backend hook in a subprocess. - """ - return self._call_hook('build_sdist', { - 'sdist_directory': abspath(sdist_directory), - 'config_settings': config_settings, - }) - - def _call_hook(self, hook_name, kwargs): - # On Python 2, pytoml returns Unicode values (which is correct) but the - # environment passed to check_call needs to contain string values. We - # convert here by encoding using ASCII (the backend can only contain - # letters, digits and _, . and : characters, and will be used as a - # Python identifier, so non-ASCII content is wrong on Python 2 in - # any case). - if sys.version_info[0] == 2: - build_backend = self.build_backend.encode('ASCII') - else: - build_backend = self.build_backend - - with tempdir() as td: - compat.write_json({'kwargs': kwargs}, pjoin(td, 'input.json'), - indent=2) - - # Run the hook in a subprocess - self._subprocess_runner( - [sys.executable, _in_proc_script, hook_name, td], - cwd=self.source_dir, - extra_environ={'PEP517_BUILD_BACKEND': build_backend} - ) - - data = compat.read_json(pjoin(td, 'output.json')) - if data.get('unsupported'): - raise UnsupportedOperation - if data.get('no_backend'): - raise BackendUnavailable - return data['return_val'] diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pkg_resources/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pkg_resources/__init__.py deleted file mode 100644 index 9c4fd8e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pkg_resources/__init__.py +++ /dev/null @@ -1,3171 +0,0 @@ -# coding: utf-8 -""" -Package resource API --------------------- - -A resource is a logical file contained within a package, or a logical -subdirectory thereof. The package resource API expects resource names -to have their path parts separated with ``/``, *not* whatever the local -path separator is. Do not use os.path operations to manipulate resource -names being passed into the API. - -The package resource API is designed to work with normal filesystem packages, -.egg files, and unpacked .egg files. It can also work in a limited way with -.zip files and with custom PEP 302 loaders that support the ``get_data()`` -method. -""" - -from __future__ import absolute_import - -import sys -import os -import io -import time -import re -import types -import zipfile -import zipimport -import warnings -import stat -import functools -import pkgutil -import operator -import platform -import collections -import plistlib -import email.parser -import errno -import tempfile -import textwrap -import itertools -import inspect -from pkgutil import get_importer - -try: - import _imp -except ImportError: - # Python 3.2 compatibility - import imp as _imp - -try: - FileExistsError -except NameError: - FileExistsError = OSError - -from pip._vendor import six -from pip._vendor.six.moves import urllib, map, filter - -# capture these to bypass sandboxing -from os import utime -try: - from os import mkdir, rename, unlink - WRITE_SUPPORT = True -except ImportError: - # no write support, probably under GAE - WRITE_SUPPORT = False - -from os import open as os_open -from os.path import isdir, split - -try: - import importlib.machinery as importlib_machinery - # access attribute to force import under delayed import mechanisms. - importlib_machinery.__name__ -except ImportError: - importlib_machinery = None - -from . import py31compat -from pip._vendor import appdirs -from pip._vendor import packaging -__import__('pip._vendor.packaging.version') -__import__('pip._vendor.packaging.specifiers') -__import__('pip._vendor.packaging.requirements') -__import__('pip._vendor.packaging.markers') - - -__metaclass__ = type - - -if (3, 0) < sys.version_info < (3, 4): - raise RuntimeError("Python 3.4 or later is required") - -if six.PY2: - # Those builtin exceptions are only defined in Python 3 - PermissionError = None - NotADirectoryError = None - -# declare some globals that will be defined later to -# satisfy the linters. -require = None -working_set = None -add_activation_listener = None -resources_stream = None -cleanup_resources = None -resource_dir = None -resource_stream = None -set_extraction_path = None -resource_isdir = None -resource_string = None -iter_entry_points = None -resource_listdir = None -resource_filename = None -resource_exists = None -_distribution_finders = None -_namespace_handlers = None -_namespace_packages = None - - -class PEP440Warning(RuntimeWarning): - """ - Used when there is an issue with a version or specifier not complying with - PEP 440. - """ - - -def parse_version(v): - try: - return packaging.version.Version(v) - except packaging.version.InvalidVersion: - return packaging.version.LegacyVersion(v) - - -_state_vars = {} - - -def _declare_state(vartype, **kw): - globals().update(kw) - _state_vars.update(dict.fromkeys(kw, vartype)) - - -def __getstate__(): - state = {} - g = globals() - for k, v in _state_vars.items(): - state[k] = g['_sget_' + v](g[k]) - return state - - -def __setstate__(state): - g = globals() - for k, v in state.items(): - g['_sset_' + _state_vars[k]](k, g[k], v) - return state - - -def _sget_dict(val): - return val.copy() - - -def _sset_dict(key, ob, state): - ob.clear() - ob.update(state) - - -def _sget_object(val): - return val.__getstate__() - - -def _sset_object(key, ob, state): - ob.__setstate__(state) - - -_sget_none = _sset_none = lambda *args: None - - -def get_supported_platform(): - """Return this platform's maximum compatible version. - - distutils.util.get_platform() normally reports the minimum version - of Mac OS X that would be required to *use* extensions produced by - distutils. But what we want when checking compatibility is to know the - version of Mac OS X that we are *running*. To allow usage of packages that - explicitly require a newer version of Mac OS X, we must also know the - current version of the OS. - - If this condition occurs for any other platform with a version in its - platform strings, this function should be extended accordingly. - """ - plat = get_build_platform() - m = macosVersionString.match(plat) - if m is not None and sys.platform == "darwin": - try: - plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) - except ValueError: - # not Mac OS X - pass - return plat - - -__all__ = [ - # Basic resource access and distribution/entry point discovery - 'require', 'run_script', 'get_provider', 'get_distribution', - 'load_entry_point', 'get_entry_map', 'get_entry_info', - 'iter_entry_points', - 'resource_string', 'resource_stream', 'resource_filename', - 'resource_listdir', 'resource_exists', 'resource_isdir', - - # Environmental control - 'declare_namespace', 'working_set', 'add_activation_listener', - 'find_distributions', 'set_extraction_path', 'cleanup_resources', - 'get_default_cache', - - # Primary implementation classes - 'Environment', 'WorkingSet', 'ResourceManager', - 'Distribution', 'Requirement', 'EntryPoint', - - # Exceptions - 'ResolutionError', 'VersionConflict', 'DistributionNotFound', - 'UnknownExtra', 'ExtractionError', - - # Warnings - 'PEP440Warning', - - # Parsing functions and string utilities - 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', - 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', - 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', - - # filesystem utilities - 'ensure_directory', 'normalize_path', - - # Distribution "precedence" constants - 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', - - # "Provider" interfaces, implementations, and registration/lookup APIs - 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', - 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', - 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', - 'register_finder', 'register_namespace_handler', 'register_loader_type', - 'fixup_namespace_packages', 'get_importer', - - # Warnings - 'PkgResourcesDeprecationWarning', - - # Deprecated/backward compatibility only - 'run_main', 'AvailableDistributions', -] - - -class ResolutionError(Exception): - """Abstract base for dependency resolution errors""" - - def __repr__(self): - return self.__class__.__name__ + repr(self.args) - - -class VersionConflict(ResolutionError): - """ - An already-installed version conflicts with the requested version. - - Should be initialized with the installed Distribution and the requested - Requirement. - """ - - _template = "{self.dist} is installed but {self.req} is required" - - @property - def dist(self): - return self.args[0] - - @property - def req(self): - return self.args[1] - - def report(self): - return self._template.format(**locals()) - - def with_context(self, required_by): - """ - If required_by is non-empty, return a version of self that is a - ContextualVersionConflict. - """ - if not required_by: - return self - args = self.args + (required_by,) - return ContextualVersionConflict(*args) - - -class ContextualVersionConflict(VersionConflict): - """ - A VersionConflict that accepts a third parameter, the set of the - requirements that required the installed Distribution. - """ - - _template = VersionConflict._template + ' by {self.required_by}' - - @property - def required_by(self): - return self.args[2] - - -class DistributionNotFound(ResolutionError): - """A requested distribution was not found""" - - _template = ("The '{self.req}' distribution was not found " - "and is required by {self.requirers_str}") - - @property - def req(self): - return self.args[0] - - @property - def requirers(self): - return self.args[1] - - @property - def requirers_str(self): - if not self.requirers: - return 'the application' - return ', '.join(self.requirers) - - def report(self): - return self._template.format(**locals()) - - def __str__(self): - return self.report() - - -class UnknownExtra(ResolutionError): - """Distribution doesn't have an "extra feature" of the given name""" - - -_provider_factories = {} - -PY_MAJOR = sys.version[:3] -EGG_DIST = 3 -BINARY_DIST = 2 -SOURCE_DIST = 1 -CHECKOUT_DIST = 0 -DEVELOP_DIST = -1 - - -def register_loader_type(loader_type, provider_factory): - """Register `provider_factory` to make providers for `loader_type` - - `loader_type` is the type or class of a PEP 302 ``module.__loader__``, - and `provider_factory` is a function that, passed a *module* object, - returns an ``IResourceProvider`` for that module. - """ - _provider_factories[loader_type] = provider_factory - - -def get_provider(moduleOrReq): - """Return an IResourceProvider for the named module or requirement""" - if isinstance(moduleOrReq, Requirement): - return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] - try: - module = sys.modules[moduleOrReq] - except KeyError: - __import__(moduleOrReq) - module = sys.modules[moduleOrReq] - loader = getattr(module, '__loader__', None) - return _find_adapter(_provider_factories, loader)(module) - - -def _macosx_vers(_cache=[]): - if not _cache: - version = platform.mac_ver()[0] - # fallback for MacPorts - if version == '': - plist = '/System/Library/CoreServices/SystemVersion.plist' - if os.path.exists(plist): - if hasattr(plistlib, 'readPlist'): - plist_content = plistlib.readPlist(plist) - if 'ProductVersion' in plist_content: - version = plist_content['ProductVersion'] - - _cache.append(version.split('.')) - return _cache[0] - - -def _macosx_arch(machine): - return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) - - -def get_build_platform(): - """Return this platform's string for platform-specific distributions - - XXX Currently this is the same as ``distutils.util.get_platform()``, but it - needs some hacks for Linux and Mac OS X. - """ - from sysconfig import get_platform - - plat = get_platform() - if sys.platform == "darwin" and not plat.startswith('macosx-'): - try: - version = _macosx_vers() - machine = os.uname()[4].replace(" ", "_") - return "macosx-%d.%d-%s" % ( - int(version[0]), int(version[1]), - _macosx_arch(machine), - ) - except ValueError: - # if someone is running a non-Mac darwin system, this will fall - # through to the default implementation - pass - return plat - - -macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") -darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") -# XXX backward compat -get_platform = get_build_platform - - -def compatible_platforms(provided, required): - """Can code for the `provided` platform run on the `required` platform? - - Returns true if either platform is ``None``, or the platforms are equal. - - XXX Needs compatibility checks for Linux and other unixy OSes. - """ - if provided is None or required is None or provided == required: - # easy case - return True - - # Mac OS X special cases - reqMac = macosVersionString.match(required) - if reqMac: - provMac = macosVersionString.match(provided) - - # is this a Mac package? - if not provMac: - # this is backwards compatibility for packages built before - # setuptools 0.6. All packages built after this point will - # use the new macosx designation. - provDarwin = darwinVersionString.match(provided) - if provDarwin: - dversion = int(provDarwin.group(1)) - macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) - if dversion == 7 and macosversion >= "10.3" or \ - dversion == 8 and macosversion >= "10.4": - return True - # egg isn't macosx or legacy darwin - return False - - # are they the same major version and machine type? - if provMac.group(1) != reqMac.group(1) or \ - provMac.group(3) != reqMac.group(3): - return False - - # is the required OS major update >= the provided one? - if int(provMac.group(2)) > int(reqMac.group(2)): - return False - - return True - - # XXX Linux and other platforms' special cases should go here - return False - - -def run_script(dist_spec, script_name): - """Locate distribution `dist_spec` and run its `script_name` script""" - ns = sys._getframe(1).f_globals - name = ns['__name__'] - ns.clear() - ns['__name__'] = name - require(dist_spec)[0].run_script(script_name, ns) - - -# backward compatibility -run_main = run_script - - -def get_distribution(dist): - """Return a current distribution object for a Requirement or string""" - if isinstance(dist, six.string_types): - dist = Requirement.parse(dist) - if isinstance(dist, Requirement): - dist = get_provider(dist) - if not isinstance(dist, Distribution): - raise TypeError("Expected string, Requirement, or Distribution", dist) - return dist - - -def load_entry_point(dist, group, name): - """Return `name` entry point of `group` for `dist` or raise ImportError""" - return get_distribution(dist).load_entry_point(group, name) - - -def get_entry_map(dist, group=None): - """Return the entry point map for `group`, or the full entry map""" - return get_distribution(dist).get_entry_map(group) - - -def get_entry_info(dist, group, name): - """Return the EntryPoint object for `group`+`name`, or ``None``""" - return get_distribution(dist).get_entry_info(group, name) - - -class IMetadataProvider: - def has_metadata(name): - """Does the package's distribution contain the named metadata?""" - - def get_metadata(name): - """The named metadata resource as a string""" - - def get_metadata_lines(name): - """Yield named metadata resource as list of non-blank non-comment lines - - Leading and trailing whitespace is stripped from each line, and lines - with ``#`` as the first non-blank character are omitted.""" - - def metadata_isdir(name): - """Is the named metadata a directory? (like ``os.path.isdir()``)""" - - def metadata_listdir(name): - """List of metadata names in the directory (like ``os.listdir()``)""" - - def run_script(script_name, namespace): - """Execute the named script in the supplied namespace dictionary""" - - -class IResourceProvider(IMetadataProvider): - """An object that provides access to package resources""" - - def get_resource_filename(manager, resource_name): - """Return a true filesystem path for `resource_name` - - `manager` must be an ``IResourceManager``""" - - def get_resource_stream(manager, resource_name): - """Return a readable file-like object for `resource_name` - - `manager` must be an ``IResourceManager``""" - - def get_resource_string(manager, resource_name): - """Return a string containing the contents of `resource_name` - - `manager` must be an ``IResourceManager``""" - - def has_resource(resource_name): - """Does the package contain the named resource?""" - - def resource_isdir(resource_name): - """Is the named resource a directory? (like ``os.path.isdir()``)""" - - def resource_listdir(resource_name): - """List of resource names in the directory (like ``os.listdir()``)""" - - -class WorkingSet: - """A collection of active distributions on sys.path (or a similar list)""" - - def __init__(self, entries=None): - """Create working set from list of path entries (default=sys.path)""" - self.entries = [] - self.entry_keys = {} - self.by_key = {} - self.callbacks = [] - - if entries is None: - entries = sys.path - - for entry in entries: - self.add_entry(entry) - - @classmethod - def _build_master(cls): - """ - Prepare the master working set. - """ - ws = cls() - try: - from __main__ import __requires__ - except ImportError: - # The main program does not list any requirements - return ws - - # ensure the requirements are met - try: - ws.require(__requires__) - except VersionConflict: - return cls._build_from_requirements(__requires__) - - return ws - - @classmethod - def _build_from_requirements(cls, req_spec): - """ - Build a working set from a requirement spec. Rewrites sys.path. - """ - # try it without defaults already on sys.path - # by starting with an empty path - ws = cls([]) - reqs = parse_requirements(req_spec) - dists = ws.resolve(reqs, Environment()) - for dist in dists: - ws.add(dist) - - # add any missing entries from sys.path - for entry in sys.path: - if entry not in ws.entries: - ws.add_entry(entry) - - # then copy back to sys.path - sys.path[:] = ws.entries - return ws - - def add_entry(self, entry): - """Add a path item to ``.entries``, finding any distributions on it - - ``find_distributions(entry, True)`` is used to find distributions - corresponding to the path entry, and they are added. `entry` is - always appended to ``.entries``, even if it is already present. - (This is because ``sys.path`` can contain the same value more than - once, and the ``.entries`` of the ``sys.path`` WorkingSet should always - equal ``sys.path``.) - """ - self.entry_keys.setdefault(entry, []) - self.entries.append(entry) - for dist in find_distributions(entry, True): - self.add(dist, entry, False) - - def __contains__(self, dist): - """True if `dist` is the active distribution for its project""" - return self.by_key.get(dist.key) == dist - - def find(self, req): - """Find a distribution matching requirement `req` - - If there is an active distribution for the requested project, this - returns it as long as it meets the version requirement specified by - `req`. But, if there is an active distribution for the project and it - does *not* meet the `req` requirement, ``VersionConflict`` is raised. - If there is no active distribution for the requested project, ``None`` - is returned. - """ - dist = self.by_key.get(req.key) - if dist is not None and dist not in req: - # XXX add more info - raise VersionConflict(dist, req) - return dist - - def iter_entry_points(self, group, name=None): - """Yield entry point objects from `group` matching `name` - - If `name` is None, yields all entry points in `group` from all - distributions in the working set, otherwise only ones matching - both `group` and `name` are yielded (in distribution order). - """ - return ( - entry - for dist in self - for entry in dist.get_entry_map(group).values() - if name is None or name == entry.name - ) - - def run_script(self, requires, script_name): - """Locate distribution for `requires` and run `script_name` script""" - ns = sys._getframe(1).f_globals - name = ns['__name__'] - ns.clear() - ns['__name__'] = name - self.require(requires)[0].run_script(script_name, ns) - - def __iter__(self): - """Yield distributions for non-duplicate projects in the working set - - The yield order is the order in which the items' path entries were - added to the working set. - """ - seen = {} - for item in self.entries: - if item not in self.entry_keys: - # workaround a cache issue - continue - - for key in self.entry_keys[item]: - if key not in seen: - seen[key] = 1 - yield self.by_key[key] - - def add(self, dist, entry=None, insert=True, replace=False): - """Add `dist` to working set, associated with `entry` - - If `entry` is unspecified, it defaults to the ``.location`` of `dist`. - On exit from this routine, `entry` is added to the end of the working - set's ``.entries`` (if it wasn't already present). - - `dist` is only added to the working set if it's for a project that - doesn't already have a distribution in the set, unless `replace=True`. - If it's added, any callbacks registered with the ``subscribe()`` method - will be called. - """ - if insert: - dist.insert_on(self.entries, entry, replace=replace) - - if entry is None: - entry = dist.location - keys = self.entry_keys.setdefault(entry, []) - keys2 = self.entry_keys.setdefault(dist.location, []) - if not replace and dist.key in self.by_key: - # ignore hidden distros - return - - self.by_key[dist.key] = dist - if dist.key not in keys: - keys.append(dist.key) - if dist.key not in keys2: - keys2.append(dist.key) - self._added_new(dist) - - def resolve(self, requirements, env=None, installer=None, - replace_conflicting=False, extras=None): - """List all distributions needed to (recursively) meet `requirements` - - `requirements` must be a sequence of ``Requirement`` objects. `env`, - if supplied, should be an ``Environment`` instance. If - not supplied, it defaults to all distributions available within any - entry or distribution in the working set. `installer`, if supplied, - will be invoked with each requirement that cannot be met by an - already-installed distribution; it should return a ``Distribution`` or - ``None``. - - Unless `replace_conflicting=True`, raises a VersionConflict exception - if - any requirements are found on the path that have the correct name but - the wrong version. Otherwise, if an `installer` is supplied it will be - invoked to obtain the correct version of the requirement and activate - it. - - `extras` is a list of the extras to be used with these requirements. - This is important because extra requirements may look like `my_req; - extra = "my_extra"`, which would otherwise be interpreted as a purely - optional requirement. Instead, we want to be able to assert that these - requirements are truly required. - """ - - # set up the stack - requirements = list(requirements)[::-1] - # set of processed requirements - processed = {} - # key -> dist - best = {} - to_activate = [] - - req_extras = _ReqExtras() - - # Mapping of requirement to set of distributions that required it; - # useful for reporting info about conflicts. - required_by = collections.defaultdict(set) - - while requirements: - # process dependencies breadth-first - req = requirements.pop(0) - if req in processed: - # Ignore cyclic or redundant dependencies - continue - - if not req_extras.markers_pass(req, extras): - continue - - dist = best.get(req.key) - if dist is None: - # Find the best distribution and add it to the map - dist = self.by_key.get(req.key) - if dist is None or (dist not in req and replace_conflicting): - ws = self - if env is None: - if dist is None: - env = Environment(self.entries) - else: - # Use an empty environment and workingset to avoid - # any further conflicts with the conflicting - # distribution - env = Environment([]) - ws = WorkingSet([]) - dist = best[req.key] = env.best_match( - req, ws, installer, - replace_conflicting=replace_conflicting - ) - if dist is None: - requirers = required_by.get(req, None) - raise DistributionNotFound(req, requirers) - to_activate.append(dist) - if dist not in req: - # Oops, the "best" so far conflicts with a dependency - dependent_req = required_by[req] - raise VersionConflict(dist, req).with_context(dependent_req) - - # push the new requirements onto the stack - new_requirements = dist.requires(req.extras)[::-1] - requirements.extend(new_requirements) - - # Register the new requirements needed by req - for new_requirement in new_requirements: - required_by[new_requirement].add(req.project_name) - req_extras[new_requirement] = req.extras - - processed[req] = True - - # return list of distros to activate - return to_activate - - def find_plugins( - self, plugin_env, full_env=None, installer=None, fallback=True): - """Find all activatable distributions in `plugin_env` - - Example usage:: - - distributions, errors = working_set.find_plugins( - Environment(plugin_dirlist) - ) - # add plugins+libs to sys.path - map(working_set.add, distributions) - # display errors - print('Could not load', errors) - - The `plugin_env` should be an ``Environment`` instance that contains - only distributions that are in the project's "plugin directory" or - directories. The `full_env`, if supplied, should be an ``Environment`` - contains all currently-available distributions. If `full_env` is not - supplied, one is created automatically from the ``WorkingSet`` this - method is called on, which will typically mean that every directory on - ``sys.path`` will be scanned for distributions. - - `installer` is a standard installer callback as used by the - ``resolve()`` method. The `fallback` flag indicates whether we should - attempt to resolve older versions of a plugin if the newest version - cannot be resolved. - - This method returns a 2-tuple: (`distributions`, `error_info`), where - `distributions` is a list of the distributions found in `plugin_env` - that were loadable, along with any other distributions that are needed - to resolve their dependencies. `error_info` is a dictionary mapping - unloadable plugin distributions to an exception instance describing the - error that occurred. Usually this will be a ``DistributionNotFound`` or - ``VersionConflict`` instance. - """ - - plugin_projects = list(plugin_env) - # scan project names in alphabetic order - plugin_projects.sort() - - error_info = {} - distributions = {} - - if full_env is None: - env = Environment(self.entries) - env += plugin_env - else: - env = full_env + plugin_env - - shadow_set = self.__class__([]) - # put all our entries in shadow_set - list(map(shadow_set.add, self)) - - for project_name in plugin_projects: - - for dist in plugin_env[project_name]: - - req = [dist.as_requirement()] - - try: - resolvees = shadow_set.resolve(req, env, installer) - - except ResolutionError as v: - # save error info - error_info[dist] = v - if fallback: - # try the next older version of project - continue - else: - # give up on this project, keep going - break - - else: - list(map(shadow_set.add, resolvees)) - distributions.update(dict.fromkeys(resolvees)) - - # success, no need to try any more versions of this project - break - - distributions = list(distributions) - distributions.sort() - - return distributions, error_info - - def require(self, *requirements): - """Ensure that distributions matching `requirements` are activated - - `requirements` must be a string or a (possibly-nested) sequence - thereof, specifying the distributions and versions required. The - return value is a sequence of the distributions that needed to be - activated to fulfill the requirements; all relevant distributions are - included, even if they were already activated in this working set. - """ - needed = self.resolve(parse_requirements(requirements)) - - for dist in needed: - self.add(dist) - - return needed - - def subscribe(self, callback, existing=True): - """Invoke `callback` for all distributions - - If `existing=True` (default), - call on all existing ones, as well. - """ - if callback in self.callbacks: - return - self.callbacks.append(callback) - if not existing: - return - for dist in self: - callback(dist) - - def _added_new(self, dist): - for callback in self.callbacks: - callback(dist) - - def __getstate__(self): - return ( - self.entries[:], self.entry_keys.copy(), self.by_key.copy(), - self.callbacks[:] - ) - - def __setstate__(self, e_k_b_c): - entries, keys, by_key, callbacks = e_k_b_c - self.entries = entries[:] - self.entry_keys = keys.copy() - self.by_key = by_key.copy() - self.callbacks = callbacks[:] - - -class _ReqExtras(dict): - """ - Map each requirement to the extras that demanded it. - """ - - def markers_pass(self, req, extras=None): - """ - Evaluate markers for req against each extra that - demanded it. - - Return False if the req has a marker and fails - evaluation. Otherwise, return True. - """ - extra_evals = ( - req.marker.evaluate({'extra': extra}) - for extra in self.get(req, ()) + (extras or (None,)) - ) - return not req.marker or any(extra_evals) - - -class Environment: - """Searchable snapshot of distributions on a search path""" - - def __init__( - self, search_path=None, platform=get_supported_platform(), - python=PY_MAJOR): - """Snapshot distributions available on a search path - - Any distributions found on `search_path` are added to the environment. - `search_path` should be a sequence of ``sys.path`` items. If not - supplied, ``sys.path`` is used. - - `platform` is an optional string specifying the name of the platform - that platform-specific distributions must be compatible with. If - unspecified, it defaults to the current platform. `python` is an - optional string naming the desired version of Python (e.g. ``'3.6'``); - it defaults to the current version. - - You may explicitly set `platform` (and/or `python`) to ``None`` if you - wish to map *all* distributions, not just those compatible with the - running platform or Python version. - """ - self._distmap = {} - self.platform = platform - self.python = python - self.scan(search_path) - - def can_add(self, dist): - """Is distribution `dist` acceptable for this environment? - - The distribution must match the platform and python version - requirements specified when this environment was created, or False - is returned. - """ - py_compat = ( - self.python is None - or dist.py_version is None - or dist.py_version == self.python - ) - return py_compat and compatible_platforms(dist.platform, self.platform) - - def remove(self, dist): - """Remove `dist` from the environment""" - self._distmap[dist.key].remove(dist) - - def scan(self, search_path=None): - """Scan `search_path` for distributions usable in this environment - - Any distributions found are added to the environment. - `search_path` should be a sequence of ``sys.path`` items. If not - supplied, ``sys.path`` is used. Only distributions conforming to - the platform/python version defined at initialization are added. - """ - if search_path is None: - search_path = sys.path - - for item in search_path: - for dist in find_distributions(item): - self.add(dist) - - def __getitem__(self, project_name): - """Return a newest-to-oldest list of distributions for `project_name` - - Uses case-insensitive `project_name` comparison, assuming all the - project's distributions use their project's name converted to all - lowercase as their key. - - """ - distribution_key = project_name.lower() - return self._distmap.get(distribution_key, []) - - def add(self, dist): - """Add `dist` if we ``can_add()`` it and it has not already been added - """ - if self.can_add(dist) and dist.has_version(): - dists = self._distmap.setdefault(dist.key, []) - if dist not in dists: - dists.append(dist) - dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) - - def best_match( - self, req, working_set, installer=None, replace_conflicting=False): - """Find distribution best matching `req` and usable on `working_set` - - This calls the ``find(req)`` method of the `working_set` to see if a - suitable distribution is already active. (This may raise - ``VersionConflict`` if an unsuitable version of the project is already - active in the specified `working_set`.) If a suitable distribution - isn't active, this method returns the newest distribution in the - environment that meets the ``Requirement`` in `req`. If no suitable - distribution is found, and `installer` is supplied, then the result of - calling the environment's ``obtain(req, installer)`` method will be - returned. - """ - try: - dist = working_set.find(req) - except VersionConflict: - if not replace_conflicting: - raise - dist = None - if dist is not None: - return dist - for dist in self[req.key]: - if dist in req: - return dist - # try to download/install - return self.obtain(req, installer) - - def obtain(self, requirement, installer=None): - """Obtain a distribution matching `requirement` (e.g. via download) - - Obtain a distro that matches requirement (e.g. via download). In the - base ``Environment`` class, this routine just returns - ``installer(requirement)``, unless `installer` is None, in which case - None is returned instead. This method is a hook that allows subclasses - to attempt other ways of obtaining a distribution before falling back - to the `installer` argument.""" - if installer is not None: - return installer(requirement) - - def __iter__(self): - """Yield the unique project names of the available distributions""" - for key in self._distmap.keys(): - if self[key]: - yield key - - def __iadd__(self, other): - """In-place addition of a distribution or environment""" - if isinstance(other, Distribution): - self.add(other) - elif isinstance(other, Environment): - for project in other: - for dist in other[project]: - self.add(dist) - else: - raise TypeError("Can't add %r to environment" % (other,)) - return self - - def __add__(self, other): - """Add an environment or distribution to an environment""" - new = self.__class__([], platform=None, python=None) - for env in self, other: - new += env - return new - - -# XXX backward compatibility -AvailableDistributions = Environment - - -class ExtractionError(RuntimeError): - """An error occurred extracting a resource - - The following attributes are available from instances of this exception: - - manager - The resource manager that raised this exception - - cache_path - The base directory for resource extraction - - original_error - The exception instance that caused extraction to fail - """ - - -class ResourceManager: - """Manage resource extraction and packages""" - extraction_path = None - - def __init__(self): - self.cached_files = {} - - def resource_exists(self, package_or_requirement, resource_name): - """Does the named resource exist?""" - return get_provider(package_or_requirement).has_resource(resource_name) - - def resource_isdir(self, package_or_requirement, resource_name): - """Is the named resource an existing directory?""" - return get_provider(package_or_requirement).resource_isdir( - resource_name - ) - - def resource_filename(self, package_or_requirement, resource_name): - """Return a true filesystem path for specified resource""" - return get_provider(package_or_requirement).get_resource_filename( - self, resource_name - ) - - def resource_stream(self, package_or_requirement, resource_name): - """Return a readable file-like object for specified resource""" - return get_provider(package_or_requirement).get_resource_stream( - self, resource_name - ) - - def resource_string(self, package_or_requirement, resource_name): - """Return specified resource as a string""" - return get_provider(package_or_requirement).get_resource_string( - self, resource_name - ) - - def resource_listdir(self, package_or_requirement, resource_name): - """List the contents of the named resource directory""" - return get_provider(package_or_requirement).resource_listdir( - resource_name - ) - - def extraction_error(self): - """Give an error message for problems extracting file(s)""" - - old_exc = sys.exc_info()[1] - cache_path = self.extraction_path or get_default_cache() - - tmpl = textwrap.dedent(""" - Can't extract file(s) to egg cache - - The following error occurred while trying to extract file(s) - to the Python egg cache: - - {old_exc} - - The Python egg cache directory is currently set to: - - {cache_path} - - Perhaps your account does not have write access to this directory? - You can change the cache directory by setting the PYTHON_EGG_CACHE - environment variable to point to an accessible directory. - """).lstrip() - err = ExtractionError(tmpl.format(**locals())) - err.manager = self - err.cache_path = cache_path - err.original_error = old_exc - raise err - - def get_cache_path(self, archive_name, names=()): - """Return absolute location in cache for `archive_name` and `names` - - The parent directory of the resulting path will be created if it does - not already exist. `archive_name` should be the base filename of the - enclosing egg (which may not be the name of the enclosing zipfile!), - including its ".egg" extension. `names`, if provided, should be a - sequence of path name parts "under" the egg's extraction location. - - This method should only be called by resource providers that need to - obtain an extraction location, and only for names they intend to - extract, as it tracks the generated names for possible cleanup later. - """ - extract_path = self.extraction_path or get_default_cache() - target_path = os.path.join(extract_path, archive_name + '-tmp', *names) - try: - _bypass_ensure_directory(target_path) - except Exception: - self.extraction_error() - - self._warn_unsafe_extraction_path(extract_path) - - self.cached_files[target_path] = 1 - return target_path - - @staticmethod - def _warn_unsafe_extraction_path(path): - """ - If the default extraction path is overridden and set to an insecure - location, such as /tmp, it opens up an opportunity for an attacker to - replace an extracted file with an unauthorized payload. Warn the user - if a known insecure location is used. - - See Distribute #375 for more details. - """ - if os.name == 'nt' and not path.startswith(os.environ['windir']): - # On Windows, permissions are generally restrictive by default - # and temp directories are not writable by other users, so - # bypass the warning. - return - mode = os.stat(path).st_mode - if mode & stat.S_IWOTH or mode & stat.S_IWGRP: - msg = ( - "%s is writable by group/others and vulnerable to attack " - "when " - "used with get_resource_filename. Consider a more secure " - "location (set with .set_extraction_path or the " - "PYTHON_EGG_CACHE environment variable)." % path - ) - warnings.warn(msg, UserWarning) - - def postprocess(self, tempname, filename): - """Perform any platform-specific postprocessing of `tempname` - - This is where Mac header rewrites should be done; other platforms don't - have anything special they should do. - - Resource providers should call this method ONLY after successfully - extracting a compressed resource. They must NOT call it on resources - that are already in the filesystem. - - `tempname` is the current (temporary) name of the file, and `filename` - is the name it will be renamed to by the caller after this routine - returns. - """ - - if os.name == 'posix': - # Make the resource executable - mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 - os.chmod(tempname, mode) - - def set_extraction_path(self, path): - """Set the base path where resources will be extracted to, if needed. - - If you do not call this routine before any extractions take place, the - path defaults to the return value of ``get_default_cache()``. (Which - is based on the ``PYTHON_EGG_CACHE`` environment variable, with various - platform-specific fallbacks. See that routine's documentation for more - details.) - - Resources are extracted to subdirectories of this path based upon - information given by the ``IResourceProvider``. You may set this to a - temporary directory, but then you must call ``cleanup_resources()`` to - delete the extracted files when done. There is no guarantee that - ``cleanup_resources()`` will be able to remove all extracted files. - - (Note: you may not change the extraction path for a given resource - manager once resources have been extracted, unless you first call - ``cleanup_resources()``.) - """ - if self.cached_files: - raise ValueError( - "Can't change extraction path, files already extracted" - ) - - self.extraction_path = path - - def cleanup_resources(self, force=False): - """ - Delete all extracted resource files and directories, returning a list - of the file and directory names that could not be successfully removed. - This function does not have any concurrency protection, so it should - generally only be called when the extraction path is a temporary - directory exclusive to a single process. This method is not - automatically called; you must call it explicitly or register it as an - ``atexit`` function if you wish to ensure cleanup of a temporary - directory used for extractions. - """ - # XXX - - -def get_default_cache(): - """ - Return the ``PYTHON_EGG_CACHE`` environment variable - or a platform-relevant user cache dir for an app - named "Python-Eggs". - """ - return ( - os.environ.get('PYTHON_EGG_CACHE') - or appdirs.user_cache_dir(appname='Python-Eggs') - ) - - -def safe_name(name): - """Convert an arbitrary string to a standard distribution name - - Any runs of non-alphanumeric/. characters are replaced with a single '-'. - """ - return re.sub('[^A-Za-z0-9.]+', '-', name) - - -def safe_version(version): - """ - Convert an arbitrary string to a standard version string - """ - try: - # normalize the version - return str(packaging.version.Version(version)) - except packaging.version.InvalidVersion: - version = version.replace(' ', '.') - return re.sub('[^A-Za-z0-9.]+', '-', version) - - -def safe_extra(extra): - """Convert an arbitrary string to a standard 'extra' name - - Any runs of non-alphanumeric characters are replaced with a single '_', - and the result is always lowercased. - """ - return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() - - -def to_filename(name): - """Convert a project or version name to its filename-escaped form - - Any '-' characters are currently replaced with '_'. - """ - return name.replace('-', '_') - - -def invalid_marker(text): - """ - Validate text as a PEP 508 environment marker; return an exception - if invalid or False otherwise. - """ - try: - evaluate_marker(text) - except SyntaxError as e: - e.filename = None - e.lineno = None - return e - return False - - -def evaluate_marker(text, extra=None): - """ - Evaluate a PEP 508 environment marker. - Return a boolean indicating the marker result in this environment. - Raise SyntaxError if marker is invalid. - - This implementation uses the 'pyparsing' module. - """ - try: - marker = packaging.markers.Marker(text) - return marker.evaluate() - except packaging.markers.InvalidMarker as e: - raise SyntaxError(e) - - -class NullProvider: - """Try to implement resources and metadata for arbitrary PEP 302 loaders""" - - egg_name = None - egg_info = None - loader = None - - def __init__(self, module): - self.loader = getattr(module, '__loader__', None) - self.module_path = os.path.dirname(getattr(module, '__file__', '')) - - def get_resource_filename(self, manager, resource_name): - return self._fn(self.module_path, resource_name) - - def get_resource_stream(self, manager, resource_name): - return io.BytesIO(self.get_resource_string(manager, resource_name)) - - def get_resource_string(self, manager, resource_name): - return self._get(self._fn(self.module_path, resource_name)) - - def has_resource(self, resource_name): - return self._has(self._fn(self.module_path, resource_name)) - - def has_metadata(self, name): - return self.egg_info and self._has(self._fn(self.egg_info, name)) - - def get_metadata(self, name): - if not self.egg_info: - return "" - value = self._get(self._fn(self.egg_info, name)) - return value.decode('utf-8') if six.PY3 else value - - def get_metadata_lines(self, name): - return yield_lines(self.get_metadata(name)) - - def resource_isdir(self, resource_name): - return self._isdir(self._fn(self.module_path, resource_name)) - - def metadata_isdir(self, name): - return self.egg_info and self._isdir(self._fn(self.egg_info, name)) - - def resource_listdir(self, resource_name): - return self._listdir(self._fn(self.module_path, resource_name)) - - def metadata_listdir(self, name): - if self.egg_info: - return self._listdir(self._fn(self.egg_info, name)) - return [] - - def run_script(self, script_name, namespace): - script = 'scripts/' + script_name - if not self.has_metadata(script): - raise ResolutionError( - "Script {script!r} not found in metadata at {self.egg_info!r}" - .format(**locals()), - ) - script_text = self.get_metadata(script).replace('\r\n', '\n') - script_text = script_text.replace('\r', '\n') - script_filename = self._fn(self.egg_info, script) - namespace['__file__'] = script_filename - if os.path.exists(script_filename): - source = open(script_filename).read() - code = compile(source, script_filename, 'exec') - exec(code, namespace, namespace) - else: - from linecache import cache - cache[script_filename] = ( - len(script_text), 0, script_text.split('\n'), script_filename - ) - script_code = compile(script_text, script_filename, 'exec') - exec(script_code, namespace, namespace) - - def _has(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _isdir(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _listdir(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _fn(self, base, resource_name): - if resource_name: - return os.path.join(base, *resource_name.split('/')) - return base - - def _get(self, path): - if hasattr(self.loader, 'get_data'): - return self.loader.get_data(path) - raise NotImplementedError( - "Can't perform this operation for loaders without 'get_data()'" - ) - - -register_loader_type(object, NullProvider) - - -class EggProvider(NullProvider): - """Provider based on a virtual filesystem""" - - def __init__(self, module): - NullProvider.__init__(self, module) - self._setup_prefix() - - def _setup_prefix(self): - # we assume here that our metadata may be nested inside a "basket" - # of multiple eggs; that's why we use module_path instead of .archive - path = self.module_path - old = None - while path != old: - if _is_egg_path(path): - self.egg_name = os.path.basename(path) - self.egg_info = os.path.join(path, 'EGG-INFO') - self.egg_root = path - break - old = path - path, base = os.path.split(path) - - -class DefaultProvider(EggProvider): - """Provides access to package resources in the filesystem""" - - def _has(self, path): - return os.path.exists(path) - - def _isdir(self, path): - return os.path.isdir(path) - - def _listdir(self, path): - return os.listdir(path) - - def get_resource_stream(self, manager, resource_name): - return open(self._fn(self.module_path, resource_name), 'rb') - - def _get(self, path): - with open(path, 'rb') as stream: - return stream.read() - - @classmethod - def _register(cls): - loader_names = 'SourceFileLoader', 'SourcelessFileLoader', - for name in loader_names: - loader_cls = getattr(importlib_machinery, name, type(None)) - register_loader_type(loader_cls, cls) - - -DefaultProvider._register() - - -class EmptyProvider(NullProvider): - """Provider that returns nothing for all requests""" - - module_path = None - - _isdir = _has = lambda self, path: False - - def _get(self, path): - return '' - - def _listdir(self, path): - return [] - - def __init__(self): - pass - - -empty_provider = EmptyProvider() - - -class ZipManifests(dict): - """ - zip manifest builder - """ - - @classmethod - def build(cls, path): - """ - Build a dictionary similar to the zipimport directory - caches, except instead of tuples, store ZipInfo objects. - - Use a platform-specific path separator (os.sep) for the path keys - for compatibility with pypy on Windows. - """ - with zipfile.ZipFile(path) as zfile: - items = ( - ( - name.replace('/', os.sep), - zfile.getinfo(name), - ) - for name in zfile.namelist() - ) - return dict(items) - - load = build - - -class MemoizedZipManifests(ZipManifests): - """ - Memoized zipfile manifests. - """ - manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') - - def load(self, path): - """ - Load a manifest at path or return a suitable manifest already loaded. - """ - path = os.path.normpath(path) - mtime = os.stat(path).st_mtime - - if path not in self or self[path].mtime != mtime: - manifest = self.build(path) - self[path] = self.manifest_mod(manifest, mtime) - - return self[path].manifest - - -class ZipProvider(EggProvider): - """Resource support for zips and eggs""" - - eagers = None - _zip_manifests = MemoizedZipManifests() - - def __init__(self, module): - EggProvider.__init__(self, module) - self.zip_pre = self.loader.archive + os.sep - - def _zipinfo_name(self, fspath): - # Convert a virtual filename (full path to file) into a zipfile subpath - # usable with the zipimport directory cache for our target archive - fspath = fspath.rstrip(os.sep) - if fspath == self.loader.archive: - return '' - if fspath.startswith(self.zip_pre): - return fspath[len(self.zip_pre):] - raise AssertionError( - "%s is not a subpath of %s" % (fspath, self.zip_pre) - ) - - def _parts(self, zip_path): - # Convert a zipfile subpath into an egg-relative path part list. - # pseudo-fs path - fspath = self.zip_pre + zip_path - if fspath.startswith(self.egg_root + os.sep): - return fspath[len(self.egg_root) + 1:].split(os.sep) - raise AssertionError( - "%s is not a subpath of %s" % (fspath, self.egg_root) - ) - - @property - def zipinfo(self): - return self._zip_manifests.load(self.loader.archive) - - def get_resource_filename(self, manager, resource_name): - if not self.egg_name: - raise NotImplementedError( - "resource_filename() only supported for .egg, not .zip" - ) - # no need to lock for extraction, since we use temp names - zip_path = self._resource_to_zip(resource_name) - eagers = self._get_eager_resources() - if '/'.join(self._parts(zip_path)) in eagers: - for name in eagers: - self._extract_resource(manager, self._eager_to_zip(name)) - return self._extract_resource(manager, zip_path) - - @staticmethod - def _get_date_and_size(zip_stat): - size = zip_stat.file_size - # ymdhms+wday, yday, dst - date_time = zip_stat.date_time + (0, 0, -1) - # 1980 offset already done - timestamp = time.mktime(date_time) - return timestamp, size - - def _extract_resource(self, manager, zip_path): - - if zip_path in self._index(): - for name in self._index()[zip_path]: - last = self._extract_resource( - manager, os.path.join(zip_path, name) - ) - # return the extracted directory name - return os.path.dirname(last) - - timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) - - if not WRITE_SUPPORT: - raise IOError('"os.rename" and "os.unlink" are not supported ' - 'on this platform') - try: - - real_path = manager.get_cache_path( - self.egg_name, self._parts(zip_path) - ) - - if self._is_current(real_path, zip_path): - return real_path - - outf, tmpnam = _mkstemp( - ".$extract", - dir=os.path.dirname(real_path), - ) - os.write(outf, self.loader.get_data(zip_path)) - os.close(outf) - utime(tmpnam, (timestamp, timestamp)) - manager.postprocess(tmpnam, real_path) - - try: - rename(tmpnam, real_path) - - except os.error: - if os.path.isfile(real_path): - if self._is_current(real_path, zip_path): - # the file became current since it was checked above, - # so proceed. - return real_path - # Windows, del old file and retry - elif os.name == 'nt': - unlink(real_path) - rename(tmpnam, real_path) - return real_path - raise - - except os.error: - # report a user-friendly error - manager.extraction_error() - - return real_path - - def _is_current(self, file_path, zip_path): - """ - Return True if the file_path is current for this zip_path - """ - timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) - if not os.path.isfile(file_path): - return False - stat = os.stat(file_path) - if stat.st_size != size or stat.st_mtime != timestamp: - return False - # check that the contents match - zip_contents = self.loader.get_data(zip_path) - with open(file_path, 'rb') as f: - file_contents = f.read() - return zip_contents == file_contents - - def _get_eager_resources(self): - if self.eagers is None: - eagers = [] - for name in ('native_libs.txt', 'eager_resources.txt'): - if self.has_metadata(name): - eagers.extend(self.get_metadata_lines(name)) - self.eagers = eagers - return self.eagers - - def _index(self): - try: - return self._dirindex - except AttributeError: - ind = {} - for path in self.zipinfo: - parts = path.split(os.sep) - while parts: - parent = os.sep.join(parts[:-1]) - if parent in ind: - ind[parent].append(parts[-1]) - break - else: - ind[parent] = [parts.pop()] - self._dirindex = ind - return ind - - def _has(self, fspath): - zip_path = self._zipinfo_name(fspath) - return zip_path in self.zipinfo or zip_path in self._index() - - def _isdir(self, fspath): - return self._zipinfo_name(fspath) in self._index() - - def _listdir(self, fspath): - return list(self._index().get(self._zipinfo_name(fspath), ())) - - def _eager_to_zip(self, resource_name): - return self._zipinfo_name(self._fn(self.egg_root, resource_name)) - - def _resource_to_zip(self, resource_name): - return self._zipinfo_name(self._fn(self.module_path, resource_name)) - - -register_loader_type(zipimport.zipimporter, ZipProvider) - - -class FileMetadata(EmptyProvider): - """Metadata handler for standalone PKG-INFO files - - Usage:: - - metadata = FileMetadata("/path/to/PKG-INFO") - - This provider rejects all data and metadata requests except for PKG-INFO, - which is treated as existing, and will be the contents of the file at - the provided location. - """ - - def __init__(self, path): - self.path = path - - def has_metadata(self, name): - return name == 'PKG-INFO' and os.path.isfile(self.path) - - def get_metadata(self, name): - if name != 'PKG-INFO': - raise KeyError("No metadata except PKG-INFO is available") - - with io.open(self.path, encoding='utf-8', errors="replace") as f: - metadata = f.read() - self._warn_on_replacement(metadata) - return metadata - - def _warn_on_replacement(self, metadata): - # Python 2.7 compat for: replacement_char = '�' - replacement_char = b'\xef\xbf\xbd'.decode('utf-8') - if replacement_char in metadata: - tmpl = "{self.path} could not be properly decoded in UTF-8" - msg = tmpl.format(**locals()) - warnings.warn(msg) - - def get_metadata_lines(self, name): - return yield_lines(self.get_metadata(name)) - - -class PathMetadata(DefaultProvider): - """Metadata provider for egg directories - - Usage:: - - # Development eggs: - - egg_info = "/path/to/PackageName.egg-info" - base_dir = os.path.dirname(egg_info) - metadata = PathMetadata(base_dir, egg_info) - dist_name = os.path.splitext(os.path.basename(egg_info))[0] - dist = Distribution(basedir, project_name=dist_name, metadata=metadata) - - # Unpacked egg directories: - - egg_path = "/path/to/PackageName-ver-pyver-etc.egg" - metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) - dist = Distribution.from_filename(egg_path, metadata=metadata) - """ - - def __init__(self, path, egg_info): - self.module_path = path - self.egg_info = egg_info - - -class EggMetadata(ZipProvider): - """Metadata provider for .egg files""" - - def __init__(self, importer): - """Create a metadata provider from a zipimporter""" - - self.zip_pre = importer.archive + os.sep - self.loader = importer - if importer.prefix: - self.module_path = os.path.join(importer.archive, importer.prefix) - else: - self.module_path = importer.archive - self._setup_prefix() - - -_declare_state('dict', _distribution_finders={}) - - -def register_finder(importer_type, distribution_finder): - """Register `distribution_finder` to find distributions in sys.path items - - `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item - handler), and `distribution_finder` is a callable that, passed a path - item and the importer instance, yields ``Distribution`` instances found on - that path item. See ``pkg_resources.find_on_path`` for an example.""" - _distribution_finders[importer_type] = distribution_finder - - -def find_distributions(path_item, only=False): - """Yield distributions accessible via `path_item`""" - importer = get_importer(path_item) - finder = _find_adapter(_distribution_finders, importer) - return finder(importer, path_item, only) - - -def find_eggs_in_zip(importer, path_item, only=False): - """ - Find eggs in zip files; possibly multiple nested eggs. - """ - if importer.archive.endswith('.whl'): - # wheels are not supported with this finder - # they don't have PKG-INFO metadata, and won't ever contain eggs - return - metadata = EggMetadata(importer) - if metadata.has_metadata('PKG-INFO'): - yield Distribution.from_filename(path_item, metadata=metadata) - if only: - # don't yield nested distros - return - for subitem in metadata.resource_listdir('/'): - if _is_egg_path(subitem): - subpath = os.path.join(path_item, subitem) - dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) - for dist in dists: - yield dist - elif subitem.lower().endswith('.dist-info'): - subpath = os.path.join(path_item, subitem) - submeta = EggMetadata(zipimport.zipimporter(subpath)) - submeta.egg_info = subpath - yield Distribution.from_location(path_item, subitem, submeta) - - -register_finder(zipimport.zipimporter, find_eggs_in_zip) - - -def find_nothing(importer, path_item, only=False): - return () - - -register_finder(object, find_nothing) - - -def _by_version_descending(names): - """ - Given a list of filenames, return them in descending order - by version number. - - >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' - >>> _by_version_descending(names) - ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] - >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' - >>> _by_version_descending(names) - ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] - >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' - >>> _by_version_descending(names) - ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] - """ - def _by_version(name): - """ - Parse each component of the filename - """ - name, ext = os.path.splitext(name) - parts = itertools.chain(name.split('-'), [ext]) - return [packaging.version.parse(part) for part in parts] - - return sorted(names, key=_by_version, reverse=True) - - -def find_on_path(importer, path_item, only=False): - """Yield distributions accessible on a sys.path directory""" - path_item = _normalize_cached(path_item) - - if _is_unpacked_egg(path_item): - yield Distribution.from_filename( - path_item, metadata=PathMetadata( - path_item, os.path.join(path_item, 'EGG-INFO') - ) - ) - return - - entries = safe_listdir(path_item) - - # for performance, before sorting by version, - # screen entries for only those that will yield - # distributions - filtered = ( - entry - for entry in entries - if dist_factory(path_item, entry, only) - ) - - # scan for .egg and .egg-info in directory - path_item_entries = _by_version_descending(filtered) - for entry in path_item_entries: - fullpath = os.path.join(path_item, entry) - factory = dist_factory(path_item, entry, only) - for dist in factory(fullpath): - yield dist - - -def dist_factory(path_item, entry, only): - """ - Return a dist_factory for a path_item and entry - """ - lower = entry.lower() - is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) - return ( - distributions_from_metadata - if is_meta else - find_distributions - if not only and _is_egg_path(entry) else - resolve_egg_link - if not only and lower.endswith('.egg-link') else - NoDists() - ) - - -class NoDists: - """ - >>> bool(NoDists()) - False - - >>> list(NoDists()('anything')) - [] - """ - def __bool__(self): - return False - if six.PY2: - __nonzero__ = __bool__ - - def __call__(self, fullpath): - return iter(()) - - -def safe_listdir(path): - """ - Attempt to list contents of path, but suppress some exceptions. - """ - try: - return os.listdir(path) - except (PermissionError, NotADirectoryError): - pass - except OSError as e: - # Ignore the directory if does not exist, not a directory or - # permission denied - ignorable = ( - e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) - # Python 2 on Windows needs to be handled this way :( - or getattr(e, "winerror", None) == 267 - ) - if not ignorable: - raise - return () - - -def distributions_from_metadata(path): - root = os.path.dirname(path) - if os.path.isdir(path): - if len(os.listdir(path)) == 0: - # empty metadata dir; skip - return - metadata = PathMetadata(root, path) - else: - metadata = FileMetadata(path) - entry = os.path.basename(path) - yield Distribution.from_location( - root, entry, metadata, precedence=DEVELOP_DIST, - ) - - -def non_empty_lines(path): - """ - Yield non-empty lines from file at path - """ - with open(path) as f: - for line in f: - line = line.strip() - if line: - yield line - - -def resolve_egg_link(path): - """ - Given a path to an .egg-link, resolve distributions - present in the referenced path. - """ - referenced_paths = non_empty_lines(path) - resolved_paths = ( - os.path.join(os.path.dirname(path), ref) - for ref in referenced_paths - ) - dist_groups = map(find_distributions, resolved_paths) - return next(dist_groups, ()) - - -register_finder(pkgutil.ImpImporter, find_on_path) - -if hasattr(importlib_machinery, 'FileFinder'): - register_finder(importlib_machinery.FileFinder, find_on_path) - -_declare_state('dict', _namespace_handlers={}) -_declare_state('dict', _namespace_packages={}) - - -def register_namespace_handler(importer_type, namespace_handler): - """Register `namespace_handler` to declare namespace packages - - `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item - handler), and `namespace_handler` is a callable like this:: - - def namespace_handler(importer, path_entry, moduleName, module): - # return a path_entry to use for child packages - - Namespace handlers are only called if the importer object has already - agreed that it can handle the relevant path item, and they should only - return a subpath if the module __path__ does not already contain an - equivalent subpath. For an example namespace handler, see - ``pkg_resources.file_ns_handler``. - """ - _namespace_handlers[importer_type] = namespace_handler - - -def _handle_ns(packageName, path_item): - """Ensure that named package includes a subpath of path_item (if needed)""" - - importer = get_importer(path_item) - if importer is None: - return None - - # capture warnings due to #1111 - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - loader = importer.find_module(packageName) - - if loader is None: - return None - module = sys.modules.get(packageName) - if module is None: - module = sys.modules[packageName] = types.ModuleType(packageName) - module.__path__ = [] - _set_parent_ns(packageName) - elif not hasattr(module, '__path__'): - raise TypeError("Not a package:", packageName) - handler = _find_adapter(_namespace_handlers, importer) - subpath = handler(importer, path_item, packageName, module) - if subpath is not None: - path = module.__path__ - path.append(subpath) - loader.load_module(packageName) - _rebuild_mod_path(path, packageName, module) - return subpath - - -def _rebuild_mod_path(orig_path, package_name, module): - """ - Rebuild module.__path__ ensuring that all entries are ordered - corresponding to their sys.path order - """ - sys_path = [_normalize_cached(p) for p in sys.path] - - def safe_sys_path_index(entry): - """ - Workaround for #520 and #513. - """ - try: - return sys_path.index(entry) - except ValueError: - return float('inf') - - def position_in_sys_path(path): - """ - Return the ordinal of the path based on its position in sys.path - """ - path_parts = path.split(os.sep) - module_parts = package_name.count('.') + 1 - parts = path_parts[:-module_parts] - return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) - - new_path = sorted(orig_path, key=position_in_sys_path) - new_path = [_normalize_cached(p) for p in new_path] - - if isinstance(module.__path__, list): - module.__path__[:] = new_path - else: - module.__path__ = new_path - - -def declare_namespace(packageName): - """Declare that package 'packageName' is a namespace package""" - - _imp.acquire_lock() - try: - if packageName in _namespace_packages: - return - - path = sys.path - parent, _, _ = packageName.rpartition('.') - - if parent: - declare_namespace(parent) - if parent not in _namespace_packages: - __import__(parent) - try: - path = sys.modules[parent].__path__ - except AttributeError: - raise TypeError("Not a package:", parent) - - # Track what packages are namespaces, so when new path items are added, - # they can be updated - _namespace_packages.setdefault(parent or None, []).append(packageName) - _namespace_packages.setdefault(packageName, []) - - for path_item in path: - # Ensure all the parent's path items are reflected in the child, - # if they apply - _handle_ns(packageName, path_item) - - finally: - _imp.release_lock() - - -def fixup_namespace_packages(path_item, parent=None): - """Ensure that previously-declared namespace packages include path_item""" - _imp.acquire_lock() - try: - for package in _namespace_packages.get(parent, ()): - subpath = _handle_ns(package, path_item) - if subpath: - fixup_namespace_packages(subpath, package) - finally: - _imp.release_lock() - - -def file_ns_handler(importer, path_item, packageName, module): - """Compute an ns-package subpath for a filesystem or zipfile importer""" - - subpath = os.path.join(path_item, packageName.split('.')[-1]) - normalized = _normalize_cached(subpath) - for item in module.__path__: - if _normalize_cached(item) == normalized: - break - else: - # Only return the path if it's not already there - return subpath - - -register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) -register_namespace_handler(zipimport.zipimporter, file_ns_handler) - -if hasattr(importlib_machinery, 'FileFinder'): - register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) - - -def null_ns_handler(importer, path_item, packageName, module): - return None - - -register_namespace_handler(object, null_ns_handler) - - -def normalize_path(filename): - """Normalize a file/dir name for comparison purposes""" - return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename)))) - - -def _cygwin_patch(filename): # pragma: nocover - """ - Contrary to POSIX 2008, on Cygwin, getcwd (3) contains - symlink components. Using - os.path.abspath() works around this limitation. A fix in os.getcwd() - would probably better, in Cygwin even more so, except - that this seems to be by design... - """ - return os.path.abspath(filename) if sys.platform == 'cygwin' else filename - - -def _normalize_cached(filename, _cache={}): - try: - return _cache[filename] - except KeyError: - _cache[filename] = result = normalize_path(filename) - return result - - -def _is_egg_path(path): - """ - Determine if given path appears to be an egg. - """ - return path.lower().endswith('.egg') - - -def _is_unpacked_egg(path): - """ - Determine if given path appears to be an unpacked egg. - """ - return ( - _is_egg_path(path) and - os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) - ) - - -def _set_parent_ns(packageName): - parts = packageName.split('.') - name = parts.pop() - if parts: - parent = '.'.join(parts) - setattr(sys.modules[parent], name, sys.modules[packageName]) - - -def yield_lines(strs): - """Yield non-empty/non-comment lines of a string or sequence""" - if isinstance(strs, six.string_types): - for s in strs.splitlines(): - s = s.strip() - # skip blank lines/comments - if s and not s.startswith('#'): - yield s - else: - for ss in strs: - for s in yield_lines(ss): - yield s - - -MODULE = re.compile(r"\w+(\.\w+)*$").match -EGG_NAME = re.compile( - r""" - (?P<name>[^-]+) ( - -(?P<ver>[^-]+) ( - -py(?P<pyver>[^-]+) ( - -(?P<plat>.+) - )? - )? - )? - """, - re.VERBOSE | re.IGNORECASE, -).match - - -class EntryPoint: - """Object representing an advertised importable object""" - - def __init__(self, name, module_name, attrs=(), extras=(), dist=None): - if not MODULE(module_name): - raise ValueError("Invalid module name", module_name) - self.name = name - self.module_name = module_name - self.attrs = tuple(attrs) - self.extras = tuple(extras) - self.dist = dist - - def __str__(self): - s = "%s = %s" % (self.name, self.module_name) - if self.attrs: - s += ':' + '.'.join(self.attrs) - if self.extras: - s += ' [%s]' % ','.join(self.extras) - return s - - def __repr__(self): - return "EntryPoint.parse(%r)" % str(self) - - def load(self, require=True, *args, **kwargs): - """ - Require packages for this EntryPoint, then resolve it. - """ - if not require or args or kwargs: - warnings.warn( - "Parameters to load are deprecated. Call .resolve and " - ".require separately.", - PkgResourcesDeprecationWarning, - stacklevel=2, - ) - if require: - self.require(*args, **kwargs) - return self.resolve() - - def resolve(self): - """ - Resolve the entry point from its module and attrs. - """ - module = __import__(self.module_name, fromlist=['__name__'], level=0) - try: - return functools.reduce(getattr, self.attrs, module) - except AttributeError as exc: - raise ImportError(str(exc)) - - def require(self, env=None, installer=None): - if self.extras and not self.dist: - raise UnknownExtra("Can't require() without a distribution", self) - - # Get the requirements for this entry point with all its extras and - # then resolve them. We have to pass `extras` along when resolving so - # that the working set knows what extras we want. Otherwise, for - # dist-info distributions, the working set will assume that the - # requirements for that extra are purely optional and skip over them. - reqs = self.dist.requires(self.extras) - items = working_set.resolve(reqs, env, installer, extras=self.extras) - list(map(working_set.add, items)) - - pattern = re.compile( - r'\s*' - r'(?P<name>.+?)\s*' - r'=\s*' - r'(?P<module>[\w.]+)\s*' - r'(:\s*(?P<attr>[\w.]+))?\s*' - r'(?P<extras>\[.*\])?\s*$' - ) - - @classmethod - def parse(cls, src, dist=None): - """Parse a single entry point from string `src` - - Entry point syntax follows the form:: - - name = some.module:some.attr [extra1, extra2] - - The entry name and module name are required, but the ``:attrs`` and - ``[extras]`` parts are optional - """ - m = cls.pattern.match(src) - if not m: - msg = "EntryPoint must be in 'name=module:attrs [extras]' format" - raise ValueError(msg, src) - res = m.groupdict() - extras = cls._parse_extras(res['extras']) - attrs = res['attr'].split('.') if res['attr'] else () - return cls(res['name'], res['module'], attrs, extras, dist) - - @classmethod - def _parse_extras(cls, extras_spec): - if not extras_spec: - return () - req = Requirement.parse('x' + extras_spec) - if req.specs: - raise ValueError() - return req.extras - - @classmethod - def parse_group(cls, group, lines, dist=None): - """Parse an entry point group""" - if not MODULE(group): - raise ValueError("Invalid group name", group) - this = {} - for line in yield_lines(lines): - ep = cls.parse(line, dist) - if ep.name in this: - raise ValueError("Duplicate entry point", group, ep.name) - this[ep.name] = ep - return this - - @classmethod - def parse_map(cls, data, dist=None): - """Parse a map of entry point groups""" - if isinstance(data, dict): - data = data.items() - else: - data = split_sections(data) - maps = {} - for group, lines in data: - if group is None: - if not lines: - continue - raise ValueError("Entry points must be listed in groups") - group = group.strip() - if group in maps: - raise ValueError("Duplicate group name", group) - maps[group] = cls.parse_group(group, lines, dist) - return maps - - -def _remove_md5_fragment(location): - if not location: - return '' - parsed = urllib.parse.urlparse(location) - if parsed[-1].startswith('md5='): - return urllib.parse.urlunparse(parsed[:-1] + ('',)) - return location - - -def _version_from_file(lines): - """ - Given an iterable of lines from a Metadata file, return - the value of the Version field, if present, or None otherwise. - """ - def is_version_line(line): - return line.lower().startswith('version:') - version_lines = filter(is_version_line, lines) - line = next(iter(version_lines), '') - _, _, value = line.partition(':') - return safe_version(value.strip()) or None - - -class Distribution: - """Wrap an actual or potential sys.path entry w/metadata""" - PKG_INFO = 'PKG-INFO' - - def __init__( - self, location=None, metadata=None, project_name=None, - version=None, py_version=PY_MAJOR, platform=None, - precedence=EGG_DIST): - self.project_name = safe_name(project_name or 'Unknown') - if version is not None: - self._version = safe_version(version) - self.py_version = py_version - self.platform = platform - self.location = location - self.precedence = precedence - self._provider = metadata or empty_provider - - @classmethod - def from_location(cls, location, basename, metadata=None, **kw): - project_name, version, py_version, platform = [None] * 4 - basename, ext = os.path.splitext(basename) - if ext.lower() in _distributionImpl: - cls = _distributionImpl[ext.lower()] - - match = EGG_NAME(basename) - if match: - project_name, version, py_version, platform = match.group( - 'name', 'ver', 'pyver', 'plat' - ) - return cls( - location, metadata, project_name=project_name, version=version, - py_version=py_version, platform=platform, **kw - )._reload_version() - - def _reload_version(self): - return self - - @property - def hashcmp(self): - return ( - self.parsed_version, - self.precedence, - self.key, - _remove_md5_fragment(self.location), - self.py_version or '', - self.platform or '', - ) - - def __hash__(self): - return hash(self.hashcmp) - - def __lt__(self, other): - return self.hashcmp < other.hashcmp - - def __le__(self, other): - return self.hashcmp <= other.hashcmp - - def __gt__(self, other): - return self.hashcmp > other.hashcmp - - def __ge__(self, other): - return self.hashcmp >= other.hashcmp - - def __eq__(self, other): - if not isinstance(other, self.__class__): - # It's not a Distribution, so they are not equal - return False - return self.hashcmp == other.hashcmp - - def __ne__(self, other): - return not self == other - - # These properties have to be lazy so that we don't have to load any - # metadata until/unless it's actually needed. (i.e., some distributions - # may not know their name or version without loading PKG-INFO) - - @property - def key(self): - try: - return self._key - except AttributeError: - self._key = key = self.project_name.lower() - return key - - @property - def parsed_version(self): - if not hasattr(self, "_parsed_version"): - self._parsed_version = parse_version(self.version) - - return self._parsed_version - - def _warn_legacy_version(self): - LV = packaging.version.LegacyVersion - is_legacy = isinstance(self._parsed_version, LV) - if not is_legacy: - return - - # While an empty version is technically a legacy version and - # is not a valid PEP 440 version, it's also unlikely to - # actually come from someone and instead it is more likely that - # it comes from setuptools attempting to parse a filename and - # including it in the list. So for that we'll gate this warning - # on if the version is anything at all or not. - if not self.version: - return - - tmpl = textwrap.dedent(""" - '{project_name} ({version})' is being parsed as a legacy, - non PEP 440, - version. You may find odd behavior and sort order. - In particular it will be sorted as less than 0.0. It - is recommended to migrate to PEP 440 compatible - versions. - """).strip().replace('\n', ' ') - - warnings.warn(tmpl.format(**vars(self)), PEP440Warning) - - @property - def version(self): - try: - return self._version - except AttributeError: - version = _version_from_file(self._get_metadata(self.PKG_INFO)) - if version is None: - tmpl = "Missing 'Version:' header and/or %s file" - raise ValueError(tmpl % self.PKG_INFO, self) - return version - - @property - def _dep_map(self): - """ - A map of extra to its list of (direct) requirements - for this distribution, including the null extra. - """ - try: - return self.__dep_map - except AttributeError: - self.__dep_map = self._filter_extras(self._build_dep_map()) - return self.__dep_map - - @staticmethod - def _filter_extras(dm): - """ - Given a mapping of extras to dependencies, strip off - environment markers and filter out any dependencies - not matching the markers. - """ - for extra in list(filter(None, dm)): - new_extra = extra - reqs = dm.pop(extra) - new_extra, _, marker = extra.partition(':') - fails_marker = marker and ( - invalid_marker(marker) - or not evaluate_marker(marker) - ) - if fails_marker: - reqs = [] - new_extra = safe_extra(new_extra) or None - - dm.setdefault(new_extra, []).extend(reqs) - return dm - - def _build_dep_map(self): - dm = {} - for name in 'requires.txt', 'depends.txt': - for extra, reqs in split_sections(self._get_metadata(name)): - dm.setdefault(extra, []).extend(parse_requirements(reqs)) - return dm - - def requires(self, extras=()): - """List of Requirements needed for this distro if `extras` are used""" - dm = self._dep_map - deps = [] - deps.extend(dm.get(None, ())) - for ext in extras: - try: - deps.extend(dm[safe_extra(ext)]) - except KeyError: - raise UnknownExtra( - "%s has no such extra feature %r" % (self, ext) - ) - return deps - - def _get_metadata(self, name): - if self.has_metadata(name): - for line in self.get_metadata_lines(name): - yield line - - def activate(self, path=None, replace=False): - """Ensure distribution is importable on `path` (default=sys.path)""" - if path is None: - path = sys.path - self.insert_on(path, replace=replace) - if path is sys.path: - fixup_namespace_packages(self.location) - for pkg in self._get_metadata('namespace_packages.txt'): - if pkg in sys.modules: - declare_namespace(pkg) - - def egg_name(self): - """Return what this distribution's standard .egg filename should be""" - filename = "%s-%s-py%s" % ( - to_filename(self.project_name), to_filename(self.version), - self.py_version or PY_MAJOR - ) - - if self.platform: - filename += '-' + self.platform - return filename - - def __repr__(self): - if self.location: - return "%s (%s)" % (self, self.location) - else: - return str(self) - - def __str__(self): - try: - version = getattr(self, 'version', None) - except ValueError: - version = None - version = version or "[unknown version]" - return "%s %s" % (self.project_name, version) - - def __getattr__(self, attr): - """Delegate all unrecognized public attributes to .metadata provider""" - if attr.startswith('_'): - raise AttributeError(attr) - return getattr(self._provider, attr) - - def __dir__(self): - return list( - set(super(Distribution, self).__dir__()) - | set( - attr for attr in self._provider.__dir__() - if not attr.startswith('_') - ) - ) - - if not hasattr(object, '__dir__'): - # python 2.7 not supported - del __dir__ - - @classmethod - def from_filename(cls, filename, metadata=None, **kw): - return cls.from_location( - _normalize_cached(filename), os.path.basename(filename), metadata, - **kw - ) - - def as_requirement(self): - """Return a ``Requirement`` that matches this distribution exactly""" - if isinstance(self.parsed_version, packaging.version.Version): - spec = "%s==%s" % (self.project_name, self.parsed_version) - else: - spec = "%s===%s" % (self.project_name, self.parsed_version) - - return Requirement.parse(spec) - - def load_entry_point(self, group, name): - """Return the `name` entry point of `group` or raise ImportError""" - ep = self.get_entry_info(group, name) - if ep is None: - raise ImportError("Entry point %r not found" % ((group, name),)) - return ep.load() - - def get_entry_map(self, group=None): - """Return the entry point map for `group`, or the full entry map""" - try: - ep_map = self._ep_map - except AttributeError: - ep_map = self._ep_map = EntryPoint.parse_map( - self._get_metadata('entry_points.txt'), self - ) - if group is not None: - return ep_map.get(group, {}) - return ep_map - - def get_entry_info(self, group, name): - """Return the EntryPoint object for `group`+`name`, or ``None``""" - return self.get_entry_map(group).get(name) - - def insert_on(self, path, loc=None, replace=False): - """Ensure self.location is on path - - If replace=False (default): - - If location is already in path anywhere, do nothing. - - Else: - - If it's an egg and its parent directory is on path, - insert just ahead of the parent. - - Else: add to the end of path. - If replace=True: - - If location is already on path anywhere (not eggs) - or higher priority than its parent (eggs) - do nothing. - - Else: - - If it's an egg and its parent directory is on path, - insert just ahead of the parent, - removing any lower-priority entries. - - Else: add it to the front of path. - """ - - loc = loc or self.location - if not loc: - return - - nloc = _normalize_cached(loc) - bdir = os.path.dirname(nloc) - npath = [(p and _normalize_cached(p) or p) for p in path] - - for p, item in enumerate(npath): - if item == nloc: - if replace: - break - else: - # don't modify path (even removing duplicates) if - # found and not replace - return - elif item == bdir and self.precedence == EGG_DIST: - # if it's an .egg, give it precedence over its directory - # UNLESS it's already been added to sys.path and replace=False - if (not replace) and nloc in npath[p:]: - return - if path is sys.path: - self.check_version_conflict() - path.insert(p, loc) - npath.insert(p, nloc) - break - else: - if path is sys.path: - self.check_version_conflict() - if replace: - path.insert(0, loc) - else: - path.append(loc) - return - - # p is the spot where we found or inserted loc; now remove duplicates - while True: - try: - np = npath.index(nloc, p + 1) - except ValueError: - break - else: - del npath[np], path[np] - # ha! - p = np - - return - - def check_version_conflict(self): - if self.key == 'setuptools': - # ignore the inevitable setuptools self-conflicts :( - return - - nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) - loc = normalize_path(self.location) - for modname in self._get_metadata('top_level.txt'): - if (modname not in sys.modules or modname in nsp - or modname in _namespace_packages): - continue - if modname in ('pkg_resources', 'setuptools', 'site'): - continue - fn = getattr(sys.modules[modname], '__file__', None) - if fn and (normalize_path(fn).startswith(loc) or - fn.startswith(self.location)): - continue - issue_warning( - "Module %s was already imported from %s, but %s is being added" - " to sys.path" % (modname, fn, self.location), - ) - - def has_version(self): - try: - self.version - except ValueError: - issue_warning("Unbuilt egg for " + repr(self)) - return False - return True - - def clone(self, **kw): - """Copy this distribution, substituting in any changed keyword args""" - names = 'project_name version py_version platform location precedence' - for attr in names.split(): - kw.setdefault(attr, getattr(self, attr, None)) - kw.setdefault('metadata', self._provider) - return self.__class__(**kw) - - @property - def extras(self): - return [dep for dep in self._dep_map if dep] - - -class EggInfoDistribution(Distribution): - def _reload_version(self): - """ - Packages installed by distutils (e.g. numpy or scipy), - which uses an old safe_version, and so - their version numbers can get mangled when - converted to filenames (e.g., 1.11.0.dev0+2329eae to - 1.11.0.dev0_2329eae). These distributions will not be - parsed properly - downstream by Distribution and safe_version, so - take an extra step and try to get the version number from - the metadata file itself instead of the filename. - """ - md_version = _version_from_file(self._get_metadata(self.PKG_INFO)) - if md_version: - self._version = md_version - return self - - -class DistInfoDistribution(Distribution): - """ - Wrap an actual or potential sys.path entry - w/metadata, .dist-info style. - """ - PKG_INFO = 'METADATA' - EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") - - @property - def _parsed_pkg_info(self): - """Parse and cache metadata""" - try: - return self._pkg_info - except AttributeError: - metadata = self.get_metadata(self.PKG_INFO) - self._pkg_info = email.parser.Parser().parsestr(metadata) - return self._pkg_info - - @property - def _dep_map(self): - try: - return self.__dep_map - except AttributeError: - self.__dep_map = self._compute_dependencies() - return self.__dep_map - - def _compute_dependencies(self): - """Recompute this distribution's dependencies.""" - dm = self.__dep_map = {None: []} - - reqs = [] - # Including any condition expressions - for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: - reqs.extend(parse_requirements(req)) - - def reqs_for_extra(extra): - for req in reqs: - if not req.marker or req.marker.evaluate({'extra': extra}): - yield req - - common = frozenset(reqs_for_extra(None)) - dm[None].extend(common) - - for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: - s_extra = safe_extra(extra.strip()) - dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) - - return dm - - -_distributionImpl = { - '.egg': Distribution, - '.egg-info': EggInfoDistribution, - '.dist-info': DistInfoDistribution, -} - - -def issue_warning(*args, **kw): - level = 1 - g = globals() - try: - # find the first stack frame that is *not* code in - # the pkg_resources module, to use for the warning - while sys._getframe(level).f_globals is g: - level += 1 - except ValueError: - pass - warnings.warn(stacklevel=level + 1, *args, **kw) - - -class RequirementParseError(ValueError): - def __str__(self): - return ' '.join(self.args) - - -def parse_requirements(strs): - """Yield ``Requirement`` objects for each specification in `strs` - - `strs` must be a string, or a (possibly-nested) iterable thereof. - """ - # create a steppable iterator, so we can handle \-continuations - lines = iter(yield_lines(strs)) - - for line in lines: - # Drop comments -- a hash without a space may be in a URL. - if ' #' in line: - line = line[:line.find(' #')] - # If there is a line continuation, drop it, and append the next line. - if line.endswith('\\'): - line = line[:-2].strip() - try: - line += next(lines) - except StopIteration: - return - yield Requirement(line) - - -class Requirement(packaging.requirements.Requirement): - def __init__(self, requirement_string): - """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" - try: - super(Requirement, self).__init__(requirement_string) - except packaging.requirements.InvalidRequirement as e: - raise RequirementParseError(str(e)) - self.unsafe_name = self.name - project_name = safe_name(self.name) - self.project_name, self.key = project_name, project_name.lower() - self.specs = [ - (spec.operator, spec.version) for spec in self.specifier] - self.extras = tuple(map(safe_extra, self.extras)) - self.hashCmp = ( - self.key, - self.specifier, - frozenset(self.extras), - str(self.marker) if self.marker else None, - ) - self.__hash = hash(self.hashCmp) - - def __eq__(self, other): - return ( - isinstance(other, Requirement) and - self.hashCmp == other.hashCmp - ) - - def __ne__(self, other): - return not self == other - - def __contains__(self, item): - if isinstance(item, Distribution): - if item.key != self.key: - return False - - item = item.version - - # Allow prereleases always in order to match the previous behavior of - # this method. In the future this should be smarter and follow PEP 440 - # more accurately. - return self.specifier.contains(item, prereleases=True) - - def __hash__(self): - return self.__hash - - def __repr__(self): - return "Requirement.parse(%r)" % str(self) - - @staticmethod - def parse(s): - req, = parse_requirements(s) - return req - - -def _always_object(classes): - """ - Ensure object appears in the mro even - for old-style classes. - """ - if object not in classes: - return classes + (object,) - return classes - - -def _find_adapter(registry, ob): - """Return an adapter factory for `ob` from `registry`""" - types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) - for t in types: - if t in registry: - return registry[t] - - -def ensure_directory(path): - """Ensure that the parent directory of `path` exists""" - dirname = os.path.dirname(path) - py31compat.makedirs(dirname, exist_ok=True) - - -def _bypass_ensure_directory(path): - """Sandbox-bypassing version of ensure_directory()""" - if not WRITE_SUPPORT: - raise IOError('"os.mkdir" not supported on this platform.') - dirname, filename = split(path) - if dirname and filename and not isdir(dirname): - _bypass_ensure_directory(dirname) - try: - mkdir(dirname, 0o755) - except FileExistsError: - pass - - -def split_sections(s): - """Split a string or iterable thereof into (section, content) pairs - - Each ``section`` is a stripped version of the section header ("[section]") - and each ``content`` is a list of stripped lines excluding blank lines and - comment-only lines. If there are any such lines before the first section - header, they're returned in a first ``section`` of ``None``. - """ - section = None - content = [] - for line in yield_lines(s): - if line.startswith("["): - if line.endswith("]"): - if section or content: - yield section, content - section = line[1:-1].strip() - content = [] - else: - raise ValueError("Invalid section heading", line) - else: - content.append(line) - - # wrap up last segment - yield section, content - - -def _mkstemp(*args, **kw): - old_open = os.open - try: - # temporarily bypass sandboxing - os.open = os_open - return tempfile.mkstemp(*args, **kw) - finally: - # and then put it back - os.open = old_open - - -# Silence the PEP440Warning by default, so that end users don't get hit by it -# randomly just because they use pkg_resources. We want to append the rule -# because we want earlier uses of filterwarnings to take precedence over this -# one. -warnings.filterwarnings("ignore", category=PEP440Warning, append=True) - - -# from jaraco.functools 1.3 -def _call_aside(f, *args, **kwargs): - f(*args, **kwargs) - return f - - -@_call_aside -def _initialize(g=globals()): - "Set up global resource manager (deliberately not state-saved)" - manager = ResourceManager() - g['_manager'] = manager - g.update( - (name, getattr(manager, name)) - for name in dir(manager) - if not name.startswith('_') - ) - - -@_call_aside -def _initialize_master_working_set(): - """ - Prepare the master working set and make the ``require()`` - API available. - - This function has explicit effects on the global state - of pkg_resources. It is intended to be invoked once at - the initialization of this module. - - Invocation by other packages is unsupported and done - at their own risk. - """ - working_set = WorkingSet._build_master() - _declare_state('object', working_set=working_set) - - require = working_set.require - iter_entry_points = working_set.iter_entry_points - add_activation_listener = working_set.subscribe - run_script = working_set.run_script - # backward compatibility - run_main = run_script - # Activate all distributions already on sys.path with replace=False and - # ensure that all distributions added to the working set in the future - # (e.g. by calling ``require()``) will get activated as well, - # with higher priority (replace=True). - tuple( - dist.activate(replace=False) - for dist in working_set - ) - add_activation_listener( - lambda dist: dist.activate(replace=True), - existing=False, - ) - working_set.entries = [] - # match order - list(map(working_set.add_entry, sys.path)) - globals().update(locals()) - -class PkgResourcesDeprecationWarning(Warning): - """ - Base class for warning about deprecations in ``pkg_resources`` - - This class is not derived from ``DeprecationWarning``, and as such is - visible by default. - """ diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pkg_resources/py31compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pkg_resources/py31compat.py deleted file mode 100644 index a2d3007..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pkg_resources/py31compat.py +++ /dev/null @@ -1,23 +0,0 @@ -import os -import errno -import sys - -from pip._vendor import six - - -def _makedirs_31(path, exist_ok=False): - try: - os.makedirs(path) - except OSError as exc: - if not exist_ok or exc.errno != errno.EEXIST: - raise - - -# rely on compatibility behavior until mode considerations -# and exists_ok considerations are disentangled. -# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 -needs_makedirs = ( - six.PY2 or - (3, 4) <= sys.version_info < (3, 4, 1) -) -makedirs = _makedirs_31 if needs_makedirs else os.makedirs diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/__init__.py deleted file mode 100644 index a41f65d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/__init__.py +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from __future__ import division - -from collections import deque -from datetime import timedelta -from math import ceil -from sys import stderr -from time import time - - -__version__ = '1.4' - - -class Infinite(object): - file = stderr - sma_window = 10 # Simple Moving Average window - - def __init__(self, *args, **kwargs): - self.index = 0 - self.start_ts = time() - self.avg = 0 - self._ts = self.start_ts - self._xput = deque(maxlen=self.sma_window) - for key, val in kwargs.items(): - setattr(self, key, val) - - def __getitem__(self, key): - if key.startswith('_'): - return None - return getattr(self, key, None) - - @property - def elapsed(self): - return int(time() - self.start_ts) - - @property - def elapsed_td(self): - return timedelta(seconds=self.elapsed) - - def update_avg(self, n, dt): - if n > 0: - self._xput.append(dt / n) - self.avg = sum(self._xput) / len(self._xput) - - def update(self): - pass - - def start(self): - pass - - def finish(self): - pass - - def next(self, n=1): - now = time() - dt = now - self._ts - self.update_avg(n, dt) - self._ts = now - self.index = self.index + n - self.update() - - def iter(self, it): - try: - for x in it: - yield x - self.next() - finally: - self.finish() - - -class Progress(Infinite): - def __init__(self, *args, **kwargs): - super(Progress, self).__init__(*args, **kwargs) - self.max = kwargs.get('max', 100) - - @property - def eta(self): - return int(ceil(self.avg * self.remaining)) - - @property - def eta_td(self): - return timedelta(seconds=self.eta) - - @property - def percent(self): - return self.progress * 100 - - @property - def progress(self): - return min(1, self.index / self.max) - - @property - def remaining(self): - return max(self.max - self.index, 0) - - def start(self): - self.update() - - def goto(self, index): - incr = index - self.index - self.next(incr) - - def iter(self, it): - try: - self.max = len(it) - except TypeError: - pass - - try: - for x in it: - yield x - self.next() - finally: - self.finish() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/bar.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/bar.py deleted file mode 100644 index 025e61c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/bar.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from __future__ import unicode_literals - -import sys - -from . import Progress -from .helpers import WritelnMixin - - -class Bar(WritelnMixin, Progress): - width = 32 - message = '' - suffix = '%(index)d/%(max)d' - bar_prefix = ' |' - bar_suffix = '| ' - empty_fill = ' ' - fill = '#' - hide_cursor = True - - def update(self): - filled_length = int(self.width * self.progress) - empty_length = self.width - filled_length - - message = self.message % self - bar = self.fill * filled_length - empty = self.empty_fill * empty_length - suffix = self.suffix % self - line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, - suffix]) - self.writeln(line) - - -class ChargingBar(Bar): - suffix = '%(percent)d%%' - bar_prefix = ' ' - bar_suffix = ' ' - empty_fill = '∙' - fill = '█' - - -class FillingSquaresBar(ChargingBar): - empty_fill = '▢' - fill = '▣' - - -class FillingCirclesBar(ChargingBar): - empty_fill = '◯' - fill = '◉' - - -class IncrementalBar(Bar): - if sys.platform.startswith('win'): - phases = (u' ', u'▌', u'█') - else: - phases = (' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█') - - def update(self): - nphases = len(self.phases) - filled_len = self.width * self.progress - nfull = int(filled_len) # Number of full chars - phase = int((filled_len - nfull) * nphases) # Phase of last char - nempty = self.width - nfull # Number of empty chars - - message = self.message % self - bar = self.phases[-1] * nfull - current = self.phases[phase] if phase > 0 else '' - empty = self.empty_fill * max(0, nempty - len(current)) - suffix = self.suffix % self - line = ''.join([message, self.bar_prefix, bar, current, empty, - self.bar_suffix, suffix]) - self.writeln(line) - - -class PixelBar(IncrementalBar): - phases = ('⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿') - - -class ShadyBar(IncrementalBar): - phases = (' ', '░', '▒', '▓', '█') diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/counter.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/counter.py deleted file mode 100644 index 6b45a1e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/counter.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from __future__ import unicode_literals -from . import Infinite, Progress -from .helpers import WriteMixin - - -class Counter(WriteMixin, Infinite): - message = '' - hide_cursor = True - - def update(self): - self.write(str(self.index)) - - -class Countdown(WriteMixin, Progress): - hide_cursor = True - - def update(self): - self.write(str(self.remaining)) - - -class Stack(WriteMixin, Progress): - phases = (' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█') - hide_cursor = True - - def update(self): - nphases = len(self.phases) - i = min(nphases - 1, int(self.progress * nphases)) - self.write(self.phases[i]) - - -class Pie(Stack): - phases = ('○', '◔', '◑', '◕', '●') diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/helpers.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/helpers.py deleted file mode 100644 index 0cde44e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/helpers.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from __future__ import print_function - - -HIDE_CURSOR = '\x1b[?25l' -SHOW_CURSOR = '\x1b[?25h' - - -class WriteMixin(object): - hide_cursor = False - - def __init__(self, message=None, **kwargs): - super(WriteMixin, self).__init__(**kwargs) - self._width = 0 - if message: - self.message = message - - if self.file and self.file.isatty(): - if self.hide_cursor: - print(HIDE_CURSOR, end='', file=self.file) - print(self.message, end='', file=self.file) - self.file.flush() - - def write(self, s): - if self.file and self.file.isatty(): - b = '\b' * self._width - c = s.ljust(self._width) - print(b + c, end='', file=self.file) - self._width = max(self._width, len(s)) - self.file.flush() - - def finish(self): - if self.file and self.file.isatty() and self.hide_cursor: - print(SHOW_CURSOR, end='', file=self.file) - - -class WritelnMixin(object): - hide_cursor = False - - def __init__(self, message=None, **kwargs): - super(WritelnMixin, self).__init__(**kwargs) - if message: - self.message = message - - if self.file and self.file.isatty() and self.hide_cursor: - print(HIDE_CURSOR, end='', file=self.file) - - def clearln(self): - if self.file and self.file.isatty(): - print('\r\x1b[K', end='', file=self.file) - - def writeln(self, line): - if self.file and self.file.isatty(): - self.clearln() - print(line, end='', file=self.file) - self.file.flush() - - def finish(self): - if self.file and self.file.isatty(): - print(file=self.file) - if self.hide_cursor: - print(SHOW_CURSOR, end='', file=self.file) - - -from signal import signal, SIGINT -from sys import exit - - -class SigIntMixin(object): - """Registers a signal handler that calls finish on SIGINT""" - - def __init__(self, *args, **kwargs): - super(SigIntMixin, self).__init__(*args, **kwargs) - signal(SIGINT, self._sigint_handler) - - def _sigint_handler(self, signum, frame): - self.finish() - exit(0) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/spinner.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/spinner.py deleted file mode 100644 index 464c7b2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/progress/spinner.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from __future__ import unicode_literals -from . import Infinite -from .helpers import WriteMixin - - -class Spinner(WriteMixin, Infinite): - message = '' - phases = ('-', '\\', '|', '/') - hide_cursor = True - - def update(self): - i = self.index % len(self.phases) - self.write(self.phases[i]) - - -class PieSpinner(Spinner): - phases = ['◷', '◶', '◵', '◴'] - - -class MoonSpinner(Spinner): - phases = ['◑', '◒', '◐', '◓'] - - -class LineSpinner(Spinner): - phases = ['⎺', '⎻', '⎼', '⎽', '⎼', '⎻'] - -class PixelSpinner(Spinner): - phases = ['⣾','⣷', '⣯', '⣟', '⡿', '⢿', '⣻', '⣽'] diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pyparsing.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pyparsing.py deleted file mode 100644 index bea4d9c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pyparsing.py +++ /dev/null @@ -1,6452 +0,0 @@ -#-*- coding: utf-8 -*- -# module pyparsing.py -# -# Copyright (c) 2003-2019 Paul T. McGuire -# -# 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. -# - -__doc__ = \ -""" -pyparsing module - Classes and methods to define and execute parsing grammars -============================================================================= - -The pyparsing module is an alternative approach to creating and -executing simple grammars, vs. the traditional lex/yacc approach, or the -use of regular expressions. With pyparsing, you don't need to learn -a new syntax for defining grammars or matching expressions - the parsing -module provides a library of classes that you use to construct the -grammar directly in Python. - -Here is a program to parse "Hello, World!" (or any greeting of the form -``"<salutation>, <addressee>!"``), built up using :class:`Word`, -:class:`Literal`, and :class:`And` elements -(the :class:`'+'<ParserElement.__add__>` operators create :class:`And` expressions, -and the strings are auto-converted to :class:`Literal` expressions):: - - from pip._vendor.pyparsing import Word, alphas - - # define grammar of a greeting - greet = Word(alphas) + "," + Word(alphas) + "!" - - hello = "Hello, World!" - print (hello, "->", greet.parseString(hello)) - -The program outputs the following:: - - Hello, World! -> ['Hello', ',', 'World', '!'] - -The Python representation of the grammar is quite readable, owing to the -self-explanatory class names, and the use of '+', '|' and '^' operators. - -The :class:`ParseResults` object returned from -:class:`ParserElement.parseString` can be -accessed as a nested list, a dictionary, or an object with named -attributes. - -The pyparsing module handles some of the problems that are typically -vexing when writing text parsers: - - - extra or missing whitespace (the above program will also handle - "Hello,World!", "Hello , World !", etc.) - - quoted strings - - embedded comments - - -Getting Started - ------------------ -Visit the classes :class:`ParserElement` and :class:`ParseResults` to -see the base classes that most other pyparsing -classes inherit from. Use the docstrings for examples of how to: - - - construct literal match expressions from :class:`Literal` and - :class:`CaselessLiteral` classes - - construct character word-group expressions using the :class:`Word` - class - - see how to create repetitive expressions using :class:`ZeroOrMore` - and :class:`OneOrMore` classes - - use :class:`'+'<And>`, :class:`'|'<MatchFirst>`, :class:`'^'<Or>`, - and :class:`'&'<Each>` operators to combine simple expressions into - more complex ones - - associate names with your parsed results using - :class:`ParserElement.setResultsName` - - find some helpful expression short-cuts like :class:`delimitedList` - and :class:`oneOf` - - find more useful common expressions in the :class:`pyparsing_common` - namespace class -""" - -__version__ = "2.3.1" -__versionTime__ = "09 Jan 2019 23:26 UTC" -__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" - -import string -from weakref import ref as wkref -import copy -import sys -import warnings -import re -import sre_constants -import collections -import pprint -import traceback -import types -from datetime import datetime - -try: - # Python 3 - from itertools import filterfalse -except ImportError: - from itertools import ifilterfalse as filterfalse - -try: - from _thread import RLock -except ImportError: - from threading import RLock - -try: - # Python 3 - from collections.abc import Iterable - from collections.abc import MutableMapping -except ImportError: - # Python 2.7 - from collections import Iterable - from collections import MutableMapping - -try: - from collections import OrderedDict as _OrderedDict -except ImportError: - try: - from ordereddict import OrderedDict as _OrderedDict - except ImportError: - _OrderedDict = None - -try: - from types import SimpleNamespace -except ImportError: - class SimpleNamespace: pass - - -#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) - -__all__ = [ -'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', -'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', -'PrecededBy', 'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', -'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', -'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', -'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', -'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', 'Char', -'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', -'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', -'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', -'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', -'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', -'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', -'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', -'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', -'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', -'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', -'CloseMatch', 'tokenMap', 'pyparsing_common', 'pyparsing_unicode', 'unicode_set', -] - -system_version = tuple(sys.version_info)[:3] -PY_3 = system_version[0] == 3 -if PY_3: - _MAX_INT = sys.maxsize - basestring = str - unichr = chr - unicode = str - _ustr = str - - # build list of single arg builtins, that can be used as parse actions - singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] - -else: - _MAX_INT = sys.maxint - range = xrange - - def _ustr(obj): - """Drop-in replacement for str(obj) that tries to be Unicode - friendly. It first tries str(obj). If that fails with - a UnicodeEncodeError, then it tries unicode(obj). It then - < returns the unicode object | encodes it with the default - encoding | ... >. - """ - if isinstance(obj,unicode): - return obj - - try: - # If this works, then _ustr(obj) has the same behaviour as str(obj), so - # it won't break any existing code. - return str(obj) - - except UnicodeEncodeError: - # Else encode it - ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') - xmlcharref = Regex(r'&#\d+;') - xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) - return xmlcharref.transformString(ret) - - # build list of single arg builtins, tolerant of Python version, that can be used as parse actions - singleArgBuiltins = [] - import __builtin__ - for fname in "sum len sorted reversed list tuple set any all min max".split(): - try: - singleArgBuiltins.append(getattr(__builtin__,fname)) - except AttributeError: - continue - -_generatorType = type((y for y in range(1))) - -def _xml_escape(data): - """Escape &, <, >, ", ', etc. in a string of data.""" - - # ampersand must be replaced first - from_symbols = '&><"\'' - to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) - for from_,to_ in zip(from_symbols, to_symbols): - data = data.replace(from_, to_) - return data - -alphas = string.ascii_uppercase + string.ascii_lowercase -nums = "0123456789" -hexnums = nums + "ABCDEFabcdef" -alphanums = alphas + nums -_bslash = chr(92) -printables = "".join(c for c in string.printable if c not in string.whitespace) - -class ParseBaseException(Exception): - """base exception class for all parsing runtime exceptions""" - # Performance tuning: we construct a *lot* of these, so keep this - # constructor as small and fast as possible - def __init__( self, pstr, loc=0, msg=None, elem=None ): - self.loc = loc - if msg is None: - self.msg = pstr - self.pstr = "" - else: - self.msg = msg - self.pstr = pstr - self.parserElement = elem - self.args = (pstr, loc, msg) - - @classmethod - def _from_exception(cls, pe): - """ - internal factory method to simplify creating one type of ParseException - from another - avoids having __init__ signature conflicts among subclasses - """ - return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) - - def __getattr__( self, aname ): - """supported attributes by name are: - - lineno - returns the line number of the exception text - - col - returns the column number of the exception text - - line - returns the line containing the exception text - """ - if( aname == "lineno" ): - return lineno( self.loc, self.pstr ) - elif( aname in ("col", "column") ): - return col( self.loc, self.pstr ) - elif( aname == "line" ): - return line( self.loc, self.pstr ) - else: - raise AttributeError(aname) - - def __str__( self ): - return "%s (at char %d), (line:%d, col:%d)" % \ - ( self.msg, self.loc, self.lineno, self.column ) - def __repr__( self ): - return _ustr(self) - def markInputline( self, markerString = ">!<" ): - """Extracts the exception line from the input string, and marks - the location of the exception with a special symbol. - """ - line_str = self.line - line_column = self.column - 1 - if markerString: - line_str = "".join((line_str[:line_column], - markerString, line_str[line_column:])) - return line_str.strip() - def __dir__(self): - return "lineno col line".split() + dir(type(self)) - -class ParseException(ParseBaseException): - """ - Exception thrown when parse expressions don't match class; - supported attributes by name are: - - lineno - returns the line number of the exception text - - col - returns the column number of the exception text - - line - returns the line containing the exception text - - Example:: - - try: - Word(nums).setName("integer").parseString("ABC") - except ParseException as pe: - print(pe) - print("column: {}".format(pe.col)) - - prints:: - - Expected integer (at char 0), (line:1, col:1) - column: 1 - - """ - - @staticmethod - def explain(exc, depth=16): - """ - Method to take an exception and translate the Python internal traceback into a list - of the pyparsing expressions that caused the exception to be raised. - - Parameters: - - - exc - exception raised during parsing (need not be a ParseException, in support - of Python exceptions that might be raised in a parse action) - - depth (default=16) - number of levels back in the stack trace to list expression - and function names; if None, the full stack trace names will be listed; if 0, only - the failing input line, marker, and exception string will be shown - - Returns a multi-line string listing the ParserElements and/or function names in the - exception's stack trace. - - Note: the diagnostic output will include string representations of the expressions - that failed to parse. These representations will be more helpful if you use `setName` to - give identifiable names to your expressions. Otherwise they will use the default string - forms, which may be cryptic to read. - - explain() is only supported under Python 3. - """ - import inspect - - if depth is None: - depth = sys.getrecursionlimit() - ret = [] - if isinstance(exc, ParseBaseException): - ret.append(exc.line) - ret.append(' ' * (exc.col - 1) + '^') - ret.append("{0}: {1}".format(type(exc).__name__, exc)) - - if depth > 0: - callers = inspect.getinnerframes(exc.__traceback__, context=depth) - seen = set() - for i, ff in enumerate(callers[-depth:]): - frm = ff.frame - - f_self = frm.f_locals.get('self', None) - if isinstance(f_self, ParserElement): - if frm.f_code.co_name not in ('parseImpl', '_parseNoCache'): - continue - if f_self in seen: - continue - seen.add(f_self) - - self_type = type(f_self) - ret.append("{0}.{1} - {2}".format(self_type.__module__, - self_type.__name__, - f_self)) - elif f_self is not None: - self_type = type(f_self) - ret.append("{0}.{1}".format(self_type.__module__, - self_type.__name__)) - else: - code = frm.f_code - if code.co_name in ('wrapper', '<module>'): - continue - - ret.append("{0}".format(code.co_name)) - - depth -= 1 - if not depth: - break - - return '\n'.join(ret) - - -class ParseFatalException(ParseBaseException): - """user-throwable exception thrown when inconsistent parse content - is found; stops all parsing immediately""" - pass - -class ParseSyntaxException(ParseFatalException): - """just like :class:`ParseFatalException`, but thrown internally - when an :class:`ErrorStop<And._ErrorStop>` ('-' operator) indicates - that parsing is to stop immediately because an unbacktrackable - syntax error has been found. - """ - pass - -#~ class ReparseException(ParseBaseException): - #~ """Experimental class - parse actions can raise this exception to cause - #~ pyparsing to reparse the input string: - #~ - with a modified input string, and/or - #~ - with a modified start location - #~ Set the values of the ReparseException in the constructor, and raise the - #~ exception in a parse action to cause pyparsing to use the new string/location. - #~ Setting the values as None causes no change to be made. - #~ """ - #~ def __init_( self, newstring, restartLoc ): - #~ self.newParseText = newstring - #~ self.reparseLoc = restartLoc - -class RecursiveGrammarException(Exception): - """exception thrown by :class:`ParserElement.validate` if the - grammar could be improperly recursive - """ - def __init__( self, parseElementList ): - self.parseElementTrace = parseElementList - - def __str__( self ): - return "RecursiveGrammarException: %s" % self.parseElementTrace - -class _ParseResultsWithOffset(object): - def __init__(self,p1,p2): - self.tup = (p1,p2) - def __getitem__(self,i): - return self.tup[i] - def __repr__(self): - return repr(self.tup[0]) - def setOffset(self,i): - self.tup = (self.tup[0],i) - -class ParseResults(object): - """Structured parse results, to provide multiple means of access to - the parsed data: - - - as a list (``len(results)``) - - by list index (``results[0], results[1]``, etc.) - - by attribute (``results.<resultsName>`` - see :class:`ParserElement.setResultsName`) - - Example:: - - integer = Word(nums) - date_str = (integer.setResultsName("year") + '/' - + integer.setResultsName("month") + '/' - + integer.setResultsName("day")) - # equivalent form: - # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - # parseString returns a ParseResults object - result = date_str.parseString("1999/12/31") - - def test(s, fn=repr): - print("%s -> %s" % (s, fn(eval(s)))) - test("list(result)") - test("result[0]") - test("result['month']") - test("result.day") - test("'month' in result") - test("'minutes' in result") - test("result.dump()", str) - - prints:: - - list(result) -> ['1999', '/', '12', '/', '31'] - result[0] -> '1999' - result['month'] -> '12' - result.day -> '31' - 'month' in result -> True - 'minutes' in result -> False - result.dump() -> ['1999', '/', '12', '/', '31'] - - day: 31 - - month: 12 - - year: 1999 - """ - def __new__(cls, toklist=None, name=None, asList=True, modal=True ): - if isinstance(toklist, cls): - return toklist - retobj = object.__new__(cls) - retobj.__doinit = True - return retobj - - # Performance tuning: we construct a *lot* of these, so keep this - # constructor as small and fast as possible - def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): - if self.__doinit: - self.__doinit = False - self.__name = None - self.__parent = None - self.__accumNames = {} - self.__asList = asList - self.__modal = modal - if toklist is None: - toklist = [] - if isinstance(toklist, list): - self.__toklist = toklist[:] - elif isinstance(toklist, _generatorType): - self.__toklist = list(toklist) - else: - self.__toklist = [toklist] - self.__tokdict = dict() - - if name is not None and name: - if not modal: - self.__accumNames[name] = 0 - if isinstance(name,int): - name = _ustr(name) # will always return a str, but use _ustr for consistency - self.__name = name - if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): - if isinstance(toklist,basestring): - toklist = [ toklist ] - if asList: - if isinstance(toklist,ParseResults): - self[name] = _ParseResultsWithOffset(ParseResults(toklist.__toklist), 0) - else: - self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) - self[name].__name = name - else: - try: - self[name] = toklist[0] - except (KeyError,TypeError,IndexError): - self[name] = toklist - - def __getitem__( self, i ): - if isinstance( i, (int,slice) ): - return self.__toklist[i] - else: - if i not in self.__accumNames: - return self.__tokdict[i][-1][0] - else: - return ParseResults([ v[0] for v in self.__tokdict[i] ]) - - def __setitem__( self, k, v, isinstance=isinstance ): - if isinstance(v,_ParseResultsWithOffset): - self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] - sub = v[0] - elif isinstance(k,(int,slice)): - self.__toklist[k] = v - sub = v - else: - self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] - sub = v - if isinstance(sub,ParseResults): - sub.__parent = wkref(self) - - def __delitem__( self, i ): - if isinstance(i,(int,slice)): - mylen = len( self.__toklist ) - del self.__toklist[i] - - # convert int to slice - if isinstance(i, int): - if i < 0: - i += mylen - i = slice(i, i+1) - # get removed indices - removed = list(range(*i.indices(mylen))) - removed.reverse() - # fixup indices in token dictionary - for name,occurrences in self.__tokdict.items(): - for j in removed: - for k, (value, position) in enumerate(occurrences): - occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) - else: - del self.__tokdict[i] - - def __contains__( self, k ): - return k in self.__tokdict - - def __len__( self ): return len( self.__toklist ) - def __bool__(self): return ( not not self.__toklist ) - __nonzero__ = __bool__ - def __iter__( self ): return iter( self.__toklist ) - def __reversed__( self ): return iter( self.__toklist[::-1] ) - def _iterkeys( self ): - if hasattr(self.__tokdict, "iterkeys"): - return self.__tokdict.iterkeys() - else: - return iter(self.__tokdict) - - def _itervalues( self ): - return (self[k] for k in self._iterkeys()) - - def _iteritems( self ): - return ((k, self[k]) for k in self._iterkeys()) - - if PY_3: - keys = _iterkeys - """Returns an iterator of all named result keys.""" - - values = _itervalues - """Returns an iterator of all named result values.""" - - items = _iteritems - """Returns an iterator of all named result key-value tuples.""" - - else: - iterkeys = _iterkeys - """Returns an iterator of all named result keys (Python 2.x only).""" - - itervalues = _itervalues - """Returns an iterator of all named result values (Python 2.x only).""" - - iteritems = _iteritems - """Returns an iterator of all named result key-value tuples (Python 2.x only).""" - - def keys( self ): - """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" - return list(self.iterkeys()) - - def values( self ): - """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" - return list(self.itervalues()) - - def items( self ): - """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" - return list(self.iteritems()) - - def haskeys( self ): - """Since keys() returns an iterator, this method is helpful in bypassing - code that looks for the existence of any defined results names.""" - return bool(self.__tokdict) - - def pop( self, *args, **kwargs): - """ - Removes and returns item at specified index (default= ``last``). - Supports both ``list`` and ``dict`` semantics for ``pop()``. If - passed no argument or an integer argument, it will use ``list`` - semantics and pop tokens from the list of parsed tokens. If passed - a non-integer argument (most likely a string), it will use ``dict`` - semantics and pop the corresponding value from any defined results - names. A second default return value argument is supported, just as in - ``dict.pop()``. - - Example:: - - def remove_first(tokens): - tokens.pop(0) - print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] - - label = Word(alphas) - patt = label("LABEL") + OneOrMore(Word(nums)) - print(patt.parseString("AAB 123 321").dump()) - - # Use pop() in a parse action to remove named result (note that corresponding value is not - # removed from list form of results) - def remove_LABEL(tokens): - tokens.pop("LABEL") - return tokens - patt.addParseAction(remove_LABEL) - print(patt.parseString("AAB 123 321").dump()) - - prints:: - - ['AAB', '123', '321'] - - LABEL: AAB - - ['AAB', '123', '321'] - """ - if not args: - args = [-1] - for k,v in kwargs.items(): - if k == 'default': - args = (args[0], v) - else: - raise TypeError("pop() got an unexpected keyword argument '%s'" % k) - if (isinstance(args[0], int) or - len(args) == 1 or - args[0] in self): - index = args[0] - ret = self[index] - del self[index] - return ret - else: - defaultvalue = args[1] - return defaultvalue - - def get(self, key, defaultValue=None): - """ - Returns named result matching the given key, or if there is no - such name, then returns the given ``defaultValue`` or ``None`` if no - ``defaultValue`` is specified. - - Similar to ``dict.get()``. - - Example:: - - integer = Word(nums) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - result = date_str.parseString("1999/12/31") - print(result.get("year")) # -> '1999' - print(result.get("hour", "not specified")) # -> 'not specified' - print(result.get("hour")) # -> None - """ - if key in self: - return self[key] - else: - return defaultValue - - def insert( self, index, insStr ): - """ - Inserts new element at location index in the list of parsed tokens. - - Similar to ``list.insert()``. - - Example:: - - print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - - # use a parse action to insert the parse location in the front of the parsed results - def insert_locn(locn, tokens): - tokens.insert(0, locn) - print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] - """ - self.__toklist.insert(index, insStr) - # fixup indices in token dictionary - for name,occurrences in self.__tokdict.items(): - for k, (value, position) in enumerate(occurrences): - occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) - - def append( self, item ): - """ - Add single element to end of ParseResults list of elements. - - Example:: - - print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - - # use a parse action to compute the sum of the parsed integers, and add it to the end - def append_sum(tokens): - tokens.append(sum(map(int, tokens))) - print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] - """ - self.__toklist.append(item) - - def extend( self, itemseq ): - """ - Add sequence of elements to end of ParseResults list of elements. - - Example:: - - patt = OneOrMore(Word(alphas)) - - # use a parse action to append the reverse of the matched strings, to make a palindrome - def make_palindrome(tokens): - tokens.extend(reversed([t[::-1] for t in tokens])) - return ''.join(tokens) - print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' - """ - if isinstance(itemseq, ParseResults): - self += itemseq - else: - self.__toklist.extend(itemseq) - - def clear( self ): - """ - Clear all elements and results names. - """ - del self.__toklist[:] - self.__tokdict.clear() - - def __getattr__( self, name ): - try: - return self[name] - except KeyError: - return "" - - if name in self.__tokdict: - if name not in self.__accumNames: - return self.__tokdict[name][-1][0] - else: - return ParseResults([ v[0] for v in self.__tokdict[name] ]) - else: - return "" - - def __add__( self, other ): - ret = self.copy() - ret += other - return ret - - def __iadd__( self, other ): - if other.__tokdict: - offset = len(self.__toklist) - addoffset = lambda a: offset if a<0 else a+offset - otheritems = other.__tokdict.items() - otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) - for (k,vlist) in otheritems for v in vlist] - for k,v in otherdictitems: - self[k] = v - if isinstance(v[0],ParseResults): - v[0].__parent = wkref(self) - - self.__toklist += other.__toklist - self.__accumNames.update( other.__accumNames ) - return self - - def __radd__(self, other): - if isinstance(other,int) and other == 0: - # useful for merging many ParseResults using sum() builtin - return self.copy() - else: - # this may raise a TypeError - so be it - return other + self - - def __repr__( self ): - return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) - - def __str__( self ): - return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' - - def _asStringList( self, sep='' ): - out = [] - for item in self.__toklist: - if out and sep: - out.append(sep) - if isinstance( item, ParseResults ): - out += item._asStringList() - else: - out.append( _ustr(item) ) - return out - - def asList( self ): - """ - Returns the parse results as a nested list of matching tokens, all converted to strings. - - Example:: - - patt = OneOrMore(Word(alphas)) - result = patt.parseString("sldkj lsdkj sldkj") - # even though the result prints in string-like form, it is actually a pyparsing ParseResults - print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] - - # Use asList() to create an actual list - result_list = result.asList() - print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] - """ - return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] - - def asDict( self ): - """ - Returns the named parse results as a nested dictionary. - - Example:: - - integer = Word(nums) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - result = date_str.parseString('12/31/1999') - print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) - - result_dict = result.asDict() - print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} - - # even though a ParseResults supports dict-like access, sometime you just need to have a dict - import json - print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable - print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} - """ - if PY_3: - item_fn = self.items - else: - item_fn = self.iteritems - - def toItem(obj): - if isinstance(obj, ParseResults): - if obj.haskeys(): - return obj.asDict() - else: - return [toItem(v) for v in obj] - else: - return obj - - return dict((k,toItem(v)) for k,v in item_fn()) - - def copy( self ): - """ - Returns a new copy of a :class:`ParseResults` object. - """ - ret = ParseResults( self.__toklist ) - ret.__tokdict = dict(self.__tokdict.items()) - ret.__parent = self.__parent - ret.__accumNames.update( self.__accumNames ) - ret.__name = self.__name - return ret - - def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): - """ - (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. - """ - nl = "\n" - out = [] - namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() - for v in vlist) - nextLevelIndent = indent + " " - - # collapse out indents if formatting is not desired - if not formatted: - indent = "" - nextLevelIndent = "" - nl = "" - - selfTag = None - if doctag is not None: - selfTag = doctag - else: - if self.__name: - selfTag = self.__name - - if not selfTag: - if namedItemsOnly: - return "" - else: - selfTag = "ITEM" - - out += [ nl, indent, "<", selfTag, ">" ] - - for i,res in enumerate(self.__toklist): - if isinstance(res,ParseResults): - if i in namedItems: - out += [ res.asXML(namedItems[i], - namedItemsOnly and doctag is None, - nextLevelIndent, - formatted)] - else: - out += [ res.asXML(None, - namedItemsOnly and doctag is None, - nextLevelIndent, - formatted)] - else: - # individual token, see if there is a name for it - resTag = None - if i in namedItems: - resTag = namedItems[i] - if not resTag: - if namedItemsOnly: - continue - else: - resTag = "ITEM" - xmlBodyText = _xml_escape(_ustr(res)) - out += [ nl, nextLevelIndent, "<", resTag, ">", - xmlBodyText, - "</", resTag, ">" ] - - out += [ nl, indent, "</", selfTag, ">" ] - return "".join(out) - - def __lookup(self,sub): - for k,vlist in self.__tokdict.items(): - for v,loc in vlist: - if sub is v: - return k - return None - - def getName(self): - r""" - Returns the results name for this token expression. Useful when several - different expressions might match at a particular location. - - Example:: - - integer = Word(nums) - ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") - house_number_expr = Suppress('#') + Word(nums, alphanums) - user_data = (Group(house_number_expr)("house_number") - | Group(ssn_expr)("ssn") - | Group(integer)("age")) - user_info = OneOrMore(user_data) - - result = user_info.parseString("22 111-22-3333 #221B") - for item in result: - print(item.getName(), ':', item[0]) - - prints:: - - age : 22 - ssn : 111-22-3333 - house_number : 221B - """ - if self.__name: - return self.__name - elif self.__parent: - par = self.__parent() - if par: - return par.__lookup(self) - else: - return None - elif (len(self) == 1 and - len(self.__tokdict) == 1 and - next(iter(self.__tokdict.values()))[0][1] in (0,-1)): - return next(iter(self.__tokdict.keys())) - else: - return None - - def dump(self, indent='', depth=0, full=True): - """ - Diagnostic method for listing out the contents of - a :class:`ParseResults`. Accepts an optional ``indent`` argument so - that this string can be embedded in a nested display of other data. - - Example:: - - integer = Word(nums) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - result = date_str.parseString('12/31/1999') - print(result.dump()) - - prints:: - - ['12', '/', '31', '/', '1999'] - - day: 1999 - - month: 31 - - year: 12 - """ - out = [] - NL = '\n' - out.append( indent+_ustr(self.asList()) ) - if full: - if self.haskeys(): - items = sorted((str(k), v) for k,v in self.items()) - for k,v in items: - if out: - out.append(NL) - out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) - if isinstance(v,ParseResults): - if v: - out.append( v.dump(indent,depth+1) ) - else: - out.append(_ustr(v)) - else: - out.append(repr(v)) - elif any(isinstance(vv,ParseResults) for vv in self): - v = self - for i,vv in enumerate(v): - if isinstance(vv,ParseResults): - out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) - else: - out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) - - return "".join(out) - - def pprint(self, *args, **kwargs): - """ - Pretty-printer for parsed results as a list, using the - `pprint <https://docs.python.org/3/library/pprint.html>`_ module. - Accepts additional positional or keyword args as defined for - `pprint.pprint <https://docs.python.org/3/library/pprint.html#pprint.pprint>`_ . - - Example:: - - ident = Word(alphas, alphanums) - num = Word(nums) - func = Forward() - term = ident | num | Group('(' + func + ')') - func <<= ident + Group(Optional(delimitedList(term))) - result = func.parseString("fna a,b,(fnb c,d,200),100") - result.pprint(width=40) - - prints:: - - ['fna', - ['a', - 'b', - ['(', 'fnb', ['c', 'd', '200'], ')'], - '100']] - """ - pprint.pprint(self.asList(), *args, **kwargs) - - # add support for pickle protocol - def __getstate__(self): - return ( self.__toklist, - ( self.__tokdict.copy(), - self.__parent is not None and self.__parent() or None, - self.__accumNames, - self.__name ) ) - - def __setstate__(self,state): - self.__toklist = state[0] - (self.__tokdict, - par, - inAccumNames, - self.__name) = state[1] - self.__accumNames = {} - self.__accumNames.update(inAccumNames) - if par is not None: - self.__parent = wkref(par) - else: - self.__parent = None - - def __getnewargs__(self): - return self.__toklist, self.__name, self.__asList, self.__modal - - def __dir__(self): - return (dir(type(self)) + list(self.keys())) - -MutableMapping.register(ParseResults) - -def col (loc,strg): - """Returns current column within a string, counting newlines as line separators. - The first column is number 1. - - Note: the default parsing behavior is to expand tabs in the input string - before starting the parsing process. See - :class:`ParserElement.parseString` for more - information on parsing strings containing ``<TAB>`` s, and suggested - methods to maintain a consistent view of the parsed string, the parse - location, and line and column positions within the parsed string. - """ - s = strg - return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) - -def lineno(loc,strg): - """Returns current line number within a string, counting newlines as line separators. - The first line is number 1. - - Note - the default parsing behavior is to expand tabs in the input string - before starting the parsing process. See :class:`ParserElement.parseString` - for more information on parsing strings containing ``<TAB>`` s, and - suggested methods to maintain a consistent view of the parsed string, the - parse location, and line and column positions within the parsed string. - """ - return strg.count("\n",0,loc) + 1 - -def line( loc, strg ): - """Returns the line of text containing loc within a string, counting newlines as line separators. - """ - lastCR = strg.rfind("\n", 0, loc) - nextCR = strg.find("\n", loc) - if nextCR >= 0: - return strg[lastCR+1:nextCR] - else: - return strg[lastCR+1:] - -def _defaultStartDebugAction( instring, loc, expr ): - print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) - -def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): - print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) - -def _defaultExceptionDebugAction( instring, loc, expr, exc ): - print ("Exception raised:" + _ustr(exc)) - -def nullDebugAction(*args): - """'Do-nothing' debug action, to suppress debugging output during parsing.""" - pass - -# Only works on Python 3.x - nonlocal is toxic to Python 2 installs -#~ 'decorator to trim function calls to match the arity of the target' -#~ def _trim_arity(func, maxargs=3): - #~ if func in singleArgBuiltins: - #~ return lambda s,l,t: func(t) - #~ limit = 0 - #~ foundArity = False - #~ def wrapper(*args): - #~ nonlocal limit,foundArity - #~ while 1: - #~ try: - #~ ret = func(*args[limit:]) - #~ foundArity = True - #~ return ret - #~ except TypeError: - #~ if limit == maxargs or foundArity: - #~ raise - #~ limit += 1 - #~ continue - #~ return wrapper - -# this version is Python 2.x-3.x cross-compatible -'decorator to trim function calls to match the arity of the target' -def _trim_arity(func, maxargs=2): - if func in singleArgBuiltins: - return lambda s,l,t: func(t) - limit = [0] - foundArity = [False] - - # traceback return data structure changed in Py3.5 - normalize back to plain tuples - if system_version[:2] >= (3,5): - def extract_stack(limit=0): - # special handling for Python 3.5.0 - extra deep call stack by 1 - offset = -3 if system_version == (3,5,0) else -2 - frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] - return [frame_summary[:2]] - def extract_tb(tb, limit=0): - frames = traceback.extract_tb(tb, limit=limit) - frame_summary = frames[-1] - return [frame_summary[:2]] - else: - extract_stack = traceback.extract_stack - extract_tb = traceback.extract_tb - - # synthesize what would be returned by traceback.extract_stack at the call to - # user's parse action 'func', so that we don't incur call penalty at parse time - - LINE_DIFF = 6 - # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND - # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! - this_line = extract_stack(limit=2)[-1] - pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) - - def wrapper(*args): - while 1: - try: - ret = func(*args[limit[0]:]) - foundArity[0] = True - return ret - except TypeError: - # re-raise TypeErrors if they did not come from our arity testing - if foundArity[0]: - raise - else: - try: - tb = sys.exc_info()[-1] - if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: - raise - finally: - del tb - - if limit[0] <= maxargs: - limit[0] += 1 - continue - raise - - # copy func name to wrapper for sensible debug output - func_name = "<parse action>" - try: - func_name = getattr(func, '__name__', - getattr(func, '__class__').__name__) - except Exception: - func_name = str(func) - wrapper.__name__ = func_name - - return wrapper - -class ParserElement(object): - """Abstract base level parser element class.""" - DEFAULT_WHITE_CHARS = " \n\t\r" - verbose_stacktrace = False - - @staticmethod - def setDefaultWhitespaceChars( chars ): - r""" - Overrides the default whitespace chars - - Example:: - - # default whitespace chars are space, <TAB> and newline - OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] - - # change to just treat newline as significant - ParserElement.setDefaultWhitespaceChars(" \t") - OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] - """ - ParserElement.DEFAULT_WHITE_CHARS = chars - - @staticmethod - def inlineLiteralsUsing(cls): - """ - Set class to be used for inclusion of string literals into a parser. - - Example:: - - # default literal class used is Literal - integer = Word(nums) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] - - - # change to Suppress - ParserElement.inlineLiteralsUsing(Suppress) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] - """ - ParserElement._literalStringClass = cls - - def __init__( self, savelist=False ): - self.parseAction = list() - self.failAction = None - #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall - self.strRepr = None - self.resultsName = None - self.saveAsList = savelist - self.skipWhitespace = True - self.whiteChars = set(ParserElement.DEFAULT_WHITE_CHARS) - self.copyDefaultWhiteChars = True - self.mayReturnEmpty = False # used when checking for left-recursion - self.keepTabs = False - self.ignoreExprs = list() - self.debug = False - self.streamlined = False - self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index - self.errmsg = "" - self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) - self.debugActions = ( None, None, None ) #custom debug actions - self.re = None - self.callPreparse = True # used to avoid redundant calls to preParse - self.callDuringTry = False - - def copy( self ): - """ - Make a copy of this :class:`ParserElement`. Useful for defining - different parse actions for the same parsing pattern, using copies of - the original parse element. - - Example:: - - integer = Word(nums).setParseAction(lambda toks: int(toks[0])) - integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") - integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") - - print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) - - prints:: - - [5120, 100, 655360, 268435456] - - Equivalent form of ``expr.copy()`` is just ``expr()``:: - - integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") - """ - cpy = copy.copy( self ) - cpy.parseAction = self.parseAction[:] - cpy.ignoreExprs = self.ignoreExprs[:] - if self.copyDefaultWhiteChars: - cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS - return cpy - - def setName( self, name ): - """ - Define name for this expression, makes debugging and exception messages clearer. - - Example:: - - Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) - Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) - """ - self.name = name - self.errmsg = "Expected " + self.name - if hasattr(self,"exception"): - self.exception.msg = self.errmsg - return self - - def setResultsName( self, name, listAllMatches=False ): - """ - Define name for referencing matching tokens as a nested attribute - of the returned parse results. - NOTE: this returns a *copy* of the original :class:`ParserElement` object; - this is so that the client can define a basic element, such as an - integer, and reference it in multiple places with different names. - - You can also set results names using the abbreviated syntax, - ``expr("name")`` in place of ``expr.setResultsName("name")`` - - see :class:`__call__`. - - Example:: - - date_str = (integer.setResultsName("year") + '/' - + integer.setResultsName("month") + '/' - + integer.setResultsName("day")) - - # equivalent form: - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - """ - newself = self.copy() - if name.endswith("*"): - name = name[:-1] - listAllMatches=True - newself.resultsName = name - newself.modalResults = not listAllMatches - return newself - - def setBreak(self,breakFlag = True): - """Method to invoke the Python pdb debugger when this element is - about to be parsed. Set ``breakFlag`` to True to enable, False to - disable. - """ - if breakFlag: - _parseMethod = self._parse - def breaker(instring, loc, doActions=True, callPreParse=True): - import pdb - pdb.set_trace() - return _parseMethod( instring, loc, doActions, callPreParse ) - breaker._originalParseMethod = _parseMethod - self._parse = breaker - else: - if hasattr(self._parse,"_originalParseMethod"): - self._parse = self._parse._originalParseMethod - return self - - def setParseAction( self, *fns, **kwargs ): - """ - Define one or more actions to perform when successfully matching parse element definition. - Parse action fn is a callable method with 0-3 arguments, called as ``fn(s,loc,toks)`` , - ``fn(loc,toks)`` , ``fn(toks)`` , or just ``fn()`` , where: - - - s = the original string being parsed (see note below) - - loc = the location of the matching substring - - toks = a list of the matched tokens, packaged as a :class:`ParseResults` object - - If the functions in fns modify the tokens, they can return them as the return - value from fn, and the modified list of tokens will replace the original. - Otherwise, fn does not need to return any value. - - Optional keyword arguments: - - callDuringTry = (default= ``False`` ) indicate if parse action should be run during lookaheads and alternate testing - - Note: the default parsing behavior is to expand tabs in the input string - before starting the parsing process. See :class:`parseString for more - information on parsing strings containing ``<TAB>`` s, and suggested - methods to maintain a consistent view of the parsed string, the parse - location, and line and column positions within the parsed string. - - Example:: - - integer = Word(nums) - date_str = integer + '/' + integer + '/' + integer - - date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] - - # use parse action to convert to ints at parse time - integer = Word(nums).setParseAction(lambda toks: int(toks[0])) - date_str = integer + '/' + integer + '/' + integer - - # note that integer fields are now ints, not strings - date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] - """ - self.parseAction = list(map(_trim_arity, list(fns))) - self.callDuringTry = kwargs.get("callDuringTry", False) - return self - - def addParseAction( self, *fns, **kwargs ): - """ - Add one or more parse actions to expression's list of parse actions. See :class:`setParseAction`. - - See examples in :class:`copy`. - """ - self.parseAction += list(map(_trim_arity, list(fns))) - self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) - return self - - def addCondition(self, *fns, **kwargs): - """Add a boolean predicate function to expression's list of parse actions. See - :class:`setParseAction` for function call signatures. Unlike ``setParseAction``, - functions passed to ``addCondition`` need to return boolean success/fail of the condition. - - Optional keyword arguments: - - message = define a custom message to be used in the raised exception - - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException - - Example:: - - integer = Word(nums).setParseAction(lambda toks: int(toks[0])) - year_int = integer.copy() - year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") - date_str = year_int + '/' + integer + '/' + integer - - result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) - """ - msg = kwargs.get("message", "failed user-defined condition") - exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException - for fn in fns: - fn = _trim_arity(fn) - def pa(s,l,t): - if not bool(fn(s,l,t)): - raise exc_type(s,l,msg) - self.parseAction.append(pa) - self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) - return self - - def setFailAction( self, fn ): - """Define action to perform if parsing fails at this expression. - Fail acton fn is a callable function that takes the arguments - ``fn(s,loc,expr,err)`` where: - - s = string being parsed - - loc = location where expression match was attempted and failed - - expr = the parse expression that failed - - err = the exception thrown - The function returns no value. It may throw :class:`ParseFatalException` - if it is desired to stop parsing immediately.""" - self.failAction = fn - return self - - def _skipIgnorables( self, instring, loc ): - exprsFound = True - while exprsFound: - exprsFound = False - for e in self.ignoreExprs: - try: - while 1: - loc,dummy = e._parse( instring, loc ) - exprsFound = True - except ParseException: - pass - return loc - - def preParse( self, instring, loc ): - if self.ignoreExprs: - loc = self._skipIgnorables( instring, loc ) - - if self.skipWhitespace: - wt = self.whiteChars - instrlen = len(instring) - while loc < instrlen and instring[loc] in wt: - loc += 1 - - return loc - - def parseImpl( self, instring, loc, doActions=True ): - return loc, [] - - def postParse( self, instring, loc, tokenlist ): - return tokenlist - - #~ @profile - def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): - debugging = ( self.debug ) #and doActions ) - - if debugging or self.failAction: - #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) - if (self.debugActions[0] ): - self.debugActions[0]( instring, loc, self ) - if callPreParse and self.callPreparse: - preloc = self.preParse( instring, loc ) - else: - preloc = loc - tokensStart = preloc - try: - try: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - except IndexError: - raise ParseException( instring, len(instring), self.errmsg, self ) - except ParseBaseException as err: - #~ print ("Exception raised:", err) - if self.debugActions[2]: - self.debugActions[2]( instring, tokensStart, self, err ) - if self.failAction: - self.failAction( instring, tokensStart, self, err ) - raise - else: - if callPreParse and self.callPreparse: - preloc = self.preParse( instring, loc ) - else: - preloc = loc - tokensStart = preloc - if self.mayIndexError or preloc >= len(instring): - try: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - except IndexError: - raise ParseException( instring, len(instring), self.errmsg, self ) - else: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - - tokens = self.postParse( instring, loc, tokens ) - - retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) - if self.parseAction and (doActions or self.callDuringTry): - if debugging: - try: - for fn in self.parseAction: - try: - tokens = fn( instring, tokensStart, retTokens ) - except IndexError as parse_action_exc: - exc = ParseException("exception raised in parse action") - exc.__cause__ = parse_action_exc - raise exc - - if tokens is not None and tokens is not retTokens: - retTokens = ParseResults( tokens, - self.resultsName, - asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), - modal=self.modalResults ) - except ParseBaseException as err: - #~ print "Exception raised in user parse action:", err - if (self.debugActions[2] ): - self.debugActions[2]( instring, tokensStart, self, err ) - raise - else: - for fn in self.parseAction: - try: - tokens = fn( instring, tokensStart, retTokens ) - except IndexError as parse_action_exc: - exc = ParseException("exception raised in parse action") - exc.__cause__ = parse_action_exc - raise exc - - if tokens is not None and tokens is not retTokens: - retTokens = ParseResults( tokens, - self.resultsName, - asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), - modal=self.modalResults ) - if debugging: - #~ print ("Matched",self,"->",retTokens.asList()) - if (self.debugActions[1] ): - self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) - - return loc, retTokens - - def tryParse( self, instring, loc ): - try: - return self._parse( instring, loc, doActions=False )[0] - except ParseFatalException: - raise ParseException( instring, loc, self.errmsg, self) - - def canParseNext(self, instring, loc): - try: - self.tryParse(instring, loc) - except (ParseException, IndexError): - return False - else: - return True - - class _UnboundedCache(object): - def __init__(self): - cache = {} - self.not_in_cache = not_in_cache = object() - - def get(self, key): - return cache.get(key, not_in_cache) - - def set(self, key, value): - cache[key] = value - - def clear(self): - cache.clear() - - def cache_len(self): - return len(cache) - - self.get = types.MethodType(get, self) - self.set = types.MethodType(set, self) - self.clear = types.MethodType(clear, self) - self.__len__ = types.MethodType(cache_len, self) - - if _OrderedDict is not None: - class _FifoCache(object): - def __init__(self, size): - self.not_in_cache = not_in_cache = object() - - cache = _OrderedDict() - - def get(self, key): - return cache.get(key, not_in_cache) - - def set(self, key, value): - cache[key] = value - while len(cache) > size: - try: - cache.popitem(False) - except KeyError: - pass - - def clear(self): - cache.clear() - - def cache_len(self): - return len(cache) - - self.get = types.MethodType(get, self) - self.set = types.MethodType(set, self) - self.clear = types.MethodType(clear, self) - self.__len__ = types.MethodType(cache_len, self) - - else: - class _FifoCache(object): - def __init__(self, size): - self.not_in_cache = not_in_cache = object() - - cache = {} - key_fifo = collections.deque([], size) - - def get(self, key): - return cache.get(key, not_in_cache) - - def set(self, key, value): - cache[key] = value - while len(key_fifo) > size: - cache.pop(key_fifo.popleft(), None) - key_fifo.append(key) - - def clear(self): - cache.clear() - key_fifo.clear() - - def cache_len(self): - return len(cache) - - self.get = types.MethodType(get, self) - self.set = types.MethodType(set, self) - self.clear = types.MethodType(clear, self) - self.__len__ = types.MethodType(cache_len, self) - - # argument cache for optimizing repeated calls when backtracking through recursive expressions - packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail - packrat_cache_lock = RLock() - packrat_cache_stats = [0, 0] - - # this method gets repeatedly called during backtracking with the same arguments - - # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression - def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): - HIT, MISS = 0, 1 - lookup = (self, instring, loc, callPreParse, doActions) - with ParserElement.packrat_cache_lock: - cache = ParserElement.packrat_cache - value = cache.get(lookup) - if value is cache.not_in_cache: - ParserElement.packrat_cache_stats[MISS] += 1 - try: - value = self._parseNoCache(instring, loc, doActions, callPreParse) - except ParseBaseException as pe: - # cache a copy of the exception, without the traceback - cache.set(lookup, pe.__class__(*pe.args)) - raise - else: - cache.set(lookup, (value[0], value[1].copy())) - return value - else: - ParserElement.packrat_cache_stats[HIT] += 1 - if isinstance(value, Exception): - raise value - return (value[0], value[1].copy()) - - _parse = _parseNoCache - - @staticmethod - def resetCache(): - ParserElement.packrat_cache.clear() - ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) - - _packratEnabled = False - @staticmethod - def enablePackrat(cache_size_limit=128): - """Enables "packrat" parsing, which adds memoizing to the parsing logic. - Repeated parse attempts at the same string location (which happens - often in many complex grammars) can immediately return a cached value, - instead of re-executing parsing/validating code. Memoizing is done of - both valid results and parsing exceptions. - - Parameters: - - - cache_size_limit - (default= ``128``) - if an integer value is provided - will limit the size of the packrat cache; if None is passed, then - the cache size will be unbounded; if 0 is passed, the cache will - be effectively disabled. - - This speedup may break existing programs that use parse actions that - have side-effects. For this reason, packrat parsing is disabled when - you first import pyparsing. To activate the packrat feature, your - program must call the class method :class:`ParserElement.enablePackrat`. - For best results, call ``enablePackrat()`` immediately after - importing pyparsing. - - Example:: - - from pip._vendor import pyparsing - pyparsing.ParserElement.enablePackrat() - """ - if not ParserElement._packratEnabled: - ParserElement._packratEnabled = True - if cache_size_limit is None: - ParserElement.packrat_cache = ParserElement._UnboundedCache() - else: - ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) - ParserElement._parse = ParserElement._parseCache - - def parseString( self, instring, parseAll=False ): - """ - Execute the parse expression with the given string. - This is the main interface to the client code, once the complete - expression has been built. - - If you want the grammar to require that the entire input string be - successfully parsed, then set ``parseAll`` to True (equivalent to ending - the grammar with ``StringEnd()``). - - Note: ``parseString`` implicitly calls ``expandtabs()`` on the input string, - in order to report proper column numbers in parse actions. - If the input string contains tabs and - the grammar uses parse actions that use the ``loc`` argument to index into the - string being parsed, you can ensure you have a consistent view of the input - string by: - - - calling ``parseWithTabs`` on your grammar before calling ``parseString`` - (see :class:`parseWithTabs`) - - define your parse action using the full ``(s,loc,toks)`` signature, and - reference the input string using the parse action's ``s`` argument - - explictly expand the tabs in your input string before calling - ``parseString`` - - Example:: - - Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] - Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text - """ - ParserElement.resetCache() - if not self.streamlined: - self.streamline() - #~ self.saveAsList = True - for e in self.ignoreExprs: - e.streamline() - if not self.keepTabs: - instring = instring.expandtabs() - try: - loc, tokens = self._parse( instring, 0 ) - if parseAll: - loc = self.preParse( instring, loc ) - se = Empty() + StringEnd() - se._parse( instring, loc ) - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - else: - return tokens - - def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): - """ - Scan the input string for expression matches. Each match will return the - matching tokens, start location, and end location. May be called with optional - ``maxMatches`` argument, to clip scanning after 'n' matches are found. If - ``overlap`` is specified, then overlapping matches will be reported. - - Note that the start and end locations are reported relative to the string - being parsed. See :class:`parseString` for more information on parsing - strings with embedded tabs. - - Example:: - - source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" - print(source) - for tokens,start,end in Word(alphas).scanString(source): - print(' '*start + '^'*(end-start)) - print(' '*start + tokens[0]) - - prints:: - - sldjf123lsdjjkf345sldkjf879lkjsfd987 - ^^^^^ - sldjf - ^^^^^^^ - lsdjjkf - ^^^^^^ - sldkjf - ^^^^^^ - lkjsfd - """ - if not self.streamlined: - self.streamline() - for e in self.ignoreExprs: - e.streamline() - - if not self.keepTabs: - instring = _ustr(instring).expandtabs() - instrlen = len(instring) - loc = 0 - preparseFn = self.preParse - parseFn = self._parse - ParserElement.resetCache() - matches = 0 - try: - while loc <= instrlen and matches < maxMatches: - try: - preloc = preparseFn( instring, loc ) - nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) - except ParseException: - loc = preloc+1 - else: - if nextLoc > loc: - matches += 1 - yield tokens, preloc, nextLoc - if overlap: - nextloc = preparseFn( instring, loc ) - if nextloc > loc: - loc = nextLoc - else: - loc += 1 - else: - loc = nextLoc - else: - loc = preloc+1 - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - - def transformString( self, instring ): - """ - Extension to :class:`scanString`, to modify matching text with modified tokens that may - be returned from a parse action. To use ``transformString``, define a grammar and - attach a parse action to it that modifies the returned token list. - Invoking ``transformString()`` on a target string will then scan for matches, - and replace the matched text patterns according to the logic in the parse - action. ``transformString()`` returns the resulting transformed string. - - Example:: - - wd = Word(alphas) - wd.setParseAction(lambda toks: toks[0].title()) - - print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) - - prints:: - - Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. - """ - out = [] - lastE = 0 - # force preservation of <TAB>s, to minimize unwanted transformation of string, and to - # keep string locs straight between transformString and scanString - self.keepTabs = True - try: - for t,s,e in self.scanString( instring ): - out.append( instring[lastE:s] ) - if t: - if isinstance(t,ParseResults): - out += t.asList() - elif isinstance(t,list): - out += t - else: - out.append(t) - lastE = e - out.append(instring[lastE:]) - out = [o for o in out if o] - return "".join(map(_ustr,_flatten(out))) - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - - def searchString( self, instring, maxMatches=_MAX_INT ): - """ - Another extension to :class:`scanString`, simplifying the access to the tokens found - to match the given parse expression. May be called with optional - ``maxMatches`` argument, to clip searching after 'n' matches are found. - - Example:: - - # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters - cap_word = Word(alphas.upper(), alphas.lower()) - - print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) - - # the sum() builtin can be used to merge results into a single ParseResults object - print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) - - prints:: - - [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] - ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] - """ - try: - return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - - def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): - """ - Generator method to split a string using the given expression as a separator. - May be called with optional ``maxsplit`` argument, to limit the number of splits; - and the optional ``includeSeparators`` argument (default= ``False``), if the separating - matching text should be included in the split results. - - Example:: - - punc = oneOf(list(".,;:/-!?")) - print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) - - prints:: - - ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] - """ - splits = 0 - last = 0 - for t,s,e in self.scanString(instring, maxMatches=maxsplit): - yield instring[last:s] - if includeSeparators: - yield t[0] - last = e - yield instring[last:] - - def __add__(self, other ): - """ - Implementation of + operator - returns :class:`And`. Adding strings to a ParserElement - converts them to :class:`Literal`s by default. - - Example:: - - greet = Word(alphas) + "," + Word(alphas) + "!" - hello = "Hello, World!" - print (hello, "->", greet.parseString(hello)) - - prints:: - - Hello, World! -> ['Hello', ',', 'World', '!'] - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return And( [ self, other ] ) - - def __radd__(self, other ): - """ - Implementation of + operator when left operand is not a :class:`ParserElement` - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other + self - - def __sub__(self, other): - """ - Implementation of - operator, returns :class:`And` with error stop - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return self + And._ErrorStop() + other - - def __rsub__(self, other ): - """ - Implementation of - operator when left operand is not a :class:`ParserElement` - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other - self - - def __mul__(self,other): - """ - Implementation of * operator, allows use of ``expr * 3`` in place of - ``expr + expr + expr``. Expressions may also me multiplied by a 2-integer - tuple, similar to ``{min,max}`` multipliers in regular expressions. Tuples - may also include ``None`` as in: - - ``expr*(n,None)`` or ``expr*(n,)`` is equivalent - to ``expr*n + ZeroOrMore(expr)`` - (read as "at least n instances of ``expr``") - - ``expr*(None,n)`` is equivalent to ``expr*(0,n)`` - (read as "0 to n instances of ``expr``") - - ``expr*(None,None)`` is equivalent to ``ZeroOrMore(expr)`` - - ``expr*(1,None)`` is equivalent to ``OneOrMore(expr)`` - - Note that ``expr*(None,n)`` does not raise an exception if - more than n exprs exist in the input stream; that is, - ``expr*(None,n)`` does not enforce a maximum number of expr - occurrences. If this behavior is desired, then write - ``expr*(None,n) + ~expr`` - """ - if isinstance(other,int): - minElements, optElements = other,0 - elif isinstance(other,tuple): - other = (other + (None, None))[:2] - if other[0] is None: - other = (0, other[1]) - if isinstance(other[0],int) and other[1] is None: - if other[0] == 0: - return ZeroOrMore(self) - if other[0] == 1: - return OneOrMore(self) - else: - return self*other[0] + ZeroOrMore(self) - elif isinstance(other[0],int) and isinstance(other[1],int): - minElements, optElements = other - optElements -= minElements - else: - raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) - else: - raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) - - if minElements < 0: - raise ValueError("cannot multiply ParserElement by negative value") - if optElements < 0: - raise ValueError("second tuple value must be greater or equal to first tuple value") - if minElements == optElements == 0: - raise ValueError("cannot multiply ParserElement by 0 or (0,0)") - - if (optElements): - def makeOptionalList(n): - if n>1: - return Optional(self + makeOptionalList(n-1)) - else: - return Optional(self) - if minElements: - if minElements == 1: - ret = self + makeOptionalList(optElements) - else: - ret = And([self]*minElements) + makeOptionalList(optElements) - else: - ret = makeOptionalList(optElements) - else: - if minElements == 1: - ret = self - else: - ret = And([self]*minElements) - return ret - - def __rmul__(self, other): - return self.__mul__(other) - - def __or__(self, other ): - """ - Implementation of | operator - returns :class:`MatchFirst` - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return MatchFirst( [ self, other ] ) - - def __ror__(self, other ): - """ - Implementation of | operator when left operand is not a :class:`ParserElement` - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other | self - - def __xor__(self, other ): - """ - Implementation of ^ operator - returns :class:`Or` - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return Or( [ self, other ] ) - - def __rxor__(self, other ): - """ - Implementation of ^ operator when left operand is not a :class:`ParserElement` - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other ^ self - - def __and__(self, other ): - """ - Implementation of & operator - returns :class:`Each` - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return Each( [ self, other ] ) - - def __rand__(self, other ): - """ - Implementation of & operator when left operand is not a :class:`ParserElement` - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other & self - - def __invert__( self ): - """ - Implementation of ~ operator - returns :class:`NotAny` - """ - return NotAny( self ) - - def __call__(self, name=None): - """ - Shortcut for :class:`setResultsName`, with ``listAllMatches=False``. - - If ``name`` is given with a trailing ``'*'`` character, then ``listAllMatches`` will be - passed as ``True``. - - If ``name` is omitted, same as calling :class:`copy`. - - Example:: - - # these are equivalent - userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") - userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") - """ - if name is not None: - return self.setResultsName(name) - else: - return self.copy() - - def suppress( self ): - """ - Suppresses the output of this :class:`ParserElement`; useful to keep punctuation from - cluttering up returned output. - """ - return Suppress( self ) - - def leaveWhitespace( self ): - """ - Disables the skipping of whitespace before matching the characters in the - :class:`ParserElement`'s defined pattern. This is normally only used internally by - the pyparsing module, but may be needed in some whitespace-sensitive grammars. - """ - self.skipWhitespace = False - return self - - def setWhitespaceChars( self, chars ): - """ - Overrides the default whitespace chars - """ - self.skipWhitespace = True - self.whiteChars = chars - self.copyDefaultWhiteChars = False - return self - - def parseWithTabs( self ): - """ - Overrides default behavior to expand ``<TAB>``s to spaces before parsing the input string. - Must be called before ``parseString`` when the input grammar contains elements that - match ``<TAB>`` characters. - """ - self.keepTabs = True - return self - - def ignore( self, other ): - """ - Define expression to be ignored (e.g., comments) while doing pattern - matching; may be called repeatedly, to define multiple comment or other - ignorable patterns. - - Example:: - - patt = OneOrMore(Word(alphas)) - patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] - - patt.ignore(cStyleComment) - patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] - """ - if isinstance(other, basestring): - other = Suppress(other) - - if isinstance( other, Suppress ): - if other not in self.ignoreExprs: - self.ignoreExprs.append(other) - else: - self.ignoreExprs.append( Suppress( other.copy() ) ) - return self - - def setDebugActions( self, startAction, successAction, exceptionAction ): - """ - Enable display of debugging messages while doing pattern matching. - """ - self.debugActions = (startAction or _defaultStartDebugAction, - successAction or _defaultSuccessDebugAction, - exceptionAction or _defaultExceptionDebugAction) - self.debug = True - return self - - def setDebug( self, flag=True ): - """ - Enable display of debugging messages while doing pattern matching. - Set ``flag`` to True to enable, False to disable. - - Example:: - - wd = Word(alphas).setName("alphaword") - integer = Word(nums).setName("numword") - term = wd | integer - - # turn on debugging for wd - wd.setDebug() - - OneOrMore(term).parseString("abc 123 xyz 890") - - prints:: - - Match alphaword at loc 0(1,1) - Matched alphaword -> ['abc'] - Match alphaword at loc 3(1,4) - Exception raised:Expected alphaword (at char 4), (line:1, col:5) - Match alphaword at loc 7(1,8) - Matched alphaword -> ['xyz'] - Match alphaword at loc 11(1,12) - Exception raised:Expected alphaword (at char 12), (line:1, col:13) - Match alphaword at loc 15(1,16) - Exception raised:Expected alphaword (at char 15), (line:1, col:16) - - The output shown is that produced by the default debug actions - custom debug actions can be - specified using :class:`setDebugActions`. Prior to attempting - to match the ``wd`` expression, the debugging message ``"Match <exprname> at loc <n>(<line>,<col>)"`` - is shown. Then if the parse succeeds, a ``"Matched"`` message is shown, or an ``"Exception raised"`` - message is shown. Also note the use of :class:`setName` to assign a human-readable name to the expression, - which makes debugging and exception messages easier to understand - for instance, the default - name created for the :class:`Word` expression without calling ``setName`` is ``"W:(ABCD...)"``. - """ - if flag: - self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) - else: - self.debug = False - return self - - def __str__( self ): - return self.name - - def __repr__( self ): - return _ustr(self) - - def streamline( self ): - self.streamlined = True - self.strRepr = None - return self - - def checkRecursion( self, parseElementList ): - pass - - def validate( self, validateTrace=[] ): - """ - Check defined expressions for valid structure, check for infinite recursive definitions. - """ - self.checkRecursion( [] ) - - def parseFile( self, file_or_filename, parseAll=False ): - """ - Execute the parse expression on the given file or filename. - If a filename is specified (instead of a file object), - the entire file is opened, read, and closed before parsing. - """ - try: - file_contents = file_or_filename.read() - except AttributeError: - with open(file_or_filename, "r") as f: - file_contents = f.read() - try: - return self.parseString(file_contents, parseAll) - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - - def __eq__(self,other): - if isinstance(other, ParserElement): - return self is other or vars(self) == vars(other) - elif isinstance(other, basestring): - return self.matches(other) - else: - return super(ParserElement,self)==other - - def __ne__(self,other): - return not (self == other) - - def __hash__(self): - return hash(id(self)) - - def __req__(self,other): - return self == other - - def __rne__(self,other): - return not (self == other) - - def matches(self, testString, parseAll=True): - """ - Method for quick testing of a parser against a test string. Good for simple - inline microtests of sub expressions while building up larger parser. - - Parameters: - - testString - to test against this expression for a match - - parseAll - (default= ``True``) - flag to pass to :class:`parseString` when running tests - - Example:: - - expr = Word(nums) - assert expr.matches("100") - """ - try: - self.parseString(_ustr(testString), parseAll=parseAll) - return True - except ParseBaseException: - return False - - def runTests(self, tests, parseAll=True, comment='#', - fullDump=True, printResults=True, failureTests=False, postParse=None): - """ - Execute the parse expression on a series of test strings, showing each - test, the parsed results or where the parse failed. Quick and easy way to - run a parse expression against a list of sample strings. - - Parameters: - - tests - a list of separate test strings, or a multiline string of test strings - - parseAll - (default= ``True``) - flag to pass to :class:`parseString` when running tests - - comment - (default= ``'#'``) - expression for indicating embedded comments in the test - string; pass None to disable comment filtering - - fullDump - (default= ``True``) - dump results as list followed by results names in nested outline; - if False, only dump nested list - - printResults - (default= ``True``) prints test output to stdout - - failureTests - (default= ``False``) indicates if these tests are expected to fail parsing - - postParse - (default= ``None``) optional callback for successful parse results; called as - `fn(test_string, parse_results)` and returns a string to be added to the test output - - Returns: a (success, results) tuple, where success indicates that all tests succeeded - (or failed if ``failureTests`` is True), and the results contain a list of lines of each - test's output - - Example:: - - number_expr = pyparsing_common.number.copy() - - result = number_expr.runTests(''' - # unsigned integer - 100 - # negative integer - -100 - # float with scientific notation - 6.02e23 - # integer with scientific notation - 1e-12 - ''') - print("Success" if result[0] else "Failed!") - - result = number_expr.runTests(''' - # stray character - 100Z - # missing leading digit before '.' - -.100 - # too many '.' - 3.14.159 - ''', failureTests=True) - print("Success" if result[0] else "Failed!") - - prints:: - - # unsigned integer - 100 - [100] - - # negative integer - -100 - [-100] - - # float with scientific notation - 6.02e23 - [6.02e+23] - - # integer with scientific notation - 1e-12 - [1e-12] - - Success - - # stray character - 100Z - ^ - FAIL: Expected end of text (at char 3), (line:1, col:4) - - # missing leading digit before '.' - -.100 - ^ - FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) - - # too many '.' - 3.14.159 - ^ - FAIL: Expected end of text (at char 4), (line:1, col:5) - - Success - - Each test string must be on a single line. If you want to test a string that spans multiple - lines, create a test like this:: - - expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") - - (Note that this is a raw string literal, you must include the leading 'r'.) - """ - if isinstance(tests, basestring): - tests = list(map(str.strip, tests.rstrip().splitlines())) - if isinstance(comment, basestring): - comment = Literal(comment) - allResults = [] - comments = [] - success = True - for t in tests: - if comment is not None and comment.matches(t, False) or comments and not t: - comments.append(t) - continue - if not t: - continue - out = ['\n'.join(comments), t] - comments = [] - try: - # convert newline marks to actual newlines, and strip leading BOM if present - t = t.replace(r'\n','\n').lstrip('\ufeff') - result = self.parseString(t, parseAll=parseAll) - out.append(result.dump(full=fullDump)) - success = success and not failureTests - if postParse is not None: - try: - pp_value = postParse(t, result) - if pp_value is not None: - out.append(str(pp_value)) - except Exception as e: - out.append("{0} failed: {1}: {2}".format(postParse.__name__, type(e).__name__, e)) - except ParseBaseException as pe: - fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" - if '\n' in t: - out.append(line(pe.loc, t)) - out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) - else: - out.append(' '*pe.loc + '^' + fatal) - out.append("FAIL: " + str(pe)) - success = success and failureTests - result = pe - except Exception as exc: - out.append("FAIL-EXCEPTION: " + str(exc)) - success = success and failureTests - result = exc - - if printResults: - if fullDump: - out.append('') - print('\n'.join(out)) - - allResults.append((t, result)) - - return success, allResults - - -class Token(ParserElement): - """Abstract :class:`ParserElement` subclass, for defining atomic - matching patterns. - """ - def __init__( self ): - super(Token,self).__init__( savelist=False ) - - -class Empty(Token): - """An empty token, will always match. - """ - def __init__( self ): - super(Empty,self).__init__() - self.name = "Empty" - self.mayReturnEmpty = True - self.mayIndexError = False - - -class NoMatch(Token): - """A token that will never match. - """ - def __init__( self ): - super(NoMatch,self).__init__() - self.name = "NoMatch" - self.mayReturnEmpty = True - self.mayIndexError = False - self.errmsg = "Unmatchable token" - - def parseImpl( self, instring, loc, doActions=True ): - raise ParseException(instring, loc, self.errmsg, self) - - -class Literal(Token): - """Token to exactly match a specified string. - - Example:: - - Literal('blah').parseString('blah') # -> ['blah'] - Literal('blah').parseString('blahfooblah') # -> ['blah'] - Literal('blah').parseString('bla') # -> Exception: Expected "blah" - - For case-insensitive matching, use :class:`CaselessLiteral`. - - For keyword matching (force word break before and after the matched string), - use :class:`Keyword` or :class:`CaselessKeyword`. - """ - def __init__( self, matchString ): - super(Literal,self).__init__() - self.match = matchString - self.matchLen = len(matchString) - try: - self.firstMatchChar = matchString[0] - except IndexError: - warnings.warn("null string passed to Literal; use Empty() instead", - SyntaxWarning, stacklevel=2) - self.__class__ = Empty - self.name = '"%s"' % _ustr(self.match) - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = False - self.mayIndexError = False - - # Performance tuning: this routine gets called a *lot* - # if this is a single character match string and the first character matches, - # short-circuit as quickly as possible, and avoid calling startswith - #~ @profile - def parseImpl( self, instring, loc, doActions=True ): - if (instring[loc] == self.firstMatchChar and - (self.matchLen==1 or instring.startswith(self.match,loc)) ): - return loc+self.matchLen, self.match - raise ParseException(instring, loc, self.errmsg, self) -_L = Literal -ParserElement._literalStringClass = Literal - -class Keyword(Token): - """Token to exactly match a specified string as a keyword, that is, - it must be immediately followed by a non-keyword character. Compare - with :class:`Literal`: - - - ``Literal("if")`` will match the leading ``'if'`` in - ``'ifAndOnlyIf'``. - - ``Keyword("if")`` will not; it will only match the leading - ``'if'`` in ``'if x=1'``, or ``'if(y==2)'`` - - Accepts two optional constructor arguments in addition to the - keyword string: - - - ``identChars`` is a string of characters that would be valid - identifier characters, defaulting to all alphanumerics + "_" and - "$" - - ``caseless`` allows case-insensitive matching, default is ``False``. - - Example:: - - Keyword("start").parseString("start") # -> ['start'] - Keyword("start").parseString("starting") # -> Exception - - For case-insensitive matching, use :class:`CaselessKeyword`. - """ - DEFAULT_KEYWORD_CHARS = alphanums+"_$" - - def __init__( self, matchString, identChars=None, caseless=False ): - super(Keyword,self).__init__() - if identChars is None: - identChars = Keyword.DEFAULT_KEYWORD_CHARS - self.match = matchString - self.matchLen = len(matchString) - try: - self.firstMatchChar = matchString[0] - except IndexError: - warnings.warn("null string passed to Keyword; use Empty() instead", - SyntaxWarning, stacklevel=2) - self.name = '"%s"' % self.match - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = False - self.mayIndexError = False - self.caseless = caseless - if caseless: - self.caselessmatch = matchString.upper() - identChars = identChars.upper() - self.identChars = set(identChars) - - def parseImpl( self, instring, loc, doActions=True ): - if self.caseless: - if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and - (loc == 0 or instring[loc-1].upper() not in self.identChars) ): - return loc+self.matchLen, self.match - else: - if (instring[loc] == self.firstMatchChar and - (self.matchLen==1 or instring.startswith(self.match,loc)) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and - (loc == 0 or instring[loc-1] not in self.identChars) ): - return loc+self.matchLen, self.match - raise ParseException(instring, loc, self.errmsg, self) - - def copy(self): - c = super(Keyword,self).copy() - c.identChars = Keyword.DEFAULT_KEYWORD_CHARS - return c - - @staticmethod - def setDefaultKeywordChars( chars ): - """Overrides the default Keyword chars - """ - Keyword.DEFAULT_KEYWORD_CHARS = chars - -class CaselessLiteral(Literal): - """Token to match a specified string, ignoring case of letters. - Note: the matched results will always be in the case of the given - match string, NOT the case of the input text. - - Example:: - - OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] - - (Contrast with example for :class:`CaselessKeyword`.) - """ - def __init__( self, matchString ): - super(CaselessLiteral,self).__init__( matchString.upper() ) - # Preserve the defining literal. - self.returnString = matchString - self.name = "'%s'" % self.returnString - self.errmsg = "Expected " + self.name - - def parseImpl( self, instring, loc, doActions=True ): - if instring[ loc:loc+self.matchLen ].upper() == self.match: - return loc+self.matchLen, self.returnString - raise ParseException(instring, loc, self.errmsg, self) - -class CaselessKeyword(Keyword): - """ - Caseless version of :class:`Keyword`. - - Example:: - - OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] - - (Contrast with example for :class:`CaselessLiteral`.) - """ - def __init__( self, matchString, identChars=None ): - super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) - -class CloseMatch(Token): - """A variation on :class:`Literal` which matches "close" matches, - that is, strings with at most 'n' mismatching characters. - :class:`CloseMatch` takes parameters: - - - ``match_string`` - string to be matched - - ``maxMismatches`` - (``default=1``) maximum number of - mismatches allowed to count as a match - - The results from a successful parse will contain the matched text - from the input string and the following named results: - - - ``mismatches`` - a list of the positions within the - match_string where mismatches were found - - ``original`` - the original match_string used to compare - against the input string - - If ``mismatches`` is an empty list, then the match was an exact - match. - - Example:: - - patt = CloseMatch("ATCATCGAATGGA") - patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) - patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) - - # exact match - patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) - - # close match allowing up to 2 mismatches - patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) - patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) - """ - def __init__(self, match_string, maxMismatches=1): - super(CloseMatch,self).__init__() - self.name = match_string - self.match_string = match_string - self.maxMismatches = maxMismatches - self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) - self.mayIndexError = False - self.mayReturnEmpty = False - - def parseImpl( self, instring, loc, doActions=True ): - start = loc - instrlen = len(instring) - maxloc = start + len(self.match_string) - - if maxloc <= instrlen: - match_string = self.match_string - match_stringloc = 0 - mismatches = [] - maxMismatches = self.maxMismatches - - for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): - src,mat = s_m - if src != mat: - mismatches.append(match_stringloc) - if len(mismatches) > maxMismatches: - break - else: - loc = match_stringloc + 1 - results = ParseResults([instring[start:loc]]) - results['original'] = self.match_string - results['mismatches'] = mismatches - return loc, results - - raise ParseException(instring, loc, self.errmsg, self) - - -class Word(Token): - """Token for matching words composed of allowed character sets. - Defined with string containing all allowed initial characters, an - optional string containing allowed body characters (if omitted, - defaults to the initial character set), and an optional minimum, - maximum, and/or exact length. The default value for ``min`` is - 1 (a minimum value < 1 is not valid); the default values for - ``max`` and ``exact`` are 0, meaning no maximum or exact - length restriction. An optional ``excludeChars`` parameter can - list characters that might be found in the input ``bodyChars`` - string; useful to define a word of all printables except for one or - two characters, for instance. - - :class:`srange` is useful for defining custom character set strings - for defining ``Word`` expressions, using range notation from - regular expression character sets. - - A common mistake is to use :class:`Word` to match a specific literal - string, as in ``Word("Address")``. Remember that :class:`Word` - uses the string argument to define *sets* of matchable characters. - This expression would match "Add", "AAA", "dAred", or any other word - made up of the characters 'A', 'd', 'r', 'e', and 's'. To match an - exact literal string, use :class:`Literal` or :class:`Keyword`. - - pyparsing includes helper strings for building Words: - - - :class:`alphas` - - :class:`nums` - - :class:`alphanums` - - :class:`hexnums` - - :class:`alphas8bit` (alphabetic characters in ASCII range 128-255 - - accented, tilded, umlauted, etc.) - - :class:`punc8bit` (non-alphabetic characters in ASCII range - 128-255 - currency, symbols, superscripts, diacriticals, etc.) - - :class:`printables` (any non-whitespace character) - - Example:: - - # a word composed of digits - integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) - - # a word with a leading capital, and zero or more lowercase - capital_word = Word(alphas.upper(), alphas.lower()) - - # hostnames are alphanumeric, with leading alpha, and '-' - hostname = Word(alphas, alphanums+'-') - - # roman numeral (not a strict parser, accepts invalid mix of characters) - roman = Word("IVXLCDM") - - # any string of non-whitespace characters, except for ',' - csv_value = Word(printables, excludeChars=",") - """ - def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): - super(Word,self).__init__() - if excludeChars: - initChars = ''.join(c for c in initChars if c not in excludeChars) - if bodyChars: - bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) - self.initCharsOrig = initChars - self.initChars = set(initChars) - if bodyChars : - self.bodyCharsOrig = bodyChars - self.bodyChars = set(bodyChars) - else: - self.bodyCharsOrig = initChars - self.bodyChars = set(initChars) - - self.maxSpecified = max > 0 - - if min < 1: - raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayIndexError = False - self.asKeyword = asKeyword - - if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): - if self.bodyCharsOrig == self.initCharsOrig: - self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) - elif len(self.initCharsOrig) == 1: - self.reString = "%s[%s]*" % \ - (re.escape(self.initCharsOrig), - _escapeRegexRangeChars(self.bodyCharsOrig),) - else: - self.reString = "[%s][%s]*" % \ - (_escapeRegexRangeChars(self.initCharsOrig), - _escapeRegexRangeChars(self.bodyCharsOrig),) - if self.asKeyword: - self.reString = r"\b"+self.reString+r"\b" - try: - self.re = re.compile( self.reString ) - except Exception: - self.re = None - - def parseImpl( self, instring, loc, doActions=True ): - if self.re: - result = self.re.match(instring,loc) - if not result: - raise ParseException(instring, loc, self.errmsg, self) - - loc = result.end() - return loc, result.group() - - if not(instring[ loc ] in self.initChars): - raise ParseException(instring, loc, self.errmsg, self) - - start = loc - loc += 1 - instrlen = len(instring) - bodychars = self.bodyChars - maxloc = start + self.maxLen - maxloc = min( maxloc, instrlen ) - while loc < maxloc and instring[loc] in bodychars: - loc += 1 - - throwException = False - if loc - start < self.minLen: - throwException = True - if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: - throwException = True - if self.asKeyword: - if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): - throwException = True - - if throwException: - raise ParseException(instring, loc, self.errmsg, self) - - return loc, instring[start:loc] - - def __str__( self ): - try: - return super(Word,self).__str__() - except Exception: - pass - - - if self.strRepr is None: - - def charsAsStr(s): - if len(s)>4: - return s[:4]+"..." - else: - return s - - if ( self.initCharsOrig != self.bodyCharsOrig ): - self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) - else: - self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) - - return self.strRepr - - -class Char(Word): - """A short-cut class for defining ``Word(characters, exact=1)``, - when defining a match of any single character in a string of - characters. - """ - def __init__(self, charset): - super(Char, self).__init__(charset, exact=1) - self.reString = "[%s]" % _escapeRegexRangeChars(self.initCharsOrig) - self.re = re.compile( self.reString ) - - -class Regex(Token): - r"""Token for matching strings that match a given regular - expression. Defined with string specifying the regular expression in - a form recognized by the stdlib Python `re module <https://docs.python.org/3/library/re.html>`_. - If the given regex contains named groups (defined using ``(?P<name>...)``), - these will be preserved as named parse results. - - Example:: - - realnum = Regex(r"[+-]?\d+\.\d*") - date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') - # ref: https://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression - roman = Regex(r"M{0,4}(CM|CD|D?{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") - """ - compiledREtype = type(re.compile("[A-Z]")) - def __init__( self, pattern, flags=0, asGroupList=False, asMatch=False): - """The parameters ``pattern`` and ``flags`` are passed - to the ``re.compile()`` function as-is. See the Python - `re module <https://docs.python.org/3/library/re.html>`_ module for an - explanation of the acceptable patterns and flags. - """ - super(Regex,self).__init__() - - if isinstance(pattern, basestring): - if not pattern: - warnings.warn("null string passed to Regex; use Empty() instead", - SyntaxWarning, stacklevel=2) - - self.pattern = pattern - self.flags = flags - - try: - self.re = re.compile(self.pattern, self.flags) - self.reString = self.pattern - except sre_constants.error: - warnings.warn("invalid pattern (%s) passed to Regex" % pattern, - SyntaxWarning, stacklevel=2) - raise - - elif isinstance(pattern, Regex.compiledREtype): - self.re = pattern - self.pattern = \ - self.reString = str(pattern) - self.flags = flags - - else: - raise ValueError("Regex may only be constructed with a string or a compiled RE object") - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayIndexError = False - self.mayReturnEmpty = True - self.asGroupList = asGroupList - self.asMatch = asMatch - - def parseImpl( self, instring, loc, doActions=True ): - result = self.re.match(instring,loc) - if not result: - raise ParseException(instring, loc, self.errmsg, self) - - loc = result.end() - if self.asMatch: - ret = result - elif self.asGroupList: - ret = result.groups() - else: - ret = ParseResults(result.group()) - d = result.groupdict() - if d: - for k, v in d.items(): - ret[k] = v - return loc,ret - - def __str__( self ): - try: - return super(Regex,self).__str__() - except Exception: - pass - - if self.strRepr is None: - self.strRepr = "Re:(%s)" % repr(self.pattern) - - return self.strRepr - - def sub(self, repl): - """ - Return Regex with an attached parse action to transform the parsed - result as if called using `re.sub(expr, repl, string) <https://docs.python.org/3/library/re.html#re.sub>`_. - - Example:: - - make_html = Regex(r"(\w+):(.*?):").sub(r"<\1>\2</\1>") - print(make_html.transformString("h1:main title:")) - # prints "<h1>main title</h1>" - """ - if self.asGroupList: - warnings.warn("cannot use sub() with Regex(asGroupList=True)", - SyntaxWarning, stacklevel=2) - raise SyntaxError() - - if self.asMatch and callable(repl): - warnings.warn("cannot use sub() with a callable with Regex(asMatch=True)", - SyntaxWarning, stacklevel=2) - raise SyntaxError() - - if self.asMatch: - def pa(tokens): - return tokens[0].expand(repl) - else: - def pa(tokens): - return self.re.sub(repl, tokens[0]) - return self.addParseAction(pa) - -class QuotedString(Token): - r""" - Token for matching strings that are delimited by quoting characters. - - Defined with the following parameters: - - - quoteChar - string of one or more characters defining the - quote delimiting string - - escChar - character to escape quotes, typically backslash - (default= ``None`` ) - - escQuote - special quote sequence to escape an embedded quote - string (such as SQL's ``""`` to escape an embedded ``"``) - (default= ``None`` ) - - multiline - boolean indicating whether quotes can span - multiple lines (default= ``False`` ) - - unquoteResults - boolean indicating whether the matched text - should be unquoted (default= ``True`` ) - - endQuoteChar - string of one or more characters defining the - end of the quote delimited string (default= ``None`` => same as - quoteChar) - - convertWhitespaceEscapes - convert escaped whitespace - (``'\t'``, ``'\n'``, etc.) to actual whitespace - (default= ``True`` ) - - Example:: - - qs = QuotedString('"') - print(qs.searchString('lsjdf "This is the quote" sldjf')) - complex_qs = QuotedString('{{', endQuoteChar='}}') - print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) - sql_qs = QuotedString('"', escQuote='""') - print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) - - prints:: - - [['This is the quote']] - [['This is the "quote"']] - [['This is the quote with "embedded" quotes']] - """ - def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): - super(QuotedString,self).__init__() - - # remove white space from quote chars - wont work anyway - quoteChar = quoteChar.strip() - if not quoteChar: - warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) - raise SyntaxError() - - if endQuoteChar is None: - endQuoteChar = quoteChar - else: - endQuoteChar = endQuoteChar.strip() - if not endQuoteChar: - warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) - raise SyntaxError() - - self.quoteChar = quoteChar - self.quoteCharLen = len(quoteChar) - self.firstQuoteChar = quoteChar[0] - self.endQuoteChar = endQuoteChar - self.endQuoteCharLen = len(endQuoteChar) - self.escChar = escChar - self.escQuote = escQuote - self.unquoteResults = unquoteResults - self.convertWhitespaceEscapes = convertWhitespaceEscapes - - if multiline: - self.flags = re.MULTILINE | re.DOTALL - self.pattern = r'%s(?:[^%s%s]' % \ - ( re.escape(self.quoteChar), - _escapeRegexRangeChars(self.endQuoteChar[0]), - (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) - else: - self.flags = 0 - self.pattern = r'%s(?:[^%s\n\r%s]' % \ - ( re.escape(self.quoteChar), - _escapeRegexRangeChars(self.endQuoteChar[0]), - (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) - if len(self.endQuoteChar) > 1: - self.pattern += ( - '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), - _escapeRegexRangeChars(self.endQuoteChar[i])) - for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' - ) - if escQuote: - self.pattern += (r'|(?:%s)' % re.escape(escQuote)) - if escChar: - self.pattern += (r'|(?:%s.)' % re.escape(escChar)) - self.escCharReplacePattern = re.escape(self.escChar)+"(.)" - self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) - - try: - self.re = re.compile(self.pattern, self.flags) - self.reString = self.pattern - except sre_constants.error: - warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, - SyntaxWarning, stacklevel=2) - raise - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayIndexError = False - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None - if not result: - raise ParseException(instring, loc, self.errmsg, self) - - loc = result.end() - ret = result.group() - - if self.unquoteResults: - - # strip off quotes - ret = ret[self.quoteCharLen:-self.endQuoteCharLen] - - if isinstance(ret,basestring): - # replace escaped whitespace - if '\\' in ret and self.convertWhitespaceEscapes: - ws_map = { - r'\t' : '\t', - r'\n' : '\n', - r'\f' : '\f', - r'\r' : '\r', - } - for wslit,wschar in ws_map.items(): - ret = ret.replace(wslit, wschar) - - # replace escaped characters - if self.escChar: - ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) - - # replace escaped quotes - if self.escQuote: - ret = ret.replace(self.escQuote, self.endQuoteChar) - - return loc, ret - - def __str__( self ): - try: - return super(QuotedString,self).__str__() - except Exception: - pass - - if self.strRepr is None: - self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) - - return self.strRepr - - -class CharsNotIn(Token): - """Token for matching words composed of characters *not* in a given - set (will include whitespace in matched characters if not listed in - the provided exclusion set - see example). Defined with string - containing all disallowed characters, and an optional minimum, - maximum, and/or exact length. The default value for ``min`` is - 1 (a minimum value < 1 is not valid); the default values for - ``max`` and ``exact`` are 0, meaning no maximum or exact - length restriction. - - Example:: - - # define a comma-separated-value as anything that is not a ',' - csv_value = CharsNotIn(',') - print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) - - prints:: - - ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] - """ - def __init__( self, notChars, min=1, max=0, exact=0 ): - super(CharsNotIn,self).__init__() - self.skipWhitespace = False - self.notChars = notChars - - if min < 1: - raise ValueError( - "cannot specify a minimum length < 1; use " + - "Optional(CharsNotIn()) if zero-length char group is permitted") - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = ( self.minLen == 0 ) - self.mayIndexError = False - - def parseImpl( self, instring, loc, doActions=True ): - if instring[loc] in self.notChars: - raise ParseException(instring, loc, self.errmsg, self) - - start = loc - loc += 1 - notchars = self.notChars - maxlen = min( start+self.maxLen, len(instring) ) - while loc < maxlen and \ - (instring[loc] not in notchars): - loc += 1 - - if loc - start < self.minLen: - raise ParseException(instring, loc, self.errmsg, self) - - return loc, instring[start:loc] - - def __str__( self ): - try: - return super(CharsNotIn, self).__str__() - except Exception: - pass - - if self.strRepr is None: - if len(self.notChars) > 4: - self.strRepr = "!W:(%s...)" % self.notChars[:4] - else: - self.strRepr = "!W:(%s)" % self.notChars - - return self.strRepr - -class White(Token): - """Special matching class for matching whitespace. Normally, - whitespace is ignored by pyparsing grammars. This class is included - when some whitespace structures are significant. Define with - a string containing the whitespace characters to be matched; default - is ``" \\t\\r\\n"``. Also takes optional ``min``, - ``max``, and ``exact`` arguments, as defined for the - :class:`Word` class. - """ - whiteStrs = { - ' ' : '<SP>', - '\t': '<TAB>', - '\n': '<LF>', - '\r': '<CR>', - '\f': '<FF>', - 'u\00A0': '<NBSP>', - 'u\1680': '<OGHAM_SPACE_MARK>', - 'u\180E': '<MONGOLIAN_VOWEL_SEPARATOR>', - 'u\2000': '<EN_QUAD>', - 'u\2001': '<EM_QUAD>', - 'u\2002': '<EN_SPACE>', - 'u\2003': '<EM_SPACE>', - 'u\2004': '<THREE-PER-EM_SPACE>', - 'u\2005': '<FOUR-PER-EM_SPACE>', - 'u\2006': '<SIX-PER-EM_SPACE>', - 'u\2007': '<FIGURE_SPACE>', - 'u\2008': '<PUNCTUATION_SPACE>', - 'u\2009': '<THIN_SPACE>', - 'u\200A': '<HAIR_SPACE>', - 'u\200B': '<ZERO_WIDTH_SPACE>', - 'u\202F': '<NNBSP>', - 'u\205F': '<MMSP>', - 'u\3000': '<IDEOGRAPHIC_SPACE>', - } - def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): - super(White,self).__init__() - self.matchWhite = ws - self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) - #~ self.leaveWhitespace() - self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) - self.mayReturnEmpty = True - self.errmsg = "Expected " + self.name - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - def parseImpl( self, instring, loc, doActions=True ): - if not(instring[ loc ] in self.matchWhite): - raise ParseException(instring, loc, self.errmsg, self) - start = loc - loc += 1 - maxloc = start + self.maxLen - maxloc = min( maxloc, len(instring) ) - while loc < maxloc and instring[loc] in self.matchWhite: - loc += 1 - - if loc - start < self.minLen: - raise ParseException(instring, loc, self.errmsg, self) - - return loc, instring[start:loc] - - -class _PositionToken(Token): - def __init__( self ): - super(_PositionToken,self).__init__() - self.name=self.__class__.__name__ - self.mayReturnEmpty = True - self.mayIndexError = False - -class GoToColumn(_PositionToken): - """Token to advance to a specific column of input text; useful for - tabular report scraping. - """ - def __init__( self, colno ): - super(GoToColumn,self).__init__() - self.col = colno - - def preParse( self, instring, loc ): - if col(loc,instring) != self.col: - instrlen = len(instring) - if self.ignoreExprs: - loc = self._skipIgnorables( instring, loc ) - while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : - loc += 1 - return loc - - def parseImpl( self, instring, loc, doActions=True ): - thiscol = col( loc, instring ) - if thiscol > self.col: - raise ParseException( instring, loc, "Text not in expected column", self ) - newloc = loc + self.col - thiscol - ret = instring[ loc: newloc ] - return newloc, ret - - -class LineStart(_PositionToken): - """Matches if current position is at the beginning of a line within - the parse string - - Example:: - - test = '''\ - AAA this line - AAA and this line - AAA but not this one - B AAA and definitely not this one - ''' - - for t in (LineStart() + 'AAA' + restOfLine).searchString(test): - print(t) - - prints:: - - ['AAA', ' this line'] - ['AAA', ' and this line'] - - """ - def __init__( self ): - super(LineStart,self).__init__() - self.errmsg = "Expected start of line" - - def parseImpl( self, instring, loc, doActions=True ): - if col(loc, instring) == 1: - return loc, [] - raise ParseException(instring, loc, self.errmsg, self) - -class LineEnd(_PositionToken): - """Matches if current position is at the end of a line within the - parse string - """ - def __init__( self ): - super(LineEnd,self).__init__() - self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) - self.errmsg = "Expected end of line" - - def parseImpl( self, instring, loc, doActions=True ): - if loc<len(instring): - if instring[loc] == "\n": - return loc+1, "\n" - else: - raise ParseException(instring, loc, self.errmsg, self) - elif loc == len(instring): - return loc+1, [] - else: - raise ParseException(instring, loc, self.errmsg, self) - -class StringStart(_PositionToken): - """Matches if current position is at the beginning of the parse - string - """ - def __init__( self ): - super(StringStart,self).__init__() - self.errmsg = "Expected start of text" - - def parseImpl( self, instring, loc, doActions=True ): - if loc != 0: - # see if entire string up to here is just whitespace and ignoreables - if loc != self.preParse( instring, 0 ): - raise ParseException(instring, loc, self.errmsg, self) - return loc, [] - -class StringEnd(_PositionToken): - """Matches if current position is at the end of the parse string - """ - def __init__( self ): - super(StringEnd,self).__init__() - self.errmsg = "Expected end of text" - - def parseImpl( self, instring, loc, doActions=True ): - if loc < len(instring): - raise ParseException(instring, loc, self.errmsg, self) - elif loc == len(instring): - return loc+1, [] - elif loc > len(instring): - return loc, [] - else: - raise ParseException(instring, loc, self.errmsg, self) - -class WordStart(_PositionToken): - """Matches if the current position is at the beginning of a Word, - and is not preceded by any character in a given set of - ``wordChars`` (default= ``printables``). To emulate the - ``\b`` behavior of regular expressions, use - ``WordStart(alphanums)``. ``WordStart`` will also match at - the beginning of the string being parsed, or at the beginning of - a line. - """ - def __init__(self, wordChars = printables): - super(WordStart,self).__init__() - self.wordChars = set(wordChars) - self.errmsg = "Not at the start of a word" - - def parseImpl(self, instring, loc, doActions=True ): - if loc != 0: - if (instring[loc-1] in self.wordChars or - instring[loc] not in self.wordChars): - raise ParseException(instring, loc, self.errmsg, self) - return loc, [] - -class WordEnd(_PositionToken): - """Matches if the current position is at the end of a Word, and is - not followed by any character in a given set of ``wordChars`` - (default= ``printables``). To emulate the ``\b`` behavior of - regular expressions, use ``WordEnd(alphanums)``. ``WordEnd`` - will also match at the end of the string being parsed, or at the end - of a line. - """ - def __init__(self, wordChars = printables): - super(WordEnd,self).__init__() - self.wordChars = set(wordChars) - self.skipWhitespace = False - self.errmsg = "Not at the end of a word" - - def parseImpl(self, instring, loc, doActions=True ): - instrlen = len(instring) - if instrlen>0 and loc<instrlen: - if (instring[loc] in self.wordChars or - instring[loc-1] not in self.wordChars): - raise ParseException(instring, loc, self.errmsg, self) - return loc, [] - - -class ParseExpression(ParserElement): - """Abstract subclass of ParserElement, for combining and - post-processing parsed tokens. - """ - def __init__( self, exprs, savelist = False ): - super(ParseExpression,self).__init__(savelist) - if isinstance( exprs, _generatorType ): - exprs = list(exprs) - - if isinstance( exprs, basestring ): - self.exprs = [ ParserElement._literalStringClass( exprs ) ] - elif isinstance( exprs, Iterable ): - exprs = list(exprs) - # if sequence of strings provided, wrap with Literal - if all(isinstance(expr, basestring) for expr in exprs): - exprs = map(ParserElement._literalStringClass, exprs) - self.exprs = list(exprs) - else: - try: - self.exprs = list( exprs ) - except TypeError: - self.exprs = [ exprs ] - self.callPreparse = False - - def __getitem__( self, i ): - return self.exprs[i] - - def append( self, other ): - self.exprs.append( other ) - self.strRepr = None - return self - - def leaveWhitespace( self ): - """Extends ``leaveWhitespace`` defined in base class, and also invokes ``leaveWhitespace`` on - all contained expressions.""" - self.skipWhitespace = False - self.exprs = [ e.copy() for e in self.exprs ] - for e in self.exprs: - e.leaveWhitespace() - return self - - def ignore( self, other ): - if isinstance( other, Suppress ): - if other not in self.ignoreExprs: - super( ParseExpression, self).ignore( other ) - for e in self.exprs: - e.ignore( self.ignoreExprs[-1] ) - else: - super( ParseExpression, self).ignore( other ) - for e in self.exprs: - e.ignore( self.ignoreExprs[-1] ) - return self - - def __str__( self ): - try: - return super(ParseExpression,self).__str__() - except Exception: - pass - - if self.strRepr is None: - self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) - return self.strRepr - - def streamline( self ): - super(ParseExpression,self).streamline() - - for e in self.exprs: - e.streamline() - - # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) - # but only if there are no parse actions or resultsNames on the nested And's - # (likewise for Or's and MatchFirst's) - if ( len(self.exprs) == 2 ): - other = self.exprs[0] - if ( isinstance( other, self.__class__ ) and - not(other.parseAction) and - other.resultsName is None and - not other.debug ): - self.exprs = other.exprs[:] + [ self.exprs[1] ] - self.strRepr = None - self.mayReturnEmpty |= other.mayReturnEmpty - self.mayIndexError |= other.mayIndexError - - other = self.exprs[-1] - if ( isinstance( other, self.__class__ ) and - not(other.parseAction) and - other.resultsName is None and - not other.debug ): - self.exprs = self.exprs[:-1] + other.exprs[:] - self.strRepr = None - self.mayReturnEmpty |= other.mayReturnEmpty - self.mayIndexError |= other.mayIndexError - - self.errmsg = "Expected " + _ustr(self) - - return self - - def setResultsName( self, name, listAllMatches=False ): - ret = super(ParseExpression,self).setResultsName(name,listAllMatches) - return ret - - def validate( self, validateTrace=[] ): - tmp = validateTrace[:]+[self] - for e in self.exprs: - e.validate(tmp) - self.checkRecursion( [] ) - - def copy(self): - ret = super(ParseExpression,self).copy() - ret.exprs = [e.copy() for e in self.exprs] - return ret - -class And(ParseExpression): - """ - Requires all given :class:`ParseExpression` s to be found in the given order. - Expressions may be separated by whitespace. - May be constructed using the ``'+'`` operator. - May also be constructed using the ``'-'`` operator, which will - suppress backtracking. - - Example:: - - integer = Word(nums) - name_expr = OneOrMore(Word(alphas)) - - expr = And([integer("id"),name_expr("name"),integer("age")]) - # more easily written as: - expr = integer("id") + name_expr("name") + integer("age") - """ - - class _ErrorStop(Empty): - def __init__(self, *args, **kwargs): - super(And._ErrorStop,self).__init__(*args, **kwargs) - self.name = '-' - self.leaveWhitespace() - - def __init__( self, exprs, savelist = True ): - super(And,self).__init__(exprs, savelist) - self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) - self.setWhitespaceChars( self.exprs[0].whiteChars ) - self.skipWhitespace = self.exprs[0].skipWhitespace - self.callPreparse = True - - def streamline(self): - super(And, self).streamline() - self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) - return self - - def parseImpl( self, instring, loc, doActions=True ): - # pass False as last arg to _parse for first element, since we already - # pre-parsed the string as part of our And pre-parsing - loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) - errorStop = False - for e in self.exprs[1:]: - if isinstance(e, And._ErrorStop): - errorStop = True - continue - if errorStop: - try: - loc, exprtokens = e._parse( instring, loc, doActions ) - except ParseSyntaxException: - raise - except ParseBaseException as pe: - pe.__traceback__ = None - raise ParseSyntaxException._from_exception(pe) - except IndexError: - raise ParseSyntaxException(instring, len(instring), self.errmsg, self) - else: - loc, exprtokens = e._parse( instring, loc, doActions ) - if exprtokens or exprtokens.haskeys(): - resultlist += exprtokens - return loc, resultlist - - def __iadd__(self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - return self.append( other ) #And( [ self, other ] ) - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - if not e.mayReturnEmpty: - break - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" - - return self.strRepr - - -class Or(ParseExpression): - """Requires that at least one :class:`ParseExpression` is found. If - two expressions match, the expression that matches the longest - string will be used. May be constructed using the ``'^'`` - operator. - - Example:: - - # construct Or using '^' operator - - number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) - print(number.searchString("123 3.1416 789")) - - prints:: - - [['123'], ['3.1416'], ['789']] - """ - def __init__( self, exprs, savelist = False ): - super(Or,self).__init__(exprs, savelist) - if self.exprs: - self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) - else: - self.mayReturnEmpty = True - - def streamline(self): - super(Or, self).streamline() - self.saveAsList = any(e.saveAsList for e in self.exprs) - return self - - def parseImpl( self, instring, loc, doActions=True ): - maxExcLoc = -1 - maxException = None - matches = [] - for e in self.exprs: - try: - loc2 = e.tryParse( instring, loc ) - except ParseException as err: - err.__traceback__ = None - if err.loc > maxExcLoc: - maxException = err - maxExcLoc = err.loc - except IndexError: - if len(instring) > maxExcLoc: - maxException = ParseException(instring,len(instring),e.errmsg,self) - maxExcLoc = len(instring) - else: - # save match among all matches, to retry longest to shortest - matches.append((loc2, e)) - - if matches: - matches.sort(key=lambda x: -x[0]) - for _,e in matches: - try: - return e._parse( instring, loc, doActions ) - except ParseException as err: - err.__traceback__ = None - if err.loc > maxExcLoc: - maxException = err - maxExcLoc = err.loc - - if maxException is not None: - maxException.msg = self.errmsg - raise maxException - else: - raise ParseException(instring, loc, "no defined alternatives to match", self) - - - def __ixor__(self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - return self.append( other ) #Or( [ self, other ] ) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class MatchFirst(ParseExpression): - """Requires that at least one :class:`ParseExpression` is found. If - two expressions match, the first one listed is the one that will - match. May be constructed using the ``'|'`` operator. - - Example:: - - # construct MatchFirst using '|' operator - - # watch the order of expressions to match - number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) - print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] - - # put more selective expression first - number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) - print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] - """ - def __init__( self, exprs, savelist = False ): - super(MatchFirst,self).__init__(exprs, savelist) - if self.exprs: - self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) - # self.saveAsList = any(e.saveAsList for e in self.exprs) - else: - self.mayReturnEmpty = True - - def streamline(self): - super(MatchFirst, self).streamline() - self.saveAsList = any(e.saveAsList for e in self.exprs) - return self - - def parseImpl( self, instring, loc, doActions=True ): - maxExcLoc = -1 - maxException = None - for e in self.exprs: - try: - ret = e._parse( instring, loc, doActions ) - return ret - except ParseException as err: - if err.loc > maxExcLoc: - maxException = err - maxExcLoc = err.loc - except IndexError: - if len(instring) > maxExcLoc: - maxException = ParseException(instring,len(instring),e.errmsg,self) - maxExcLoc = len(instring) - - # only got here if no expression matched, raise exception for match that made it the furthest - else: - if maxException is not None: - maxException.msg = self.errmsg - raise maxException - else: - raise ParseException(instring, loc, "no defined alternatives to match", self) - - def __ior__(self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - return self.append( other ) #MatchFirst( [ self, other ] ) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class Each(ParseExpression): - """Requires all given :class:`ParseExpression` s to be found, but in - any order. Expressions may be separated by whitespace. - - May be constructed using the ``'&'`` operator. - - Example:: - - color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") - shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") - integer = Word(nums) - shape_attr = "shape:" + shape_type("shape") - posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") - color_attr = "color:" + color("color") - size_attr = "size:" + integer("size") - - # use Each (using operator '&') to accept attributes in any order - # (shape and posn are required, color and size are optional) - shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) - - shape_spec.runTests(''' - shape: SQUARE color: BLACK posn: 100, 120 - shape: CIRCLE size: 50 color: BLUE posn: 50,80 - color:GREEN size:20 shape:TRIANGLE posn:20,40 - ''' - ) - - prints:: - - shape: SQUARE color: BLACK posn: 100, 120 - ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] - - color: BLACK - - posn: ['100', ',', '120'] - - x: 100 - - y: 120 - - shape: SQUARE - - - shape: CIRCLE size: 50 color: BLUE posn: 50,80 - ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] - - color: BLUE - - posn: ['50', ',', '80'] - - x: 50 - - y: 80 - - shape: CIRCLE - - size: 50 - - - color: GREEN size: 20 shape: TRIANGLE posn: 20,40 - ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] - - color: GREEN - - posn: ['20', ',', '40'] - - x: 20 - - y: 40 - - shape: TRIANGLE - - size: 20 - """ - def __init__( self, exprs, savelist = True ): - super(Each,self).__init__(exprs, savelist) - self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) - self.skipWhitespace = True - self.initExprGroups = True - self.saveAsList = True - - def streamline(self): - super(Each, self).streamline() - self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) - return self - - def parseImpl( self, instring, loc, doActions=True ): - if self.initExprGroups: - self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) - opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] - opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] - self.optionals = opt1 + opt2 - self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] - self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] - self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] - self.required += self.multirequired - self.initExprGroups = False - tmpLoc = loc - tmpReqd = self.required[:] - tmpOpt = self.optionals[:] - matchOrder = [] - - keepMatching = True - while keepMatching: - tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired - failed = [] - for e in tmpExprs: - try: - tmpLoc = e.tryParse( instring, tmpLoc ) - except ParseException: - failed.append(e) - else: - matchOrder.append(self.opt1map.get(id(e),e)) - if e in tmpReqd: - tmpReqd.remove(e) - elif e in tmpOpt: - tmpOpt.remove(e) - if len(failed) == len(tmpExprs): - keepMatching = False - - if tmpReqd: - missing = ", ".join(_ustr(e) for e in tmpReqd) - raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) - - # add any unmatched Optionals, in case they have default values defined - matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] - - resultlist = [] - for e in matchOrder: - loc,results = e._parse(instring,loc,doActions) - resultlist.append(results) - - finalResults = sum(resultlist, ParseResults([])) - return loc, finalResults - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class ParseElementEnhance(ParserElement): - """Abstract subclass of :class:`ParserElement`, for combining and - post-processing parsed tokens. - """ - def __init__( self, expr, savelist=False ): - super(ParseElementEnhance,self).__init__(savelist) - if isinstance( expr, basestring ): - if issubclass(ParserElement._literalStringClass, Token): - expr = ParserElement._literalStringClass(expr) - else: - expr = ParserElement._literalStringClass(Literal(expr)) - self.expr = expr - self.strRepr = None - if expr is not None: - self.mayIndexError = expr.mayIndexError - self.mayReturnEmpty = expr.mayReturnEmpty - self.setWhitespaceChars( expr.whiteChars ) - self.skipWhitespace = expr.skipWhitespace - self.saveAsList = expr.saveAsList - self.callPreparse = expr.callPreparse - self.ignoreExprs.extend(expr.ignoreExprs) - - def parseImpl( self, instring, loc, doActions=True ): - if self.expr is not None: - return self.expr._parse( instring, loc, doActions, callPreParse=False ) - else: - raise ParseException("",loc,self.errmsg,self) - - def leaveWhitespace( self ): - self.skipWhitespace = False - self.expr = self.expr.copy() - if self.expr is not None: - self.expr.leaveWhitespace() - return self - - def ignore( self, other ): - if isinstance( other, Suppress ): - if other not in self.ignoreExprs: - super( ParseElementEnhance, self).ignore( other ) - if self.expr is not None: - self.expr.ignore( self.ignoreExprs[-1] ) - else: - super( ParseElementEnhance, self).ignore( other ) - if self.expr is not None: - self.expr.ignore( self.ignoreExprs[-1] ) - return self - - def streamline( self ): - super(ParseElementEnhance,self).streamline() - if self.expr is not None: - self.expr.streamline() - return self - - def checkRecursion( self, parseElementList ): - if self in parseElementList: - raise RecursiveGrammarException( parseElementList+[self] ) - subRecCheckList = parseElementList[:] + [ self ] - if self.expr is not None: - self.expr.checkRecursion( subRecCheckList ) - - def validate( self, validateTrace=[] ): - tmp = validateTrace[:]+[self] - if self.expr is not None: - self.expr.validate(tmp) - self.checkRecursion( [] ) - - def __str__( self ): - try: - return super(ParseElementEnhance,self).__str__() - except Exception: - pass - - if self.strRepr is None and self.expr is not None: - self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) - return self.strRepr - - -class FollowedBy(ParseElementEnhance): - """Lookahead matching of the given parse expression. - ``FollowedBy`` does *not* advance the parsing position within - the input string, it only verifies that the specified parse - expression matches at the current position. ``FollowedBy`` - always returns a null token list. If any results names are defined - in the lookahead expression, those *will* be returned for access by - name. - - Example:: - - # use FollowedBy to match a label only if it is followed by a ':' - data_word = Word(alphas) - label = data_word + FollowedBy(':') - attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) - - OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() - - prints:: - - [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] - """ - def __init__( self, expr ): - super(FollowedBy,self).__init__(expr) - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - _, ret = self.expr._parse(instring, loc, doActions=doActions) - del ret[:] - return loc, ret - - -class PrecededBy(ParseElementEnhance): - """Lookbehind matching of the given parse expression. - ``PrecededBy`` does not advance the parsing position within the - input string, it only verifies that the specified parse expression - matches prior to the current position. ``PrecededBy`` always - returns a null token list, but if a results name is defined on the - given expression, it is returned. - - Parameters: - - - expr - expression that must match prior to the current parse - location - - retreat - (default= ``None``) - (int) maximum number of characters - to lookbehind prior to the current parse location - - If the lookbehind expression is a string, Literal, Keyword, or - a Word or CharsNotIn with a specified exact or maximum length, then - the retreat parameter is not required. Otherwise, retreat must be - specified to give a maximum number of characters to look back from - the current parse position for a lookbehind match. - - Example:: - - # VB-style variable names with type prefixes - int_var = PrecededBy("#") + pyparsing_common.identifier - str_var = PrecededBy("$") + pyparsing_common.identifier - - """ - def __init__(self, expr, retreat=None): - super(PrecededBy, self).__init__(expr) - self.expr = self.expr().leaveWhitespace() - self.mayReturnEmpty = True - self.mayIndexError = False - self.exact = False - if isinstance(expr, str): - retreat = len(expr) - self.exact = True - elif isinstance(expr, (Literal, Keyword)): - retreat = expr.matchLen - self.exact = True - elif isinstance(expr, (Word, CharsNotIn)) and expr.maxLen != _MAX_INT: - retreat = expr.maxLen - self.exact = True - elif isinstance(expr, _PositionToken): - retreat = 0 - self.exact = True - self.retreat = retreat - self.errmsg = "not preceded by " + str(expr) - self.skipWhitespace = False - - def parseImpl(self, instring, loc=0, doActions=True): - if self.exact: - if loc < self.retreat: - raise ParseException(instring, loc, self.errmsg) - start = loc - self.retreat - _, ret = self.expr._parse(instring, start) - else: - # retreat specified a maximum lookbehind window, iterate - test_expr = self.expr + StringEnd() - instring_slice = instring[:loc] - last_expr = ParseException(instring, loc, self.errmsg) - for offset in range(1, min(loc, self.retreat+1)): - try: - _, ret = test_expr._parse(instring_slice, loc-offset) - except ParseBaseException as pbe: - last_expr = pbe - else: - break - else: - raise last_expr - # return empty list of tokens, but preserve any defined results names - del ret[:] - return loc, ret - - -class NotAny(ParseElementEnhance): - """Lookahead to disallow matching with the given parse expression. - ``NotAny`` does *not* advance the parsing position within the - input string, it only verifies that the specified parse expression - does *not* match at the current position. Also, ``NotAny`` does - *not* skip over leading whitespace. ``NotAny`` always returns - a null token list. May be constructed using the '~' operator. - - Example:: - - AND, OR, NOT = map(CaselessKeyword, "AND OR NOT".split()) - - # take care not to mistake keywords for identifiers - ident = ~(AND | OR | NOT) + Word(alphas) - boolean_term = Optional(NOT) + ident - - # very crude boolean expression - to support parenthesis groups and - # operation hierarchy, use infixNotation - boolean_expr = boolean_term + ZeroOrMore((AND | OR) + boolean_term) - - # integers that are followed by "." are actually floats - integer = Word(nums) + ~Char(".") - """ - def __init__( self, expr ): - super(NotAny,self).__init__(expr) - #~ self.leaveWhitespace() - self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs - self.mayReturnEmpty = True - self.errmsg = "Found unwanted token, "+_ustr(self.expr) - - def parseImpl( self, instring, loc, doActions=True ): - if self.expr.canParseNext(instring, loc): - raise ParseException(instring, loc, self.errmsg, self) - return loc, [] - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "~{" + _ustr(self.expr) + "}" - - return self.strRepr - -class _MultipleMatch(ParseElementEnhance): - def __init__( self, expr, stopOn=None): - super(_MultipleMatch, self).__init__(expr) - self.saveAsList = True - ender = stopOn - if isinstance(ender, basestring): - ender = ParserElement._literalStringClass(ender) - self.not_ender = ~ender if ender is not None else None - - def parseImpl( self, instring, loc, doActions=True ): - self_expr_parse = self.expr._parse - self_skip_ignorables = self._skipIgnorables - check_ender = self.not_ender is not None - if check_ender: - try_not_ender = self.not_ender.tryParse - - # must be at least one (but first see if we are the stopOn sentinel; - # if so, fail) - if check_ender: - try_not_ender(instring, loc) - loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) - try: - hasIgnoreExprs = (not not self.ignoreExprs) - while 1: - if check_ender: - try_not_ender(instring, loc) - if hasIgnoreExprs: - preloc = self_skip_ignorables( instring, loc ) - else: - preloc = loc - loc, tmptokens = self_expr_parse( instring, preloc, doActions ) - if tmptokens or tmptokens.haskeys(): - tokens += tmptokens - except (ParseException,IndexError): - pass - - return loc, tokens - -class OneOrMore(_MultipleMatch): - """Repetition of one or more of the given expression. - - Parameters: - - expr - expression that must match one or more times - - stopOn - (default= ``None``) - expression for a terminating sentinel - (only required if the sentinel would ordinarily match the repetition - expression) - - Example:: - - data_word = Word(alphas) - label = data_word + FollowedBy(':') - attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) - - text = "shape: SQUARE posn: upper left color: BLACK" - OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] - - # use stopOn attribute for OneOrMore to avoid reading label string as part of the data - attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) - OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] - - # could also be written as - (attr_expr * (1,)).parseString(text).pprint() - """ - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + _ustr(self.expr) + "}..." - - return self.strRepr - -class ZeroOrMore(_MultipleMatch): - """Optional repetition of zero or more of the given expression. - - Parameters: - - expr - expression that must match zero or more times - - stopOn - (default= ``None``) - expression for a terminating sentinel - (only required if the sentinel would ordinarily match the repetition - expression) - - Example: similar to :class:`OneOrMore` - """ - def __init__( self, expr, stopOn=None): - super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - try: - return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) - except (ParseException,IndexError): - return loc, [] - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "[" + _ustr(self.expr) + "]..." - - return self.strRepr - -class _NullToken(object): - def __bool__(self): - return False - __nonzero__ = __bool__ - def __str__(self): - return "" - -_optionalNotMatched = _NullToken() -class Optional(ParseElementEnhance): - """Optional matching of the given expression. - - Parameters: - - expr - expression that must match zero or more times - - default (optional) - value to be returned if the optional expression is not found. - - Example:: - - # US postal code can be a 5-digit zip, plus optional 4-digit qualifier - zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) - zip.runTests(''' - # traditional ZIP code - 12345 - - # ZIP+4 form - 12101-0001 - - # invalid ZIP - 98765- - ''') - - prints:: - - # traditional ZIP code - 12345 - ['12345'] - - # ZIP+4 form - 12101-0001 - ['12101-0001'] - - # invalid ZIP - 98765- - ^ - FAIL: Expected end of text (at char 5), (line:1, col:6) - """ - def __init__( self, expr, default=_optionalNotMatched ): - super(Optional,self).__init__( expr, savelist=False ) - self.saveAsList = self.expr.saveAsList - self.defaultValue = default - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - try: - loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) - except (ParseException,IndexError): - if self.defaultValue is not _optionalNotMatched: - if self.expr.resultsName: - tokens = ParseResults([ self.defaultValue ]) - tokens[self.expr.resultsName] = self.defaultValue - else: - tokens = [ self.defaultValue ] - else: - tokens = [] - return loc, tokens - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "[" + _ustr(self.expr) + "]" - - return self.strRepr - -class SkipTo(ParseElementEnhance): - """Token for skipping over all undefined text until the matched - expression is found. - - Parameters: - - expr - target expression marking the end of the data to be skipped - - include - (default= ``False``) if True, the target expression is also parsed - (the skipped text and target expression are returned as a 2-element list). - - ignore - (default= ``None``) used to define grammars (typically quoted strings and - comments) that might contain false matches to the target expression - - failOn - (default= ``None``) define expressions that are not allowed to be - included in the skipped test; if found before the target expression is found, - the SkipTo is not a match - - Example:: - - report = ''' - Outstanding Issues Report - 1 Jan 2000 - - # | Severity | Description | Days Open - -----+----------+-------------------------------------------+----------- - 101 | Critical | Intermittent system crash | 6 - 94 | Cosmetic | Spelling error on Login ('log|n') | 14 - 79 | Minor | System slow when running too many reports | 47 - ''' - integer = Word(nums) - SEP = Suppress('|') - # use SkipTo to simply match everything up until the next SEP - # - ignore quoted strings, so that a '|' character inside a quoted string does not match - # - parse action will call token.strip() for each matched token, i.e., the description body - string_data = SkipTo(SEP, ignore=quotedString) - string_data.setParseAction(tokenMap(str.strip)) - ticket_expr = (integer("issue_num") + SEP - + string_data("sev") + SEP - + string_data("desc") + SEP - + integer("days_open")) - - for tkt in ticket_expr.searchString(report): - print tkt.dump() - - prints:: - - ['101', 'Critical', 'Intermittent system crash', '6'] - - days_open: 6 - - desc: Intermittent system crash - - issue_num: 101 - - sev: Critical - ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] - - days_open: 14 - - desc: Spelling error on Login ('log|n') - - issue_num: 94 - - sev: Cosmetic - ['79', 'Minor', 'System slow when running too many reports', '47'] - - days_open: 47 - - desc: System slow when running too many reports - - issue_num: 79 - - sev: Minor - """ - def __init__( self, other, include=False, ignore=None, failOn=None ): - super( SkipTo, self ).__init__( other ) - self.ignoreExpr = ignore - self.mayReturnEmpty = True - self.mayIndexError = False - self.includeMatch = include - self.saveAsList = False - if isinstance(failOn, basestring): - self.failOn = ParserElement._literalStringClass(failOn) - else: - self.failOn = failOn - self.errmsg = "No match found for "+_ustr(self.expr) - - def parseImpl( self, instring, loc, doActions=True ): - startloc = loc - instrlen = len(instring) - expr = self.expr - expr_parse = self.expr._parse - self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None - self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None - - tmploc = loc - while tmploc <= instrlen: - if self_failOn_canParseNext is not None: - # break if failOn expression matches - if self_failOn_canParseNext(instring, tmploc): - break - - if self_ignoreExpr_tryParse is not None: - # advance past ignore expressions - while 1: - try: - tmploc = self_ignoreExpr_tryParse(instring, tmploc) - except ParseBaseException: - break - - try: - expr_parse(instring, tmploc, doActions=False, callPreParse=False) - except (ParseException, IndexError): - # no match, advance loc in string - tmploc += 1 - else: - # matched skipto expr, done - break - - else: - # ran off the end of the input string without matching skipto expr, fail - raise ParseException(instring, loc, self.errmsg, self) - - # build up return values - loc = tmploc - skiptext = instring[startloc:loc] - skipresult = ParseResults(skiptext) - - if self.includeMatch: - loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) - skipresult += mat - - return loc, skipresult - -class Forward(ParseElementEnhance): - """Forward declaration of an expression to be defined later - - used for recursive grammars, such as algebraic infix notation. - When the expression is known, it is assigned to the ``Forward`` - variable using the '<<' operator. - - Note: take care when assigning to ``Forward`` not to overlook - precedence of operators. - - Specifically, '|' has a lower precedence than '<<', so that:: - - fwdExpr << a | b | c - - will actually be evaluated as:: - - (fwdExpr << a) | b | c - - thereby leaving b and c out as parseable alternatives. It is recommended that you - explicitly group the values inserted into the ``Forward``:: - - fwdExpr << (a | b | c) - - Converting to use the '<<=' operator instead will avoid this problem. - - See :class:`ParseResults.pprint` for an example of a recursive - parser created using ``Forward``. - """ - def __init__( self, other=None ): - super(Forward,self).__init__( other, savelist=False ) - - def __lshift__( self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass(other) - self.expr = other - self.strRepr = None - self.mayIndexError = self.expr.mayIndexError - self.mayReturnEmpty = self.expr.mayReturnEmpty - self.setWhitespaceChars( self.expr.whiteChars ) - self.skipWhitespace = self.expr.skipWhitespace - self.saveAsList = self.expr.saveAsList - self.ignoreExprs.extend(self.expr.ignoreExprs) - return self - - def __ilshift__(self, other): - return self << other - - def leaveWhitespace( self ): - self.skipWhitespace = False - return self - - def streamline( self ): - if not self.streamlined: - self.streamlined = True - if self.expr is not None: - self.expr.streamline() - return self - - def validate( self, validateTrace=[] ): - if self not in validateTrace: - tmp = validateTrace[:]+[self] - if self.expr is not None: - self.expr.validate(tmp) - self.checkRecursion([]) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - return self.__class__.__name__ + ": ..." - - # stubbed out for now - creates awful memory and perf issues - self._revertClass = self.__class__ - self.__class__ = _ForwardNoRecurse - try: - if self.expr is not None: - retString = _ustr(self.expr) - else: - retString = "None" - finally: - self.__class__ = self._revertClass - return self.__class__.__name__ + ": " + retString - - def copy(self): - if self.expr is not None: - return super(Forward,self).copy() - else: - ret = Forward() - ret <<= self - return ret - -class _ForwardNoRecurse(Forward): - def __str__( self ): - return "..." - -class TokenConverter(ParseElementEnhance): - """ - Abstract subclass of :class:`ParseExpression`, for converting parsed results. - """ - def __init__( self, expr, savelist=False ): - super(TokenConverter,self).__init__( expr )#, savelist ) - self.saveAsList = False - -class Combine(TokenConverter): - """Converter to concatenate all matching tokens to a single string. - By default, the matching patterns must also be contiguous in the - input string; this can be disabled by specifying - ``'adjacent=False'`` in the constructor. - - Example:: - - real = Word(nums) + '.' + Word(nums) - print(real.parseString('3.1416')) # -> ['3', '.', '1416'] - # will also erroneously match the following - print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] - - real = Combine(Word(nums) + '.' + Word(nums)) - print(real.parseString('3.1416')) # -> ['3.1416'] - # no match when there are internal spaces - print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) - """ - def __init__( self, expr, joinString="", adjacent=True ): - super(Combine,self).__init__( expr ) - # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself - if adjacent: - self.leaveWhitespace() - self.adjacent = adjacent - self.skipWhitespace = True - self.joinString = joinString - self.callPreparse = True - - def ignore( self, other ): - if self.adjacent: - ParserElement.ignore(self, other) - else: - super( Combine, self).ignore( other ) - return self - - def postParse( self, instring, loc, tokenlist ): - retToks = tokenlist.copy() - del retToks[:] - retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) - - if self.resultsName and retToks.haskeys(): - return [ retToks ] - else: - return retToks - -class Group(TokenConverter): - """Converter to return the matched tokens as a list - useful for - returning tokens of :class:`ZeroOrMore` and :class:`OneOrMore` expressions. - - Example:: - - ident = Word(alphas) - num = Word(nums) - term = ident | num - func = ident + Optional(delimitedList(term)) - print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] - - func = ident + Group(Optional(delimitedList(term))) - print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] - """ - def __init__( self, expr ): - super(Group,self).__init__( expr ) - self.saveAsList = expr.saveAsList - - def postParse( self, instring, loc, tokenlist ): - return [ tokenlist ] - -class Dict(TokenConverter): - """Converter to return a repetitive expression as a list, but also - as a dictionary. Each element can also be referenced using the first - token in the expression as its key. Useful for tabular report - scraping when the first column can be used as a item key. - - Example:: - - data_word = Word(alphas) - label = data_word + FollowedBy(':') - attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) - - text = "shape: SQUARE posn: upper left color: light blue texture: burlap" - attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) - - # print attributes as plain groups - print(OneOrMore(attr_expr).parseString(text).dump()) - - # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names - result = Dict(OneOrMore(Group(attr_expr))).parseString(text) - print(result.dump()) - - # access named fields as dict entries, or output as dict - print(result['shape']) - print(result.asDict()) - - prints:: - - ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] - [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] - - color: light blue - - posn: upper left - - shape: SQUARE - - texture: burlap - SQUARE - {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} - - See more examples at :class:`ParseResults` of accessing fields by results name. - """ - def __init__( self, expr ): - super(Dict,self).__init__( expr ) - self.saveAsList = True - - def postParse( self, instring, loc, tokenlist ): - for i,tok in enumerate(tokenlist): - if len(tok) == 0: - continue - ikey = tok[0] - if isinstance(ikey,int): - ikey = _ustr(tok[0]).strip() - if len(tok)==1: - tokenlist[ikey] = _ParseResultsWithOffset("",i) - elif len(tok)==2 and not isinstance(tok[1],ParseResults): - tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) - else: - dictvalue = tok.copy() #ParseResults(i) - del dictvalue[0] - if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): - tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) - else: - tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) - - if self.resultsName: - return [ tokenlist ] - else: - return tokenlist - - -class Suppress(TokenConverter): - """Converter for ignoring the results of a parsed expression. - - Example:: - - source = "a, b, c,d" - wd = Word(alphas) - wd_list1 = wd + ZeroOrMore(',' + wd) - print(wd_list1.parseString(source)) - - # often, delimiters that are useful during parsing are just in the - # way afterward - use Suppress to keep them out of the parsed output - wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) - print(wd_list2.parseString(source)) - - prints:: - - ['a', ',', 'b', ',', 'c', ',', 'd'] - ['a', 'b', 'c', 'd'] - - (See also :class:`delimitedList`.) - """ - def postParse( self, instring, loc, tokenlist ): - return [] - - def suppress( self ): - return self - - -class OnlyOnce(object): - """Wrapper for parse actions, to ensure they are only called once. - """ - def __init__(self, methodCall): - self.callable = _trim_arity(methodCall) - self.called = False - def __call__(self,s,l,t): - if not self.called: - results = self.callable(s,l,t) - self.called = True - return results - raise ParseException(s,l,"") - def reset(self): - self.called = False - -def traceParseAction(f): - """Decorator for debugging parse actions. - - When the parse action is called, this decorator will print - ``">> entering method-name(line:<current_source_line>, <parse_location>, <matched_tokens>)"``. - When the parse action completes, the decorator will print - ``"<<"`` followed by the returned value, or any exception that the parse action raised. - - Example:: - - wd = Word(alphas) - - @traceParseAction - def remove_duplicate_chars(tokens): - return ''.join(sorted(set(''.join(tokens)))) - - wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) - print(wds.parseString("slkdjs sld sldd sdlf sdljf")) - - prints:: - - >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) - <<leaving remove_duplicate_chars (ret: 'dfjkls') - ['dfjkls'] - """ - f = _trim_arity(f) - def z(*paArgs): - thisFunc = f.__name__ - s,l,t = paArgs[-3:] - if len(paArgs)>3: - thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc - sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) - try: - ret = f(*paArgs) - except Exception as exc: - sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) - raise - sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) - return ret - try: - z.__name__ = f.__name__ - except AttributeError: - pass - return z - -# -# global helpers -# -def delimitedList( expr, delim=",", combine=False ): - """Helper to define a delimited list of expressions - the delimiter - defaults to ','. By default, the list elements and delimiters can - have intervening whitespace, and comments, but this can be - overridden by passing ``combine=True`` in the constructor. If - ``combine`` is set to ``True``, the matching tokens are - returned as a single token string, with the delimiters included; - otherwise, the matching tokens are returned as a list of tokens, - with the delimiters suppressed. - - Example:: - - delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] - delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] - """ - dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." - if combine: - return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) - else: - return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) - -def countedArray( expr, intExpr=None ): - """Helper to define a counted list of expressions. - - This helper defines a pattern of the form:: - - integer expr expr expr... - - where the leading integer tells how many expr expressions follow. - The matched tokens returns the array of expr tokens as a list - the - leading count token is suppressed. - - If ``intExpr`` is specified, it should be a pyparsing expression - that produces an integer value. - - Example:: - - countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] - - # in this parser, the leading integer value is given in binary, - # '10' indicating that 2 values are in the array - binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) - countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] - """ - arrayExpr = Forward() - def countFieldParseAction(s,l,t): - n = t[0] - arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) - return [] - if intExpr is None: - intExpr = Word(nums).setParseAction(lambda t:int(t[0])) - else: - intExpr = intExpr.copy() - intExpr.setName("arrayLen") - intExpr.addParseAction(countFieldParseAction, callDuringTry=True) - return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') - -def _flatten(L): - ret = [] - for i in L: - if isinstance(i,list): - ret.extend(_flatten(i)) - else: - ret.append(i) - return ret - -def matchPreviousLiteral(expr): - """Helper to define an expression that is indirectly defined from - the tokens matched in a previous expression, that is, it looks for - a 'repeat' of a previous expression. For example:: - - first = Word(nums) - second = matchPreviousLiteral(first) - matchExpr = first + ":" + second - - will match ``"1:1"``, but not ``"1:2"``. Because this - matches a previous literal, will also match the leading - ``"1:1"`` in ``"1:10"``. If this is not desired, use - :class:`matchPreviousExpr`. Do *not* use with packrat parsing - enabled. - """ - rep = Forward() - def copyTokenToRepeater(s,l,t): - if t: - if len(t) == 1: - rep << t[0] - else: - # flatten t tokens - tflat = _flatten(t.asList()) - rep << And(Literal(tt) for tt in tflat) - else: - rep << Empty() - expr.addParseAction(copyTokenToRepeater, callDuringTry=True) - rep.setName('(prev) ' + _ustr(expr)) - return rep - -def matchPreviousExpr(expr): - """Helper to define an expression that is indirectly defined from - the tokens matched in a previous expression, that is, it looks for - a 'repeat' of a previous expression. For example:: - - first = Word(nums) - second = matchPreviousExpr(first) - matchExpr = first + ":" + second - - will match ``"1:1"``, but not ``"1:2"``. Because this - matches by expressions, will *not* match the leading ``"1:1"`` - in ``"1:10"``; the expressions are evaluated first, and then - compared, so ``"1"`` is compared with ``"10"``. Do *not* use - with packrat parsing enabled. - """ - rep = Forward() - e2 = expr.copy() - rep <<= e2 - def copyTokenToRepeater(s,l,t): - matchTokens = _flatten(t.asList()) - def mustMatchTheseTokens(s,l,t): - theseTokens = _flatten(t.asList()) - if theseTokens != matchTokens: - raise ParseException("",0,"") - rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) - expr.addParseAction(copyTokenToRepeater, callDuringTry=True) - rep.setName('(prev) ' + _ustr(expr)) - return rep - -def _escapeRegexRangeChars(s): - #~ escape these chars: ^-] - for c in r"\^-]": - s = s.replace(c,_bslash+c) - s = s.replace("\n",r"\n") - s = s.replace("\t",r"\t") - return _ustr(s) - -def oneOf( strs, caseless=False, useRegex=True ): - """Helper to quickly define a set of alternative Literals, and makes - sure to do longest-first testing when there is a conflict, - regardless of the input order, but returns - a :class:`MatchFirst` for best performance. - - Parameters: - - - strs - a string of space-delimited literals, or a collection of - string literals - - caseless - (default= ``False``) - treat all literals as - caseless - - useRegex - (default= ``True``) - as an optimization, will - generate a Regex object; otherwise, will generate - a :class:`MatchFirst` object (if ``caseless=True``, or if - creating a :class:`Regex` raises an exception) - - Example:: - - comp_oper = oneOf("< = > <= >= !=") - var = Word(alphas) - number = Word(nums) - term = var | number - comparison_expr = term + comp_oper + term - print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) - - prints:: - - [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] - """ - if caseless: - isequal = ( lambda a,b: a.upper() == b.upper() ) - masks = ( lambda a,b: b.upper().startswith(a.upper()) ) - parseElementClass = CaselessLiteral - else: - isequal = ( lambda a,b: a == b ) - masks = ( lambda a,b: b.startswith(a) ) - parseElementClass = Literal - - symbols = [] - if isinstance(strs,basestring): - symbols = strs.split() - elif isinstance(strs, Iterable): - symbols = list(strs) - else: - warnings.warn("Invalid argument to oneOf, expected string or iterable", - SyntaxWarning, stacklevel=2) - if not symbols: - return NoMatch() - - i = 0 - while i < len(symbols)-1: - cur = symbols[i] - for j,other in enumerate(symbols[i+1:]): - if ( isequal(other, cur) ): - del symbols[i+j+1] - break - elif ( masks(cur, other) ): - del symbols[i+j+1] - symbols.insert(i,other) - cur = other - break - else: - i += 1 - - if not caseless and useRegex: - #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) - try: - if len(symbols)==len("".join(symbols)): - return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) - else: - return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) - except Exception: - warnings.warn("Exception creating Regex for oneOf, building MatchFirst", - SyntaxWarning, stacklevel=2) - - - # last resort, just use MatchFirst - return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) - -def dictOf( key, value ): - """Helper to easily and clearly define a dictionary by specifying - the respective patterns for the key and value. Takes care of - defining the :class:`Dict`, :class:`ZeroOrMore`, and - :class:`Group` tokens in the proper order. The key pattern - can include delimiting markers or punctuation, as long as they are - suppressed, thereby leaving the significant key text. The value - pattern can include named results, so that the :class:`Dict` results - can include named token fields. - - Example:: - - text = "shape: SQUARE posn: upper left color: light blue texture: burlap" - attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) - print(OneOrMore(attr_expr).parseString(text).dump()) - - attr_label = label - attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) - - # similar to Dict, but simpler call format - result = dictOf(attr_label, attr_value).parseString(text) - print(result.dump()) - print(result['shape']) - print(result.shape) # object attribute access works too - print(result.asDict()) - - prints:: - - [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] - - color: light blue - - posn: upper left - - shape: SQUARE - - texture: burlap - SQUARE - SQUARE - {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} - """ - return Dict(OneOrMore(Group(key + value))) - -def originalTextFor(expr, asString=True): - """Helper to return the original, untokenized text for a given - expression. Useful to restore the parsed fields of an HTML start - tag into the raw tag text itself, or to revert separate tokens with - intervening whitespace back to the original matching input text. By - default, returns astring containing the original parsed text. - - If the optional ``asString`` argument is passed as - ``False``, then the return value is - a :class:`ParseResults` containing any results names that - were originally matched, and a single token containing the original - matched text from the input string. So if the expression passed to - :class:`originalTextFor` contains expressions with defined - results names, you must set ``asString`` to ``False`` if you - want to preserve those results name values. - - Example:: - - src = "this is test <b> bold <i>text</i> </b> normal text " - for tag in ("b","i"): - opener,closer = makeHTMLTags(tag) - patt = originalTextFor(opener + SkipTo(closer) + closer) - print(patt.searchString(src)[0]) - - prints:: - - ['<b> bold <i>text</i> </b>'] - ['<i>text</i>'] - """ - locMarker = Empty().setParseAction(lambda s,loc,t: loc) - endlocMarker = locMarker.copy() - endlocMarker.callPreparse = False - matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") - if asString: - extractText = lambda s,l,t: s[t._original_start:t._original_end] - else: - def extractText(s,l,t): - t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] - matchExpr.setParseAction(extractText) - matchExpr.ignoreExprs = expr.ignoreExprs - return matchExpr - -def ungroup(expr): - """Helper to undo pyparsing's default grouping of And expressions, - even if all but one are non-empty. - """ - return TokenConverter(expr).setParseAction(lambda t:t[0]) - -def locatedExpr(expr): - """Helper to decorate a returned token with its starting and ending - locations in the input string. - - This helper adds the following results names: - - - locn_start = location where matched expression begins - - locn_end = location where matched expression ends - - value = the actual parsed results - - Be careful if the input text contains ``<TAB>`` characters, you - may want to call :class:`ParserElement.parseWithTabs` - - Example:: - - wd = Word(alphas) - for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): - print(match) - - prints:: - - [[0, 'ljsdf', 5]] - [[8, 'lksdjjf', 15]] - [[18, 'lkkjj', 23]] - """ - locator = Empty().setParseAction(lambda s,l,t: l) - return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) - - -# convenience constants for positional expressions -empty = Empty().setName("empty") -lineStart = LineStart().setName("lineStart") -lineEnd = LineEnd().setName("lineEnd") -stringStart = StringStart().setName("stringStart") -stringEnd = StringEnd().setName("stringEnd") - -_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) -_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) -_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) -_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) -_charRange = Group(_singleChar + Suppress("-") + _singleChar) -_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" - -def srange(s): - r"""Helper to easily define string ranges for use in Word - construction. Borrows syntax from regexp '[]' string range - definitions:: - - srange("[0-9]") -> "0123456789" - srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" - srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" - - The input string must be enclosed in []'s, and the returned string - is the expanded character set joined into a single string. The - values enclosed in the []'s may be: - - - a single character - - an escaped character with a leading backslash (such as ``\-`` - or ``\]``) - - an escaped hex character with a leading ``'\x'`` - (``\x21``, which is a ``'!'`` character) (``\0x##`` - is also supported for backwards compatibility) - - an escaped octal character with a leading ``'\0'`` - (``\041``, which is a ``'!'`` character) - - a range of any of the above, separated by a dash (``'a-z'``, - etc.) - - any combination of the above (``'aeiouy'``, - ``'a-zA-Z0-9_$'``, etc.) - """ - _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) - try: - return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) - except Exception: - return "" - -def matchOnlyAtCol(n): - """Helper method for defining parse actions that require matching at - a specific column in the input text. - """ - def verifyCol(strg,locn,toks): - if col(locn,strg) != n: - raise ParseException(strg,locn,"matched token not at column %d" % n) - return verifyCol - -def replaceWith(replStr): - """Helper method for common parse actions that simply return - a literal value. Especially useful when used with - :class:`transformString<ParserElement.transformString>` (). - - Example:: - - num = Word(nums).setParseAction(lambda toks: int(toks[0])) - na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) - term = na | num - - OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] - """ - return lambda s,l,t: [replStr] - -def removeQuotes(s,l,t): - """Helper parse action for removing quotation marks from parsed - quoted strings. - - Example:: - - # by default, quotation marks are included in parsed results - quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] - - # use removeQuotes to strip quotation marks from parsed results - quotedString.setParseAction(removeQuotes) - quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] - """ - return t[0][1:-1] - -def tokenMap(func, *args): - """Helper to define a parse action by mapping a function to all - elements of a ParseResults list. If any additional args are passed, - they are forwarded to the given function as additional arguments - after the token, as in - ``hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))``, - which will convert the parsed data to an integer using base 16. - - Example (compare the last to example in :class:`ParserElement.transformString`:: - - hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) - hex_ints.runTests(''' - 00 11 22 aa FF 0a 0d 1a - ''') - - upperword = Word(alphas).setParseAction(tokenMap(str.upper)) - OneOrMore(upperword).runTests(''' - my kingdom for a horse - ''') - - wd = Word(alphas).setParseAction(tokenMap(str.title)) - OneOrMore(wd).setParseAction(' '.join).runTests(''' - now is the winter of our discontent made glorious summer by this sun of york - ''') - - prints:: - - 00 11 22 aa FF 0a 0d 1a - [0, 17, 34, 170, 255, 10, 13, 26] - - my kingdom for a horse - ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] - - now is the winter of our discontent made glorious summer by this sun of york - ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] - """ - def pa(s,l,t): - return [func(tokn, *args) for tokn in t] - - try: - func_name = getattr(func, '__name__', - getattr(func, '__class__').__name__) - except Exception: - func_name = str(func) - pa.__name__ = func_name - - return pa - -upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) -"""(Deprecated) Helper parse action to convert tokens to upper case. -Deprecated in favor of :class:`pyparsing_common.upcaseTokens`""" - -downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) -"""(Deprecated) Helper parse action to convert tokens to lower case. -Deprecated in favor of :class:`pyparsing_common.downcaseTokens`""" - -def _makeTags(tagStr, xml): - """Internal helper to construct opening and closing tag expressions, given a tag name""" - if isinstance(tagStr,basestring): - resname = tagStr - tagStr = Keyword(tagStr, caseless=not xml) - else: - resname = tagStr.name - - tagAttrName = Word(alphas,alphanums+"_-:") - if (xml): - tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) - openTag = Suppress("<") + tagStr("tag") + \ - Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ - Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") - else: - printablesLessRAbrack = "".join(c for c in printables if c not in ">") - tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) - openTag = Suppress("<") + tagStr("tag") + \ - Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ - Optional( Suppress("=") + tagAttrValue ) ))) + \ - Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") - closeTag = Combine(_L("</") + tagStr + ">") - - openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) - closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) - openTag.tag = resname - closeTag.tag = resname - return openTag, closeTag - -def makeHTMLTags(tagStr): - """Helper to construct opening and closing tag expressions for HTML, - given a tag name. Matches tags in either upper or lower case, - attributes with namespaces and with quoted or unquoted values. - - Example:: - - text = '<td>More info at the <a href="https://github.com/pyparsing/pyparsing/wiki">pyparsing</a> wiki page</td>' - # makeHTMLTags returns pyparsing expressions for the opening and - # closing tags as a 2-tuple - a,a_end = makeHTMLTags("A") - link_expr = a + SkipTo(a_end)("link_text") + a_end - - for link in link_expr.searchString(text): - # attributes in the <A> tag (like "href" shown here) are - # also accessible as named results - print(link.link_text, '->', link.href) - - prints:: - - pyparsing -> https://github.com/pyparsing/pyparsing/wiki - """ - return _makeTags( tagStr, False ) - -def makeXMLTags(tagStr): - """Helper to construct opening and closing tag expressions for XML, - given a tag name. Matches tags only in the given upper/lower case. - - Example: similar to :class:`makeHTMLTags` - """ - return _makeTags( tagStr, True ) - -def withAttribute(*args,**attrDict): - """Helper to create a validating parse action to be used with start - tags created with :class:`makeXMLTags` or - :class:`makeHTMLTags`. Use ``withAttribute`` to qualify - a starting tag with a required attribute value, to avoid false - matches on common tags such as ``<TD>`` or ``<DIV>``. - - Call ``withAttribute`` with a series of attribute names and - values. Specify the list of filter attributes names and values as: - - - keyword arguments, as in ``(align="right")``, or - - as an explicit dict with ``**`` operator, when an attribute - name is also a Python reserved word, as in ``**{"class":"Customer", "align":"right"}`` - - a list of name-value tuples, as in ``(("ns1:class", "Customer"), ("ns2:align","right"))`` - - For attribute names with a namespace prefix, you must use the second - form. Attribute names are matched insensitive to upper/lower case. - - If just testing for ``class`` (with or without a namespace), use - :class:`withClass`. - - To verify that the attribute exists, but without specifying a value, - pass ``withAttribute.ANY_VALUE`` as the value. - - Example:: - - html = ''' - <div> - Some text - <div type="grid">1 4 0 1 0</div> - <div type="graph">1,3 2,3 1,1</div> - <div>this has no type</div> - </div> - - ''' - div,div_end = makeHTMLTags("div") - - # only match div tag having a type attribute with value "grid" - div_grid = div().setParseAction(withAttribute(type="grid")) - grid_expr = div_grid + SkipTo(div | div_end)("body") - for grid_header in grid_expr.searchString(html): - print(grid_header.body) - - # construct a match with any div tag having a type attribute, regardless of the value - div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) - div_expr = div_any_type + SkipTo(div | div_end)("body") - for div_header in div_expr.searchString(html): - print(div_header.body) - - prints:: - - 1 4 0 1 0 - - 1 4 0 1 0 - 1,3 2,3 1,1 - """ - if args: - attrs = args[:] - else: - attrs = attrDict.items() - attrs = [(k,v) for k,v in attrs] - def pa(s,l,tokens): - for attrName,attrValue in attrs: - if attrName not in tokens: - raise ParseException(s,l,"no matching attribute " + attrName) - if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: - raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % - (attrName, tokens[attrName], attrValue)) - return pa -withAttribute.ANY_VALUE = object() - -def withClass(classname, namespace=''): - """Simplified version of :class:`withAttribute` when - matching on a div class - made difficult because ``class`` is - a reserved word in Python. - - Example:: - - html = ''' - <div> - Some text - <div class="grid">1 4 0 1 0</div> - <div class="graph">1,3 2,3 1,1</div> - <div>this <div> has no class</div> - </div> - - ''' - div,div_end = makeHTMLTags("div") - div_grid = div().setParseAction(withClass("grid")) - - grid_expr = div_grid + SkipTo(div | div_end)("body") - for grid_header in grid_expr.searchString(html): - print(grid_header.body) - - div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) - div_expr = div_any_type + SkipTo(div | div_end)("body") - for div_header in div_expr.searchString(html): - print(div_header.body) - - prints:: - - 1 4 0 1 0 - - 1 4 0 1 0 - 1,3 2,3 1,1 - """ - classattr = "%s:class" % namespace if namespace else "class" - return withAttribute(**{classattr : classname}) - -opAssoc = SimpleNamespace() -opAssoc.LEFT = object() -opAssoc.RIGHT = object() - -def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): - """Helper method for constructing grammars of expressions made up of - operators working in a precedence hierarchy. Operators may be unary - or binary, left- or right-associative. Parse actions can also be - attached to operator expressions. The generated parser will also - recognize the use of parentheses to override operator precedences - (see example below). - - Note: if you define a deep operator list, you may see performance - issues when using infixNotation. See - :class:`ParserElement.enablePackrat` for a mechanism to potentially - improve your parser performance. - - Parameters: - - baseExpr - expression representing the most basic element for the - nested - - opList - list of tuples, one for each operator precedence level - in the expression grammar; each tuple is of the form ``(opExpr, - numTerms, rightLeftAssoc, parseAction)``, where: - - - opExpr is the pyparsing expression for the operator; may also - be a string, which will be converted to a Literal; if numTerms - is 3, opExpr is a tuple of two expressions, for the two - operators separating the 3 terms - - numTerms is the number of terms for this operator (must be 1, - 2, or 3) - - rightLeftAssoc is the indicator whether the operator is right - or left associative, using the pyparsing-defined constants - ``opAssoc.RIGHT`` and ``opAssoc.LEFT``. - - parseAction is the parse action to be associated with - expressions matching this operator expression (the parse action - tuple member may be omitted); if the parse action is passed - a tuple or list of functions, this is equivalent to calling - ``setParseAction(*fn)`` - (:class:`ParserElement.setParseAction`) - - lpar - expression for matching left-parentheses - (default= ``Suppress('(')``) - - rpar - expression for matching right-parentheses - (default= ``Suppress(')')``) - - Example:: - - # simple example of four-function arithmetic with ints and - # variable names - integer = pyparsing_common.signed_integer - varname = pyparsing_common.identifier - - arith_expr = infixNotation(integer | varname, - [ - ('-', 1, opAssoc.RIGHT), - (oneOf('* /'), 2, opAssoc.LEFT), - (oneOf('+ -'), 2, opAssoc.LEFT), - ]) - - arith_expr.runTests(''' - 5+3*6 - (5+3)*6 - -2--11 - ''', fullDump=False) - - prints:: - - 5+3*6 - [[5, '+', [3, '*', 6]]] - - (5+3)*6 - [[[5, '+', 3], '*', 6]] - - -2--11 - [[['-', 2], '-', ['-', 11]]] - """ - # captive version of FollowedBy that does not do parse actions or capture results names - class _FB(FollowedBy): - def parseImpl(self, instring, loc, doActions=True): - self.expr.tryParse(instring, loc) - return loc, [] - - ret = Forward() - lastExpr = baseExpr | ( lpar + ret + rpar ) - for i,operDef in enumerate(opList): - opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] - termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr - if arity == 3: - if opExpr is None or len(opExpr) != 2: - raise ValueError( - "if numterms=3, opExpr must be a tuple or list of two expressions") - opExpr1, opExpr2 = opExpr - thisExpr = Forward().setName(termName) - if rightLeftAssoc == opAssoc.LEFT: - if arity == 1: - matchExpr = _FB(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) - elif arity == 2: - if opExpr is not None: - matchExpr = _FB(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) - else: - matchExpr = _FB(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) - elif arity == 3: - matchExpr = _FB(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ - Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) - else: - raise ValueError("operator must be unary (1), binary (2), or ternary (3)") - elif rightLeftAssoc == opAssoc.RIGHT: - if arity == 1: - # try to avoid LR with this extra test - if not isinstance(opExpr, Optional): - opExpr = Optional(opExpr) - matchExpr = _FB(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) - elif arity == 2: - if opExpr is not None: - matchExpr = _FB(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) - else: - matchExpr = _FB(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) - elif arity == 3: - matchExpr = _FB(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ - Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) - else: - raise ValueError("operator must be unary (1), binary (2), or ternary (3)") - else: - raise ValueError("operator must indicate right or left associativity") - if pa: - if isinstance(pa, (tuple, list)): - matchExpr.setParseAction(*pa) - else: - matchExpr.setParseAction(pa) - thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) - lastExpr = thisExpr - ret <<= lastExpr - return ret - -operatorPrecedence = infixNotation -"""(Deprecated) Former name of :class:`infixNotation`, will be -dropped in a future release.""" - -dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") -sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") -quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| - Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") -unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") - -def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): - """Helper method for defining nested lists enclosed in opening and - closing delimiters ("(" and ")" are the default). - - Parameters: - - opener - opening character for a nested list - (default= ``"("``); can also be a pyparsing expression - - closer - closing character for a nested list - (default= ``")"``); can also be a pyparsing expression - - content - expression for items within the nested lists - (default= ``None``) - - ignoreExpr - expression for ignoring opening and closing - delimiters (default= :class:`quotedString`) - - If an expression is not provided for the content argument, the - nested expression will capture all whitespace-delimited content - between delimiters as a list of separate values. - - Use the ``ignoreExpr`` argument to define expressions that may - contain opening or closing characters that should not be treated as - opening or closing characters for nesting, such as quotedString or - a comment expression. Specify multiple expressions using an - :class:`Or` or :class:`MatchFirst`. The default is - :class:`quotedString`, but if no expressions are to be ignored, then - pass ``None`` for this argument. - - Example:: - - data_type = oneOf("void int short long char float double") - decl_data_type = Combine(data_type + Optional(Word('*'))) - ident = Word(alphas+'_', alphanums+'_') - number = pyparsing_common.number - arg = Group(decl_data_type + ident) - LPAR,RPAR = map(Suppress, "()") - - code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) - - c_function = (decl_data_type("type") - + ident("name") - + LPAR + Optional(delimitedList(arg), [])("args") + RPAR - + code_body("body")) - c_function.ignore(cStyleComment) - - source_code = ''' - int is_odd(int x) { - return (x%2); - } - - int dec_to_hex(char hchar) { - if (hchar >= '0' && hchar <= '9') { - return (ord(hchar)-ord('0')); - } else { - return (10+ord(hchar)-ord('A')); - } - } - ''' - for func in c_function.searchString(source_code): - print("%(name)s (%(type)s) args: %(args)s" % func) - - - prints:: - - is_odd (int) args: [['int', 'x']] - dec_to_hex (int) args: [['char', 'hchar']] - """ - if opener == closer: - raise ValueError("opening and closing strings cannot be the same") - if content is None: - if isinstance(opener,basestring) and isinstance(closer,basestring): - if len(opener) == 1 and len(closer)==1: - if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS - ).setParseAction(lambda t:t[0].strip())) - else: - if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - ~Literal(opener) + ~Literal(closer) + - CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + - CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - raise ValueError("opening and closing arguments must be strings if no content expression is given") - ret = Forward() - if ignoreExpr is not None: - ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) - else: - ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) - ret.setName('nested %s%s expression' % (opener,closer)) - return ret - -def indentedBlock(blockStatementExpr, indentStack, indent=True): - """Helper method for defining space-delimited indentation blocks, - such as those used to define block statements in Python source code. - - Parameters: - - - blockStatementExpr - expression defining syntax of statement that - is repeated within the indented block - - indentStack - list created by caller to manage indentation stack - (multiple statementWithIndentedBlock expressions within a single - grammar should share a common indentStack) - - indent - boolean indicating whether block must be indented beyond - the the current level; set to False for block of left-most - statements (default= ``True``) - - A valid block must contain at least one ``blockStatement``. - - Example:: - - data = ''' - def A(z): - A1 - B = 100 - G = A2 - A2 - A3 - B - def BB(a,b,c): - BB1 - def BBA(): - bba1 - bba2 - bba3 - C - D - def spam(x,y): - def eggs(z): - pass - ''' - - - indentStack = [1] - stmt = Forward() - - identifier = Word(alphas, alphanums) - funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") - func_body = indentedBlock(stmt, indentStack) - funcDef = Group( funcDecl + func_body ) - - rvalue = Forward() - funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") - rvalue << (funcCall | identifier | Word(nums)) - assignment = Group(identifier + "=" + rvalue) - stmt << ( funcDef | assignment | identifier ) - - module_body = OneOrMore(stmt) - - parseTree = module_body.parseString(data) - parseTree.pprint() - - prints:: - - [['def', - 'A', - ['(', 'z', ')'], - ':', - [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], - 'B', - ['def', - 'BB', - ['(', 'a', 'b', 'c', ')'], - ':', - [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], - 'C', - 'D', - ['def', - 'spam', - ['(', 'x', 'y', ')'], - ':', - [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] - """ - def checkPeerIndent(s,l,t): - if l >= len(s): return - curCol = col(l,s) - if curCol != indentStack[-1]: - if curCol > indentStack[-1]: - raise ParseFatalException(s,l,"illegal nesting") - raise ParseException(s,l,"not a peer entry") - - def checkSubIndent(s,l,t): - curCol = col(l,s) - if curCol > indentStack[-1]: - indentStack.append( curCol ) - else: - raise ParseException(s,l,"not a subentry") - - def checkUnindent(s,l,t): - if l >= len(s): return - curCol = col(l,s) - if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): - raise ParseException(s,l,"not an unindent") - indentStack.pop() - - NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) - INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') - PEER = Empty().setParseAction(checkPeerIndent).setName('') - UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') - if indent: - smExpr = Group( Optional(NL) + - #~ FollowedBy(blockStatementExpr) + - INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) - else: - smExpr = Group( Optional(NL) + - (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) - blockStatementExpr.ignore(_bslash + LineEnd()) - return smExpr.setName('indented block') - -alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") -punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") - -anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) -_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) -commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") -def replaceHTMLEntity(t): - """Helper parser action to replace common HTML entities with their special characters""" - return _htmlEntityMap.get(t.entity) - -# it's easy to get these comment structures wrong - they're very common, so may as well make them available -cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") -"Comment of the form ``/* ... */``" - -htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") -"Comment of the form ``<!-- ... -->``" - -restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") -dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") -"Comment of the form ``// ... (to end of line)``" - -cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") -"Comment of either form :class:`cStyleComment` or :class:`dblSlashComment`" - -javaStyleComment = cppStyleComment -"Same as :class:`cppStyleComment`" - -pythonStyleComment = Regex(r"#.*").setName("Python style comment") -"Comment of the form ``# ... (to end of line)``" - -_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + - Optional( Word(" \t") + - ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") -commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") -"""(Deprecated) Predefined expression of 1 or more printable words or -quoted strings, separated by commas. - -This expression is deprecated in favor of :class:`pyparsing_common.comma_separated_list`. -""" - -# some other useful expressions - using lower-case class name since we are really using this as a namespace -class pyparsing_common: - """Here are some common low-level expressions that may be useful in - jump-starting parser development: - - - numeric forms (:class:`integers<integer>`, :class:`reals<real>`, - :class:`scientific notation<sci_real>`) - - common :class:`programming identifiers<identifier>` - - network addresses (:class:`MAC<mac_address>`, - :class:`IPv4<ipv4_address>`, :class:`IPv6<ipv6_address>`) - - ISO8601 :class:`dates<iso8601_date>` and - :class:`datetime<iso8601_datetime>` - - :class:`UUID<uuid>` - - :class:`comma-separated list<comma_separated_list>` - - Parse actions: - - - :class:`convertToInteger` - - :class:`convertToFloat` - - :class:`convertToDate` - - :class:`convertToDatetime` - - :class:`stripHTMLTags` - - :class:`upcaseTokens` - - :class:`downcaseTokens` - - Example:: - - pyparsing_common.number.runTests(''' - # any int or real number, returned as the appropriate type - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - ''') - - pyparsing_common.fnumber.runTests(''' - # any int or real number, returned as float - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - ''') - - pyparsing_common.hex_integer.runTests(''' - # hex numbers - 100 - FF - ''') - - pyparsing_common.fraction.runTests(''' - # fractions - 1/2 - -3/4 - ''') - - pyparsing_common.mixed_integer.runTests(''' - # mixed fractions - 1 - 1/2 - -3/4 - 1-3/4 - ''') - - import uuid - pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) - pyparsing_common.uuid.runTests(''' - # uuid - 12345678-1234-5678-1234-567812345678 - ''') - - prints:: - - # any int or real number, returned as the appropriate type - 100 - [100] - - -100 - [-100] - - +100 - [100] - - 3.14159 - [3.14159] - - 6.02e23 - [6.02e+23] - - 1e-12 - [1e-12] - - # any int or real number, returned as float - 100 - [100.0] - - -100 - [-100.0] - - +100 - [100.0] - - 3.14159 - [3.14159] - - 6.02e23 - [6.02e+23] - - 1e-12 - [1e-12] - - # hex numbers - 100 - [256] - - FF - [255] - - # fractions - 1/2 - [0.5] - - -3/4 - [-0.75] - - # mixed fractions - 1 - [1] - - 1/2 - [0.5] - - -3/4 - [-0.75] - - 1-3/4 - [1.75] - - # uuid - 12345678-1234-5678-1234-567812345678 - [UUID('12345678-1234-5678-1234-567812345678')] - """ - - convertToInteger = tokenMap(int) - """ - Parse action for converting parsed integers to Python int - """ - - convertToFloat = tokenMap(float) - """ - Parse action for converting parsed numbers to Python float - """ - - integer = Word(nums).setName("integer").setParseAction(convertToInteger) - """expression that parses an unsigned integer, returns an int""" - - hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) - """expression that parses a hexadecimal integer, returns an int""" - - signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) - """expression that parses an integer with optional leading sign, returns an int""" - - fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") - """fractional expression of an integer divided by an integer, returns a float""" - fraction.addParseAction(lambda t: t[0]/t[-1]) - - mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") - """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" - mixed_integer.addParseAction(sum) - - real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) - """expression that parses a floating point number and returns a float""" - - sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) - """expression that parses a floating point number with optional - scientific notation and returns a float""" - - # streamlining this expression makes the docs nicer-looking - number = (sci_real | real | signed_integer).streamline() - """any numeric expression, returns the corresponding Python type""" - - fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) - """any int or real number, returned as float""" - - identifier = Word(alphas+'_', alphanums+'_').setName("identifier") - """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" - - ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") - "IPv4 address (``0.0.0.0 - 255.255.255.255``)" - - _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") - _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") - _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") - _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) - _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") - ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") - "IPv6 address (long, short, or mixed form)" - - mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") - "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" - - @staticmethod - def convertToDate(fmt="%Y-%m-%d"): - """ - Helper to create a parse action for converting parsed date string to Python datetime.date - - Params - - - fmt - format to be passed to datetime.strptime (default= ``"%Y-%m-%d"``) - - Example:: - - date_expr = pyparsing_common.iso8601_date.copy() - date_expr.setParseAction(pyparsing_common.convertToDate()) - print(date_expr.parseString("1999-12-31")) - - prints:: - - [datetime.date(1999, 12, 31)] - """ - def cvt_fn(s,l,t): - try: - return datetime.strptime(t[0], fmt).date() - except ValueError as ve: - raise ParseException(s, l, str(ve)) - return cvt_fn - - @staticmethod - def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): - """Helper to create a parse action for converting parsed - datetime string to Python datetime.datetime - - Params - - - fmt - format to be passed to datetime.strptime (default= ``"%Y-%m-%dT%H:%M:%S.%f"``) - - Example:: - - dt_expr = pyparsing_common.iso8601_datetime.copy() - dt_expr.setParseAction(pyparsing_common.convertToDatetime()) - print(dt_expr.parseString("1999-12-31T23:59:59.999")) - - prints:: - - [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] - """ - def cvt_fn(s,l,t): - try: - return datetime.strptime(t[0], fmt) - except ValueError as ve: - raise ParseException(s, l, str(ve)) - return cvt_fn - - iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") - "ISO8601 date (``yyyy-mm-dd``)" - - iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") - "ISO8601 datetime (``yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)``) - trailing seconds, milliseconds, and timezone optional; accepts separating ``'T'`` or ``' '``" - - uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") - "UUID (``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``)" - - _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() - @staticmethod - def stripHTMLTags(s, l, tokens): - """Parse action to remove HTML tags from web page HTML source - - Example:: - - # strip HTML links from normal text - text = '<td>More info at the <a href="https://github.com/pyparsing/pyparsing/wiki">pyparsing</a> wiki page</td>' - td,td_end = makeHTMLTags("TD") - table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end - print(table_text.parseString(text).body) - - Prints:: - - More info at the pyparsing wiki page - """ - return pyparsing_common._html_stripper.transformString(tokens[0]) - - _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') - + Optional( White(" \t") ) ) ).streamline().setName("commaItem") - comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") - """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" - - upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) - """Parse action to convert tokens to upper case.""" - - downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) - """Parse action to convert tokens to lower case.""" - - -class _lazyclassproperty(object): - def __init__(self, fn): - self.fn = fn - self.__doc__ = fn.__doc__ - self.__name__ = fn.__name__ - - def __get__(self, obj, cls): - if cls is None: - cls = type(obj) - if not hasattr(cls, '_intern') or any(cls._intern is getattr(superclass, '_intern', []) for superclass in cls.__mro__[1:]): - cls._intern = {} - attrname = self.fn.__name__ - if attrname not in cls._intern: - cls._intern[attrname] = self.fn(cls) - return cls._intern[attrname] - - -class unicode_set(object): - """ - A set of Unicode characters, for language-specific strings for - ``alphas``, ``nums``, ``alphanums``, and ``printables``. - A unicode_set is defined by a list of ranges in the Unicode character - set, in a class attribute ``_ranges``, such as:: - - _ranges = [(0x0020, 0x007e), (0x00a0, 0x00ff),] - - A unicode set can also be defined using multiple inheritance of other unicode sets:: - - class CJK(Chinese, Japanese, Korean): - pass - """ - _ranges = [] - - @classmethod - def _get_chars_for_ranges(cls): - ret = [] - for cc in cls.__mro__: - if cc is unicode_set: - break - for rr in cc._ranges: - ret.extend(range(rr[0], rr[-1]+1)) - return [unichr(c) for c in sorted(set(ret))] - - @_lazyclassproperty - def printables(cls): - "all non-whitespace characters in this range" - return u''.join(filterfalse(unicode.isspace, cls._get_chars_for_ranges())) - - @_lazyclassproperty - def alphas(cls): - "all alphabetic characters in this range" - return u''.join(filter(unicode.isalpha, cls._get_chars_for_ranges())) - - @_lazyclassproperty - def nums(cls): - "all numeric digit characters in this range" - return u''.join(filter(unicode.isdigit, cls._get_chars_for_ranges())) - - @_lazyclassproperty - def alphanums(cls): - "all alphanumeric characters in this range" - return cls.alphas + cls.nums - - -class pyparsing_unicode(unicode_set): - """ - A namespace class for defining common language unicode_sets. - """ - _ranges = [(32, sys.maxunicode)] - - class Latin1(unicode_set): - "Unicode set for Latin-1 Unicode Character Range" - _ranges = [(0x0020, 0x007e), (0x00a0, 0x00ff),] - - class LatinA(unicode_set): - "Unicode set for Latin-A Unicode Character Range" - _ranges = [(0x0100, 0x017f),] - - class LatinB(unicode_set): - "Unicode set for Latin-B Unicode Character Range" - _ranges = [(0x0180, 0x024f),] - - class Greek(unicode_set): - "Unicode set for Greek Unicode Character Ranges" - _ranges = [ - (0x0370, 0x03ff), (0x1f00, 0x1f15), (0x1f18, 0x1f1d), (0x1f20, 0x1f45), (0x1f48, 0x1f4d), - (0x1f50, 0x1f57), (0x1f59,), (0x1f5b,), (0x1f5d,), (0x1f5f, 0x1f7d), (0x1f80, 0x1fb4), (0x1fb6, 0x1fc4), - (0x1fc6, 0x1fd3), (0x1fd6, 0x1fdb), (0x1fdd, 0x1fef), (0x1ff2, 0x1ff4), (0x1ff6, 0x1ffe), - ] - - class Cyrillic(unicode_set): - "Unicode set for Cyrillic Unicode Character Range" - _ranges = [(0x0400, 0x04ff)] - - class Chinese(unicode_set): - "Unicode set for Chinese Unicode Character Range" - _ranges = [(0x4e00, 0x9fff), (0x3000, 0x303f), ] - - class Japanese(unicode_set): - "Unicode set for Japanese Unicode Character Range, combining Kanji, Hiragana, and Katakana ranges" - _ranges = [ ] - - class Kanji(unicode_set): - "Unicode set for Kanji Unicode Character Range" - _ranges = [(0x4E00, 0x9Fbf), (0x3000, 0x303f), ] - - class Hiragana(unicode_set): - "Unicode set for Hiragana Unicode Character Range" - _ranges = [(0x3040, 0x309f), ] - - class Katakana(unicode_set): - "Unicode set for Katakana Unicode Character Range" - _ranges = [(0x30a0, 0x30ff), ] - - class Korean(unicode_set): - "Unicode set for Korean Unicode Character Range" - _ranges = [(0xac00, 0xd7af), (0x1100, 0x11ff), (0x3130, 0x318f), (0xa960, 0xa97f), (0xd7b0, 0xd7ff), (0x3000, 0x303f), ] - - class CJK(Chinese, Japanese, Korean): - "Unicode set for combined Chinese, Japanese, and Korean (CJK) Unicode Character Range" - pass - - class Thai(unicode_set): - "Unicode set for Thai Unicode Character Range" - _ranges = [(0x0e01, 0x0e3a), (0x0e3f, 0x0e5b), ] - - class Arabic(unicode_set): - "Unicode set for Arabic Unicode Character Range" - _ranges = [(0x0600, 0x061b), (0x061e, 0x06ff), (0x0700, 0x077f), ] - - class Hebrew(unicode_set): - "Unicode set for Hebrew Unicode Character Range" - _ranges = [(0x0590, 0x05ff), ] - - class Devanagari(unicode_set): - "Unicode set for Devanagari Unicode Character Range" - _ranges = [(0x0900, 0x097f), (0xa8e0, 0xa8ff)] - -pyparsing_unicode.Japanese._ranges = (pyparsing_unicode.Japanese.Kanji._ranges - + pyparsing_unicode.Japanese.Hiragana._ranges - + pyparsing_unicode.Japanese.Katakana._ranges) - -# define ranges in language character sets -if PY_3: - setattr(pyparsing_unicode, "العربية", pyparsing_unicode.Arabic) - setattr(pyparsing_unicode, "中文", pyparsing_unicode.Chinese) - setattr(pyparsing_unicode, "кириллица", pyparsing_unicode.Cyrillic) - setattr(pyparsing_unicode, "Ελληνικά", pyparsing_unicode.Greek) - setattr(pyparsing_unicode, "עִברִית", pyparsing_unicode.Hebrew) - setattr(pyparsing_unicode, "日本語", pyparsing_unicode.Japanese) - setattr(pyparsing_unicode.Japanese, "漢字", pyparsing_unicode.Japanese.Kanji) - setattr(pyparsing_unicode.Japanese, "カタカナ", pyparsing_unicode.Japanese.Katakana) - setattr(pyparsing_unicode.Japanese, "ひらがな", pyparsing_unicode.Japanese.Hiragana) - setattr(pyparsing_unicode, "한국어", pyparsing_unicode.Korean) - setattr(pyparsing_unicode, "ไทย", pyparsing_unicode.Thai) - setattr(pyparsing_unicode, "देवनागरी", pyparsing_unicode.Devanagari) - - -if __name__ == "__main__": - - selectToken = CaselessLiteral("select") - fromToken = CaselessLiteral("from") - - ident = Word(alphas, alphanums + "_$") - - columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) - columnNameList = Group(delimitedList(columnName)).setName("columns") - columnSpec = ('*' | columnNameList) - - tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) - tableNameList = Group(delimitedList(tableName)).setName("tables") - - simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") - - # demo runTests method, including embedded comments in test string - simpleSQL.runTests(""" - # '*' as column list and dotted table name - select * from SYS.XYZZY - - # caseless match on "SELECT", and casts back to "select" - SELECT * from XYZZY, ABC - - # list of column names, and mixed case SELECT keyword - Select AA,BB,CC from Sys.dual - - # multiple tables - Select A, B, C from Sys.dual, Table2 - - # invalid SELECT keyword - should fail - Xelect A, B, C from Sys.dual - - # incomplete command - should fail - Select - - # invalid column name - should fail - Select ^^^ frox Sys.dual - - """) - - pyparsing_common.number.runTests(""" - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - """) - - # any int or real number, returned as float - pyparsing_common.fnumber.runTests(""" - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - """) - - pyparsing_common.hex_integer.runTests(""" - 100 - FF - """) - - import uuid - pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) - pyparsing_common.uuid.runTests(""" - 12345678-1234-5678-1234-567812345678 - """) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/__init__.py deleted file mode 100644 index 8ed060f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .core import TomlError -from .parser import load, loads -from .test import translate_to_test -from .writer import dump, dumps \ No newline at end of file diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/core.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/core.py deleted file mode 100644 index c182734..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/core.py +++ /dev/null @@ -1,13 +0,0 @@ -class TomlError(RuntimeError): - def __init__(self, message, line, col, filename): - RuntimeError.__init__(self, message, line, col, filename) - self.message = message - self.line = line - self.col = col - self.filename = filename - - def __str__(self): - return '{}({}, {}): {}'.format(self.filename, self.line, self.col, self.message) - - def __repr__(self): - return 'TomlError({!r}, {!r}, {!r}, {!r})'.format(self.message, self.line, self.col, self.filename) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/parser.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/parser.py deleted file mode 100644 index 3493aa6..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/parser.py +++ /dev/null @@ -1,341 +0,0 @@ -import string, re, sys, datetime -from .core import TomlError -from .utils import rfc3339_re, parse_rfc3339_re - -if sys.version_info[0] == 2: - _chr = unichr -else: - _chr = chr - -def load(fin, translate=lambda t, x, v: v, object_pairs_hook=dict): - return loads(fin.read(), translate=translate, object_pairs_hook=object_pairs_hook, filename=getattr(fin, 'name', repr(fin))) - -def loads(s, filename='<string>', translate=lambda t, x, v: v, object_pairs_hook=dict): - if isinstance(s, bytes): - s = s.decode('utf-8') - - s = s.replace('\r\n', '\n') - - root = object_pairs_hook() - tables = object_pairs_hook() - scope = root - - src = _Source(s, filename=filename) - ast = _p_toml(src, object_pairs_hook=object_pairs_hook) - - def error(msg): - raise TomlError(msg, pos[0], pos[1], filename) - - def process_value(v, object_pairs_hook): - kind, text, value, pos = v - if kind == 'str' and value.startswith('\n'): - value = value[1:] - if kind == 'array': - if value and any(k != value[0][0] for k, t, v, p in value[1:]): - error('array-type-mismatch') - value = [process_value(item, object_pairs_hook=object_pairs_hook) for item in value] - elif kind == 'table': - value = object_pairs_hook([(k, process_value(value[k], object_pairs_hook=object_pairs_hook)) for k in value]) - return translate(kind, text, value) - - for kind, value, pos in ast: - if kind == 'kv': - k, v = value - if k in scope: - error('duplicate_keys. Key "{0}" was used more than once.'.format(k)) - scope[k] = process_value(v, object_pairs_hook=object_pairs_hook) - else: - is_table_array = (kind == 'table_array') - cur = tables - for name in value[:-1]: - if isinstance(cur.get(name), list): - d, cur = cur[name][-1] - else: - d, cur = cur.setdefault(name, (None, object_pairs_hook())) - - scope = object_pairs_hook() - name = value[-1] - if name not in cur: - if is_table_array: - cur[name] = [(scope, object_pairs_hook())] - else: - cur[name] = (scope, object_pairs_hook()) - elif isinstance(cur[name], list): - if not is_table_array: - error('table_type_mismatch') - cur[name].append((scope, object_pairs_hook())) - else: - if is_table_array: - error('table_type_mismatch') - old_scope, next_table = cur[name] - if old_scope is not None: - error('duplicate_tables') - cur[name] = (scope, next_table) - - def merge_tables(scope, tables): - if scope is None: - scope = object_pairs_hook() - for k in tables: - if k in scope: - error('key_table_conflict') - v = tables[k] - if isinstance(v, list): - scope[k] = [merge_tables(sc, tbl) for sc, tbl in v] - else: - scope[k] = merge_tables(v[0], v[1]) - return scope - - return merge_tables(root, tables) - -class _Source: - def __init__(self, s, filename=None): - self.s = s - self._pos = (1, 1) - self._last = None - self._filename = filename - self.backtrack_stack = [] - - def last(self): - return self._last - - def pos(self): - return self._pos - - def fail(self): - return self._expect(None) - - def consume_dot(self): - if self.s: - self._last = self.s[0] - self.s = self[1:] - self._advance(self._last) - return self._last - return None - - def expect_dot(self): - return self._expect(self.consume_dot()) - - def consume_eof(self): - if not self.s: - self._last = '' - return True - return False - - def expect_eof(self): - return self._expect(self.consume_eof()) - - def consume(self, s): - if self.s.startswith(s): - self.s = self.s[len(s):] - self._last = s - self._advance(s) - return True - return False - - def expect(self, s): - return self._expect(self.consume(s)) - - def consume_re(self, re): - m = re.match(self.s) - if m: - self.s = self.s[len(m.group(0)):] - self._last = m - self._advance(m.group(0)) - return m - return None - - def expect_re(self, re): - return self._expect(self.consume_re(re)) - - def __enter__(self): - self.backtrack_stack.append((self.s, self._pos)) - - def __exit__(self, type, value, traceback): - if type is None: - self.backtrack_stack.pop() - else: - self.s, self._pos = self.backtrack_stack.pop() - return type == TomlError - - def commit(self): - self.backtrack_stack[-1] = (self.s, self._pos) - - def _expect(self, r): - if not r: - raise TomlError('msg', self._pos[0], self._pos[1], self._filename) - return r - - def _advance(self, s): - suffix_pos = s.rfind('\n') - if suffix_pos == -1: - self._pos = (self._pos[0], self._pos[1] + len(s)) - else: - self._pos = (self._pos[0] + s.count('\n'), len(s) - suffix_pos) - -_ews_re = re.compile(r'(?:[ \t]|#[^\n]*\n|#[^\n]*\Z|\n)*') -def _p_ews(s): - s.expect_re(_ews_re) - -_ws_re = re.compile(r'[ \t]*') -def _p_ws(s): - s.expect_re(_ws_re) - -_escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"', - '\\': '\\', 'f': '\f' } - -_basicstr_re = re.compile(r'[^"\\\000-\037]*') -_short_uni_re = re.compile(r'u([0-9a-fA-F]{4})') -_long_uni_re = re.compile(r'U([0-9a-fA-F]{8})') -_escapes_re = re.compile(r'[btnfr\"\\]') -_newline_esc_re = re.compile('\n[ \t\n]*') -def _p_basicstr_content(s, content=_basicstr_re): - res = [] - while True: - res.append(s.expect_re(content).group(0)) - if not s.consume('\\'): - break - if s.consume_re(_newline_esc_re): - pass - elif s.consume_re(_short_uni_re) or s.consume_re(_long_uni_re): - v = int(s.last().group(1), 16) - if 0xd800 <= v < 0xe000: - s.fail() - res.append(_chr(v)) - else: - s.expect_re(_escapes_re) - res.append(_escapes[s.last().group(0)]) - return ''.join(res) - -_key_re = re.compile(r'[0-9a-zA-Z-_]+') -def _p_key(s): - with s: - s.expect('"') - r = _p_basicstr_content(s, _basicstr_re) - s.expect('"') - return r - if s.consume('\''): - if s.consume('\'\''): - r = s.expect_re(_litstr_ml_re).group(0) - s.expect('\'\'\'') - else: - r = s.expect_re(_litstr_re).group(0) - s.expect('\'') - return r - return s.expect_re(_key_re).group(0) - -_float_re = re.compile(r'[+-]?(?:0|[1-9](?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?(?:\d(?:_?\d)*))?') - -_basicstr_ml_re = re.compile(r'(?:""?(?!")|[^"\\\000-\011\013-\037])*') -_litstr_re = re.compile(r"[^'\000\010\012-\037]*") -_litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\010\013-\037]))*") -def _p_value(s, object_pairs_hook): - pos = s.pos() - - if s.consume('true'): - return 'bool', s.last(), True, pos - if s.consume('false'): - return 'bool', s.last(), False, pos - - if s.consume('"'): - if s.consume('""'): - r = _p_basicstr_content(s, _basicstr_ml_re) - s.expect('"""') - else: - r = _p_basicstr_content(s, _basicstr_re) - s.expect('"') - return 'str', r, r, pos - - if s.consume('\''): - if s.consume('\'\''): - r = s.expect_re(_litstr_ml_re).group(0) - s.expect('\'\'\'') - else: - r = s.expect_re(_litstr_re).group(0) - s.expect('\'') - return 'str', r, r, pos - - if s.consume_re(rfc3339_re): - m = s.last() - return 'datetime', m.group(0), parse_rfc3339_re(m), pos - - if s.consume_re(_float_re): - m = s.last().group(0) - r = m.replace('_','') - if '.' in m or 'e' in m or 'E' in m: - return 'float', m, float(r), pos - else: - return 'int', m, int(r, 10), pos - - if s.consume('['): - items = [] - with s: - while True: - _p_ews(s) - items.append(_p_value(s, object_pairs_hook=object_pairs_hook)) - s.commit() - _p_ews(s) - s.expect(',') - s.commit() - _p_ews(s) - s.expect(']') - return 'array', None, items, pos - - if s.consume('{'): - _p_ws(s) - items = object_pairs_hook() - if not s.consume('}'): - k = _p_key(s) - _p_ws(s) - s.expect('=') - _p_ws(s) - items[k] = _p_value(s, object_pairs_hook=object_pairs_hook) - _p_ws(s) - while s.consume(','): - _p_ws(s) - k = _p_key(s) - _p_ws(s) - s.expect('=') - _p_ws(s) - items[k] = _p_value(s, object_pairs_hook=object_pairs_hook) - _p_ws(s) - s.expect('}') - return 'table', None, items, pos - - s.fail() - -def _p_stmt(s, object_pairs_hook): - pos = s.pos() - if s.consume( '['): - is_array = s.consume('[') - _p_ws(s) - keys = [_p_key(s)] - _p_ws(s) - while s.consume('.'): - _p_ws(s) - keys.append(_p_key(s)) - _p_ws(s) - s.expect(']') - if is_array: - s.expect(']') - return 'table_array' if is_array else 'table', keys, pos - - key = _p_key(s) - _p_ws(s) - s.expect('=') - _p_ws(s) - value = _p_value(s, object_pairs_hook=object_pairs_hook) - return 'kv', (key, value), pos - -_stmtsep_re = re.compile(r'(?:[ \t]*(?:#[^\n]*)?\n)+[ \t]*') -def _p_toml(s, object_pairs_hook): - stmts = [] - _p_ews(s) - with s: - stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook)) - while True: - s.commit() - s.expect_re(_stmtsep_re) - stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook)) - _p_ews(s) - s.expect_eof() - return stmts diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/test.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/test.py deleted file mode 100644 index ec8abfc..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/test.py +++ /dev/null @@ -1,30 +0,0 @@ -import datetime -from .utils import format_rfc3339 - -try: - _string_types = (str, unicode) - _int_types = (int, long) -except NameError: - _string_types = str - _int_types = int - -def translate_to_test(v): - if isinstance(v, dict): - return { k: translate_to_test(v) for k, v in v.items() } - if isinstance(v, list): - a = [translate_to_test(x) for x in v] - if v and isinstance(v[0], dict): - return a - else: - return {'type': 'array', 'value': a} - if isinstance(v, datetime.datetime): - return {'type': 'datetime', 'value': format_rfc3339(v)} - if isinstance(v, bool): - return {'type': 'bool', 'value': 'true' if v else 'false'} - if isinstance(v, _int_types): - return {'type': 'integer', 'value': str(v)} - if isinstance(v, float): - return {'type': 'float', 'value': '{:.17}'.format(v)} - if isinstance(v, _string_types): - return {'type': 'string', 'value': v} - raise RuntimeError('unexpected value: {!r}'.format(v)) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/utils.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/utils.py deleted file mode 100644 index 636a680..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/utils.py +++ /dev/null @@ -1,67 +0,0 @@ -import datetime -import re - -rfc3339_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))') - -def parse_rfc3339(v): - m = rfc3339_re.match(v) - if not m or m.group(0) != v: - return None - return parse_rfc3339_re(m) - -def parse_rfc3339_re(m): - r = map(int, m.groups()[:6]) - if m.group(7): - micro = float(m.group(7)) - else: - micro = 0 - - if m.group(8): - g = int(m.group(8), 10) * 60 + int(m.group(9), 10) - tz = _TimeZone(datetime.timedelta(0, g * 60)) - else: - tz = _TimeZone(datetime.timedelta(0, 0)) - - y, m, d, H, M, S = r - return datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz) - - -def format_rfc3339(v): - offs = v.utcoffset() - offs = int(offs.total_seconds()) // 60 if offs is not None else 0 - - if offs == 0: - suffix = 'Z' - else: - if offs > 0: - suffix = '+' - else: - suffix = '-' - offs = -offs - suffix = '{0}{1:02}:{2:02}'.format(suffix, offs // 60, offs % 60) - - if v.microsecond: - return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix - else: - return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix - -class _TimeZone(datetime.tzinfo): - def __init__(self, offset): - self._offset = offset - - def utcoffset(self, dt): - return self._offset - - def dst(self, dt): - return None - - def tzname(self, dt): - m = self._offset.total_seconds() // 60 - if m < 0: - res = '-' - m = -m - else: - res = '+' - h = m // 60 - m = m - h * 60 - return '{}{:.02}{:.02}'.format(res, h, m) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/writer.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/writer.py deleted file mode 100644 index 73b5089..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/pytoml/writer.py +++ /dev/null @@ -1,106 +0,0 @@ -from __future__ import unicode_literals -import io, datetime, math, string, sys - -from .utils import format_rfc3339 - -if sys.version_info[0] == 3: - long = int - unicode = str - - -def dumps(obj, sort_keys=False): - fout = io.StringIO() - dump(obj, fout, sort_keys=sort_keys) - return fout.getvalue() - - -_escapes = {'\n': 'n', '\r': 'r', '\\': '\\', '\t': 't', '\b': 'b', '\f': 'f', '"': '"'} - - -def _escape_string(s): - res = [] - start = 0 - - def flush(): - if start != i: - res.append(s[start:i]) - return i + 1 - - i = 0 - while i < len(s): - c = s[i] - if c in '"\\\n\r\t\b\f': - start = flush() - res.append('\\' + _escapes[c]) - elif ord(c) < 0x20: - start = flush() - res.append('\\u%04x' % ord(c)) - i += 1 - - flush() - return '"' + ''.join(res) + '"' - - -_key_chars = string.digits + string.ascii_letters + '-_' -def _escape_id(s): - if any(c not in _key_chars for c in s): - return _escape_string(s) - return s - - -def _format_value(v): - if isinstance(v, bool): - return 'true' if v else 'false' - if isinstance(v, int) or isinstance(v, long): - return unicode(v) - if isinstance(v, float): - if math.isnan(v) or math.isinf(v): - raise ValueError("{0} is not a valid TOML value".format(v)) - else: - return repr(v) - elif isinstance(v, unicode) or isinstance(v, bytes): - return _escape_string(v) - elif isinstance(v, datetime.datetime): - return format_rfc3339(v) - elif isinstance(v, list): - return '[{0}]'.format(', '.join(_format_value(obj) for obj in v)) - elif isinstance(v, dict): - return '{{{0}}}'.format(', '.join('{} = {}'.format(_escape_id(k), _format_value(obj)) for k, obj in v.items())) - else: - raise RuntimeError(v) - - -def dump(obj, fout, sort_keys=False): - tables = [((), obj, False)] - - while tables: - name, table, is_array = tables.pop() - if name: - section_name = '.'.join(_escape_id(c) for c in name) - if is_array: - fout.write('[[{0}]]\n'.format(section_name)) - else: - fout.write('[{0}]\n'.format(section_name)) - - table_keys = sorted(table.keys()) if sort_keys else table.keys() - new_tables = [] - has_kv = False - for k in table_keys: - v = table[k] - if isinstance(v, dict): - new_tables.append((name + (k,), v, False)) - elif isinstance(v, list) and v and all(isinstance(o, dict) for o in v): - new_tables.extend((name + (k,), d, True) for d in v) - elif v is None: - # based on mojombo's comment: https://github.com/toml-lang/toml/issues/146#issuecomment-25019344 - fout.write( - '#{} = null # To use: uncomment and replace null with value\n'.format(_escape_id(k))) - has_kv = True - else: - fout.write('{0} = {1}\n'.format(_escape_id(k), _format_value(v))) - has_kv = True - - tables.extend(reversed(new_tables)) - - if (name or has_kv) and tables: - fout.write('\n') diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/__init__.py deleted file mode 100644 index 80c4ce1..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/__init__.py +++ /dev/null @@ -1,133 +0,0 @@ -# -*- coding: utf-8 -*- - -# __ -# /__) _ _ _ _ _/ _ -# / ( (- (/ (/ (- _) / _) -# / - -""" -Requests HTTP Library -~~~~~~~~~~~~~~~~~~~~~ - -Requests is an HTTP library, written in Python, for human beings. Basic GET -usage: - - >>> import requests - >>> r = requests.get('https://www.python.org') - >>> r.status_code - 200 - >>> 'Python is a programming language' in r.content - True - -... or POST: - - >>> payload = dict(key1='value1', key2='value2') - >>> r = requests.post('https://httpbin.org/post', data=payload) - >>> print(r.text) - { - ... - "form": { - "key2": "value2", - "key1": "value1" - }, - ... - } - -The other HTTP methods are supported - see `requests.api`. Full documentation -is at <http://python-requests.org>. - -:copyright: (c) 2017 by Kenneth Reitz. -:license: Apache 2.0, see LICENSE for more details. -""" - -from pip._vendor import urllib3 -from pip._vendor import chardet -import warnings -from .exceptions import RequestsDependencyWarning - - -def check_compatibility(urllib3_version, chardet_version): - urllib3_version = urllib3_version.split('.') - assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. - - # Sometimes, urllib3 only reports its version as 16.1. - if len(urllib3_version) == 2: - urllib3_version.append('0') - - # Check urllib3 for compatibility. - major, minor, patch = urllib3_version # noqa: F811 - major, minor, patch = int(major), int(minor), int(patch) - # urllib3 >= 1.21.1, <= 1.24 - assert major == 1 - assert minor >= 21 - assert minor <= 24 - - # Check chardet for compatibility. - major, minor, patch = chardet_version.split('.')[:3] - major, minor, patch = int(major), int(minor), int(patch) - # chardet >= 3.0.2, < 3.1.0 - assert major == 3 - assert minor < 1 - assert patch >= 2 - - -def _check_cryptography(cryptography_version): - # cryptography < 1.3.4 - try: - cryptography_version = list(map(int, cryptography_version.split('.'))) - except ValueError: - return - - if cryptography_version < [1, 3, 4]: - warning = 'Old version of cryptography ({}) may cause slowdown.'.format(cryptography_version) - warnings.warn(warning, RequestsDependencyWarning) - -# Check imported dependencies for compatibility. -try: - check_compatibility(urllib3.__version__, chardet.__version__) -except (AssertionError, ValueError): - warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported " - "version!".format(urllib3.__version__, chardet.__version__), - RequestsDependencyWarning) - -# Attempt to enable urllib3's SNI support, if possible -from pip._internal.utils.compat import WINDOWS -if not WINDOWS: - try: - from pip._vendor.urllib3.contrib import pyopenssl - pyopenssl.inject_into_urllib3() - - # Check cryptography version - from cryptography import __version__ as cryptography_version - _check_cryptography(cryptography_version) - except ImportError: - pass - -# urllib3's DependencyWarnings should be silenced. -from pip._vendor.urllib3.exceptions import DependencyWarning -warnings.simplefilter('ignore', DependencyWarning) - -from .__version__ import __title__, __description__, __url__, __version__ -from .__version__ import __build__, __author__, __author_email__, __license__ -from .__version__ import __copyright__, __cake__ - -from . import utils -from . import packages -from .models import Request, Response, PreparedRequest -from .api import request, get, head, post, patch, put, delete, options -from .sessions import session, Session -from .status_codes import codes -from .exceptions import ( - RequestException, Timeout, URLRequired, - TooManyRedirects, HTTPError, ConnectionError, - FileModeWarning, ConnectTimeout, ReadTimeout -) - -# Set default logging handler to avoid "No handler found" warnings. -import logging -from logging import NullHandler - -logging.getLogger(__name__).addHandler(NullHandler()) - -# FileModeWarnings go off per the default. -warnings.simplefilter('default', FileModeWarning, append=True) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/__version__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/__version__.py deleted file mode 100644 index f5b5d03..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/__version__.py +++ /dev/null @@ -1,14 +0,0 @@ -# .-. .-. .-. . . .-. .-. .-. .-. -# |( |- |.| | | |- `-. | `-. -# ' ' `-' `-`.`-' `-' `-' ' `-' - -__title__ = 'requests' -__description__ = 'Python HTTP for Humans.' -__url__ = 'http://python-requests.org' -__version__ = '2.21.0' -__build__ = 0x022100 -__author__ = 'Kenneth Reitz' -__author_email__ = 'me@kennethreitz.org' -__license__ = 'Apache 2.0' -__copyright__ = 'Copyright 2018 Kenneth Reitz' -__cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/_internal_utils.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/_internal_utils.py deleted file mode 100644 index 759d9a5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/_internal_utils.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests._internal_utils -~~~~~~~~~~~~~~ - -Provides utility functions that are consumed internally by Requests -which depend on extremely few external helpers (such as compat) -""" - -from .compat import is_py2, builtin_str, str - - -def to_native_string(string, encoding='ascii'): - """Given a string object, regardless of type, returns a representation of - that string in the native string type, encoding and decoding where - necessary. This assumes ASCII unless told otherwise. - """ - if isinstance(string, builtin_str): - out = string - else: - if is_py2: - out = string.encode(encoding) - else: - out = string.decode(encoding) - - return out - - -def unicode_is_ascii(u_string): - """Determine if unicode string only contains ASCII characters. - - :param str u_string: unicode string to check. Must be unicode - and not Python 2 `str`. - :rtype: bool - """ - assert isinstance(u_string, str) - try: - u_string.encode('ascii') - return True - except UnicodeEncodeError: - return False diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/adapters.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/adapters.py deleted file mode 100644 index c30e7c9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/adapters.py +++ /dev/null @@ -1,533 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.adapters -~~~~~~~~~~~~~~~~~ - -This module contains the transport adapters that Requests uses to define -and maintain connections. -""" - -import os.path -import socket - -from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url -from pip._vendor.urllib3.response import HTTPResponse -from pip._vendor.urllib3.util import parse_url -from pip._vendor.urllib3.util import Timeout as TimeoutSauce -from pip._vendor.urllib3.util.retry import Retry -from pip._vendor.urllib3.exceptions import ClosedPoolError -from pip._vendor.urllib3.exceptions import ConnectTimeoutError -from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError -from pip._vendor.urllib3.exceptions import MaxRetryError -from pip._vendor.urllib3.exceptions import NewConnectionError -from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError -from pip._vendor.urllib3.exceptions import ProtocolError -from pip._vendor.urllib3.exceptions import ReadTimeoutError -from pip._vendor.urllib3.exceptions import SSLError as _SSLError -from pip._vendor.urllib3.exceptions import ResponseError -from pip._vendor.urllib3.exceptions import LocationValueError - -from .models import Response -from .compat import urlparse, basestring -from .utils import (DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths, - get_encoding_from_headers, prepend_scheme_if_needed, - get_auth_from_url, urldefragauth, select_proxy) -from .structures import CaseInsensitiveDict -from .cookies import extract_cookies_to_jar -from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, - ProxyError, RetryError, InvalidSchema, InvalidProxyURL, - InvalidURL) -from .auth import _basic_auth_str - -try: - from pip._vendor.urllib3.contrib.socks import SOCKSProxyManager -except ImportError: - def SOCKSProxyManager(*args, **kwargs): - raise InvalidSchema("Missing dependencies for SOCKS support.") - -DEFAULT_POOLBLOCK = False -DEFAULT_POOLSIZE = 10 -DEFAULT_RETRIES = 0 -DEFAULT_POOL_TIMEOUT = None - - -class BaseAdapter(object): - """The Base Transport Adapter""" - - def __init__(self): - super(BaseAdapter, self).__init__() - - def send(self, request, stream=False, timeout=None, verify=True, - cert=None, proxies=None): - """Sends PreparedRequest object. Returns Response object. - - :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. - :param stream: (optional) Whether to stream the request content. - :param timeout: (optional) How long to wait for the server to send - data before giving up, as a float, or a :ref:`(connect timeout, - read timeout) <timeouts>` tuple. - :type timeout: float or tuple - :param verify: (optional) Either a boolean, in which case it controls whether we verify - the server's TLS certificate, or a string, in which case it must be a path - to a CA bundle to use - :param cert: (optional) Any user-provided SSL certificate to be trusted. - :param proxies: (optional) The proxies dictionary to apply to the request. - """ - raise NotImplementedError - - def close(self): - """Cleans up adapter specific items.""" - raise NotImplementedError - - -class HTTPAdapter(BaseAdapter): - """The built-in HTTP Adapter for urllib3. - - Provides a general-case interface for Requests sessions to contact HTTP and - HTTPS urls by implementing the Transport Adapter interface. This class will - usually be created by the :class:`Session <Session>` class under the - covers. - - :param pool_connections: The number of urllib3 connection pools to cache. - :param pool_maxsize: The maximum number of connections to save in the pool. - :param max_retries: The maximum number of retries each connection - should attempt. Note, this applies only to failed DNS lookups, socket - connections and connection timeouts, never to requests where data has - made it to the server. By default, Requests does not retry failed - connections. If you need granular control over the conditions under - which we retry a request, import urllib3's ``Retry`` class and pass - that instead. - :param pool_block: Whether the connection pool should block for connections. - - Usage:: - - >>> import requests - >>> s = requests.Session() - >>> a = requests.adapters.HTTPAdapter(max_retries=3) - >>> s.mount('http://', a) - """ - __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', - '_pool_block'] - - def __init__(self, pool_connections=DEFAULT_POOLSIZE, - pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, - pool_block=DEFAULT_POOLBLOCK): - if max_retries == DEFAULT_RETRIES: - self.max_retries = Retry(0, read=False) - else: - self.max_retries = Retry.from_int(max_retries) - self.config = {} - self.proxy_manager = {} - - super(HTTPAdapter, self).__init__() - - self._pool_connections = pool_connections - self._pool_maxsize = pool_maxsize - self._pool_block = pool_block - - self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) - - def __getstate__(self): - return {attr: getattr(self, attr, None) for attr in self.__attrs__} - - def __setstate__(self, state): - # Can't handle by adding 'proxy_manager' to self.__attrs__ because - # self.poolmanager uses a lambda function, which isn't pickleable. - self.proxy_manager = {} - self.config = {} - - for attr, value in state.items(): - setattr(self, attr, value) - - self.init_poolmanager(self._pool_connections, self._pool_maxsize, - block=self._pool_block) - - def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): - """Initializes a urllib3 PoolManager. - - This method should not be called from user code, and is only - exposed for use when subclassing the - :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. - - :param connections: The number of urllib3 connection pools to cache. - :param maxsize: The maximum number of connections to save in the pool. - :param block: Block when no free connections are available. - :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. - """ - # save these values for pickling - self._pool_connections = connections - self._pool_maxsize = maxsize - self._pool_block = block - - self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, - block=block, strict=True, **pool_kwargs) - - def proxy_manager_for(self, proxy, **proxy_kwargs): - """Return urllib3 ProxyManager for the given proxy. - - This method should not be called from user code, and is only - exposed for use when subclassing the - :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. - - :param proxy: The proxy to return a urllib3 ProxyManager for. - :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. - :returns: ProxyManager - :rtype: urllib3.ProxyManager - """ - if proxy in self.proxy_manager: - manager = self.proxy_manager[proxy] - elif proxy.lower().startswith('socks'): - username, password = get_auth_from_url(proxy) - manager = self.proxy_manager[proxy] = SOCKSProxyManager( - proxy, - username=username, - password=password, - num_pools=self._pool_connections, - maxsize=self._pool_maxsize, - block=self._pool_block, - **proxy_kwargs - ) - else: - proxy_headers = self.proxy_headers(proxy) - manager = self.proxy_manager[proxy] = proxy_from_url( - proxy, - proxy_headers=proxy_headers, - num_pools=self._pool_connections, - maxsize=self._pool_maxsize, - block=self._pool_block, - **proxy_kwargs) - - return manager - - def cert_verify(self, conn, url, verify, cert): - """Verify a SSL certificate. This method should not be called from user - code, and is only exposed for use when subclassing the - :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. - - :param conn: The urllib3 connection object associated with the cert. - :param url: The requested URL. - :param verify: Either a boolean, in which case it controls whether we verify - the server's TLS certificate, or a string, in which case it must be a path - to a CA bundle to use - :param cert: The SSL certificate to verify. - """ - if url.lower().startswith('https') and verify: - - cert_loc = None - - # Allow self-specified cert location. - if verify is not True: - cert_loc = verify - - if not cert_loc: - cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) - - if not cert_loc or not os.path.exists(cert_loc): - raise IOError("Could not find a suitable TLS CA certificate bundle, " - "invalid path: {}".format(cert_loc)) - - conn.cert_reqs = 'CERT_REQUIRED' - - if not os.path.isdir(cert_loc): - conn.ca_certs = cert_loc - else: - conn.ca_cert_dir = cert_loc - else: - conn.cert_reqs = 'CERT_NONE' - conn.ca_certs = None - conn.ca_cert_dir = None - - if cert: - if not isinstance(cert, basestring): - conn.cert_file = cert[0] - conn.key_file = cert[1] - else: - conn.cert_file = cert - conn.key_file = None - if conn.cert_file and not os.path.exists(conn.cert_file): - raise IOError("Could not find the TLS certificate file, " - "invalid path: {}".format(conn.cert_file)) - if conn.key_file and not os.path.exists(conn.key_file): - raise IOError("Could not find the TLS key file, " - "invalid path: {}".format(conn.key_file)) - - def build_response(self, req, resp): - """Builds a :class:`Response <requests.Response>` object from a urllib3 - response. This should not be called from user code, and is only exposed - for use when subclassing the - :class:`HTTPAdapter <requests.adapters.HTTPAdapter>` - - :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response. - :param resp: The urllib3 response object. - :rtype: requests.Response - """ - response = Response() - - # Fallback to None if there's no status_code, for whatever reason. - response.status_code = getattr(resp, 'status', None) - - # Make headers case-insensitive. - response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {})) - - # Set encoding. - response.encoding = get_encoding_from_headers(response.headers) - response.raw = resp - response.reason = response.raw.reason - - if isinstance(req.url, bytes): - response.url = req.url.decode('utf-8') - else: - response.url = req.url - - # Add new cookies from the server. - extract_cookies_to_jar(response.cookies, req, resp) - - # Give the Response some context. - response.request = req - response.connection = self - - return response - - def get_connection(self, url, proxies=None): - """Returns a urllib3 connection for the given URL. This should not be - called from user code, and is only exposed for use when subclassing the - :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. - - :param url: The URL to connect to. - :param proxies: (optional) A Requests-style dictionary of proxies used on this request. - :rtype: urllib3.ConnectionPool - """ - proxy = select_proxy(url, proxies) - - if proxy: - proxy = prepend_scheme_if_needed(proxy, 'http') - proxy_url = parse_url(proxy) - if not proxy_url.host: - raise InvalidProxyURL("Please check proxy URL. It is malformed" - " and could be missing the host.") - proxy_manager = self.proxy_manager_for(proxy) - conn = proxy_manager.connection_from_url(url) - else: - # Only scheme should be lower case - parsed = urlparse(url) - url = parsed.geturl() - conn = self.poolmanager.connection_from_url(url) - - return conn - - def close(self): - """Disposes of any internal state. - - Currently, this closes the PoolManager and any active ProxyManager, - which closes any pooled connections. - """ - self.poolmanager.clear() - for proxy in self.proxy_manager.values(): - proxy.clear() - - def request_url(self, request, proxies): - """Obtain the url to use when making the final request. - - If the message is being sent through a HTTP proxy, the full URL has to - be used. Otherwise, we should only use the path portion of the URL. - - This should not be called from user code, and is only exposed for use - when subclassing the - :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. - - :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. - :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. - :rtype: str - """ - proxy = select_proxy(request.url, proxies) - scheme = urlparse(request.url).scheme - - is_proxied_http_request = (proxy and scheme != 'https') - using_socks_proxy = False - if proxy: - proxy_scheme = urlparse(proxy).scheme.lower() - using_socks_proxy = proxy_scheme.startswith('socks') - - url = request.path_url - if is_proxied_http_request and not using_socks_proxy: - url = urldefragauth(request.url) - - return url - - def add_headers(self, request, **kwargs): - """Add any headers needed by the connection. As of v2.0 this does - nothing by default, but is left for overriding by users that subclass - the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. - - This should not be called from user code, and is only exposed for use - when subclassing the - :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. - - :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to. - :param kwargs: The keyword arguments from the call to send(). - """ - pass - - def proxy_headers(self, proxy): - """Returns a dictionary of the headers to add to any request sent - through a proxy. This works with urllib3 magic to ensure that they are - correctly sent to the proxy, rather than in a tunnelled request if - CONNECT is being used. - - This should not be called from user code, and is only exposed for use - when subclassing the - :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. - - :param proxy: The url of the proxy being used for this request. - :rtype: dict - """ - headers = {} - username, password = get_auth_from_url(proxy) - - if username: - headers['Proxy-Authorization'] = _basic_auth_str(username, - password) - - return headers - - def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): - """Sends PreparedRequest object. Returns Response object. - - :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. - :param stream: (optional) Whether to stream the request content. - :param timeout: (optional) How long to wait for the server to send - data before giving up, as a float, or a :ref:`(connect timeout, - read timeout) <timeouts>` tuple. - :type timeout: float or tuple or urllib3 Timeout object - :param verify: (optional) Either a boolean, in which case it controls whether - we verify the server's TLS certificate, or a string, in which case it - must be a path to a CA bundle to use - :param cert: (optional) Any user-provided SSL certificate to be trusted. - :param proxies: (optional) The proxies dictionary to apply to the request. - :rtype: requests.Response - """ - - try: - conn = self.get_connection(request.url, proxies) - except LocationValueError as e: - raise InvalidURL(e, request=request) - - self.cert_verify(conn, request.url, verify, cert) - url = self.request_url(request, proxies) - self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies) - - chunked = not (request.body is None or 'Content-Length' in request.headers) - - if isinstance(timeout, tuple): - try: - connect, read = timeout - timeout = TimeoutSauce(connect=connect, read=read) - except ValueError as e: - # this may raise a string formatting error. - err = ("Invalid timeout {}. Pass a (connect, read) " - "timeout tuple, or a single float to set " - "both timeouts to the same value".format(timeout)) - raise ValueError(err) - elif isinstance(timeout, TimeoutSauce): - pass - else: - timeout = TimeoutSauce(connect=timeout, read=timeout) - - try: - if not chunked: - resp = conn.urlopen( - method=request.method, - url=url, - body=request.body, - headers=request.headers, - redirect=False, - assert_same_host=False, - preload_content=False, - decode_content=False, - retries=self.max_retries, - timeout=timeout - ) - - # Send the request. - else: - if hasattr(conn, 'proxy_pool'): - conn = conn.proxy_pool - - low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) - - try: - low_conn.putrequest(request.method, - url, - skip_accept_encoding=True) - - for header, value in request.headers.items(): - low_conn.putheader(header, value) - - low_conn.endheaders() - - for i in request.body: - low_conn.send(hex(len(i))[2:].encode('utf-8')) - low_conn.send(b'\r\n') - low_conn.send(i) - low_conn.send(b'\r\n') - low_conn.send(b'0\r\n\r\n') - - # Receive the response from the server - try: - # For Python 2.7, use buffering of HTTP responses - r = low_conn.getresponse(buffering=True) - except TypeError: - # For compatibility with Python 3.3+ - r = low_conn.getresponse() - - resp = HTTPResponse.from_httplib( - r, - pool=conn, - connection=low_conn, - preload_content=False, - decode_content=False - ) - except: - # If we hit any problems here, clean up the connection. - # Then, reraise so that we can handle the actual exception. - low_conn.close() - raise - - except (ProtocolError, socket.error) as err: - raise ConnectionError(err, request=request) - - except MaxRetryError as e: - if isinstance(e.reason, ConnectTimeoutError): - # TODO: Remove this in 3.0.0: see #2811 - if not isinstance(e.reason, NewConnectionError): - raise ConnectTimeout(e, request=request) - - if isinstance(e.reason, ResponseError): - raise RetryError(e, request=request) - - if isinstance(e.reason, _ProxyError): - raise ProxyError(e, request=request) - - if isinstance(e.reason, _SSLError): - # This branch is for urllib3 v1.22 and later. - raise SSLError(e, request=request) - - raise ConnectionError(e, request=request) - - except ClosedPoolError as e: - raise ConnectionError(e, request=request) - - except _ProxyError as e: - raise ProxyError(e) - - except (_SSLError, _HTTPError) as e: - if isinstance(e, _SSLError): - # This branch is for urllib3 versions earlier than v1.22 - raise SSLError(e, request=request) - elif isinstance(e, ReadTimeoutError): - raise ReadTimeout(e, request=request) - else: - raise - - return self.build_response(request, resp) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/api.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/api.py deleted file mode 100644 index abada96..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/api.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.api -~~~~~~~~~~~~ - -This module implements the Requests API. - -:copyright: (c) 2012 by Kenneth Reitz. -:license: Apache2, see LICENSE for more details. -""" - -from . import sessions - - -def request(method, url, **kwargs): - """Constructs and sends a :class:`Request <Request>`. - - :param method: method for the new :class:`Request` object. - :param url: URL for the new :class:`Request` object. - :param params: (optional) Dictionary, list of tuples or bytes to send - in the body of the :class:`Request`. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. - :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. - :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. - :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. - ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` - or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string - defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers - to add for the file. - :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. - :param timeout: (optional) How many seconds to wait for the server to send data - before giving up, as a float, or a :ref:`(connect timeout, read - timeout) <timeouts>` tuple. - :type timeout: float or tuple - :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. - :type allow_redirects: bool - :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. - :param verify: (optional) Either a boolean, in which case it controls whether we verify - the server's TLS certificate, or a string, in which case it must be a path - to a CA bundle to use. Defaults to ``True``. - :param stream: (optional) if ``False``, the response content will be immediately downloaded. - :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. - :return: :class:`Response <Response>` object - :rtype: requests.Response - - Usage:: - - >>> import requests - >>> req = requests.request('GET', 'https://httpbin.org/get') - <Response [200]> - """ - - # By using the 'with' statement we are sure the session is closed, thus we - # avoid leaving sockets open which can trigger a ResourceWarning in some - # cases, and look like a memory leak in others. - with sessions.Session() as session: - return session.request(method=method, url=url, **kwargs) - - -def get(url, params=None, **kwargs): - r"""Sends a GET request. - - :param url: URL for the new :class:`Request` object. - :param params: (optional) Dictionary, list of tuples or bytes to send - in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response <Response>` object - :rtype: requests.Response - """ - - kwargs.setdefault('allow_redirects', True) - return request('get', url, params=params, **kwargs) - - -def options(url, **kwargs): - r"""Sends an OPTIONS request. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response <Response>` object - :rtype: requests.Response - """ - - kwargs.setdefault('allow_redirects', True) - return request('options', url, **kwargs) - - -def head(url, **kwargs): - r"""Sends a HEAD request. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response <Response>` object - :rtype: requests.Response - """ - - kwargs.setdefault('allow_redirects', False) - return request('head', url, **kwargs) - - -def post(url, data=None, json=None, **kwargs): - r"""Sends a POST request. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) json data to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response <Response>` object - :rtype: requests.Response - """ - - return request('post', url, data=data, json=json, **kwargs) - - -def put(url, data=None, **kwargs): - r"""Sends a PUT request. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) json data to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response <Response>` object - :rtype: requests.Response - """ - - return request('put', url, data=data, **kwargs) - - -def patch(url, data=None, **kwargs): - r"""Sends a PATCH request. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) json data to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response <Response>` object - :rtype: requests.Response - """ - - return request('patch', url, data=data, **kwargs) - - -def delete(url, **kwargs): - r"""Sends a DELETE request. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response <Response>` object - :rtype: requests.Response - """ - - return request('delete', url, **kwargs) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/auth.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/auth.py deleted file mode 100644 index bdde51c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/auth.py +++ /dev/null @@ -1,305 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.auth -~~~~~~~~~~~~~ - -This module contains the authentication handlers for Requests. -""" - -import os -import re -import time -import hashlib -import threading -import warnings - -from base64 import b64encode - -from .compat import urlparse, str, basestring -from .cookies import extract_cookies_to_jar -from ._internal_utils import to_native_string -from .utils import parse_dict_header - -CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' -CONTENT_TYPE_MULTI_PART = 'multipart/form-data' - - -def _basic_auth_str(username, password): - """Returns a Basic Auth string.""" - - # "I want us to put a big-ol' comment on top of it that - # says that this behaviour is dumb but we need to preserve - # it because people are relying on it." - # - Lukasa - # - # These are here solely to maintain backwards compatibility - # for things like ints. This will be removed in 3.0.0. - if not isinstance(username, basestring): - warnings.warn( - "Non-string usernames will no longer be supported in Requests " - "3.0.0. Please convert the object you've passed in ({!r}) to " - "a string or bytes object in the near future to avoid " - "problems.".format(username), - category=DeprecationWarning, - ) - username = str(username) - - if not isinstance(password, basestring): - warnings.warn( - "Non-string passwords will no longer be supported in Requests " - "3.0.0. Please convert the object you've passed in ({!r}) to " - "a string or bytes object in the near future to avoid " - "problems.".format(password), - category=DeprecationWarning, - ) - password = str(password) - # -- End Removal -- - - if isinstance(username, str): - username = username.encode('latin1') - - if isinstance(password, str): - password = password.encode('latin1') - - authstr = 'Basic ' + to_native_string( - b64encode(b':'.join((username, password))).strip() - ) - - return authstr - - -class AuthBase(object): - """Base class that all auth implementations derive from""" - - def __call__(self, r): - raise NotImplementedError('Auth hooks must be callable.') - - -class HTTPBasicAuth(AuthBase): - """Attaches HTTP Basic Authentication to the given Request object.""" - - def __init__(self, username, password): - self.username = username - self.password = password - - def __eq__(self, other): - return all([ - self.username == getattr(other, 'username', None), - self.password == getattr(other, 'password', None) - ]) - - def __ne__(self, other): - return not self == other - - def __call__(self, r): - r.headers['Authorization'] = _basic_auth_str(self.username, self.password) - return r - - -class HTTPProxyAuth(HTTPBasicAuth): - """Attaches HTTP Proxy Authentication to a given Request object.""" - - def __call__(self, r): - r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password) - return r - - -class HTTPDigestAuth(AuthBase): - """Attaches HTTP Digest Authentication to the given Request object.""" - - def __init__(self, username, password): - self.username = username - self.password = password - # Keep state in per-thread local storage - self._thread_local = threading.local() - - def init_per_thread_state(self): - # Ensure state is initialized just once per-thread - if not hasattr(self._thread_local, 'init'): - self._thread_local.init = True - self._thread_local.last_nonce = '' - self._thread_local.nonce_count = 0 - self._thread_local.chal = {} - self._thread_local.pos = None - self._thread_local.num_401_calls = None - - def build_digest_header(self, method, url): - """ - :rtype: str - """ - - realm = self._thread_local.chal['realm'] - nonce = self._thread_local.chal['nonce'] - qop = self._thread_local.chal.get('qop') - algorithm = self._thread_local.chal.get('algorithm') - opaque = self._thread_local.chal.get('opaque') - hash_utf8 = None - - if algorithm is None: - _algorithm = 'MD5' - else: - _algorithm = algorithm.upper() - # lambdas assume digest modules are imported at the top level - if _algorithm == 'MD5' or _algorithm == 'MD5-SESS': - def md5_utf8(x): - if isinstance(x, str): - x = x.encode('utf-8') - return hashlib.md5(x).hexdigest() - hash_utf8 = md5_utf8 - elif _algorithm == 'SHA': - def sha_utf8(x): - if isinstance(x, str): - x = x.encode('utf-8') - return hashlib.sha1(x).hexdigest() - hash_utf8 = sha_utf8 - elif _algorithm == 'SHA-256': - def sha256_utf8(x): - if isinstance(x, str): - x = x.encode('utf-8') - return hashlib.sha256(x).hexdigest() - hash_utf8 = sha256_utf8 - elif _algorithm == 'SHA-512': - def sha512_utf8(x): - if isinstance(x, str): - x = x.encode('utf-8') - return hashlib.sha512(x).hexdigest() - hash_utf8 = sha512_utf8 - - KD = lambda s, d: hash_utf8("%s:%s" % (s, d)) - - if hash_utf8 is None: - return None - - # XXX not implemented yet - entdig = None - p_parsed = urlparse(url) - #: path is request-uri defined in RFC 2616 which should not be empty - path = p_parsed.path or "/" - if p_parsed.query: - path += '?' + p_parsed.query - - A1 = '%s:%s:%s' % (self.username, realm, self.password) - A2 = '%s:%s' % (method, path) - - HA1 = hash_utf8(A1) - HA2 = hash_utf8(A2) - - if nonce == self._thread_local.last_nonce: - self._thread_local.nonce_count += 1 - else: - self._thread_local.nonce_count = 1 - ncvalue = '%08x' % self._thread_local.nonce_count - s = str(self._thread_local.nonce_count).encode('utf-8') - s += nonce.encode('utf-8') - s += time.ctime().encode('utf-8') - s += os.urandom(8) - - cnonce = (hashlib.sha1(s).hexdigest()[:16]) - if _algorithm == 'MD5-SESS': - HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce)) - - if not qop: - respdig = KD(HA1, "%s:%s" % (nonce, HA2)) - elif qop == 'auth' or 'auth' in qop.split(','): - noncebit = "%s:%s:%s:%s:%s" % ( - nonce, ncvalue, cnonce, 'auth', HA2 - ) - respdig = KD(HA1, noncebit) - else: - # XXX handle auth-int. - return None - - self._thread_local.last_nonce = nonce - - # XXX should the partial digests be encoded too? - base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ - 'response="%s"' % (self.username, realm, nonce, path, respdig) - if opaque: - base += ', opaque="%s"' % opaque - if algorithm: - base += ', algorithm="%s"' % algorithm - if entdig: - base += ', digest="%s"' % entdig - if qop: - base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce) - - return 'Digest %s' % (base) - - def handle_redirect(self, r, **kwargs): - """Reset num_401_calls counter on redirects.""" - if r.is_redirect: - self._thread_local.num_401_calls = 1 - - def handle_401(self, r, **kwargs): - """ - Takes the given response and tries digest-auth, if needed. - - :rtype: requests.Response - """ - - # If response is not 4xx, do not auth - # See https://github.com/requests/requests/issues/3772 - if not 400 <= r.status_code < 500: - self._thread_local.num_401_calls = 1 - return r - - if self._thread_local.pos is not None: - # Rewind the file position indicator of the body to where - # it was to resend the request. - r.request.body.seek(self._thread_local.pos) - s_auth = r.headers.get('www-authenticate', '') - - if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2: - - self._thread_local.num_401_calls += 1 - pat = re.compile(r'digest ', flags=re.IGNORECASE) - self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1)) - - # Consume content and release the original connection - # to allow our new request to reuse the same one. - r.content - r.close() - prep = r.request.copy() - extract_cookies_to_jar(prep._cookies, r.request, r.raw) - prep.prepare_cookies(prep._cookies) - - prep.headers['Authorization'] = self.build_digest_header( - prep.method, prep.url) - _r = r.connection.send(prep, **kwargs) - _r.history.append(r) - _r.request = prep - - return _r - - self._thread_local.num_401_calls = 1 - return r - - def __call__(self, r): - # Initialize per-thread state, if needed - self.init_per_thread_state() - # If we have a saved nonce, skip the 401 - if self._thread_local.last_nonce: - r.headers['Authorization'] = self.build_digest_header(r.method, r.url) - try: - self._thread_local.pos = r.body.tell() - except AttributeError: - # In the case of HTTPDigestAuth being reused and the body of - # the previous request was a file-like object, pos has the - # file position of the previous body. Ensure it's set to - # None. - self._thread_local.pos = None - r.register_hook('response', self.handle_401) - r.register_hook('response', self.handle_redirect) - self._thread_local.num_401_calls = 1 - - return r - - def __eq__(self, other): - return all([ - self.username == getattr(other, 'username', None), - self.password == getattr(other, 'password', None) - ]) - - def __ne__(self, other): - return not self == other diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/certs.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/certs.py deleted file mode 100644 index 06a594e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/certs.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -requests.certs -~~~~~~~~~~~~~~ - -This module returns the preferred default CA certificate bundle. There is -only one — the one from the certifi package. - -If you are packaging Requests, e.g., for a Linux distribution or a managed -environment, you can change the definition of where() to return a separately -packaged CA bundle. -""" -from pip._vendor.certifi import where - -if __name__ == '__main__': - print(where()) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/compat.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/compat.py deleted file mode 100644 index 6a86893..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/compat.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.compat -~~~~~~~~~~~~~~~ - -This module handles import compatibility issues between Python 2 and -Python 3. -""" - -from pip._vendor import chardet - -import sys - -# ------- -# Pythons -# ------- - -# Syntax sugar. -_ver = sys.version_info - -#: Python 2.x? -is_py2 = (_ver[0] == 2) - -#: Python 3.x? -is_py3 = (_ver[0] == 3) - -# Note: We've patched out simplejson support in pip because it prevents -# upgrading simplejson on Windows. -# try: -# import simplejson as json -# except (ImportError, SyntaxError): -# # simplejson does not support Python 3.2, it throws a SyntaxError -# # because of u'...' Unicode literals. -import json - -# --------- -# Specifics -# --------- - -if is_py2: - from urllib import ( - quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, - proxy_bypass, proxy_bypass_environment, getproxies_environment) - from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag - from urllib2 import parse_http_list - import cookielib - from Cookie import Morsel - from StringIO import StringIO - from collections import Callable, Mapping, MutableMapping, OrderedDict - - - builtin_str = str - bytes = str - str = unicode - basestring = basestring - numeric_types = (int, long, float) - integer_types = (int, long) - -elif is_py3: - from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag - from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment - from http import cookiejar as cookielib - from http.cookies import Morsel - from io import StringIO - from collections import OrderedDict - from collections.abc import Callable, Mapping, MutableMapping - - builtin_str = str - str = str - bytes = bytes - basestring = (str, bytes) - numeric_types = (int, float) - integer_types = (int,) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/cookies.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/cookies.py deleted file mode 100644 index 56fccd9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/cookies.py +++ /dev/null @@ -1,549 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.cookies -~~~~~~~~~~~~~~~~ - -Compatibility code to be able to use `cookielib.CookieJar` with requests. - -requests.utils imports from here, so be careful with imports. -""" - -import copy -import time -import calendar - -from ._internal_utils import to_native_string -from .compat import cookielib, urlparse, urlunparse, Morsel, MutableMapping - -try: - import threading -except ImportError: - import dummy_threading as threading - - -class MockRequest(object): - """Wraps a `requests.Request` to mimic a `urllib2.Request`. - - The code in `cookielib.CookieJar` expects this interface in order to correctly - manage cookie policies, i.e., determine whether a cookie can be set, given the - domains of the request and the cookie. - - The original request object is read-only. The client is responsible for collecting - the new headers via `get_new_headers()` and interpreting them appropriately. You - probably want `get_cookie_header`, defined below. - """ - - def __init__(self, request): - self._r = request - self._new_headers = {} - self.type = urlparse(self._r.url).scheme - - def get_type(self): - return self.type - - def get_host(self): - return urlparse(self._r.url).netloc - - def get_origin_req_host(self): - return self.get_host() - - def get_full_url(self): - # Only return the response's URL if the user hadn't set the Host - # header - if not self._r.headers.get('Host'): - return self._r.url - # If they did set it, retrieve it and reconstruct the expected domain - host = to_native_string(self._r.headers['Host'], encoding='utf-8') - parsed = urlparse(self._r.url) - # Reconstruct the URL as we expect it - return urlunparse([ - parsed.scheme, host, parsed.path, parsed.params, parsed.query, - parsed.fragment - ]) - - def is_unverifiable(self): - return True - - def has_header(self, name): - return name in self._r.headers or name in self._new_headers - - def get_header(self, name, default=None): - return self._r.headers.get(name, self._new_headers.get(name, default)) - - def add_header(self, key, val): - """cookielib has no legitimate use for this method; add it back if you find one.""" - raise NotImplementedError("Cookie headers should be added with add_unredirected_header()") - - def add_unredirected_header(self, name, value): - self._new_headers[name] = value - - def get_new_headers(self): - return self._new_headers - - @property - def unverifiable(self): - return self.is_unverifiable() - - @property - def origin_req_host(self): - return self.get_origin_req_host() - - @property - def host(self): - return self.get_host() - - -class MockResponse(object): - """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. - - ...what? Basically, expose the parsed HTTP headers from the server response - the way `cookielib` expects to see them. - """ - - def __init__(self, headers): - """Make a MockResponse for `cookielib` to read. - - :param headers: a httplib.HTTPMessage or analogous carrying the headers - """ - self._headers = headers - - def info(self): - return self._headers - - def getheaders(self, name): - self._headers.getheaders(name) - - -def extract_cookies_to_jar(jar, request, response): - """Extract the cookies from the response into a CookieJar. - - :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) - :param request: our own requests.Request object - :param response: urllib3.HTTPResponse object - """ - if not (hasattr(response, '_original_response') and - response._original_response): - return - # the _original_response field is the wrapped httplib.HTTPResponse object, - req = MockRequest(request) - # pull out the HTTPMessage with the headers and put it in the mock: - res = MockResponse(response._original_response.msg) - jar.extract_cookies(res, req) - - -def get_cookie_header(jar, request): - """ - Produce an appropriate Cookie header string to be sent with `request`, or None. - - :rtype: str - """ - r = MockRequest(request) - jar.add_cookie_header(r) - return r.get_new_headers().get('Cookie') - - -def remove_cookie_by_name(cookiejar, name, domain=None, path=None): - """Unsets a cookie by name, by default over all domains and paths. - - Wraps CookieJar.clear(), is O(n). - """ - clearables = [] - for cookie in cookiejar: - if cookie.name != name: - continue - if domain is not None and domain != cookie.domain: - continue - if path is not None and path != cookie.path: - continue - clearables.append((cookie.domain, cookie.path, cookie.name)) - - for domain, path, name in clearables: - cookiejar.clear(domain, path, name) - - -class CookieConflictError(RuntimeError): - """There are two cookies that meet the criteria specified in the cookie jar. - Use .get and .set and include domain and path args in order to be more specific. - """ - - -class RequestsCookieJar(cookielib.CookieJar, MutableMapping): - """Compatibility class; is a cookielib.CookieJar, but exposes a dict - interface. - - This is the CookieJar we create by default for requests and sessions that - don't specify one, since some clients may expect response.cookies and - session.cookies to support dict operations. - - Requests does not use the dict interface internally; it's just for - compatibility with external client code. All requests code should work - out of the box with externally provided instances of ``CookieJar``, e.g. - ``LWPCookieJar`` and ``FileCookieJar``. - - Unlike a regular CookieJar, this class is pickleable. - - .. warning:: dictionary operations that are normally O(1) may be O(n). - """ - - def get(self, name, default=None, domain=None, path=None): - """Dict-like get() that also supports optional domain and path args in - order to resolve naming collisions from using one cookie jar over - multiple domains. - - .. warning:: operation is O(n), not O(1). - """ - try: - return self._find_no_duplicates(name, domain, path) - except KeyError: - return default - - def set(self, name, value, **kwargs): - """Dict-like set() that also supports optional domain and path args in - order to resolve naming collisions from using one cookie jar over - multiple domains. - """ - # support client code that unsets cookies by assignment of a None value: - if value is None: - remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path')) - return - - if isinstance(value, Morsel): - c = morsel_to_cookie(value) - else: - c = create_cookie(name, value, **kwargs) - self.set_cookie(c) - return c - - def iterkeys(self): - """Dict-like iterkeys() that returns an iterator of names of cookies - from the jar. - - .. seealso:: itervalues() and iteritems(). - """ - for cookie in iter(self): - yield cookie.name - - def keys(self): - """Dict-like keys() that returns a list of names of cookies from the - jar. - - .. seealso:: values() and items(). - """ - return list(self.iterkeys()) - - def itervalues(self): - """Dict-like itervalues() that returns an iterator of values of cookies - from the jar. - - .. seealso:: iterkeys() and iteritems(). - """ - for cookie in iter(self): - yield cookie.value - - def values(self): - """Dict-like values() that returns a list of values of cookies from the - jar. - - .. seealso:: keys() and items(). - """ - return list(self.itervalues()) - - def iteritems(self): - """Dict-like iteritems() that returns an iterator of name-value tuples - from the jar. - - .. seealso:: iterkeys() and itervalues(). - """ - for cookie in iter(self): - yield cookie.name, cookie.value - - def items(self): - """Dict-like items() that returns a list of name-value tuples from the - jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a - vanilla python dict of key value pairs. - - .. seealso:: keys() and values(). - """ - return list(self.iteritems()) - - def list_domains(self): - """Utility method to list all the domains in the jar.""" - domains = [] - for cookie in iter(self): - if cookie.domain not in domains: - domains.append(cookie.domain) - return domains - - def list_paths(self): - """Utility method to list all the paths in the jar.""" - paths = [] - for cookie in iter(self): - if cookie.path not in paths: - paths.append(cookie.path) - return paths - - def multiple_domains(self): - """Returns True if there are multiple domains in the jar. - Returns False otherwise. - - :rtype: bool - """ - domains = [] - for cookie in iter(self): - if cookie.domain is not None and cookie.domain in domains: - return True - domains.append(cookie.domain) - return False # there is only one domain in jar - - def get_dict(self, domain=None, path=None): - """Takes as an argument an optional domain and path and returns a plain - old Python dict of name-value pairs of cookies that meet the - requirements. - - :rtype: dict - """ - dictionary = {} - for cookie in iter(self): - if ( - (domain is None or cookie.domain == domain) and - (path is None or cookie.path == path) - ): - dictionary[cookie.name] = cookie.value - return dictionary - - def __contains__(self, name): - try: - return super(RequestsCookieJar, self).__contains__(name) - except CookieConflictError: - return True - - def __getitem__(self, name): - """Dict-like __getitem__() for compatibility with client code. Throws - exception if there are more than one cookie with name. In that case, - use the more explicit get() method instead. - - .. warning:: operation is O(n), not O(1). - """ - return self._find_no_duplicates(name) - - def __setitem__(self, name, value): - """Dict-like __setitem__ for compatibility with client code. Throws - exception if there is already a cookie of that name in the jar. In that - case, use the more explicit set() method instead. - """ - self.set(name, value) - - def __delitem__(self, name): - """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s - ``remove_cookie_by_name()``. - """ - remove_cookie_by_name(self, name) - - def set_cookie(self, cookie, *args, **kwargs): - if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'): - cookie.value = cookie.value.replace('\\"', '') - return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs) - - def update(self, other): - """Updates this jar with cookies from another CookieJar or dict-like""" - if isinstance(other, cookielib.CookieJar): - for cookie in other: - self.set_cookie(copy.copy(cookie)) - else: - super(RequestsCookieJar, self).update(other) - - def _find(self, name, domain=None, path=None): - """Requests uses this method internally to get cookie values. - - If there are conflicting cookies, _find arbitrarily chooses one. - See _find_no_duplicates if you want an exception thrown if there are - conflicting cookies. - - :param name: a string containing name of cookie - :param domain: (optional) string containing domain of cookie - :param path: (optional) string containing path of cookie - :return: cookie.value - """ - for cookie in iter(self): - if cookie.name == name: - if domain is None or cookie.domain == domain: - if path is None or cookie.path == path: - return cookie.value - - raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) - - def _find_no_duplicates(self, name, domain=None, path=None): - """Both ``__get_item__`` and ``get`` call this function: it's never - used elsewhere in Requests. - - :param name: a string containing name of cookie - :param domain: (optional) string containing domain of cookie - :param path: (optional) string containing path of cookie - :raises KeyError: if cookie is not found - :raises CookieConflictError: if there are multiple cookies - that match name and optionally domain and path - :return: cookie.value - """ - toReturn = None - for cookie in iter(self): - if cookie.name == name: - if domain is None or cookie.domain == domain: - if path is None or cookie.path == path: - if toReturn is not None: # if there are multiple cookies that meet passed in criteria - raise CookieConflictError('There are multiple cookies with name, %r' % (name)) - toReturn = cookie.value # we will eventually return this as long as no cookie conflict - - if toReturn: - return toReturn - raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) - - def __getstate__(self): - """Unlike a normal CookieJar, this class is pickleable.""" - state = self.__dict__.copy() - # remove the unpickleable RLock object - state.pop('_cookies_lock') - return state - - def __setstate__(self, state): - """Unlike a normal CookieJar, this class is pickleable.""" - self.__dict__.update(state) - if '_cookies_lock' not in self.__dict__: - self._cookies_lock = threading.RLock() - - def copy(self): - """Return a copy of this RequestsCookieJar.""" - new_cj = RequestsCookieJar() - new_cj.set_policy(self.get_policy()) - new_cj.update(self) - return new_cj - - def get_policy(self): - """Return the CookiePolicy instance used.""" - return self._policy - - -def _copy_cookie_jar(jar): - if jar is None: - return None - - if hasattr(jar, 'copy'): - # We're dealing with an instance of RequestsCookieJar - return jar.copy() - # We're dealing with a generic CookieJar instance - new_jar = copy.copy(jar) - new_jar.clear() - for cookie in jar: - new_jar.set_cookie(copy.copy(cookie)) - return new_jar - - -def create_cookie(name, value, **kwargs): - """Make a cookie from underspecified parameters. - - By default, the pair of `name` and `value` will be set for the domain '' - and sent on every request (this is sometimes called a "supercookie"). - """ - result = { - 'version': 0, - 'name': name, - 'value': value, - 'port': None, - 'domain': '', - 'path': '/', - 'secure': False, - 'expires': None, - 'discard': True, - 'comment': None, - 'comment_url': None, - 'rest': {'HttpOnly': None}, - 'rfc2109': False, - } - - badargs = set(kwargs) - set(result) - if badargs: - err = 'create_cookie() got unexpected keyword arguments: %s' - raise TypeError(err % list(badargs)) - - result.update(kwargs) - result['port_specified'] = bool(result['port']) - result['domain_specified'] = bool(result['domain']) - result['domain_initial_dot'] = result['domain'].startswith('.') - result['path_specified'] = bool(result['path']) - - return cookielib.Cookie(**result) - - -def morsel_to_cookie(morsel): - """Convert a Morsel object into a Cookie containing the one k/v pair.""" - - expires = None - if morsel['max-age']: - try: - expires = int(time.time() + int(morsel['max-age'])) - except ValueError: - raise TypeError('max-age: %s must be integer' % morsel['max-age']) - elif morsel['expires']: - time_template = '%a, %d-%b-%Y %H:%M:%S GMT' - expires = calendar.timegm( - time.strptime(morsel['expires'], time_template) - ) - return create_cookie( - comment=morsel['comment'], - comment_url=bool(morsel['comment']), - discard=False, - domain=morsel['domain'], - expires=expires, - name=morsel.key, - path=morsel['path'], - port=None, - rest={'HttpOnly': morsel['httponly']}, - rfc2109=False, - secure=bool(morsel['secure']), - value=morsel.value, - version=morsel['version'] or 0, - ) - - -def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): - """Returns a CookieJar from a key/value dictionary. - - :param cookie_dict: Dict of key/values to insert into CookieJar. - :param cookiejar: (optional) A cookiejar to add the cookies to. - :param overwrite: (optional) If False, will not replace cookies - already in the jar with new ones. - :rtype: CookieJar - """ - if cookiejar is None: - cookiejar = RequestsCookieJar() - - if cookie_dict is not None: - names_from_jar = [cookie.name for cookie in cookiejar] - for name in cookie_dict: - if overwrite or (name not in names_from_jar): - cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) - - return cookiejar - - -def merge_cookies(cookiejar, cookies): - """Add cookies to cookiejar and returns a merged CookieJar. - - :param cookiejar: CookieJar object to add the cookies to. - :param cookies: Dictionary or CookieJar object to be added. - :rtype: CookieJar - """ - if not isinstance(cookiejar, cookielib.CookieJar): - raise ValueError('You can only merge into CookieJar') - - if isinstance(cookies, dict): - cookiejar = cookiejar_from_dict( - cookies, cookiejar=cookiejar, overwrite=False) - elif isinstance(cookies, cookielib.CookieJar): - try: - cookiejar.update(cookies) - except AttributeError: - for cookie_in_jar in cookies: - cookiejar.set_cookie(cookie_in_jar) - - return cookiejar diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/exceptions.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/exceptions.py deleted file mode 100644 index a91e1fd..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/exceptions.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.exceptions -~~~~~~~~~~~~~~~~~~~ - -This module contains the set of Requests' exceptions. -""" -from pip._vendor.urllib3.exceptions import HTTPError as BaseHTTPError - - -class RequestException(IOError): - """There was an ambiguous exception that occurred while handling your - request. - """ - - def __init__(self, *args, **kwargs): - """Initialize RequestException with `request` and `response` objects.""" - response = kwargs.pop('response', None) - self.response = response - self.request = kwargs.pop('request', None) - if (response is not None and not self.request and - hasattr(response, 'request')): - self.request = self.response.request - super(RequestException, self).__init__(*args, **kwargs) - - -class HTTPError(RequestException): - """An HTTP error occurred.""" - - -class ConnectionError(RequestException): - """A Connection error occurred.""" - - -class ProxyError(ConnectionError): - """A proxy error occurred.""" - - -class SSLError(ConnectionError): - """An SSL error occurred.""" - - -class Timeout(RequestException): - """The request timed out. - - Catching this error will catch both - :exc:`~requests.exceptions.ConnectTimeout` and - :exc:`~requests.exceptions.ReadTimeout` errors. - """ - - -class ConnectTimeout(ConnectionError, Timeout): - """The request timed out while trying to connect to the remote server. - - Requests that produced this error are safe to retry. - """ - - -class ReadTimeout(Timeout): - """The server did not send any data in the allotted amount of time.""" - - -class URLRequired(RequestException): - """A valid URL is required to make a request.""" - - -class TooManyRedirects(RequestException): - """Too many redirects.""" - - -class MissingSchema(RequestException, ValueError): - """The URL schema (e.g. http or https) is missing.""" - - -class InvalidSchema(RequestException, ValueError): - """See defaults.py for valid schemas.""" - - -class InvalidURL(RequestException, ValueError): - """The URL provided was somehow invalid.""" - - -class InvalidHeader(RequestException, ValueError): - """The header value provided was somehow invalid.""" - - -class InvalidProxyURL(InvalidURL): - """The proxy URL provided is invalid.""" - - -class ChunkedEncodingError(RequestException): - """The server declared chunked encoding but sent an invalid chunk.""" - - -class ContentDecodingError(RequestException, BaseHTTPError): - """Failed to decode response content""" - - -class StreamConsumedError(RequestException, TypeError): - """The content for this response was already consumed""" - - -class RetryError(RequestException): - """Custom retries logic failed""" - - -class UnrewindableBodyError(RequestException): - """Requests encountered an error when trying to rewind a body""" - -# Warnings - - -class RequestsWarning(Warning): - """Base warning for Requests.""" - pass - - -class FileModeWarning(RequestsWarning, DeprecationWarning): - """A file was opened in text mode, but Requests determined its binary length.""" - pass - - -class RequestsDependencyWarning(RequestsWarning): - """An imported dependency doesn't match the expected version range.""" - pass diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/help.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/help.py deleted file mode 100644 index 3c3072b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/help.py +++ /dev/null @@ -1,119 +0,0 @@ -"""Module containing bug report helper(s).""" -from __future__ import print_function - -import json -import platform -import sys -import ssl - -from pip._vendor import idna -from pip._vendor import urllib3 -from pip._vendor import chardet - -from . import __version__ as requests_version - -try: - from pip._vendor.urllib3.contrib import pyopenssl -except ImportError: - pyopenssl = None - OpenSSL = None - cryptography = None -else: - import OpenSSL - import cryptography - - -def _implementation(): - """Return a dict with the Python implementation and version. - - Provide both the name and the version of the Python implementation - currently running. For example, on CPython 2.7.5 it will return - {'name': 'CPython', 'version': '2.7.5'}. - - This function works best on CPython and PyPy: in particular, it probably - doesn't work for Jython or IronPython. Future investigation should be done - to work out the correct shape of the code for those platforms. - """ - implementation = platform.python_implementation() - - if implementation == 'CPython': - implementation_version = platform.python_version() - elif implementation == 'PyPy': - implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, - sys.pypy_version_info.minor, - sys.pypy_version_info.micro) - if sys.pypy_version_info.releaselevel != 'final': - implementation_version = ''.join([ - implementation_version, sys.pypy_version_info.releaselevel - ]) - elif implementation == 'Jython': - implementation_version = platform.python_version() # Complete Guess - elif implementation == 'IronPython': - implementation_version = platform.python_version() # Complete Guess - else: - implementation_version = 'Unknown' - - return {'name': implementation, 'version': implementation_version} - - -def info(): - """Generate information for a bug report.""" - try: - platform_info = { - 'system': platform.system(), - 'release': platform.release(), - } - except IOError: - platform_info = { - 'system': 'Unknown', - 'release': 'Unknown', - } - - implementation_info = _implementation() - urllib3_info = {'version': urllib3.__version__} - chardet_info = {'version': chardet.__version__} - - pyopenssl_info = { - 'version': None, - 'openssl_version': '', - } - if OpenSSL: - pyopenssl_info = { - 'version': OpenSSL.__version__, - 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER, - } - cryptography_info = { - 'version': getattr(cryptography, '__version__', ''), - } - idna_info = { - 'version': getattr(idna, '__version__', ''), - } - - system_ssl = ssl.OPENSSL_VERSION_NUMBER - system_ssl_info = { - 'version': '%x' % system_ssl if system_ssl is not None else '' - } - - return { - 'platform': platform_info, - 'implementation': implementation_info, - 'system_ssl': system_ssl_info, - 'using_pyopenssl': pyopenssl is not None, - 'pyOpenSSL': pyopenssl_info, - 'urllib3': urllib3_info, - 'chardet': chardet_info, - 'cryptography': cryptography_info, - 'idna': idna_info, - 'requests': { - 'version': requests_version, - }, - } - - -def main(): - """Pretty-print the bug information as JSON.""" - print(json.dumps(info(), sort_keys=True, indent=2)) - - -if __name__ == '__main__': - main() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/hooks.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/hooks.py deleted file mode 100644 index 7a51f21..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/hooks.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.hooks -~~~~~~~~~~~~~~ - -This module provides the capabilities for the Requests hooks system. - -Available hooks: - -``response``: - The response generated from a Request. -""" -HOOKS = ['response'] - - -def default_hooks(): - return {event: [] for event in HOOKS} - -# TODO: response is the only one - - -def dispatch_hook(key, hooks, hook_data, **kwargs): - """Dispatches a hook dictionary on a given piece of data.""" - hooks = hooks or {} - hooks = hooks.get(key) - if hooks: - if hasattr(hooks, '__call__'): - hooks = [hooks] - for hook in hooks: - _hook_data = hook(hook_data, **kwargs) - if _hook_data is not None: - hook_data = _hook_data - return hook_data diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/models.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/models.py deleted file mode 100644 index 0839957..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/models.py +++ /dev/null @@ -1,953 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.models -~~~~~~~~~~~~~~~ - -This module contains the primary objects that power Requests. -""" - -import datetime -import sys - -# Import encoding now, to avoid implicit import later. -# Implicit import within threads may cause LookupError when standard library is in a ZIP, -# such as in Embedded Python. See https://github.com/requests/requests/issues/3578. -import encodings.idna - -from pip._vendor.urllib3.fields import RequestField -from pip._vendor.urllib3.filepost import encode_multipart_formdata -from pip._vendor.urllib3.util import parse_url -from pip._vendor.urllib3.exceptions import ( - DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) - -from io import UnsupportedOperation -from .hooks import default_hooks -from .structures import CaseInsensitiveDict - -from .auth import HTTPBasicAuth -from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar -from .exceptions import ( - HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, - ContentDecodingError, ConnectionError, StreamConsumedError) -from ._internal_utils import to_native_string, unicode_is_ascii -from .utils import ( - guess_filename, get_auth_from_url, requote_uri, - stream_decode_response_unicode, to_key_val_list, parse_header_links, - iter_slices, guess_json_utf, super_len, check_header_validity) -from .compat import ( - Callable, Mapping, - cookielib, urlunparse, urlsplit, urlencode, str, bytes, - is_py2, chardet, builtin_str, basestring) -from .compat import json as complexjson -from .status_codes import codes - -#: The set of HTTP status codes that indicate an automatically -#: processable redirect. -REDIRECT_STATI = ( - codes.moved, # 301 - codes.found, # 302 - codes.other, # 303 - codes.temporary_redirect, # 307 - codes.permanent_redirect, # 308 -) - -DEFAULT_REDIRECT_LIMIT = 30 -CONTENT_CHUNK_SIZE = 10 * 1024 -ITER_CHUNK_SIZE = 512 - - -class RequestEncodingMixin(object): - @property - def path_url(self): - """Build the path URL to use.""" - - url = [] - - p = urlsplit(self.url) - - path = p.path - if not path: - path = '/' - - url.append(path) - - query = p.query - if query: - url.append('?') - url.append(query) - - return ''.join(url) - - @staticmethod - def _encode_params(data): - """Encode parameters in a piece of data. - - Will successfully encode parameters when passed as a dict or a list of - 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary - if parameters are supplied as a dict. - """ - - if isinstance(data, (str, bytes)): - return data - elif hasattr(data, 'read'): - return data - elif hasattr(data, '__iter__'): - result = [] - for k, vs in to_key_val_list(data): - if isinstance(vs, basestring) or not hasattr(vs, '__iter__'): - vs = [vs] - for v in vs: - if v is not None: - result.append( - (k.encode('utf-8') if isinstance(k, str) else k, - v.encode('utf-8') if isinstance(v, str) else v)) - return urlencode(result, doseq=True) - else: - return data - - @staticmethod - def _encode_files(files, data): - """Build the body for a multipart/form-data request. - - Will successfully encode files when passed as a dict or a list of - tuples. Order is retained if data is a list of tuples but arbitrary - if parameters are supplied as a dict. - The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) - or 4-tuples (filename, fileobj, contentype, custom_headers). - """ - if (not files): - raise ValueError("Files must be provided.") - elif isinstance(data, basestring): - raise ValueError("Data must not be a string.") - - new_fields = [] - fields = to_key_val_list(data or {}) - files = to_key_val_list(files or {}) - - for field, val in fields: - if isinstance(val, basestring) or not hasattr(val, '__iter__'): - val = [val] - for v in val: - if v is not None: - # Don't call str() on bytestrings: in Py3 it all goes wrong. - if not isinstance(v, bytes): - v = str(v) - - new_fields.append( - (field.decode('utf-8') if isinstance(field, bytes) else field, - v.encode('utf-8') if isinstance(v, str) else v)) - - for (k, v) in files: - # support for explicit filename - ft = None - fh = None - if isinstance(v, (tuple, list)): - if len(v) == 2: - fn, fp = v - elif len(v) == 3: - fn, fp, ft = v - else: - fn, fp, ft, fh = v - else: - fn = guess_filename(v) or k - fp = v - - if isinstance(fp, (str, bytes, bytearray)): - fdata = fp - elif hasattr(fp, 'read'): - fdata = fp.read() - elif fp is None: - continue - else: - fdata = fp - - rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) - rf.make_multipart(content_type=ft) - new_fields.append(rf) - - body, content_type = encode_multipart_formdata(new_fields) - - return body, content_type - - -class RequestHooksMixin(object): - def register_hook(self, event, hook): - """Properly register a hook.""" - - if event not in self.hooks: - raise ValueError('Unsupported event specified, with event name "%s"' % (event)) - - if isinstance(hook, Callable): - self.hooks[event].append(hook) - elif hasattr(hook, '__iter__'): - self.hooks[event].extend(h for h in hook if isinstance(h, Callable)) - - def deregister_hook(self, event, hook): - """Deregister a previously registered hook. - Returns True if the hook existed, False if not. - """ - - try: - self.hooks[event].remove(hook) - return True - except ValueError: - return False - - -class Request(RequestHooksMixin): - """A user-created :class:`Request <Request>` object. - - Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server. - - :param method: HTTP method to use. - :param url: URL to send. - :param headers: dictionary of headers to send. - :param files: dictionary of {filename: fileobject} files to multipart upload. - :param data: the body to attach to the request. If a dictionary or - list of tuples ``[(key, value)]`` is provided, form-encoding will - take place. - :param json: json for the body to attach to the request (if files or data is not specified). - :param params: URL parameters to append to the URL. If a dictionary or - list of tuples ``[(key, value)]`` is provided, form-encoding will - take place. - :param auth: Auth handler or (user, pass) tuple. - :param cookies: dictionary or CookieJar of cookies to attach to this request. - :param hooks: dictionary of callback hooks, for internal usage. - - Usage:: - - >>> import requests - >>> req = requests.Request('GET', 'https://httpbin.org/get') - >>> req.prepare() - <PreparedRequest [GET]> - """ - - def __init__(self, - method=None, url=None, headers=None, files=None, data=None, - params=None, auth=None, cookies=None, hooks=None, json=None): - - # Default empty dicts for dict params. - data = [] if data is None else data - files = [] if files is None else files - headers = {} if headers is None else headers - params = {} if params is None else params - hooks = {} if hooks is None else hooks - - self.hooks = default_hooks() - for (k, v) in list(hooks.items()): - self.register_hook(event=k, hook=v) - - self.method = method - self.url = url - self.headers = headers - self.files = files - self.data = data - self.json = json - self.params = params - self.auth = auth - self.cookies = cookies - - def __repr__(self): - return '<Request [%s]>' % (self.method) - - def prepare(self): - """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.""" - p = PreparedRequest() - p.prepare( - method=self.method, - url=self.url, - headers=self.headers, - files=self.files, - data=self.data, - json=self.json, - params=self.params, - auth=self.auth, - cookies=self.cookies, - hooks=self.hooks, - ) - return p - - -class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): - """The fully mutable :class:`PreparedRequest <PreparedRequest>` object, - containing the exact bytes that will be sent to the server. - - Generated from either a :class:`Request <Request>` object or manually. - - Usage:: - - >>> import requests - >>> req = requests.Request('GET', 'https://httpbin.org/get') - >>> r = req.prepare() - <PreparedRequest [GET]> - - >>> s = requests.Session() - >>> s.send(r) - <Response [200]> - """ - - def __init__(self): - #: HTTP verb to send to the server. - self.method = None - #: HTTP URL to send the request to. - self.url = None - #: dictionary of HTTP headers. - self.headers = None - # The `CookieJar` used to create the Cookie header will be stored here - # after prepare_cookies is called - self._cookies = None - #: request body to send to the server. - self.body = None - #: dictionary of callback hooks, for internal usage. - self.hooks = default_hooks() - #: integer denoting starting position of a readable file-like body. - self._body_position = None - - def prepare(self, - method=None, url=None, headers=None, files=None, data=None, - params=None, auth=None, cookies=None, hooks=None, json=None): - """Prepares the entire request with the given parameters.""" - - self.prepare_method(method) - self.prepare_url(url, params) - self.prepare_headers(headers) - self.prepare_cookies(cookies) - self.prepare_body(data, files, json) - self.prepare_auth(auth, url) - - # Note that prepare_auth must be last to enable authentication schemes - # such as OAuth to work on a fully prepared request. - - # This MUST go after prepare_auth. Authenticators could add a hook - self.prepare_hooks(hooks) - - def __repr__(self): - return '<PreparedRequest [%s]>' % (self.method) - - def copy(self): - p = PreparedRequest() - p.method = self.method - p.url = self.url - p.headers = self.headers.copy() if self.headers is not None else None - p._cookies = _copy_cookie_jar(self._cookies) - p.body = self.body - p.hooks = self.hooks - p._body_position = self._body_position - return p - - def prepare_method(self, method): - """Prepares the given HTTP method.""" - self.method = method - if self.method is not None: - self.method = to_native_string(self.method.upper()) - - @staticmethod - def _get_idna_encoded_host(host): - from pip._vendor import idna - - try: - host = idna.encode(host, uts46=True).decode('utf-8') - except idna.IDNAError: - raise UnicodeError - return host - - def prepare_url(self, url, params): - """Prepares the given HTTP URL.""" - #: Accept objects that have string representations. - #: We're unable to blindly call unicode/str functions - #: as this will include the bytestring indicator (b'') - #: on python 3.x. - #: https://github.com/requests/requests/pull/2238 - if isinstance(url, bytes): - url = url.decode('utf8') - else: - url = unicode(url) if is_py2 else str(url) - - # Remove leading whitespaces from url - url = url.lstrip() - - # Don't do any URL preparation for non-HTTP schemes like `mailto`, - # `data` etc to work around exceptions from `url_parse`, which - # handles RFC 3986 only. - if ':' in url and not url.lower().startswith('http'): - self.url = url - return - - # Support for unicode domain names and paths. - try: - scheme, auth, host, port, path, query, fragment = parse_url(url) - except LocationParseError as e: - raise InvalidURL(*e.args) - - if not scheme: - error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?") - error = error.format(to_native_string(url, 'utf8')) - - raise MissingSchema(error) - - if not host: - raise InvalidURL("Invalid URL %r: No host supplied" % url) - - # In general, we want to try IDNA encoding the hostname if the string contains - # non-ASCII characters. This allows users to automatically get the correct IDNA - # behaviour. For strings containing only ASCII characters, we need to also verify - # it doesn't start with a wildcard (*), before allowing the unencoded hostname. - if not unicode_is_ascii(host): - try: - host = self._get_idna_encoded_host(host) - except UnicodeError: - raise InvalidURL('URL has an invalid label.') - elif host.startswith(u'*'): - raise InvalidURL('URL has an invalid label.') - - # Carefully reconstruct the network location - netloc = auth or '' - if netloc: - netloc += '@' - netloc += host - if port: - netloc += ':' + str(port) - - # Bare domains aren't valid URLs. - if not path: - path = '/' - - if is_py2: - if isinstance(scheme, str): - scheme = scheme.encode('utf-8') - if isinstance(netloc, str): - netloc = netloc.encode('utf-8') - if isinstance(path, str): - path = path.encode('utf-8') - if isinstance(query, str): - query = query.encode('utf-8') - if isinstance(fragment, str): - fragment = fragment.encode('utf-8') - - if isinstance(params, (str, bytes)): - params = to_native_string(params) - - enc_params = self._encode_params(params) - if enc_params: - if query: - query = '%s&%s' % (query, enc_params) - else: - query = enc_params - - url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) - self.url = url - - def prepare_headers(self, headers): - """Prepares the given HTTP headers.""" - - self.headers = CaseInsensitiveDict() - if headers: - for header in headers.items(): - # Raise exception on invalid header value. - check_header_validity(header) - name, value = header - self.headers[to_native_string(name)] = value - - def prepare_body(self, data, files, json=None): - """Prepares the given HTTP body data.""" - - # Check if file, fo, generator, iterator. - # If not, run through normal process. - - # Nottin' on you. - body = None - content_type = None - - if not data and json is not None: - # urllib3 requires a bytes-like body. Python 2's json.dumps - # provides this natively, but Python 3 gives a Unicode string. - content_type = 'application/json' - body = complexjson.dumps(json) - if not isinstance(body, bytes): - body = body.encode('utf-8') - - is_stream = all([ - hasattr(data, '__iter__'), - not isinstance(data, (basestring, list, tuple, Mapping)) - ]) - - try: - length = super_len(data) - except (TypeError, AttributeError, UnsupportedOperation): - length = None - - if is_stream: - body = data - - if getattr(body, 'tell', None) is not None: - # Record the current file position before reading. - # This will allow us to rewind a file in the event - # of a redirect. - try: - self._body_position = body.tell() - except (IOError, OSError): - # This differentiates from None, allowing us to catch - # a failed `tell()` later when trying to rewind the body - self._body_position = object() - - if files: - raise NotImplementedError('Streamed bodies and files are mutually exclusive.') - - if length: - self.headers['Content-Length'] = builtin_str(length) - else: - self.headers['Transfer-Encoding'] = 'chunked' - else: - # Multi-part file uploads. - if files: - (body, content_type) = self._encode_files(files, data) - else: - if data: - body = self._encode_params(data) - if isinstance(data, basestring) or hasattr(data, 'read'): - content_type = None - else: - content_type = 'application/x-www-form-urlencoded' - - self.prepare_content_length(body) - - # Add content-type if it wasn't explicitly provided. - if content_type and ('content-type' not in self.headers): - self.headers['Content-Type'] = content_type - - self.body = body - - def prepare_content_length(self, body): - """Prepare Content-Length header based on request method and body""" - if body is not None: - length = super_len(body) - if length: - # If length exists, set it. Otherwise, we fallback - # to Transfer-Encoding: chunked. - self.headers['Content-Length'] = builtin_str(length) - elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: - # Set Content-Length to 0 for methods that can have a body - # but don't provide one. (i.e. not GET or HEAD) - self.headers['Content-Length'] = '0' - - def prepare_auth(self, auth, url=''): - """Prepares the given HTTP auth data.""" - - # If no Auth is explicitly provided, extract it from the URL first. - if auth is None: - url_auth = get_auth_from_url(self.url) - auth = url_auth if any(url_auth) else None - - if auth: - if isinstance(auth, tuple) and len(auth) == 2: - # special-case basic HTTP auth - auth = HTTPBasicAuth(*auth) - - # Allow auth to make its changes. - r = auth(self) - - # Update self to reflect the auth changes. - self.__dict__.update(r.__dict__) - - # Recompute Content-Length - self.prepare_content_length(self.body) - - def prepare_cookies(self, cookies): - """Prepares the given HTTP cookie data. - - This function eventually generates a ``Cookie`` header from the - given cookies using cookielib. Due to cookielib's design, the header - will not be regenerated if it already exists, meaning this function - can only be called once for the life of the - :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls - to ``prepare_cookies`` will have no actual effect, unless the "Cookie" - header is removed beforehand. - """ - if isinstance(cookies, cookielib.CookieJar): - self._cookies = cookies - else: - self._cookies = cookiejar_from_dict(cookies) - - cookie_header = get_cookie_header(self._cookies, self) - if cookie_header is not None: - self.headers['Cookie'] = cookie_header - - def prepare_hooks(self, hooks): - """Prepares the given hooks.""" - # hooks can be passed as None to the prepare method and to this - # method. To prevent iterating over None, simply use an empty list - # if hooks is False-y - hooks = hooks or [] - for event in hooks: - self.register_hook(event, hooks[event]) - - -class Response(object): - """The :class:`Response <Response>` object, which contains a - server's response to an HTTP request. - """ - - __attrs__ = [ - '_content', 'status_code', 'headers', 'url', 'history', - 'encoding', 'reason', 'cookies', 'elapsed', 'request' - ] - - def __init__(self): - self._content = False - self._content_consumed = False - self._next = None - - #: Integer Code of responded HTTP Status, e.g. 404 or 200. - self.status_code = None - - #: Case-insensitive Dictionary of Response Headers. - #: For example, ``headers['content-encoding']`` will return the - #: value of a ``'Content-Encoding'`` response header. - self.headers = CaseInsensitiveDict() - - #: File-like object representation of response (for advanced usage). - #: Use of ``raw`` requires that ``stream=True`` be set on the request. - # This requirement does not apply for use internally to Requests. - self.raw = None - - #: Final URL location of Response. - self.url = None - - #: Encoding to decode with when accessing r.text. - self.encoding = None - - #: A list of :class:`Response <Response>` objects from - #: the history of the Request. Any redirect responses will end - #: up here. The list is sorted from the oldest to the most recent request. - self.history = [] - - #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". - self.reason = None - - #: A CookieJar of Cookies the server sent back. - self.cookies = cookiejar_from_dict({}) - - #: The amount of time elapsed between sending the request - #: and the arrival of the response (as a timedelta). - #: This property specifically measures the time taken between sending - #: the first byte of the request and finishing parsing the headers. It - #: is therefore unaffected by consuming the response content or the - #: value of the ``stream`` keyword argument. - self.elapsed = datetime.timedelta(0) - - #: The :class:`PreparedRequest <PreparedRequest>` object to which this - #: is a response. - self.request = None - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - def __getstate__(self): - # Consume everything; accessing the content attribute makes - # sure the content has been fully read. - if not self._content_consumed: - self.content - - return {attr: getattr(self, attr, None) for attr in self.__attrs__} - - def __setstate__(self, state): - for name, value in state.items(): - setattr(self, name, value) - - # pickled objects do not have .raw - setattr(self, '_content_consumed', True) - setattr(self, 'raw', None) - - def __repr__(self): - return '<Response [%s]>' % (self.status_code) - - def __bool__(self): - """Returns True if :attr:`status_code` is less than 400. - - This attribute checks if the status code of the response is between - 400 and 600 to see if there was a client error or a server error. If - the status code, is between 200 and 400, this will return True. This - is **not** a check to see if the response code is ``200 OK``. - """ - return self.ok - - def __nonzero__(self): - """Returns True if :attr:`status_code` is less than 400. - - This attribute checks if the status code of the response is between - 400 and 600 to see if there was a client error or a server error. If - the status code, is between 200 and 400, this will return True. This - is **not** a check to see if the response code is ``200 OK``. - """ - return self.ok - - def __iter__(self): - """Allows you to use a response as an iterator.""" - return self.iter_content(128) - - @property - def ok(self): - """Returns True if :attr:`status_code` is less than 400, False if not. - - This attribute checks if the status code of the response is between - 400 and 600 to see if there was a client error or a server error. If - the status code is between 200 and 400, this will return True. This - is **not** a check to see if the response code is ``200 OK``. - """ - try: - self.raise_for_status() - except HTTPError: - return False - return True - - @property - def is_redirect(self): - """True if this Response is a well-formed HTTP redirect that could have - been processed automatically (by :meth:`Session.resolve_redirects`). - """ - return ('location' in self.headers and self.status_code in REDIRECT_STATI) - - @property - def is_permanent_redirect(self): - """True if this Response one of the permanent versions of redirect.""" - return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) - - @property - def next(self): - """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" - return self._next - - @property - def apparent_encoding(self): - """The apparent encoding, provided by the chardet library.""" - return chardet.detect(self.content)['encoding'] - - def iter_content(self, chunk_size=1, decode_unicode=False): - """Iterates over the response data. When stream=True is set on the - request, this avoids reading the content at once into memory for - large responses. The chunk size is the number of bytes it should - read into memory. This is not necessarily the length of each item - returned as decoding can take place. - - chunk_size must be of type int or None. A value of None will - function differently depending on the value of `stream`. - stream=True will read data as it arrives in whatever size the - chunks are received. If stream=False, data is returned as - a single chunk. - - If decode_unicode is True, content will be decoded using the best - available encoding based on the response. - """ - - def generate(): - # Special case for urllib3. - if hasattr(self.raw, 'stream'): - try: - for chunk in self.raw.stream(chunk_size, decode_content=True): - yield chunk - except ProtocolError as e: - raise ChunkedEncodingError(e) - except DecodeError as e: - raise ContentDecodingError(e) - except ReadTimeoutError as e: - raise ConnectionError(e) - else: - # Standard file-like object. - while True: - chunk = self.raw.read(chunk_size) - if not chunk: - break - yield chunk - - self._content_consumed = True - - if self._content_consumed and isinstance(self._content, bool): - raise StreamConsumedError() - elif chunk_size is not None and not isinstance(chunk_size, int): - raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size)) - # simulate reading small chunks of the content - reused_chunks = iter_slices(self._content, chunk_size) - - stream_chunks = generate() - - chunks = reused_chunks if self._content_consumed else stream_chunks - - if decode_unicode: - chunks = stream_decode_response_unicode(chunks, self) - - return chunks - - def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None): - """Iterates over the response data, one line at a time. When - stream=True is set on the request, this avoids reading the - content at once into memory for large responses. - - .. note:: This method is not reentrant safe. - """ - - pending = None - - for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode): - - if pending is not None: - chunk = pending + chunk - - if delimiter: - lines = chunk.split(delimiter) - else: - lines = chunk.splitlines() - - if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: - pending = lines.pop() - else: - pending = None - - for line in lines: - yield line - - if pending is not None: - yield pending - - @property - def content(self): - """Content of the response, in bytes.""" - - if self._content is False: - # Read the contents. - if self._content_consumed: - raise RuntimeError( - 'The content for this response was already consumed') - - if self.status_code == 0 or self.raw is None: - self._content = None - else: - self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b'' - - self._content_consumed = True - # don't need to release the connection; that's been handled by urllib3 - # since we exhausted the data. - return self._content - - @property - def text(self): - """Content of the response, in unicode. - - If Response.encoding is None, encoding will be guessed using - ``chardet``. - - The encoding of the response content is determined based solely on HTTP - headers, following RFC 2616 to the letter. If you can take advantage of - non-HTTP knowledge to make a better guess at the encoding, you should - set ``r.encoding`` appropriately before accessing this property. - """ - - # Try charset from content-type - content = None - encoding = self.encoding - - if not self.content: - return str('') - - # Fallback to auto-detected encoding. - if self.encoding is None: - encoding = self.apparent_encoding - - # Decode unicode from given encoding. - try: - content = str(self.content, encoding, errors='replace') - except (LookupError, TypeError): - # A LookupError is raised if the encoding was not found which could - # indicate a misspelling or similar mistake. - # - # A TypeError can be raised if encoding is None - # - # So we try blindly encoding. - content = str(self.content, errors='replace') - - return content - - def json(self, **kwargs): - r"""Returns the json-encoded content of a response, if any. - - :param \*\*kwargs: Optional arguments that ``json.loads`` takes. - :raises ValueError: If the response body does not contain valid json. - """ - - if not self.encoding and self.content and len(self.content) > 3: - # No encoding set. JSON RFC 4627 section 3 states we should expect - # UTF-8, -16 or -32. Detect which one to use; If the detection or - # decoding fails, fall back to `self.text` (using chardet to make - # a best guess). - encoding = guess_json_utf(self.content) - if encoding is not None: - try: - return complexjson.loads( - self.content.decode(encoding), **kwargs - ) - except UnicodeDecodeError: - # Wrong UTF codec detected; usually because it's not UTF-8 - # but some other 8-bit codec. This is an RFC violation, - # and the server didn't bother to tell us what codec *was* - # used. - pass - return complexjson.loads(self.text, **kwargs) - - @property - def links(self): - """Returns the parsed header links of the response, if any.""" - - header = self.headers.get('link') - - # l = MultiDict() - l = {} - - if header: - links = parse_header_links(header) - - for link in links: - key = link.get('rel') or link.get('url') - l[key] = link - - return l - - def raise_for_status(self): - """Raises stored :class:`HTTPError`, if one occurred.""" - - http_error_msg = '' - if isinstance(self.reason, bytes): - # We attempt to decode utf-8 first because some servers - # choose to localize their reason strings. If the string - # isn't utf-8, we fall back to iso-8859-1 for all other - # encodings. (See PR #3538) - try: - reason = self.reason.decode('utf-8') - except UnicodeDecodeError: - reason = self.reason.decode('iso-8859-1') - else: - reason = self.reason - - if 400 <= self.status_code < 500: - http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url) - - elif 500 <= self.status_code < 600: - http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url) - - if http_error_msg: - raise HTTPError(http_error_msg, response=self) - - def close(self): - """Releases the connection back to the pool. Once this method has been - called the underlying ``raw`` object must not be accessed again. - - *Note: Should not normally need to be called explicitly.* - """ - if not self._content_consumed: - self.raw.close() - - release_conn = getattr(self.raw, 'release_conn', None) - if release_conn is not None: - release_conn() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/packages.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/packages.py deleted file mode 100644 index 9582fa7..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/packages.py +++ /dev/null @@ -1,16 +0,0 @@ -import sys - -# This code exists for backwards compatibility reasons. -# I don't like it either. Just look the other way. :) - -for package in ('urllib3', 'idna', 'chardet'): - vendored_package = "pip._vendor." + package - locals()[package] = __import__(vendored_package) - # This traversal is apparently necessary such that the identities are - # preserved (requests.packages.urllib3.* is urllib3.*) - for mod in list(sys.modules): - if mod == vendored_package or mod.startswith(vendored_package + '.'): - unprefixed_mod = mod[len("pip._vendor."):] - sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] - -# Kinda cool, though, right? diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/sessions.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/sessions.py deleted file mode 100644 index d73d700..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/sessions.py +++ /dev/null @@ -1,770 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.session -~~~~~~~~~~~~~~~~ - -This module provides a Session object to manage and persist settings across -requests (cookies, auth, proxies). -""" -import os -import sys -import time -from datetime import timedelta - -from .auth import _basic_auth_str -from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse, Mapping -from .cookies import ( - cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) -from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT -from .hooks import default_hooks, dispatch_hook -from ._internal_utils import to_native_string -from .utils import to_key_val_list, default_headers, DEFAULT_PORTS -from .exceptions import ( - TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) - -from .structures import CaseInsensitiveDict -from .adapters import HTTPAdapter - -from .utils import ( - requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, - get_auth_from_url, rewind_body -) - -from .status_codes import codes - -# formerly defined here, reexposed here for backward compatibility -from .models import REDIRECT_STATI - -# Preferred clock, based on which one is more accurate on a given system. -if sys.platform == 'win32': - try: # Python 3.4+ - preferred_clock = time.perf_counter - except AttributeError: # Earlier than Python 3. - preferred_clock = time.clock -else: - preferred_clock = time.time - - -def merge_setting(request_setting, session_setting, dict_class=OrderedDict): - """Determines appropriate setting for a given request, taking into account - the explicit setting on that request, and the setting in the session. If a - setting is a dictionary, they will be merged together using `dict_class` - """ - - if session_setting is None: - return request_setting - - if request_setting is None: - return session_setting - - # Bypass if not a dictionary (e.g. verify) - if not ( - isinstance(session_setting, Mapping) and - isinstance(request_setting, Mapping) - ): - return request_setting - - merged_setting = dict_class(to_key_val_list(session_setting)) - merged_setting.update(to_key_val_list(request_setting)) - - # Remove keys that are set to None. Extract keys first to avoid altering - # the dictionary during iteration. - none_keys = [k for (k, v) in merged_setting.items() if v is None] - for key in none_keys: - del merged_setting[key] - - return merged_setting - - -def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): - """Properly merges both requests and session hooks. - - This is necessary because when request_hooks == {'response': []}, the - merge breaks Session hooks entirely. - """ - if session_hooks is None or session_hooks.get('response') == []: - return request_hooks - - if request_hooks is None or request_hooks.get('response') == []: - return session_hooks - - return merge_setting(request_hooks, session_hooks, dict_class) - - -class SessionRedirectMixin(object): - - def get_redirect_target(self, resp): - """Receives a Response. Returns a redirect URI or ``None``""" - # Due to the nature of how requests processes redirects this method will - # be called at least once upon the original response and at least twice - # on each subsequent redirect response (if any). - # If a custom mixin is used to handle this logic, it may be advantageous - # to cache the redirect location onto the response object as a private - # attribute. - if resp.is_redirect: - location = resp.headers['location'] - # Currently the underlying http module on py3 decode headers - # in latin1, but empirical evidence suggests that latin1 is very - # rarely used with non-ASCII characters in HTTP headers. - # It is more likely to get UTF8 header rather than latin1. - # This causes incorrect handling of UTF8 encoded location headers. - # To solve this, we re-encode the location in latin1. - if is_py3: - location = location.encode('latin1') - return to_native_string(location, 'utf8') - return None - - def should_strip_auth(self, old_url, new_url): - """Decide whether Authorization header should be removed when redirecting""" - old_parsed = urlparse(old_url) - new_parsed = urlparse(new_url) - if old_parsed.hostname != new_parsed.hostname: - return True - # Special case: allow http -> https redirect when using the standard - # ports. This isn't specified by RFC 7235, but is kept to avoid - # breaking backwards compatibility with older versions of requests - # that allowed any redirects on the same host. - if (old_parsed.scheme == 'http' and old_parsed.port in (80, None) - and new_parsed.scheme == 'https' and new_parsed.port in (443, None)): - return False - - # Handle default port usage corresponding to scheme. - changed_port = old_parsed.port != new_parsed.port - changed_scheme = old_parsed.scheme != new_parsed.scheme - default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None) - if (not changed_scheme and old_parsed.port in default_port - and new_parsed.port in default_port): - return False - - # Standard case: root URI must match - return changed_port or changed_scheme - - def resolve_redirects(self, resp, req, stream=False, timeout=None, - verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): - """Receives a Response. Returns a generator of Responses or Requests.""" - - hist = [] # keep track of history - - url = self.get_redirect_target(resp) - previous_fragment = urlparse(req.url).fragment - while url: - prepared_request = req.copy() - - # Update history and keep track of redirects. - # resp.history must ignore the original request in this loop - hist.append(resp) - resp.history = hist[1:] - - try: - resp.content # Consume socket so it can be released - except (ChunkedEncodingError, ContentDecodingError, RuntimeError): - resp.raw.read(decode_content=False) - - if len(resp.history) >= self.max_redirects: - raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp) - - # Release the connection back into the pool. - resp.close() - - # Handle redirection without scheme (see: RFC 1808 Section 4) - if url.startswith('//'): - parsed_rurl = urlparse(resp.url) - url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url) - - # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2) - parsed = urlparse(url) - if parsed.fragment == '' and previous_fragment: - parsed = parsed._replace(fragment=previous_fragment) - elif parsed.fragment: - previous_fragment = parsed.fragment - url = parsed.geturl() - - # Facilitate relative 'location' headers, as allowed by RFC 7231. - # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') - # Compliant with RFC3986, we percent encode the url. - if not parsed.netloc: - url = urljoin(resp.url, requote_uri(url)) - else: - url = requote_uri(url) - - prepared_request.url = to_native_string(url) - - self.rebuild_method(prepared_request, resp) - - # https://github.com/requests/requests/issues/1084 - if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): - # https://github.com/requests/requests/issues/3490 - purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding') - for header in purged_headers: - prepared_request.headers.pop(header, None) - prepared_request.body = None - - headers = prepared_request.headers - try: - del headers['Cookie'] - except KeyError: - pass - - # Extract any cookies sent on the response to the cookiejar - # in the new request. Because we've mutated our copied prepared - # request, use the old one that we haven't yet touched. - extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) - merge_cookies(prepared_request._cookies, self.cookies) - prepared_request.prepare_cookies(prepared_request._cookies) - - # Rebuild auth and proxy information. - proxies = self.rebuild_proxies(prepared_request, proxies) - self.rebuild_auth(prepared_request, resp) - - # A failed tell() sets `_body_position` to `object()`. This non-None - # value ensures `rewindable` will be True, allowing us to raise an - # UnrewindableBodyError, instead of hanging the connection. - rewindable = ( - prepared_request._body_position is not None and - ('Content-Length' in headers or 'Transfer-Encoding' in headers) - ) - - # Attempt to rewind consumed file-like object. - if rewindable: - rewind_body(prepared_request) - - # Override the original request. - req = prepared_request - - if yield_requests: - yield req - else: - - resp = self.send( - req, - stream=stream, - timeout=timeout, - verify=verify, - cert=cert, - proxies=proxies, - allow_redirects=False, - **adapter_kwargs - ) - - extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) - - # extract redirect url, if any, for the next loop - url = self.get_redirect_target(resp) - yield resp - - def rebuild_auth(self, prepared_request, response): - """When being redirected we may want to strip authentication from the - request to avoid leaking credentials. This method intelligently removes - and reapplies authentication where possible to avoid credential loss. - """ - headers = prepared_request.headers - url = prepared_request.url - - if 'Authorization' in headers and self.should_strip_auth(response.request.url, url): - # If we get redirected to a new host, we should strip out any - # authentication headers. - del headers['Authorization'] - - # .netrc might have more auth for us on our new host. - new_auth = get_netrc_auth(url) if self.trust_env else None - if new_auth is not None: - prepared_request.prepare_auth(new_auth) - - return - - def rebuild_proxies(self, prepared_request, proxies): - """This method re-evaluates the proxy configuration by considering the - environment variables. If we are redirected to a URL covered by - NO_PROXY, we strip the proxy configuration. Otherwise, we set missing - proxy keys for this URL (in case they were stripped by a previous - redirect). - - This method also replaces the Proxy-Authorization header where - necessary. - - :rtype: dict - """ - proxies = proxies if proxies is not None else {} - headers = prepared_request.headers - url = prepared_request.url - scheme = urlparse(url).scheme - new_proxies = proxies.copy() - no_proxy = proxies.get('no_proxy') - - bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy) - if self.trust_env and not bypass_proxy: - environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) - - proxy = environ_proxies.get(scheme, environ_proxies.get('all')) - - if proxy: - new_proxies.setdefault(scheme, proxy) - - if 'Proxy-Authorization' in headers: - del headers['Proxy-Authorization'] - - try: - username, password = get_auth_from_url(new_proxies[scheme]) - except KeyError: - username, password = None, None - - if username and password: - headers['Proxy-Authorization'] = _basic_auth_str(username, password) - - return new_proxies - - def rebuild_method(self, prepared_request, response): - """When being redirected we may want to change the method of the request - based on certain specs or browser behavior. - """ - method = prepared_request.method - - # https://tools.ietf.org/html/rfc7231#section-6.4.4 - if response.status_code == codes.see_other and method != 'HEAD': - method = 'GET' - - # Do what the browsers do, despite standards... - # First, turn 302s into GETs. - if response.status_code == codes.found and method != 'HEAD': - method = 'GET' - - # Second, if a POST is responded to with a 301, turn it into a GET. - # This bizarre behaviour is explained in Issue 1704. - if response.status_code == codes.moved and method == 'POST': - method = 'GET' - - prepared_request.method = method - - -class Session(SessionRedirectMixin): - """A Requests session. - - Provides cookie persistence, connection-pooling, and configuration. - - Basic Usage:: - - >>> import requests - >>> s = requests.Session() - >>> s.get('https://httpbin.org/get') - <Response [200]> - - Or as a context manager:: - - >>> with requests.Session() as s: - >>> s.get('https://httpbin.org/get') - <Response [200]> - """ - - __attrs__ = [ - 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', - 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', - 'max_redirects', - ] - - def __init__(self): - - #: A case-insensitive dictionary of headers to be sent on each - #: :class:`Request <Request>` sent from this - #: :class:`Session <Session>`. - self.headers = default_headers() - - #: Default Authentication tuple or object to attach to - #: :class:`Request <Request>`. - self.auth = None - - #: Dictionary mapping protocol or protocol and host to the URL of the proxy - #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to - #: be used on each :class:`Request <Request>`. - self.proxies = {} - - #: Event-handling hooks. - self.hooks = default_hooks() - - #: Dictionary of querystring data to attach to each - #: :class:`Request <Request>`. The dictionary values may be lists for - #: representing multivalued query parameters. - self.params = {} - - #: Stream response content default. - self.stream = False - - #: SSL Verification default. - self.verify = True - - #: SSL client certificate default, if String, path to ssl client - #: cert file (.pem). If Tuple, ('cert', 'key') pair. - self.cert = None - - #: Maximum number of redirects allowed. If the request exceeds this - #: limit, a :class:`TooManyRedirects` exception is raised. - #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is - #: 30. - self.max_redirects = DEFAULT_REDIRECT_LIMIT - - #: Trust environment settings for proxy configuration, default - #: authentication and similar. - self.trust_env = True - - #: A CookieJar containing all currently outstanding cookies set on this - #: session. By default it is a - #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but - #: may be any other ``cookielib.CookieJar`` compatible object. - self.cookies = cookiejar_from_dict({}) - - # Default connection adapters. - self.adapters = OrderedDict() - self.mount('https://', HTTPAdapter()) - self.mount('http://', HTTPAdapter()) - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - def prepare_request(self, request): - """Constructs a :class:`PreparedRequest <PreparedRequest>` for - transmission and returns it. The :class:`PreparedRequest` has settings - merged from the :class:`Request <Request>` instance and those of the - :class:`Session`. - - :param request: :class:`Request` instance to prepare with this - session's settings. - :rtype: requests.PreparedRequest - """ - cookies = request.cookies or {} - - # Bootstrap CookieJar. - if not isinstance(cookies, cookielib.CookieJar): - cookies = cookiejar_from_dict(cookies) - - # Merge with session cookies - merged_cookies = merge_cookies( - merge_cookies(RequestsCookieJar(), self.cookies), cookies) - - # Set environment's basic authentication if not explicitly set. - auth = request.auth - if self.trust_env and not auth and not self.auth: - auth = get_netrc_auth(request.url) - - p = PreparedRequest() - p.prepare( - method=request.method.upper(), - url=request.url, - files=request.files, - data=request.data, - json=request.json, - headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), - params=merge_setting(request.params, self.params), - auth=merge_setting(auth, self.auth), - cookies=merged_cookies, - hooks=merge_hooks(request.hooks, self.hooks), - ) - return p - - def request(self, method, url, - params=None, data=None, headers=None, cookies=None, files=None, - auth=None, timeout=None, allow_redirects=True, proxies=None, - hooks=None, stream=None, verify=None, cert=None, json=None): - """Constructs a :class:`Request <Request>`, prepares it and sends it. - Returns :class:`Response <Response>` object. - - :param method: method for the new :class:`Request` object. - :param url: URL for the new :class:`Request` object. - :param params: (optional) Dictionary or bytes to be sent in the query - string for the :class:`Request`. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) json to send in the body of the - :class:`Request`. - :param headers: (optional) Dictionary of HTTP Headers to send with the - :class:`Request`. - :param cookies: (optional) Dict or CookieJar object to send with the - :class:`Request`. - :param files: (optional) Dictionary of ``'filename': file-like-objects`` - for multipart encoding upload. - :param auth: (optional) Auth tuple or callable to enable - Basic/Digest/Custom HTTP Auth. - :param timeout: (optional) How long to wait for the server to send - data before giving up, as a float, or a :ref:`(connect timeout, - read timeout) <timeouts>` tuple. - :type timeout: float or tuple - :param allow_redirects: (optional) Set to True by default. - :type allow_redirects: bool - :param proxies: (optional) Dictionary mapping protocol or protocol and - hostname to the URL of the proxy. - :param stream: (optional) whether to immediately download the response - content. Defaults to ``False``. - :param verify: (optional) Either a boolean, in which case it controls whether we verify - the server's TLS certificate, or a string, in which case it must be a path - to a CA bundle to use. Defaults to ``True``. - :param cert: (optional) if String, path to ssl client cert file (.pem). - If Tuple, ('cert', 'key') pair. - :rtype: requests.Response - """ - # Create the Request. - req = Request( - method=method.upper(), - url=url, - headers=headers, - files=files, - data=data or {}, - json=json, - params=params or {}, - auth=auth, - cookies=cookies, - hooks=hooks, - ) - prep = self.prepare_request(req) - - proxies = proxies or {} - - settings = self.merge_environment_settings( - prep.url, proxies, stream, verify, cert - ) - - # Send the request. - send_kwargs = { - 'timeout': timeout, - 'allow_redirects': allow_redirects, - } - send_kwargs.update(settings) - resp = self.send(prep, **send_kwargs) - - return resp - - def get(self, url, **kwargs): - r"""Sends a GET request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - kwargs.setdefault('allow_redirects', True) - return self.request('GET', url, **kwargs) - - def options(self, url, **kwargs): - r"""Sends a OPTIONS request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - kwargs.setdefault('allow_redirects', True) - return self.request('OPTIONS', url, **kwargs) - - def head(self, url, **kwargs): - r"""Sends a HEAD request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - kwargs.setdefault('allow_redirects', False) - return self.request('HEAD', url, **kwargs) - - def post(self, url, data=None, json=None, **kwargs): - r"""Sends a POST request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) json to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - return self.request('POST', url, data=data, json=json, **kwargs) - - def put(self, url, data=None, **kwargs): - r"""Sends a PUT request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - return self.request('PUT', url, data=data, **kwargs) - - def patch(self, url, data=None, **kwargs): - r"""Sends a PATCH request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - return self.request('PATCH', url, data=data, **kwargs) - - def delete(self, url, **kwargs): - r"""Sends a DELETE request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - return self.request('DELETE', url, **kwargs) - - def send(self, request, **kwargs): - """Send a given PreparedRequest. - - :rtype: requests.Response - """ - # Set defaults that the hooks can utilize to ensure they always have - # the correct parameters to reproduce the previous request. - kwargs.setdefault('stream', self.stream) - kwargs.setdefault('verify', self.verify) - kwargs.setdefault('cert', self.cert) - kwargs.setdefault('proxies', self.proxies) - - # It's possible that users might accidentally send a Request object. - # Guard against that specific failure case. - if isinstance(request, Request): - raise ValueError('You can only send PreparedRequests.') - - # Set up variables needed for resolve_redirects and dispatching of hooks - allow_redirects = kwargs.pop('allow_redirects', True) - stream = kwargs.get('stream') - hooks = request.hooks - - # Get the appropriate adapter to use - adapter = self.get_adapter(url=request.url) - - # Start time (approximately) of the request - start = preferred_clock() - - # Send the request - r = adapter.send(request, **kwargs) - - # Total elapsed time of the request (approximately) - elapsed = preferred_clock() - start - r.elapsed = timedelta(seconds=elapsed) - - # Response manipulation hooks - r = dispatch_hook('response', hooks, r, **kwargs) - - # Persist cookies - if r.history: - - # If the hooks create history then we want those cookies too - for resp in r.history: - extract_cookies_to_jar(self.cookies, resp.request, resp.raw) - - extract_cookies_to_jar(self.cookies, request, r.raw) - - # Redirect resolving generator. - gen = self.resolve_redirects(r, request, **kwargs) - - # Resolve redirects if allowed. - history = [resp for resp in gen] if allow_redirects else [] - - # Shuffle things around if there's history. - if history: - # Insert the first (original) request at the start - history.insert(0, r) - # Get the last request made - r = history.pop() - r.history = history - - # If redirects aren't being followed, store the response on the Request for Response.next(). - if not allow_redirects: - try: - r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs)) - except StopIteration: - pass - - if not stream: - r.content - - return r - - def merge_environment_settings(self, url, proxies, stream, verify, cert): - """ - Check the environment and merge it with some settings. - - :rtype: dict - """ - # Gather clues from the surrounding environment. - if self.trust_env: - # Set environment's proxies. - no_proxy = proxies.get('no_proxy') if proxies is not None else None - env_proxies = get_environ_proxies(url, no_proxy=no_proxy) - for (k, v) in env_proxies.items(): - proxies.setdefault(k, v) - - # Look for requests environment configuration and be compatible - # with cURL. - if verify is True or verify is None: - verify = (os.environ.get('REQUESTS_CA_BUNDLE') or - os.environ.get('CURL_CA_BUNDLE')) - - # Merge all the kwargs. - proxies = merge_setting(proxies, self.proxies) - stream = merge_setting(stream, self.stream) - verify = merge_setting(verify, self.verify) - cert = merge_setting(cert, self.cert) - - return {'verify': verify, 'proxies': proxies, 'stream': stream, - 'cert': cert} - - def get_adapter(self, url): - """ - Returns the appropriate connection adapter for the given URL. - - :rtype: requests.adapters.BaseAdapter - """ - for (prefix, adapter) in self.adapters.items(): - - if url.lower().startswith(prefix.lower()): - return adapter - - # Nothing matches :-/ - raise InvalidSchema("No connection adapters were found for '%s'" % url) - - def close(self): - """Closes all adapters and as such the session""" - for v in self.adapters.values(): - v.close() - - def mount(self, prefix, adapter): - """Registers a connection adapter to a prefix. - - Adapters are sorted in descending order by prefix length. - """ - self.adapters[prefix] = adapter - keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] - - for key in keys_to_move: - self.adapters[key] = self.adapters.pop(key) - - def __getstate__(self): - state = {attr: getattr(self, attr, None) for attr in self.__attrs__} - return state - - def __setstate__(self, state): - for attr, value in state.items(): - setattr(self, attr, value) - - -def session(): - """ - Returns a :class:`Session` for context-management. - - .. deprecated:: 1.0.0 - - This method has been deprecated since version 1.0.0 and is only kept for - backwards compatibility. New code should use :class:`~requests.sessions.Session` - to create a session. This may be removed at a future date. - - :rtype: Session - """ - return Session() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/status_codes.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/status_codes.py deleted file mode 100644 index 813e8c4..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/status_codes.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- - -r""" -The ``codes`` object defines a mapping from common names for HTTP statuses -to their numerical codes, accessible either as attributes or as dictionary -items. - ->>> requests.codes['temporary_redirect'] -307 ->>> requests.codes.teapot -418 ->>> requests.codes['\o/'] -200 - -Some codes have multiple names, and both upper- and lower-case versions of -the names are allowed. For example, ``codes.ok``, ``codes.OK``, and -``codes.okay`` all correspond to the HTTP status code 200. -""" - -from .structures import LookupDict - -_codes = { - - # Informational. - 100: ('continue',), - 101: ('switching_protocols',), - 102: ('processing',), - 103: ('checkpoint',), - 122: ('uri_too_long', 'request_uri_too_long'), - 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'), - 201: ('created',), - 202: ('accepted',), - 203: ('non_authoritative_info', 'non_authoritative_information'), - 204: ('no_content',), - 205: ('reset_content', 'reset'), - 206: ('partial_content', 'partial'), - 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'), - 208: ('already_reported',), - 226: ('im_used',), - - # Redirection. - 300: ('multiple_choices',), - 301: ('moved_permanently', 'moved', '\\o-'), - 302: ('found',), - 303: ('see_other', 'other'), - 304: ('not_modified',), - 305: ('use_proxy',), - 306: ('switch_proxy',), - 307: ('temporary_redirect', 'temporary_moved', 'temporary'), - 308: ('permanent_redirect', - 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 - - # Client Error. - 400: ('bad_request', 'bad'), - 401: ('unauthorized',), - 402: ('payment_required', 'payment'), - 403: ('forbidden',), - 404: ('not_found', '-o-'), - 405: ('method_not_allowed', 'not_allowed'), - 406: ('not_acceptable',), - 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'), - 408: ('request_timeout', 'timeout'), - 409: ('conflict',), - 410: ('gone',), - 411: ('length_required',), - 412: ('precondition_failed', 'precondition'), - 413: ('request_entity_too_large',), - 414: ('request_uri_too_large',), - 415: ('unsupported_media_type', 'unsupported_media', 'media_type'), - 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'), - 417: ('expectation_failed',), - 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'), - 421: ('misdirected_request',), - 422: ('unprocessable_entity', 'unprocessable'), - 423: ('locked',), - 424: ('failed_dependency', 'dependency'), - 425: ('unordered_collection', 'unordered'), - 426: ('upgrade_required', 'upgrade'), - 428: ('precondition_required', 'precondition'), - 429: ('too_many_requests', 'too_many'), - 431: ('header_fields_too_large', 'fields_too_large'), - 444: ('no_response', 'none'), - 449: ('retry_with', 'retry'), - 450: ('blocked_by_windows_parental_controls', 'parental_controls'), - 451: ('unavailable_for_legal_reasons', 'legal_reasons'), - 499: ('client_closed_request',), - - # Server Error. - 500: ('internal_server_error', 'server_error', '/o\\', '✗'), - 501: ('not_implemented',), - 502: ('bad_gateway',), - 503: ('service_unavailable', 'unavailable'), - 504: ('gateway_timeout',), - 505: ('http_version_not_supported', 'http_version'), - 506: ('variant_also_negotiates',), - 507: ('insufficient_storage',), - 509: ('bandwidth_limit_exceeded', 'bandwidth'), - 510: ('not_extended',), - 511: ('network_authentication_required', 'network_auth', 'network_authentication'), -} - -codes = LookupDict(name='status_codes') - -def _init(): - for code, titles in _codes.items(): - for title in titles: - setattr(codes, title, code) - if not title.startswith(('\\', '/')): - setattr(codes, title.upper(), code) - - def doc(code): - names = ', '.join('``%s``' % n for n in _codes[code]) - return '* %d: %s' % (code, names) - - global __doc__ - __doc__ = (__doc__ + '\n' + - '\n'.join(doc(code) for code in sorted(_codes)) - if __doc__ is not None else None) - -_init() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/structures.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/structures.py deleted file mode 100644 index da930e2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/structures.py +++ /dev/null @@ -1,103 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.structures -~~~~~~~~~~~~~~~~~~~ - -Data structures that power Requests. -""" - -from .compat import OrderedDict, Mapping, MutableMapping - - -class CaseInsensitiveDict(MutableMapping): - """A case-insensitive ``dict``-like object. - - Implements all methods and operations of - ``MutableMapping`` as well as dict's ``copy``. Also - provides ``lower_items``. - - All keys are expected to be strings. The structure remembers the - case of the last key to be set, and ``iter(instance)``, - ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` - will contain case-sensitive keys. However, querying and contains - testing is case insensitive:: - - cid = CaseInsensitiveDict() - cid['Accept'] = 'application/json' - cid['aCCEPT'] == 'application/json' # True - list(cid) == ['Accept'] # True - - For example, ``headers['content-encoding']`` will return the - value of a ``'Content-Encoding'`` response header, regardless - of how the header name was originally stored. - - If the constructor, ``.update``, or equality comparison - operations are given keys that have equal ``.lower()``s, the - behavior is undefined. - """ - - def __init__(self, data=None, **kwargs): - self._store = OrderedDict() - if data is None: - data = {} - self.update(data, **kwargs) - - def __setitem__(self, key, value): - # Use the lowercased key for lookups, but store the actual - # key alongside the value. - self._store[key.lower()] = (key, value) - - def __getitem__(self, key): - return self._store[key.lower()][1] - - def __delitem__(self, key): - del self._store[key.lower()] - - def __iter__(self): - return (casedkey for casedkey, mappedvalue in self._store.values()) - - def __len__(self): - return len(self._store) - - def lower_items(self): - """Like iteritems(), but with all lowercase keys.""" - return ( - (lowerkey, keyval[1]) - for (lowerkey, keyval) - in self._store.items() - ) - - def __eq__(self, other): - if isinstance(other, Mapping): - other = CaseInsensitiveDict(other) - else: - return NotImplemented - # Compare insensitively - return dict(self.lower_items()) == dict(other.lower_items()) - - # Copy is required - def copy(self): - return CaseInsensitiveDict(self._store.values()) - - def __repr__(self): - return str(dict(self.items())) - - -class LookupDict(dict): - """Dictionary lookup object.""" - - def __init__(self, name=None): - self.name = name - super(LookupDict, self).__init__() - - def __repr__(self): - return '<lookup \'%s\'>' % (self.name) - - def __getitem__(self, key): - # We allow fall-through here, so values default to None - - return self.__dict__.get(key, None) - - def get(self, key, default=None): - return self.__dict__.get(key, default) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/utils.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/utils.py deleted file mode 100644 index 8170a8d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/requests/utils.py +++ /dev/null @@ -1,977 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -requests.utils -~~~~~~~~~~~~~~ - -This module provides utility functions that are used within Requests -that are also useful for external consumption. -""" - -import codecs -import contextlib -import io -import os -import re -import socket -import struct -import sys -import tempfile -import warnings -import zipfile - -from .__version__ import __version__ -from . import certs -# to_native_string is unused here, but imported here for backwards compatibility -from ._internal_utils import to_native_string -from .compat import parse_http_list as _parse_list_header -from .compat import ( - quote, urlparse, bytes, str, OrderedDict, unquote, getproxies, - proxy_bypass, urlunparse, basestring, integer_types, is_py3, - proxy_bypass_environment, getproxies_environment, Mapping) -from .cookies import cookiejar_from_dict -from .structures import CaseInsensitiveDict -from .exceptions import ( - InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError) - -NETRC_FILES = ('.netrc', '_netrc') - -DEFAULT_CA_BUNDLE_PATH = certs.where() - -DEFAULT_PORTS = {'http': 80, 'https': 443} - - -if sys.platform == 'win32': - # provide a proxy_bypass version on Windows without DNS lookups - - def proxy_bypass_registry(host): - try: - if is_py3: - import winreg - else: - import _winreg as winreg - except ImportError: - return False - - try: - internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, - r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') - # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it - proxyEnable = int(winreg.QueryValueEx(internetSettings, - 'ProxyEnable')[0]) - # ProxyOverride is almost always a string - proxyOverride = winreg.QueryValueEx(internetSettings, - 'ProxyOverride')[0] - except OSError: - return False - if not proxyEnable or not proxyOverride: - return False - - # make a check value list from the registry entry: replace the - # '<local>' string by the localhost entry and the corresponding - # canonical entry. - proxyOverride = proxyOverride.split(';') - # now check if we match one of the registry values. - for test in proxyOverride: - if test == '<local>': - if '.' not in host: - return True - test = test.replace(".", r"\.") # mask dots - test = test.replace("*", r".*") # change glob sequence - test = test.replace("?", r".") # change glob char - if re.match(test, host, re.I): - return True - return False - - def proxy_bypass(host): # noqa - """Return True, if the host should be bypassed. - - Checks proxy settings gathered from the environment, if specified, - or the registry. - """ - if getproxies_environment(): - return proxy_bypass_environment(host) - else: - return proxy_bypass_registry(host) - - -def dict_to_sequence(d): - """Returns an internal sequence dictionary update.""" - - if hasattr(d, 'items'): - d = d.items() - - return d - - -def super_len(o): - total_length = None - current_position = 0 - - if hasattr(o, '__len__'): - total_length = len(o) - - elif hasattr(o, 'len'): - total_length = o.len - - elif hasattr(o, 'fileno'): - try: - fileno = o.fileno() - except io.UnsupportedOperation: - pass - else: - total_length = os.fstat(fileno).st_size - - # Having used fstat to determine the file length, we need to - # confirm that this file was opened up in binary mode. - if 'b' not in o.mode: - warnings.warn(( - "Requests has determined the content-length for this " - "request using the binary size of the file: however, the " - "file has been opened in text mode (i.e. without the 'b' " - "flag in the mode). This may lead to an incorrect " - "content-length. In Requests 3.0, support will be removed " - "for files in text mode."), - FileModeWarning - ) - - if hasattr(o, 'tell'): - try: - current_position = o.tell() - except (OSError, IOError): - # This can happen in some weird situations, such as when the file - # is actually a special file descriptor like stdin. In this - # instance, we don't know what the length is, so set it to zero and - # let requests chunk it instead. - if total_length is not None: - current_position = total_length - else: - if hasattr(o, 'seek') and total_length is None: - # StringIO and BytesIO have seek but no useable fileno - try: - # seek to end of file - o.seek(0, 2) - total_length = o.tell() - - # seek back to current position to support - # partially read file-like objects - o.seek(current_position or 0) - except (OSError, IOError): - total_length = 0 - - if total_length is None: - total_length = 0 - - return max(0, total_length - current_position) - - -def get_netrc_auth(url, raise_errors=False): - """Returns the Requests tuple auth for a given url from netrc.""" - - try: - from netrc import netrc, NetrcParseError - - netrc_path = None - - for f in NETRC_FILES: - try: - loc = os.path.expanduser('~/{}'.format(f)) - except KeyError: - # os.path.expanduser can fail when $HOME is undefined and - # getpwuid fails. See https://bugs.python.org/issue20164 & - # https://github.com/requests/requests/issues/1846 - return - - if os.path.exists(loc): - netrc_path = loc - break - - # Abort early if there isn't one. - if netrc_path is None: - return - - ri = urlparse(url) - - # Strip port numbers from netloc. This weird `if...encode`` dance is - # used for Python 3.2, which doesn't support unicode literals. - splitstr = b':' - if isinstance(url, str): - splitstr = splitstr.decode('ascii') - host = ri.netloc.split(splitstr)[0] - - try: - _netrc = netrc(netrc_path).authenticators(host) - if _netrc: - # Return with login / password - login_i = (0 if _netrc[0] else 1) - return (_netrc[login_i], _netrc[2]) - except (NetrcParseError, IOError): - # If there was a parsing error or a permissions issue reading the file, - # we'll just skip netrc auth unless explicitly asked to raise errors. - if raise_errors: - raise - - # AppEngine hackiness. - except (ImportError, AttributeError): - pass - - -def guess_filename(obj): - """Tries to guess the filename of the given object.""" - name = getattr(obj, 'name', None) - if (name and isinstance(name, basestring) and name[0] != '<' and - name[-1] != '>'): - return os.path.basename(name) - - -def extract_zipped_paths(path): - """Replace nonexistent paths that look like they refer to a member of a zip - archive with the location of an extracted copy of the target, or else - just return the provided path unchanged. - """ - if os.path.exists(path): - # this is already a valid path, no need to do anything further - return path - - # find the first valid part of the provided path and treat that as a zip archive - # assume the rest of the path is the name of a member in the archive - archive, member = os.path.split(path) - while archive and not os.path.exists(archive): - archive, prefix = os.path.split(archive) - member = '/'.join([prefix, member]) - - if not zipfile.is_zipfile(archive): - return path - - zip_file = zipfile.ZipFile(archive) - if member not in zip_file.namelist(): - return path - - # we have a valid zip archive and a valid member of that archive - tmp = tempfile.gettempdir() - extracted_path = os.path.join(tmp, *member.split('/')) - if not os.path.exists(extracted_path): - extracted_path = zip_file.extract(member, path=tmp) - - return extracted_path - - -def from_key_val_list(value): - """Take an object and test to see if it can be represented as a - dictionary. Unless it can not be represented as such, return an - OrderedDict, e.g., - - :: - - >>> from_key_val_list([('key', 'val')]) - OrderedDict([('key', 'val')]) - >>> from_key_val_list('string') - ValueError: cannot encode objects that are not 2-tuples - >>> from_key_val_list({'key': 'val'}) - OrderedDict([('key', 'val')]) - - :rtype: OrderedDict - """ - if value is None: - return None - - if isinstance(value, (str, bytes, bool, int)): - raise ValueError('cannot encode objects that are not 2-tuples') - - return OrderedDict(value) - - -def to_key_val_list(value): - """Take an object and test to see if it can be represented as a - dictionary. If it can be, return a list of tuples, e.g., - - :: - - >>> to_key_val_list([('key', 'val')]) - [('key', 'val')] - >>> to_key_val_list({'key': 'val'}) - [('key', 'val')] - >>> to_key_val_list('string') - ValueError: cannot encode objects that are not 2-tuples. - - :rtype: list - """ - if value is None: - return None - - if isinstance(value, (str, bytes, bool, int)): - raise ValueError('cannot encode objects that are not 2-tuples') - - if isinstance(value, Mapping): - value = value.items() - - return list(value) - - -# From mitsuhiko/werkzeug (used with permission). -def parse_list_header(value): - """Parse lists as described by RFC 2068 Section 2. - - In particular, parse comma-separated lists where the elements of - the list may include quoted-strings. A quoted-string could - contain a comma. A non-quoted string could have quotes in the - middle. Quotes are removed automatically after parsing. - - It basically works like :func:`parse_set_header` just that items - may appear multiple times and case sensitivity is preserved. - - The return value is a standard :class:`list`: - - >>> parse_list_header('token, "quoted value"') - ['token', 'quoted value'] - - To create a header from the :class:`list` again, use the - :func:`dump_header` function. - - :param value: a string with a list header. - :return: :class:`list` - :rtype: list - """ - result = [] - for item in _parse_list_header(value): - if item[:1] == item[-1:] == '"': - item = unquote_header_value(item[1:-1]) - result.append(item) - return result - - -# From mitsuhiko/werkzeug (used with permission). -def parse_dict_header(value): - """Parse lists of key, value pairs as described by RFC 2068 Section 2 and - convert them into a python dict: - - >>> d = parse_dict_header('foo="is a fish", bar="as well"') - >>> type(d) is dict - True - >>> sorted(d.items()) - [('bar', 'as well'), ('foo', 'is a fish')] - - If there is no value for a key it will be `None`: - - >>> parse_dict_header('key_without_value') - {'key_without_value': None} - - To create a header from the :class:`dict` again, use the - :func:`dump_header` function. - - :param value: a string with a dict header. - :return: :class:`dict` - :rtype: dict - """ - result = {} - for item in _parse_list_header(value): - if '=' not in item: - result[item] = None - continue - name, value = item.split('=', 1) - if value[:1] == value[-1:] == '"': - value = unquote_header_value(value[1:-1]) - result[name] = value - return result - - -# From mitsuhiko/werkzeug (used with permission). -def unquote_header_value(value, is_filename=False): - r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). - This does not use the real unquoting but what browsers are actually - using for quoting. - - :param value: the header value to unquote. - :rtype: str - """ - if value and value[0] == value[-1] == '"': - # this is not the real unquoting, but fixing this so that the - # RFC is met will result in bugs with internet explorer and - # probably some other browsers as well. IE for example is - # uploading files with "C:\foo\bar.txt" as filename - value = value[1:-1] - - # if this is a filename and the starting characters look like - # a UNC path, then just return the value without quotes. Using the - # replace sequence below on a UNC path has the effect of turning - # the leading double slash into a single slash and then - # _fix_ie_filename() doesn't work correctly. See #458. - if not is_filename or value[:2] != '\\\\': - return value.replace('\\\\', '\\').replace('\\"', '"') - return value - - -def dict_from_cookiejar(cj): - """Returns a key/value dictionary from a CookieJar. - - :param cj: CookieJar object to extract cookies from. - :rtype: dict - """ - - cookie_dict = {} - - for cookie in cj: - cookie_dict[cookie.name] = cookie.value - - return cookie_dict - - -def add_dict_to_cookiejar(cj, cookie_dict): - """Returns a CookieJar from a key/value dictionary. - - :param cj: CookieJar to insert cookies into. - :param cookie_dict: Dict of key/values to insert into CookieJar. - :rtype: CookieJar - """ - - return cookiejar_from_dict(cookie_dict, cj) - - -def get_encodings_from_content(content): - """Returns encodings from given content string. - - :param content: bytestring to extract encodings from. - """ - warnings.warn(( - 'In requests 3.0, get_encodings_from_content will be removed. For ' - 'more information, please see the discussion on issue #2266. (This' - ' warning should only appear once.)'), - DeprecationWarning) - - charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I) - pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I) - xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') - - return (charset_re.findall(content) + - pragma_re.findall(content) + - xml_re.findall(content)) - - -def _parse_content_type_header(header): - """Returns content type and parameters from given header - - :param header: string - :return: tuple containing content type and dictionary of - parameters - """ - - tokens = header.split(';') - content_type, params = tokens[0].strip(), tokens[1:] - params_dict = {} - items_to_strip = "\"' " - - for param in params: - param = param.strip() - if param: - key, value = param, True - index_of_equals = param.find("=") - if index_of_equals != -1: - key = param[:index_of_equals].strip(items_to_strip) - value = param[index_of_equals + 1:].strip(items_to_strip) - params_dict[key.lower()] = value - return content_type, params_dict - - -def get_encoding_from_headers(headers): - """Returns encodings from given HTTP Header Dict. - - :param headers: dictionary to extract encoding from. - :rtype: str - """ - - content_type = headers.get('content-type') - - if not content_type: - return None - - content_type, params = _parse_content_type_header(content_type) - - if 'charset' in params: - return params['charset'].strip("'\"") - - if 'text' in content_type: - return 'ISO-8859-1' - - -def stream_decode_response_unicode(iterator, r): - """Stream decodes a iterator.""" - - if r.encoding is None: - for item in iterator: - yield item - return - - decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace') - for chunk in iterator: - rv = decoder.decode(chunk) - if rv: - yield rv - rv = decoder.decode(b'', final=True) - if rv: - yield rv - - -def iter_slices(string, slice_length): - """Iterate over slices of a string.""" - pos = 0 - if slice_length is None or slice_length <= 0: - slice_length = len(string) - while pos < len(string): - yield string[pos:pos + slice_length] - pos += slice_length - - -def get_unicode_from_response(r): - """Returns the requested content back in unicode. - - :param r: Response object to get unicode content from. - - Tried: - - 1. charset from content-type - 2. fall back and replace all unicode characters - - :rtype: str - """ - warnings.warn(( - 'In requests 3.0, get_unicode_from_response will be removed. For ' - 'more information, please see the discussion on issue #2266. (This' - ' warning should only appear once.)'), - DeprecationWarning) - - tried_encodings = [] - - # Try charset from content-type - encoding = get_encoding_from_headers(r.headers) - - if encoding: - try: - return str(r.content, encoding) - except UnicodeError: - tried_encodings.append(encoding) - - # Fall back: - try: - return str(r.content, encoding, errors='replace') - except TypeError: - return r.content - - -# The unreserved URI characters (RFC 3986) -UNRESERVED_SET = frozenset( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") - - -def unquote_unreserved(uri): - """Un-escape any percent-escape sequences in a URI that are unreserved - characters. This leaves all reserved, illegal and non-ASCII bytes encoded. - - :rtype: str - """ - parts = uri.split('%') - for i in range(1, len(parts)): - h = parts[i][0:2] - if len(h) == 2 and h.isalnum(): - try: - c = chr(int(h, 16)) - except ValueError: - raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) - - if c in UNRESERVED_SET: - parts[i] = c + parts[i][2:] - else: - parts[i] = '%' + parts[i] - else: - parts[i] = '%' + parts[i] - return ''.join(parts) - - -def requote_uri(uri): - """Re-quote the given URI. - - This function passes the given URI through an unquote/quote cycle to - ensure that it is fully and consistently quoted. - - :rtype: str - """ - safe_with_percent = "!#$%&'()*+,/:;=?@[]~" - safe_without_percent = "!#$&'()*+,/:;=?@[]~" - try: - # Unquote only the unreserved characters - # Then quote only illegal characters (do not quote reserved, - # unreserved, or '%') - return quote(unquote_unreserved(uri), safe=safe_with_percent) - except InvalidURL: - # We couldn't unquote the given URI, so let's try quoting it, but - # there may be unquoted '%'s in the URI. We need to make sure they're - # properly quoted so they do not cause issues elsewhere. - return quote(uri, safe=safe_without_percent) - - -def address_in_network(ip, net): - """This function allows you to check if an IP belongs to a network subnet - - Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 - returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 - - :rtype: bool - """ - ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0] - netaddr, bits = net.split('/') - netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0] - network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask - return (ipaddr & netmask) == (network & netmask) - - -def dotted_netmask(mask): - """Converts mask from /xx format to xxx.xxx.xxx.xxx - - Example: if mask is 24 function returns 255.255.255.0 - - :rtype: str - """ - bits = 0xffffffff ^ (1 << 32 - mask) - 1 - return socket.inet_ntoa(struct.pack('>I', bits)) - - -def is_ipv4_address(string_ip): - """ - :rtype: bool - """ - try: - socket.inet_aton(string_ip) - except socket.error: - return False - return True - - -def is_valid_cidr(string_network): - """ - Very simple check of the cidr format in no_proxy variable. - - :rtype: bool - """ - if string_network.count('/') == 1: - try: - mask = int(string_network.split('/')[1]) - except ValueError: - return False - - if mask < 1 or mask > 32: - return False - - try: - socket.inet_aton(string_network.split('/')[0]) - except socket.error: - return False - else: - return False - return True - - -@contextlib.contextmanager -def set_environ(env_name, value): - """Set the environment variable 'env_name' to 'value' - - Save previous value, yield, and then restore the previous value stored in - the environment variable 'env_name'. - - If 'value' is None, do nothing""" - value_changed = value is not None - if value_changed: - old_value = os.environ.get(env_name) - os.environ[env_name] = value - try: - yield - finally: - if value_changed: - if old_value is None: - del os.environ[env_name] - else: - os.environ[env_name] = old_value - - -def should_bypass_proxies(url, no_proxy): - """ - Returns whether we should bypass proxies or not. - - :rtype: bool - """ - # Prioritize lowercase environment variables over uppercase - # to keep a consistent behaviour with other http projects (curl, wget). - get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) - - # First check whether no_proxy is defined. If it is, check that the URL - # we're getting isn't in the no_proxy list. - no_proxy_arg = no_proxy - if no_proxy is None: - no_proxy = get_proxy('no_proxy') - parsed = urlparse(url) - - if parsed.hostname is None: - # URLs don't always have hostnames, e.g. file:/// urls. - return True - - if no_proxy: - # We need to check whether we match here. We need to see if we match - # the end of the hostname, both with and without the port. - no_proxy = ( - host for host in no_proxy.replace(' ', '').split(',') if host - ) - - if is_ipv4_address(parsed.hostname): - for proxy_ip in no_proxy: - if is_valid_cidr(proxy_ip): - if address_in_network(parsed.hostname, proxy_ip): - return True - elif parsed.hostname == proxy_ip: - # If no_proxy ip was defined in plain IP notation instead of cidr notation & - # matches the IP of the index - return True - else: - host_with_port = parsed.hostname - if parsed.port: - host_with_port += ':{}'.format(parsed.port) - - for host in no_proxy: - if parsed.hostname.endswith(host) or host_with_port.endswith(host): - # The URL does match something in no_proxy, so we don't want - # to apply the proxies on this URL. - return True - - with set_environ('no_proxy', no_proxy_arg): - # parsed.hostname can be `None` in cases such as a file URI. - try: - bypass = proxy_bypass(parsed.hostname) - except (TypeError, socket.gaierror): - bypass = False - - if bypass: - return True - - return False - - -def get_environ_proxies(url, no_proxy=None): - """ - Return a dict of environment proxies. - - :rtype: dict - """ - if should_bypass_proxies(url, no_proxy=no_proxy): - return {} - else: - return getproxies() - - -def select_proxy(url, proxies): - """Select a proxy for the url, if applicable. - - :param url: The url being for the request - :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs - """ - proxies = proxies or {} - urlparts = urlparse(url) - if urlparts.hostname is None: - return proxies.get(urlparts.scheme, proxies.get('all')) - - proxy_keys = [ - urlparts.scheme + '://' + urlparts.hostname, - urlparts.scheme, - 'all://' + urlparts.hostname, - 'all', - ] - proxy = None - for proxy_key in proxy_keys: - if proxy_key in proxies: - proxy = proxies[proxy_key] - break - - return proxy - - -def default_user_agent(name="python-requests"): - """ - Return a string representing the default user agent. - - :rtype: str - """ - return '%s/%s' % (name, __version__) - - -def default_headers(): - """ - :rtype: requests.structures.CaseInsensitiveDict - """ - return CaseInsensitiveDict({ - 'User-Agent': default_user_agent(), - 'Accept-Encoding': ', '.join(('gzip', 'deflate')), - 'Accept': '*/*', - 'Connection': 'keep-alive', - }) - - -def parse_header_links(value): - """Return a list of parsed link headers proxies. - - i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg" - - :rtype: list - """ - - links = [] - - replace_chars = ' \'"' - - value = value.strip(replace_chars) - if not value: - return links - - for val in re.split(', *<', value): - try: - url, params = val.split(';', 1) - except ValueError: - url, params = val, '' - - link = {'url': url.strip('<> \'"')} - - for param in params.split(';'): - try: - key, value = param.split('=') - except ValueError: - break - - link[key.strip(replace_chars)] = value.strip(replace_chars) - - links.append(link) - - return links - - -# Null bytes; no need to recreate these on each call to guess_json_utf -_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3 -_null2 = _null * 2 -_null3 = _null * 3 - - -def guess_json_utf(data): - """ - :rtype: str - """ - # JSON always starts with two ASCII characters, so detection is as - # easy as counting the nulls and from their location and count - # determine the encoding. Also detect a BOM, if present. - sample = data[:4] - if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): - return 'utf-32' # BOM included - if sample[:3] == codecs.BOM_UTF8: - return 'utf-8-sig' # BOM included, MS style (discouraged) - if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): - return 'utf-16' # BOM included - nullcount = sample.count(_null) - if nullcount == 0: - return 'utf-8' - if nullcount == 2: - if sample[::2] == _null2: # 1st and 3rd are null - return 'utf-16-be' - if sample[1::2] == _null2: # 2nd and 4th are null - return 'utf-16-le' - # Did not detect 2 valid UTF-16 ascii-range characters - if nullcount == 3: - if sample[:3] == _null3: - return 'utf-32-be' - if sample[1:] == _null3: - return 'utf-32-le' - # Did not detect a valid UTF-32 ascii-range character - return None - - -def prepend_scheme_if_needed(url, new_scheme): - """Given a URL that may or may not have a scheme, prepend the given scheme. - Does not replace a present scheme with the one provided as an argument. - - :rtype: str - """ - scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) - - # urlparse is a finicky beast, and sometimes decides that there isn't a - # netloc present. Assume that it's being over-cautious, and switch netloc - # and path if urlparse decided there was no netloc. - if not netloc: - netloc, path = path, netloc - - return urlunparse((scheme, netloc, path, params, query, fragment)) - - -def get_auth_from_url(url): - """Given a url with authentication components, extract them into a tuple of - username,password. - - :rtype: (str,str) - """ - parsed = urlparse(url) - - try: - auth = (unquote(parsed.username), unquote(parsed.password)) - except (AttributeError, TypeError): - auth = ('', '') - - return auth - - -# Moved outside of function to avoid recompile every call -_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$') -_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$') - - -def check_header_validity(header): - """Verifies that header value is a string which doesn't contain - leading whitespace or return characters. This prevents unintended - header injection. - - :param header: tuple, in the format (name, value). - """ - name, value = header - - if isinstance(value, bytes): - pat = _CLEAN_HEADER_REGEX_BYTE - else: - pat = _CLEAN_HEADER_REGEX_STR - try: - if not pat.match(value): - raise InvalidHeader("Invalid return character or leading space in header: %s" % name) - except TypeError: - raise InvalidHeader("Value for header {%s: %s} must be of type str or " - "bytes, not %s" % (name, value, type(value))) - - -def urldefragauth(url): - """ - Given a url remove the fragment and the authentication part. - - :rtype: str - """ - scheme, netloc, path, params, query, fragment = urlparse(url) - - # see func:`prepend_scheme_if_needed` - if not netloc: - netloc, path = path, netloc - - netloc = netloc.rsplit('@', 1)[-1] - - return urlunparse((scheme, netloc, path, params, query, '')) - - -def rewind_body(prepared_request): - """Move file pointer back to its recorded starting position - so it can be read again on redirect. - """ - body_seek = getattr(prepared_request.body, 'seek', None) - if body_seek is not None and isinstance(prepared_request._body_position, integer_types): - try: - body_seek(prepared_request._body_position) - except (IOError, OSError): - raise UnrewindableBodyError("An error occurred when rewinding request " - "body for redirect.") - else: - raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/retrying.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/retrying.py deleted file mode 100644 index 6d1e627..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/retrying.py +++ /dev/null @@ -1,267 +0,0 @@ -## Copyright 2013-2014 Ray Holder -## -## 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 random -from pip._vendor import six -import sys -import time -import traceback - - -# sys.maxint / 2, since Python 3.2 doesn't have a sys.maxint... -MAX_WAIT = 1073741823 - - -def retry(*dargs, **dkw): - """ - Decorator function that instantiates the Retrying object - @param *dargs: positional arguments passed to Retrying object - @param **dkw: keyword arguments passed to the Retrying object - """ - # support both @retry and @retry() as valid syntax - if len(dargs) == 1 and callable(dargs[0]): - def wrap_simple(f): - - @six.wraps(f) - def wrapped_f(*args, **kw): - return Retrying().call(f, *args, **kw) - - return wrapped_f - - return wrap_simple(dargs[0]) - - else: - def wrap(f): - - @six.wraps(f) - def wrapped_f(*args, **kw): - return Retrying(*dargs, **dkw).call(f, *args, **kw) - - return wrapped_f - - return wrap - - -class Retrying(object): - - def __init__(self, - stop=None, wait=None, - stop_max_attempt_number=None, - stop_max_delay=None, - wait_fixed=None, - wait_random_min=None, wait_random_max=None, - wait_incrementing_start=None, wait_incrementing_increment=None, - wait_exponential_multiplier=None, wait_exponential_max=None, - retry_on_exception=None, - retry_on_result=None, - wrap_exception=False, - stop_func=None, - wait_func=None, - wait_jitter_max=None): - - self._stop_max_attempt_number = 5 if stop_max_attempt_number is None else stop_max_attempt_number - self._stop_max_delay = 100 if stop_max_delay is None else stop_max_delay - self._wait_fixed = 1000 if wait_fixed is None else wait_fixed - self._wait_random_min = 0 if wait_random_min is None else wait_random_min - self._wait_random_max = 1000 if wait_random_max is None else wait_random_max - self._wait_incrementing_start = 0 if wait_incrementing_start is None else wait_incrementing_start - self._wait_incrementing_increment = 100 if wait_incrementing_increment is None else wait_incrementing_increment - self._wait_exponential_multiplier = 1 if wait_exponential_multiplier is None else wait_exponential_multiplier - self._wait_exponential_max = MAX_WAIT if wait_exponential_max is None else wait_exponential_max - self._wait_jitter_max = 0 if wait_jitter_max is None else wait_jitter_max - - # TODO add chaining of stop behaviors - # stop behavior - stop_funcs = [] - if stop_max_attempt_number is not None: - stop_funcs.append(self.stop_after_attempt) - - if stop_max_delay is not None: - stop_funcs.append(self.stop_after_delay) - - if stop_func is not None: - self.stop = stop_func - - elif stop is None: - self.stop = lambda attempts, delay: any(f(attempts, delay) for f in stop_funcs) - - else: - self.stop = getattr(self, stop) - - # TODO add chaining of wait behaviors - # wait behavior - wait_funcs = [lambda *args, **kwargs: 0] - if wait_fixed is not None: - wait_funcs.append(self.fixed_sleep) - - if wait_random_min is not None or wait_random_max is not None: - wait_funcs.append(self.random_sleep) - - if wait_incrementing_start is not None or wait_incrementing_increment is not None: - wait_funcs.append(self.incrementing_sleep) - - if wait_exponential_multiplier is not None or wait_exponential_max is not None: - wait_funcs.append(self.exponential_sleep) - - if wait_func is not None: - self.wait = wait_func - - elif wait is None: - self.wait = lambda attempts, delay: max(f(attempts, delay) for f in wait_funcs) - - else: - self.wait = getattr(self, wait) - - # retry on exception filter - if retry_on_exception is None: - self._retry_on_exception = self.always_reject - else: - self._retry_on_exception = retry_on_exception - - # TODO simplify retrying by Exception types - # retry on result filter - if retry_on_result is None: - self._retry_on_result = self.never_reject - else: - self._retry_on_result = retry_on_result - - self._wrap_exception = wrap_exception - - def stop_after_attempt(self, previous_attempt_number, delay_since_first_attempt_ms): - """Stop after the previous attempt >= stop_max_attempt_number.""" - return previous_attempt_number >= self._stop_max_attempt_number - - def stop_after_delay(self, previous_attempt_number, delay_since_first_attempt_ms): - """Stop after the time from the first attempt >= stop_max_delay.""" - return delay_since_first_attempt_ms >= self._stop_max_delay - - def no_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): - """Don't sleep at all before retrying.""" - return 0 - - def fixed_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): - """Sleep a fixed amount of time between each retry.""" - return self._wait_fixed - - def random_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): - """Sleep a random amount of time between wait_random_min and wait_random_max""" - return random.randint(self._wait_random_min, self._wait_random_max) - - def incrementing_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): - """ - Sleep an incremental amount of time after each attempt, starting at - wait_incrementing_start and incrementing by wait_incrementing_increment - """ - result = self._wait_incrementing_start + (self._wait_incrementing_increment * (previous_attempt_number - 1)) - if result < 0: - result = 0 - return result - - def exponential_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): - exp = 2 ** previous_attempt_number - result = self._wait_exponential_multiplier * exp - if result > self._wait_exponential_max: - result = self._wait_exponential_max - if result < 0: - result = 0 - return result - - def never_reject(self, result): - return False - - def always_reject(self, result): - return True - - def should_reject(self, attempt): - reject = False - if attempt.has_exception: - reject |= self._retry_on_exception(attempt.value[1]) - else: - reject |= self._retry_on_result(attempt.value) - - return reject - - def call(self, fn, *args, **kwargs): - start_time = int(round(time.time() * 1000)) - attempt_number = 1 - while True: - try: - attempt = Attempt(fn(*args, **kwargs), attempt_number, False) - except: - tb = sys.exc_info() - attempt = Attempt(tb, attempt_number, True) - - if not self.should_reject(attempt): - return attempt.get(self._wrap_exception) - - delay_since_first_attempt_ms = int(round(time.time() * 1000)) - start_time - if self.stop(attempt_number, delay_since_first_attempt_ms): - if not self._wrap_exception and attempt.has_exception: - # get() on an attempt with an exception should cause it to be raised, but raise just in case - raise attempt.get() - else: - raise RetryError(attempt) - else: - sleep = self.wait(attempt_number, delay_since_first_attempt_ms) - if self._wait_jitter_max: - jitter = random.random() * self._wait_jitter_max - sleep = sleep + max(0, jitter) - time.sleep(sleep / 1000.0) - - attempt_number += 1 - - -class Attempt(object): - """ - An Attempt encapsulates a call to a target function that may end as a - normal return value from the function or an Exception depending on what - occurred during the execution. - """ - - def __init__(self, value, attempt_number, has_exception): - self.value = value - self.attempt_number = attempt_number - self.has_exception = has_exception - - def get(self, wrap_exception=False): - """ - Return the return value of this Attempt instance or raise an Exception. - If wrap_exception is true, this Attempt is wrapped inside of a - RetryError before being raised. - """ - if self.has_exception: - if wrap_exception: - raise RetryError(self) - else: - six.reraise(self.value[0], self.value[1], self.value[2]) - else: - return self.value - - def __repr__(self): - if self.has_exception: - return "Attempts: {0}, Error:\n{1}".format(self.attempt_number, "".join(traceback.format_tb(self.value[2]))) - else: - return "Attempts: {0}, Value: {1}".format(self.attempt_number, self.value) - - -class RetryError(Exception): - """ - A RetryError encapsulates the last Attempt instance right before giving up. - """ - - def __init__(self, last_attempt): - self.last_attempt = last_attempt - - def __str__(self): - return "RetryError[{0}]".format(self.last_attempt) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/six.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/six.py deleted file mode 100644 index 89b2188..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/six.py +++ /dev/null @@ -1,952 +0,0 @@ -# Copyright (c) 2010-2018 Benjamin Peterson -# -# 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. - -"""Utilities for writing code that runs on Python 2 and 3""" - -from __future__ import absolute_import - -import functools -import itertools -import operator -import sys -import types - -__author__ = "Benjamin Peterson <benjamin@python.org>" -__version__ = "1.12.0" - - -# Useful for very coarse version differentiation. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -PY34 = sys.version_info[0:2] >= (3, 4) - -if PY3: - string_types = str, - integer_types = int, - class_types = type, - text_type = str - binary_type = bytes - - MAXSIZE = sys.maxsize -else: - string_types = basestring, - integer_types = (int, long) - class_types = (type, types.ClassType) - text_type = unicode - binary_type = str - - if sys.platform.startswith("java"): - # Jython always uses 32 bits. - MAXSIZE = int((1 << 31) - 1) - else: - # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): - - def __len__(self): - return 1 << 31 - try: - len(X()) - except OverflowError: - # 32-bit - MAXSIZE = int((1 << 31) - 1) - else: - # 64-bit - MAXSIZE = int((1 << 63) - 1) - del X - - -def _add_doc(func, doc): - """Add documentation to a function.""" - func.__doc__ = doc - - -def _import_module(name): - """Import module, returning the module after the last dot.""" - __import__(name) - return sys.modules[name] - - -class _LazyDescr(object): - - def __init__(self, name): - self.name = name - - def __get__(self, obj, tp): - result = self._resolve() - setattr(obj, self.name, result) # Invokes __set__. - try: - # This is a bit ugly, but it avoids running this again by - # removing this descriptor. - delattr(obj.__class__, self.name) - except AttributeError: - pass - return result - - -class MovedModule(_LazyDescr): - - def __init__(self, name, old, new=None): - super(MovedModule, self).__init__(name) - if PY3: - if new is None: - new = name - self.mod = new - else: - self.mod = old - - def _resolve(self): - return _import_module(self.mod) - - def __getattr__(self, attr): - _module = self._resolve() - value = getattr(_module, attr) - setattr(self, attr, value) - return value - - -class _LazyModule(types.ModuleType): - - def __init__(self, name): - super(_LazyModule, self).__init__(name) - self.__doc__ = self.__class__.__doc__ - - def __dir__(self): - attrs = ["__doc__", "__name__"] - attrs += [attr.name for attr in self._moved_attributes] - return attrs - - # Subclasses should override this - _moved_attributes = [] - - -class MovedAttribute(_LazyDescr): - - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): - super(MovedAttribute, self).__init__(name) - if PY3: - if new_mod is None: - new_mod = name - self.mod = new_mod - if new_attr is None: - if old_attr is None: - new_attr = name - else: - new_attr = old_attr - self.attr = new_attr - else: - self.mod = old_mod - if old_attr is None: - old_attr = name - self.attr = old_attr - - def _resolve(self): - module = _import_module(self.mod) - return getattr(module, self.attr) - - -class _SixMetaPathImporter(object): - - """ - A meta path importer to import six.moves and its submodules. - - This class implements a PEP302 finder and loader. It should be compatible - with Python 2.5 and all existing versions of Python3 - """ - - def __init__(self, six_module_name): - self.name = six_module_name - self.known_modules = {} - - def _add_module(self, mod, *fullnames): - for fullname in fullnames: - self.known_modules[self.name + "." + fullname] = mod - - def _get_module(self, fullname): - return self.known_modules[self.name + "." + fullname] - - def find_module(self, fullname, path=None): - if fullname in self.known_modules: - return self - return None - - def __get_module(self, fullname): - try: - return self.known_modules[fullname] - except KeyError: - raise ImportError("This loader does not know module " + fullname) - - def load_module(self, fullname): - try: - # in case of a reload - return sys.modules[fullname] - except KeyError: - pass - mod = self.__get_module(fullname) - if isinstance(mod, MovedModule): - mod = mod._resolve() - else: - mod.__loader__ = self - sys.modules[fullname] = mod - return mod - - def is_package(self, fullname): - """ - Return true, if the named module is a package. - - We need this method to get correct spec objects with - Python 3.4 (see PEP451) - """ - return hasattr(self.__get_module(fullname), "__path__") - - def get_code(self, fullname): - """Return None - - Required, if is_package is implemented""" - self.__get_module(fullname) # eventually raises ImportError - return None - get_source = get_code # same as get_code - -_importer = _SixMetaPathImporter(__name__) - - -class _MovedItems(_LazyModule): - - """Lazy loading of moved objects""" - __path__ = [] # mark as package - - -_moved_attributes = [ - MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), - MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), - MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), - MovedAttribute("intern", "__builtin__", "sys"), - MovedAttribute("map", "itertools", "builtins", "imap", "map"), - MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), - MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), - MovedAttribute("getoutput", "commands", "subprocess"), - MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), - MovedAttribute("reduce", "__builtin__", "functools"), - MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), - MovedAttribute("StringIO", "StringIO", "io"), - MovedAttribute("UserDict", "UserDict", "collections"), - MovedAttribute("UserList", "UserList", "collections"), - MovedAttribute("UserString", "UserString", "collections"), - MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), - MovedModule("builtins", "__builtin__"), - MovedModule("configparser", "ConfigParser"), - MovedModule("copyreg", "copy_reg"), - MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), - MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), - MovedModule("http_cookies", "Cookie", "http.cookies"), - MovedModule("html_entities", "htmlentitydefs", "html.entities"), - MovedModule("html_parser", "HTMLParser", "html.parser"), - MovedModule("http_client", "httplib", "http.client"), - MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), - MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), - MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), - MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), - MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), - MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), - MovedModule("cPickle", "cPickle", "pickle"), - MovedModule("queue", "Queue"), - MovedModule("reprlib", "repr"), - MovedModule("socketserver", "SocketServer"), - MovedModule("_thread", "thread", "_thread"), - MovedModule("tkinter", "Tkinter"), - MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), - MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), - MovedModule("tkinter_tix", "Tix", "tkinter.tix"), - MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), - MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), - MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), - MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), - MovedModule("tkinter_font", "tkFont", "tkinter.font"), - MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), - MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), - MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), - MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), -] -# Add windows specific modules. -if sys.platform == "win32": - _moved_attributes += [ - MovedModule("winreg", "_winreg"), - ] - -for attr in _moved_attributes: - setattr(_MovedItems, attr.name, attr) - if isinstance(attr, MovedModule): - _importer._add_module(attr, "moves." + attr.name) -del attr - -_MovedItems._moved_attributes = _moved_attributes - -moves = _MovedItems(__name__ + ".moves") -_importer._add_module(moves, "moves") - - -class Module_six_moves_urllib_parse(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_parse""" - - -_urllib_parse_moved_attributes = [ - MovedAttribute("ParseResult", "urlparse", "urllib.parse"), - MovedAttribute("SplitResult", "urlparse", "urllib.parse"), - MovedAttribute("parse_qs", "urlparse", "urllib.parse"), - MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), - MovedAttribute("urldefrag", "urlparse", "urllib.parse"), - MovedAttribute("urljoin", "urlparse", "urllib.parse"), - MovedAttribute("urlparse", "urlparse", "urllib.parse"), - MovedAttribute("urlsplit", "urlparse", "urllib.parse"), - MovedAttribute("urlunparse", "urlparse", "urllib.parse"), - MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), - MovedAttribute("quote", "urllib", "urllib.parse"), - MovedAttribute("quote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote", "urllib", "urllib.parse"), - MovedAttribute("unquote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), - MovedAttribute("urlencode", "urllib", "urllib.parse"), - MovedAttribute("splitquery", "urllib", "urllib.parse"), - MovedAttribute("splittag", "urllib", "urllib.parse"), - MovedAttribute("splituser", "urllib", "urllib.parse"), - MovedAttribute("splitvalue", "urllib", "urllib.parse"), - MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), - MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), - MovedAttribute("uses_params", "urlparse", "urllib.parse"), - MovedAttribute("uses_query", "urlparse", "urllib.parse"), - MovedAttribute("uses_relative", "urlparse", "urllib.parse"), -] -for attr in _urllib_parse_moved_attributes: - setattr(Module_six_moves_urllib_parse, attr.name, attr) -del attr - -Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes - -_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), - "moves.urllib_parse", "moves.urllib.parse") - - -class Module_six_moves_urllib_error(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_error""" - - -_urllib_error_moved_attributes = [ - MovedAttribute("URLError", "urllib2", "urllib.error"), - MovedAttribute("HTTPError", "urllib2", "urllib.error"), - MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), -] -for attr in _urllib_error_moved_attributes: - setattr(Module_six_moves_urllib_error, attr.name, attr) -del attr - -Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes - -_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), - "moves.urllib_error", "moves.urllib.error") - - -class Module_six_moves_urllib_request(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_request""" - - -_urllib_request_moved_attributes = [ - MovedAttribute("urlopen", "urllib2", "urllib.request"), - MovedAttribute("install_opener", "urllib2", "urllib.request"), - MovedAttribute("build_opener", "urllib2", "urllib.request"), - MovedAttribute("pathname2url", "urllib", "urllib.request"), - MovedAttribute("url2pathname", "urllib", "urllib.request"), - MovedAttribute("getproxies", "urllib", "urllib.request"), - MovedAttribute("Request", "urllib2", "urllib.request"), - MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), - MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), - MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), - MovedAttribute("BaseHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), - MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), - MovedAttribute("FileHandler", "urllib2", "urllib.request"), - MovedAttribute("FTPHandler", "urllib2", "urllib.request"), - MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), - MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), - MovedAttribute("urlretrieve", "urllib", "urllib.request"), - MovedAttribute("urlcleanup", "urllib", "urllib.request"), - MovedAttribute("URLopener", "urllib", "urllib.request"), - MovedAttribute("FancyURLopener", "urllib", "urllib.request"), - MovedAttribute("proxy_bypass", "urllib", "urllib.request"), - MovedAttribute("parse_http_list", "urllib2", "urllib.request"), - MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), -] -for attr in _urllib_request_moved_attributes: - setattr(Module_six_moves_urllib_request, attr.name, attr) -del attr - -Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes - -_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), - "moves.urllib_request", "moves.urllib.request") - - -class Module_six_moves_urllib_response(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_response""" - - -_urllib_response_moved_attributes = [ - MovedAttribute("addbase", "urllib", "urllib.response"), - MovedAttribute("addclosehook", "urllib", "urllib.response"), - MovedAttribute("addinfo", "urllib", "urllib.response"), - MovedAttribute("addinfourl", "urllib", "urllib.response"), -] -for attr in _urllib_response_moved_attributes: - setattr(Module_six_moves_urllib_response, attr.name, attr) -del attr - -Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes - -_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), - "moves.urllib_response", "moves.urllib.response") - - -class Module_six_moves_urllib_robotparser(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_robotparser""" - - -_urllib_robotparser_moved_attributes = [ - MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), -] -for attr in _urllib_robotparser_moved_attributes: - setattr(Module_six_moves_urllib_robotparser, attr.name, attr) -del attr - -Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes - -_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), - "moves.urllib_robotparser", "moves.urllib.robotparser") - - -class Module_six_moves_urllib(types.ModuleType): - - """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" - __path__ = [] # mark as package - parse = _importer._get_module("moves.urllib_parse") - error = _importer._get_module("moves.urllib_error") - request = _importer._get_module("moves.urllib_request") - response = _importer._get_module("moves.urllib_response") - robotparser = _importer._get_module("moves.urllib_robotparser") - - def __dir__(self): - return ['parse', 'error', 'request', 'response', 'robotparser'] - -_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), - "moves.urllib") - - -def add_move(move): - """Add an item to six.moves.""" - setattr(_MovedItems, move.name, move) - - -def remove_move(name): - """Remove item from six.moves.""" - try: - delattr(_MovedItems, name) - except AttributeError: - try: - del moves.__dict__[name] - except KeyError: - raise AttributeError("no such move, %r" % (name,)) - - -if PY3: - _meth_func = "__func__" - _meth_self = "__self__" - - _func_closure = "__closure__" - _func_code = "__code__" - _func_defaults = "__defaults__" - _func_globals = "__globals__" -else: - _meth_func = "im_func" - _meth_self = "im_self" - - _func_closure = "func_closure" - _func_code = "func_code" - _func_defaults = "func_defaults" - _func_globals = "func_globals" - - -try: - advance_iterator = next -except NameError: - def advance_iterator(it): - return it.next() -next = advance_iterator - - -try: - callable = callable -except NameError: - def callable(obj): - return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) - - -if PY3: - def get_unbound_function(unbound): - return unbound - - create_bound_method = types.MethodType - - def create_unbound_method(func, cls): - return func - - Iterator = object -else: - def get_unbound_function(unbound): - return unbound.im_func - - def create_bound_method(func, obj): - return types.MethodType(func, obj, obj.__class__) - - def create_unbound_method(func, cls): - return types.MethodType(func, None, cls) - - class Iterator(object): - - def next(self): - return type(self).__next__(self) - - callable = callable -_add_doc(get_unbound_function, - """Get the function out of a possibly unbound function""") - - -get_method_function = operator.attrgetter(_meth_func) -get_method_self = operator.attrgetter(_meth_self) -get_function_closure = operator.attrgetter(_func_closure) -get_function_code = operator.attrgetter(_func_code) -get_function_defaults = operator.attrgetter(_func_defaults) -get_function_globals = operator.attrgetter(_func_globals) - - -if PY3: - def iterkeys(d, **kw): - return iter(d.keys(**kw)) - - def itervalues(d, **kw): - return iter(d.values(**kw)) - - def iteritems(d, **kw): - return iter(d.items(**kw)) - - def iterlists(d, **kw): - return iter(d.lists(**kw)) - - viewkeys = operator.methodcaller("keys") - - viewvalues = operator.methodcaller("values") - - viewitems = operator.methodcaller("items") -else: - def iterkeys(d, **kw): - return d.iterkeys(**kw) - - def itervalues(d, **kw): - return d.itervalues(**kw) - - def iteritems(d, **kw): - return d.iteritems(**kw) - - def iterlists(d, **kw): - return d.iterlists(**kw) - - viewkeys = operator.methodcaller("viewkeys") - - viewvalues = operator.methodcaller("viewvalues") - - viewitems = operator.methodcaller("viewitems") - -_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") -_add_doc(itervalues, "Return an iterator over the values of a dictionary.") -_add_doc(iteritems, - "Return an iterator over the (key, value) pairs of a dictionary.") -_add_doc(iterlists, - "Return an iterator over the (key, [values]) pairs of a dictionary.") - - -if PY3: - def b(s): - return s.encode("latin-1") - - def u(s): - return s - unichr = chr - import struct - int2byte = struct.Struct(">B").pack - del struct - byte2int = operator.itemgetter(0) - indexbytes = operator.getitem - iterbytes = iter - import io - StringIO = io.StringIO - BytesIO = io.BytesIO - _assertCountEqual = "assertCountEqual" - if sys.version_info[1] <= 1: - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" - else: - _assertRaisesRegex = "assertRaisesRegex" - _assertRegex = "assertRegex" -else: - def b(s): - return s - # Workaround for standalone backslash - - def u(s): - return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") - unichr = unichr - int2byte = chr - - def byte2int(bs): - return ord(bs[0]) - - def indexbytes(buf, i): - return ord(buf[i]) - iterbytes = functools.partial(itertools.imap, ord) - import StringIO - StringIO = BytesIO = StringIO.StringIO - _assertCountEqual = "assertItemsEqual" - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" -_add_doc(b, """Byte literal""") -_add_doc(u, """Text literal""") - - -def assertCountEqual(self, *args, **kwargs): - return getattr(self, _assertCountEqual)(*args, **kwargs) - - -def assertRaisesRegex(self, *args, **kwargs): - return getattr(self, _assertRaisesRegex)(*args, **kwargs) - - -def assertRegex(self, *args, **kwargs): - return getattr(self, _assertRegex)(*args, **kwargs) - - -if PY3: - exec_ = getattr(moves.builtins, "exec") - - def reraise(tp, value, tb=None): - try: - if value is None: - value = tp() - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - finally: - value = None - tb = None - -else: - def exec_(_code_, _globs_=None, _locs_=None): - """Execute code in a namespace.""" - if _globs_ is None: - frame = sys._getframe(1) - _globs_ = frame.f_globals - if _locs_ is None: - _locs_ = frame.f_locals - del frame - elif _locs_ is None: - _locs_ = _globs_ - exec("""exec _code_ in _globs_, _locs_""") - - exec_("""def reraise(tp, value, tb=None): - try: - raise tp, value, tb - finally: - tb = None -""") - - -if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, from_value): - try: - if from_value is None: - raise value - raise value from from_value - finally: - value = None -""") -elif sys.version_info[:2] > (3, 2): - exec_("""def raise_from(value, from_value): - try: - raise value from from_value - finally: - value = None -""") -else: - def raise_from(value, from_value): - raise value - - -print_ = getattr(moves.builtins, "print", None) -if print_ is None: - def print_(*args, **kwargs): - """The new-style print function for Python 2.4 and 2.5.""" - fp = kwargs.pop("file", sys.stdout) - if fp is None: - return - - def write(data): - if not isinstance(data, basestring): - data = str(data) - # If the file has an encoding, encode unicode with it. - if (isinstance(fp, file) and - isinstance(data, unicode) and - fp.encoding is not None): - errors = getattr(fp, "errors", None) - if errors is None: - errors = "strict" - data = data.encode(fp.encoding, errors) - fp.write(data) - want_unicode = False - sep = kwargs.pop("sep", None) - if sep is not None: - if isinstance(sep, unicode): - want_unicode = True - elif not isinstance(sep, str): - raise TypeError("sep must be None or a string") - end = kwargs.pop("end", None) - if end is not None: - if isinstance(end, unicode): - want_unicode = True - elif not isinstance(end, str): - raise TypeError("end must be None or a string") - if kwargs: - raise TypeError("invalid keyword arguments to print()") - if not want_unicode: - for arg in args: - if isinstance(arg, unicode): - want_unicode = True - break - if want_unicode: - newline = unicode("\n") - space = unicode(" ") - else: - newline = "\n" - space = " " - if sep is None: - sep = space - if end is None: - end = newline - for i, arg in enumerate(args): - if i: - write(sep) - write(arg) - write(end) -if sys.version_info[:2] < (3, 3): - _print = print_ - - def print_(*args, **kwargs): - fp = kwargs.get("file", sys.stdout) - flush = kwargs.pop("flush", False) - _print(*args, **kwargs) - if flush and fp is not None: - fp.flush() - -_add_doc(reraise, """Reraise an exception.""") - -if sys.version_info[0:2] < (3, 4): - def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES): - def wrapper(f): - f = functools.wraps(wrapped, assigned, updated)(f) - f.__wrapped__ = wrapped - return f - return wrapper -else: - wraps = functools.wraps - - -def with_metaclass(meta, *bases): - """Create a base class with a metaclass.""" - # This requires a bit of explanation: the basic idea is to make a dummy - # metaclass for one level of class instantiation that replaces itself with - # the actual metaclass. - class metaclass(type): - - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - - @classmethod - def __prepare__(cls, name, this_bases): - return meta.__prepare__(name, bases) - return type.__new__(metaclass, 'temporary_class', (), {}) - - -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - if hasattr(cls, '__qualname__'): - orig_vars['__qualname__'] = cls.__qualname__ - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - - -def ensure_binary(s, encoding='utf-8', errors='strict'): - """Coerce **s** to six.binary_type. - - For Python 2: - - `unicode` -> encoded to `str` - - `str` -> `str` - - For Python 3: - - `str` -> encoded to `bytes` - - `bytes` -> `bytes` - """ - if isinstance(s, text_type): - return s.encode(encoding, errors) - elif isinstance(s, binary_type): - return s - else: - raise TypeError("not expecting type '%s'" % type(s)) - - -def ensure_str(s, encoding='utf-8', errors='strict'): - """Coerce *s* to `str`. - - For Python 2: - - `unicode` -> encoded to `str` - - `str` -> `str` - - For Python 3: - - `str` -> `str` - - `bytes` -> decoded to `str` - """ - if not isinstance(s, (text_type, binary_type)): - raise TypeError("not expecting type '%s'" % type(s)) - if PY2 and isinstance(s, text_type): - s = s.encode(encoding, errors) - elif PY3 and isinstance(s, binary_type): - s = s.decode(encoding, errors) - return s - - -def ensure_text(s, encoding='utf-8', errors='strict'): - """Coerce *s* to six.text_type. - - For Python 2: - - `unicode` -> `unicode` - - `str` -> `unicode` - - For Python 3: - - `str` -> `str` - - `bytes` -> decoded to `str` - """ - if isinstance(s, binary_type): - return s.decode(encoding, errors) - elif isinstance(s, text_type): - return s - else: - raise TypeError("not expecting type '%s'" % type(s)) - - - -def python_2_unicode_compatible(klass): - """ - A decorator that defines __unicode__ and __str__ methods under Python 2. - Under Python 3 it does nothing. - - To support Python 2 and 3 with a single code base, define a __str__ method - returning text and apply this decorator to the class. - """ - if PY2: - if '__str__' not in klass.__dict__: - raise ValueError("@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % - klass.__name__) - klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode('utf-8') - return klass - - -# Complete the moves implementation. -# This code is at the end of this module to speed up module loading. -# Turn this module into a package. -__path__ = [] # required for PEP 302 and PEP 451 -__package__ = __name__ # see PEP 366 @ReservedAssignment -if globals().get("__spec__") is not None: - __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable -# Remove other six meta path importers, since they cause problems. This can -# happen if six is removed from sys.modules and then reloaded. (Setuptools does -# this for some reason.) -if sys.meta_path: - for i, importer in enumerate(sys.meta_path): - # Here's some real nastiness: Another "instance" of the six module might - # be floating around. Therefore, we can't use isinstance() to check for - # the six meta path importer, since the other six instance will have - # inserted an importer with different class. - if (type(importer).__name__ == "_SixMetaPathImporter" and - importer.name == __name__): - del sys.meta_path[i] - break - del i, importer -# Finally, add the importer to the meta path import hook. -sys.meta_path.append(_importer) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/__init__.py deleted file mode 100644 index 148a9c3..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/__init__.py +++ /dev/null @@ -1,92 +0,0 @@ -""" -urllib3 - Thread-safe connection pooling and re-using. -""" - -from __future__ import absolute_import -import warnings - -from .connectionpool import ( - HTTPConnectionPool, - HTTPSConnectionPool, - connection_from_url -) - -from . import exceptions -from .filepost import encode_multipart_formdata -from .poolmanager import PoolManager, ProxyManager, proxy_from_url -from .response import HTTPResponse -from .util.request import make_headers -from .util.url import get_host -from .util.timeout import Timeout -from .util.retry import Retry - - -# Set default logging handler to avoid "No handler found" warnings. -import logging -from logging import NullHandler - -__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' -__license__ = 'MIT' -__version__ = '1.24.1' - -__all__ = ( - 'HTTPConnectionPool', - 'HTTPSConnectionPool', - 'PoolManager', - 'ProxyManager', - 'HTTPResponse', - 'Retry', - 'Timeout', - 'add_stderr_logger', - 'connection_from_url', - 'disable_warnings', - 'encode_multipart_formdata', - 'get_host', - 'make_headers', - 'proxy_from_url', -) - -logging.getLogger(__name__).addHandler(NullHandler()) - - -def add_stderr_logger(level=logging.DEBUG): - """ - Helper for quickly adding a StreamHandler to the logger. Useful for - debugging. - - Returns the handler after adding it. - """ - # This method needs to be in this __init__.py to get the __name__ correct - # even if urllib3 is vendored within another package. - logger = logging.getLogger(__name__) - handler = logging.StreamHandler() - handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) - logger.addHandler(handler) - logger.setLevel(level) - logger.debug('Added a stderr logging handler to logger: %s', __name__) - return handler - - -# ... Clean up. -del NullHandler - - -# All warning filters *must* be appended unless you're really certain that they -# shouldn't be: otherwise, it's very hard for users to use most Python -# mechanisms to silence them. -# SecurityWarning's always go off by default. -warnings.simplefilter('always', exceptions.SecurityWarning, append=True) -# SubjectAltNameWarning's should go off once per host -warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True) -# InsecurePlatformWarning's don't vary between requests, so we keep it default. -warnings.simplefilter('default', exceptions.InsecurePlatformWarning, - append=True) -# SNIMissingWarnings should go off only once. -warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True) - - -def disable_warnings(category=exceptions.HTTPWarning): - """ - Helper for quickly disabling all urllib3 warnings. - """ - warnings.simplefilter('ignore', category) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/_collections.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/_collections.py deleted file mode 100644 index 34f2381..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/_collections.py +++ /dev/null @@ -1,329 +0,0 @@ -from __future__ import absolute_import -try: - from collections.abc import Mapping, MutableMapping -except ImportError: - from collections import Mapping, MutableMapping -try: - from threading import RLock -except ImportError: # Platform-specific: No threads available - class RLock: - def __enter__(self): - pass - - def __exit__(self, exc_type, exc_value, traceback): - pass - - -from collections import OrderedDict -from .exceptions import InvalidHeader -from .packages.six import iterkeys, itervalues, PY3 - - -__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict'] - - -_Null = object() - - -class RecentlyUsedContainer(MutableMapping): - """ - Provides a thread-safe dict-like container which maintains up to - ``maxsize`` keys while throwing away the least-recently-used keys beyond - ``maxsize``. - - :param maxsize: - Maximum number of recent elements to retain. - - :param dispose_func: - Every time an item is evicted from the container, - ``dispose_func(value)`` is called. Callback which will get called - """ - - ContainerCls = OrderedDict - - def __init__(self, maxsize=10, dispose_func=None): - self._maxsize = maxsize - self.dispose_func = dispose_func - - self._container = self.ContainerCls() - self.lock = RLock() - - def __getitem__(self, key): - # Re-insert the item, moving it to the end of the eviction line. - with self.lock: - item = self._container.pop(key) - self._container[key] = item - return item - - def __setitem__(self, key, value): - evicted_value = _Null - with self.lock: - # Possibly evict the existing value of 'key' - evicted_value = self._container.get(key, _Null) - self._container[key] = value - - # If we didn't evict an existing value, we might have to evict the - # least recently used item from the beginning of the container. - if len(self._container) > self._maxsize: - _key, evicted_value = self._container.popitem(last=False) - - if self.dispose_func and evicted_value is not _Null: - self.dispose_func(evicted_value) - - def __delitem__(self, key): - with self.lock: - value = self._container.pop(key) - - if self.dispose_func: - self.dispose_func(value) - - def __len__(self): - with self.lock: - return len(self._container) - - def __iter__(self): - raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.') - - def clear(self): - with self.lock: - # Copy pointers to all values, then wipe the mapping - values = list(itervalues(self._container)) - self._container.clear() - - if self.dispose_func: - for value in values: - self.dispose_func(value) - - def keys(self): - with self.lock: - return list(iterkeys(self._container)) - - -class HTTPHeaderDict(MutableMapping): - """ - :param headers: - An iterable of field-value pairs. Must not contain multiple field names - when compared case-insensitively. - - :param kwargs: - Additional field-value pairs to pass in to ``dict.update``. - - A ``dict`` like container for storing HTTP Headers. - - Field names are stored and compared case-insensitively in compliance with - RFC 7230. Iteration provides the first case-sensitive key seen for each - case-insensitive pair. - - Using ``__setitem__`` syntax overwrites fields that compare equal - case-insensitively in order to maintain ``dict``'s api. For fields that - compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` - in a loop. - - If multiple fields that are equal case-insensitively are passed to the - constructor or ``.update``, the behavior is undefined and some will be - lost. - - >>> headers = HTTPHeaderDict() - >>> headers.add('Set-Cookie', 'foo=bar') - >>> headers.add('set-cookie', 'baz=quxx') - >>> headers['content-length'] = '7' - >>> headers['SET-cookie'] - 'foo=bar, baz=quxx' - >>> headers['Content-Length'] - '7' - """ - - def __init__(self, headers=None, **kwargs): - super(HTTPHeaderDict, self).__init__() - self._container = OrderedDict() - if headers is not None: - if isinstance(headers, HTTPHeaderDict): - self._copy_from(headers) - else: - self.extend(headers) - if kwargs: - self.extend(kwargs) - - def __setitem__(self, key, val): - self._container[key.lower()] = [key, val] - return self._container[key.lower()] - - def __getitem__(self, key): - val = self._container[key.lower()] - return ', '.join(val[1:]) - - def __delitem__(self, key): - del self._container[key.lower()] - - def __contains__(self, key): - return key.lower() in self._container - - def __eq__(self, other): - if not isinstance(other, Mapping) and not hasattr(other, 'keys'): - return False - if not isinstance(other, type(self)): - other = type(self)(other) - return (dict((k.lower(), v) for k, v in self.itermerged()) == - dict((k.lower(), v) for k, v in other.itermerged())) - - def __ne__(self, other): - return not self.__eq__(other) - - if not PY3: # Python 2 - iterkeys = MutableMapping.iterkeys - itervalues = MutableMapping.itervalues - - __marker = object() - - def __len__(self): - return len(self._container) - - def __iter__(self): - # Only provide the originally cased names - for vals in self._container.values(): - yield vals[0] - - def pop(self, key, default=__marker): - '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. - If key is not found, d is returned if given, otherwise KeyError is raised. - ''' - # Using the MutableMapping function directly fails due to the private marker. - # Using ordinary dict.pop would expose the internal structures. - # So let's reinvent the wheel. - try: - value = self[key] - except KeyError: - if default is self.__marker: - raise - return default - else: - del self[key] - return value - - def discard(self, key): - try: - del self[key] - except KeyError: - pass - - def add(self, key, val): - """Adds a (name, value) pair, doesn't overwrite the value if it already - exists. - - >>> headers = HTTPHeaderDict(foo='bar') - >>> headers.add('Foo', 'baz') - >>> headers['foo'] - 'bar, baz' - """ - key_lower = key.lower() - new_vals = [key, val] - # Keep the common case aka no item present as fast as possible - vals = self._container.setdefault(key_lower, new_vals) - if new_vals is not vals: - vals.append(val) - - def extend(self, *args, **kwargs): - """Generic import function for any type of header-like object. - Adapted version of MutableMapping.update in order to insert items - with self.add instead of self.__setitem__ - """ - if len(args) > 1: - raise TypeError("extend() takes at most 1 positional " - "arguments ({0} given)".format(len(args))) - other = args[0] if len(args) >= 1 else () - - if isinstance(other, HTTPHeaderDict): - for key, val in other.iteritems(): - self.add(key, val) - elif isinstance(other, Mapping): - for key in other: - self.add(key, other[key]) - elif hasattr(other, "keys"): - for key in other.keys(): - self.add(key, other[key]) - else: - for key, value in other: - self.add(key, value) - - for key, value in kwargs.items(): - self.add(key, value) - - def getlist(self, key, default=__marker): - """Returns a list of all the values for the named field. Returns an - empty list if the key doesn't exist.""" - try: - vals = self._container[key.lower()] - except KeyError: - if default is self.__marker: - return [] - return default - else: - return vals[1:] - - # Backwards compatibility for httplib - getheaders = getlist - getallmatchingheaders = getlist - iget = getlist - - # Backwards compatibility for http.cookiejar - get_all = getlist - - def __repr__(self): - return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) - - def _copy_from(self, other): - for key in other: - val = other.getlist(key) - if isinstance(val, list): - # Don't need to convert tuples - val = list(val) - self._container[key.lower()] = [key] + val - - def copy(self): - clone = type(self)() - clone._copy_from(self) - return clone - - def iteritems(self): - """Iterate over all header lines, including duplicate ones.""" - for key in self: - vals = self._container[key.lower()] - for val in vals[1:]: - yield vals[0], val - - def itermerged(self): - """Iterate over all headers, merging duplicate ones together.""" - for key in self: - val = self._container[key.lower()] - yield val[0], ', '.join(val[1:]) - - def items(self): - return list(self.iteritems()) - - @classmethod - def from_httplib(cls, message): # Python 2 - """Read headers from a Python 2 httplib message object.""" - # python2.7 does not expose a proper API for exporting multiheaders - # efficiently. This function re-reads raw lines from the message - # object and extracts the multiheaders properly. - obs_fold_continued_leaders = (' ', '\t') - headers = [] - - for line in message.headers: - if line.startswith(obs_fold_continued_leaders): - if not headers: - # We received a header line that starts with OWS as described - # in RFC-7230 S3.2.4. This indicates a multiline header, but - # there exists no previous header to which we can attach it. - raise InvalidHeader( - 'Header continuation with no previous header: %s' % line - ) - else: - key, value = headers[-1] - headers[-1] = (key, value + ' ' + line.strip()) - continue - - key, value = line.split(':', 1) - headers.append((key, value.strip())) - - return cls(headers) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/connection.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/connection.py deleted file mode 100644 index 02b3665..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/connection.py +++ /dev/null @@ -1,391 +0,0 @@ -from __future__ import absolute_import -import datetime -import logging -import os -import socket -from socket import error as SocketError, timeout as SocketTimeout -import warnings -from .packages import six -from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection -from .packages.six.moves.http_client import HTTPException # noqa: F401 - -try: # Compiled with SSL? - import ssl - BaseSSLError = ssl.SSLError -except (ImportError, AttributeError): # Platform-specific: No SSL. - ssl = None - - class BaseSSLError(BaseException): - pass - - -try: # Python 3: - # Not a no-op, we're adding this to the namespace so it can be imported. - ConnectionError = ConnectionError -except NameError: # Python 2: - class ConnectionError(Exception): - pass - - -from .exceptions import ( - NewConnectionError, - ConnectTimeoutError, - SubjectAltNameWarning, - SystemTimeWarning, -) -from .packages.ssl_match_hostname import match_hostname, CertificateError - -from .util.ssl_ import ( - resolve_cert_reqs, - resolve_ssl_version, - assert_fingerprint, - create_urllib3_context, - ssl_wrap_socket -) - - -from .util import connection - -from ._collections import HTTPHeaderDict - -log = logging.getLogger(__name__) - -port_by_scheme = { - 'http': 80, - 'https': 443, -} - -# When updating RECENT_DATE, move it to within two years of the current date, -# and not less than 6 months ago. -# Example: if Today is 2018-01-01, then RECENT_DATE should be any date on or -# after 2016-01-01 (today - 2 years) AND before 2017-07-01 (today - 6 months) -RECENT_DATE = datetime.date(2017, 6, 30) - - -class DummyConnection(object): - """Used to detect a failed ConnectionCls import.""" - pass - - -class HTTPConnection(_HTTPConnection, object): - """ - Based on httplib.HTTPConnection but provides an extra constructor - backwards-compatibility layer between older and newer Pythons. - - Additional keyword parameters are used to configure attributes of the connection. - Accepted parameters include: - - - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` - - ``source_address``: Set the source address for the current connection. - - ``socket_options``: Set specific options on the underlying socket. If not specified, then - defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling - Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. - - For example, if you wish to enable TCP Keep Alive in addition to the defaults, - you might pass:: - - HTTPConnection.default_socket_options + [ - (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), - ] - - Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). - """ - - default_port = port_by_scheme['http'] - - #: Disable Nagle's algorithm by default. - #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` - default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] - - #: Whether this connection verifies the host's certificate. - is_verified = False - - def __init__(self, *args, **kw): - if six.PY3: # Python 3 - kw.pop('strict', None) - - # Pre-set source_address. - self.source_address = kw.get('source_address') - - #: The socket options provided by the user. If no options are - #: provided, we use the default options. - self.socket_options = kw.pop('socket_options', self.default_socket_options) - - _HTTPConnection.__init__(self, *args, **kw) - - @property - def host(self): - """ - Getter method to remove any trailing dots that indicate the hostname is an FQDN. - - In general, SSL certificates don't include the trailing dot indicating a - fully-qualified domain name, and thus, they don't validate properly when - checked against a domain name that includes the dot. In addition, some - servers may not expect to receive the trailing dot when provided. - - However, the hostname with trailing dot is critical to DNS resolution; doing a - lookup with the trailing dot will properly only resolve the appropriate FQDN, - whereas a lookup without a trailing dot will search the system's search domain - list. Thus, it's important to keep the original host around for use only in - those cases where it's appropriate (i.e., when doing DNS lookup to establish the - actual TCP connection across which we're going to send HTTP requests). - """ - return self._dns_host.rstrip('.') - - @host.setter - def host(self, value): - """ - Setter for the `host` property. - - We assume that only urllib3 uses the _dns_host attribute; httplib itself - only uses `host`, and it seems reasonable that other libraries follow suit. - """ - self._dns_host = value - - def _new_conn(self): - """ Establish a socket connection and set nodelay settings on it. - - :return: New socket connection. - """ - extra_kw = {} - if self.source_address: - extra_kw['source_address'] = self.source_address - - if self.socket_options: - extra_kw['socket_options'] = self.socket_options - - try: - conn = connection.create_connection( - (self._dns_host, self.port), self.timeout, **extra_kw) - - except SocketTimeout as e: - raise ConnectTimeoutError( - self, "Connection to %s timed out. (connect timeout=%s)" % - (self.host, self.timeout)) - - except SocketError as e: - raise NewConnectionError( - self, "Failed to establish a new connection: %s" % e) - - return conn - - def _prepare_conn(self, conn): - self.sock = conn - if self._tunnel_host: - # TODO: Fix tunnel so it doesn't depend on self.sock state. - self._tunnel() - # Mark this connection as not reusable - self.auto_open = 0 - - def connect(self): - conn = self._new_conn() - self._prepare_conn(conn) - - def request_chunked(self, method, url, body=None, headers=None): - """ - Alternative to the common request method, which sends the - body with chunked encoding and not as one block - """ - headers = HTTPHeaderDict(headers if headers is not None else {}) - skip_accept_encoding = 'accept-encoding' in headers - skip_host = 'host' in headers - self.putrequest( - method, - url, - skip_accept_encoding=skip_accept_encoding, - skip_host=skip_host - ) - for header, value in headers.items(): - self.putheader(header, value) - if 'transfer-encoding' not in headers: - self.putheader('Transfer-Encoding', 'chunked') - self.endheaders() - - if body is not None: - stringish_types = six.string_types + (bytes,) - if isinstance(body, stringish_types): - body = (body,) - for chunk in body: - if not chunk: - continue - if not isinstance(chunk, bytes): - chunk = chunk.encode('utf8') - len_str = hex(len(chunk))[2:] - self.send(len_str.encode('utf-8')) - self.send(b'\r\n') - self.send(chunk) - self.send(b'\r\n') - - # After the if clause, to always have a closed body - self.send(b'0\r\n\r\n') - - -class HTTPSConnection(HTTPConnection): - default_port = port_by_scheme['https'] - - ssl_version = None - - def __init__(self, host, port=None, key_file=None, cert_file=None, - strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - ssl_context=None, server_hostname=None, **kw): - - HTTPConnection.__init__(self, host, port, strict=strict, - timeout=timeout, **kw) - - self.key_file = key_file - self.cert_file = cert_file - self.ssl_context = ssl_context - self.server_hostname = server_hostname - - # Required property for Google AppEngine 1.9.0 which otherwise causes - # HTTPS requests to go out as HTTP. (See Issue #356) - self._protocol = 'https' - - def connect(self): - conn = self._new_conn() - self._prepare_conn(conn) - - if self.ssl_context is None: - self.ssl_context = create_urllib3_context( - ssl_version=resolve_ssl_version(None), - cert_reqs=resolve_cert_reqs(None), - ) - - self.sock = ssl_wrap_socket( - sock=conn, - keyfile=self.key_file, - certfile=self.cert_file, - ssl_context=self.ssl_context, - server_hostname=self.server_hostname - ) - - -class VerifiedHTTPSConnection(HTTPSConnection): - """ - Based on httplib.HTTPSConnection but wraps the socket with - SSL certification. - """ - cert_reqs = None - ca_certs = None - ca_cert_dir = None - ssl_version = None - assert_fingerprint = None - - def set_cert(self, key_file=None, cert_file=None, - cert_reqs=None, ca_certs=None, - assert_hostname=None, assert_fingerprint=None, - ca_cert_dir=None): - """ - This method should only be called once, before the connection is used. - """ - # If cert_reqs is not provided, we can try to guess. If the user gave - # us a cert database, we assume they want to use it: otherwise, if - # they gave us an SSL Context object we should use whatever is set for - # it. - if cert_reqs is None: - if ca_certs or ca_cert_dir: - cert_reqs = 'CERT_REQUIRED' - elif self.ssl_context is not None: - cert_reqs = self.ssl_context.verify_mode - - self.key_file = key_file - self.cert_file = cert_file - self.cert_reqs = cert_reqs - self.assert_hostname = assert_hostname - self.assert_fingerprint = assert_fingerprint - self.ca_certs = ca_certs and os.path.expanduser(ca_certs) - self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir) - - def connect(self): - # Add certificate verification - conn = self._new_conn() - hostname = self.host - - if self._tunnel_host: - self.sock = conn - # Calls self._set_hostport(), so self.host is - # self._tunnel_host below. - self._tunnel() - # Mark this connection as not reusable - self.auto_open = 0 - - # Override the host with the one we're requesting data from. - hostname = self._tunnel_host - - server_hostname = hostname - if self.server_hostname is not None: - server_hostname = self.server_hostname - - is_time_off = datetime.date.today() < RECENT_DATE - if is_time_off: - warnings.warn(( - 'System time is way off (before {0}). This will probably ' - 'lead to SSL verification errors').format(RECENT_DATE), - SystemTimeWarning - ) - - # Wrap socket using verification with the root certs in - # trusted_root_certs - if self.ssl_context is None: - self.ssl_context = create_urllib3_context( - ssl_version=resolve_ssl_version(self.ssl_version), - cert_reqs=resolve_cert_reqs(self.cert_reqs), - ) - - context = self.ssl_context - context.verify_mode = resolve_cert_reqs(self.cert_reqs) - self.sock = ssl_wrap_socket( - sock=conn, - keyfile=self.key_file, - certfile=self.cert_file, - ca_certs=self.ca_certs, - ca_cert_dir=self.ca_cert_dir, - server_hostname=server_hostname, - ssl_context=context) - - if self.assert_fingerprint: - assert_fingerprint(self.sock.getpeercert(binary_form=True), - self.assert_fingerprint) - elif context.verify_mode != ssl.CERT_NONE \ - and not getattr(context, 'check_hostname', False) \ - and self.assert_hostname is not False: - # While urllib3 attempts to always turn off hostname matching from - # the TLS library, this cannot always be done. So we check whether - # the TLS Library still thinks it's matching hostnames. - cert = self.sock.getpeercert() - if not cert.get('subjectAltName', ()): - warnings.warn(( - 'Certificate for {0} has no `subjectAltName`, falling back to check for a ' - '`commonName` for now. This feature is being removed by major browsers and ' - 'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 ' - 'for details.)'.format(hostname)), - SubjectAltNameWarning - ) - _match_hostname(cert, self.assert_hostname or server_hostname) - - self.is_verified = ( - context.verify_mode == ssl.CERT_REQUIRED or - self.assert_fingerprint is not None - ) - - -def _match_hostname(cert, asserted_hostname): - try: - match_hostname(cert, asserted_hostname) - except CertificateError as e: - log.error( - 'Certificate did not match expected hostname: %s. ' - 'Certificate: %s', asserted_hostname, cert - ) - # Add cert to exception and reraise so client code can inspect - # the cert when catching the exception, if they want to - e._peer_cert = cert - raise - - -if ssl: - # Make a copy for testing. - UnverifiedHTTPSConnection = HTTPSConnection - HTTPSConnection = VerifiedHTTPSConnection -else: - HTTPSConnection = DummyConnection diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/connectionpool.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/connectionpool.py deleted file mode 100644 index f7a8f19..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/connectionpool.py +++ /dev/null @@ -1,896 +0,0 @@ -from __future__ import absolute_import -import errno -import logging -import sys -import warnings - -from socket import error as SocketError, timeout as SocketTimeout -import socket - - -from .exceptions import ( - ClosedPoolError, - ProtocolError, - EmptyPoolError, - HeaderParsingError, - HostChangedError, - LocationValueError, - MaxRetryError, - ProxyError, - ReadTimeoutError, - SSLError, - TimeoutError, - InsecureRequestWarning, - NewConnectionError, -) -from .packages.ssl_match_hostname import CertificateError -from .packages import six -from .packages.six.moves import queue -from .connection import ( - port_by_scheme, - DummyConnection, - HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, - HTTPException, BaseSSLError, -) -from .request import RequestMethods -from .response import HTTPResponse - -from .util.connection import is_connection_dropped -from .util.request import set_file_position -from .util.response import assert_header_parsing -from .util.retry import Retry -from .util.timeout import Timeout -from .util.url import get_host, Url, NORMALIZABLE_SCHEMES -from .util.queue import LifoQueue - - -xrange = six.moves.xrange - -log = logging.getLogger(__name__) - -_Default = object() - - -# Pool objects -class ConnectionPool(object): - """ - Base class for all connection pools, such as - :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. - """ - - scheme = None - QueueCls = LifoQueue - - def __init__(self, host, port=None): - if not host: - raise LocationValueError("No host specified.") - - self.host = _ipv6_host(host, self.scheme) - self._proxy_host = host.lower() - self.port = port - - def __str__(self): - return '%s(host=%r, port=%r)' % (type(self).__name__, - self.host, self.port) - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.close() - # Return False to re-raise any potential exceptions - return False - - def close(self): - """ - Close all pooled connections and disable the pool. - """ - pass - - -# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 -_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK} - - -class HTTPConnectionPool(ConnectionPool, RequestMethods): - """ - Thread-safe connection pool for one host. - - :param host: - Host used for this HTTP Connection (e.g. "localhost"), passed into - :class:`httplib.HTTPConnection`. - - :param port: - Port used for this HTTP Connection (None is equivalent to 80), passed - into :class:`httplib.HTTPConnection`. - - :param strict: - Causes BadStatusLine to be raised if the status line can't be parsed - as a valid HTTP/1.0 or 1.1 status line, passed into - :class:`httplib.HTTPConnection`. - - .. note:: - Only works in Python 2. This parameter is ignored in Python 3. - - :param timeout: - Socket timeout in seconds for each individual connection. This can - be a float or integer, which sets the timeout for the HTTP request, - or an instance of :class:`urllib3.util.Timeout` which gives you more - fine-grained control over request timeouts. After the constructor has - been parsed, this is always a `urllib3.util.Timeout` object. - - :param maxsize: - Number of connections to save that can be reused. More than 1 is useful - in multithreaded situations. If ``block`` is set to False, more - connections will be created but they will not be saved once they've - been used. - - :param block: - If set to True, no more than ``maxsize`` connections will be used at - a time. When no free connections are available, the call will block - until a connection has been released. This is a useful side effect for - particular multithreaded situations where one does not want to use more - than maxsize connections per host to prevent flooding. - - :param headers: - Headers to include with all requests, unless other headers are given - explicitly. - - :param retries: - Retry configuration to use by default with requests in this pool. - - :param _proxy: - Parsed proxy URL, should not be used directly, instead, see - :class:`urllib3.connectionpool.ProxyManager`" - - :param _proxy_headers: - A dictionary with proxy headers, should not be used directly, - instead, see :class:`urllib3.connectionpool.ProxyManager`" - - :param \\**conn_kw: - Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, - :class:`urllib3.connection.HTTPSConnection` instances. - """ - - scheme = 'http' - ConnectionCls = HTTPConnection - ResponseCls = HTTPResponse - - def __init__(self, host, port=None, strict=False, - timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, - headers=None, retries=None, - _proxy=None, _proxy_headers=None, - **conn_kw): - ConnectionPool.__init__(self, host, port) - RequestMethods.__init__(self, headers) - - self.strict = strict - - if not isinstance(timeout, Timeout): - timeout = Timeout.from_float(timeout) - - if retries is None: - retries = Retry.DEFAULT - - self.timeout = timeout - self.retries = retries - - self.pool = self.QueueCls(maxsize) - self.block = block - - self.proxy = _proxy - self.proxy_headers = _proxy_headers or {} - - # Fill the queue up so that doing get() on it will block properly - for _ in xrange(maxsize): - self.pool.put(None) - - # These are mostly for testing and debugging purposes. - self.num_connections = 0 - self.num_requests = 0 - self.conn_kw = conn_kw - - if self.proxy: - # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. - # We cannot know if the user has added default socket options, so we cannot replace the - # list. - self.conn_kw.setdefault('socket_options', []) - - def _new_conn(self): - """ - Return a fresh :class:`HTTPConnection`. - """ - self.num_connections += 1 - log.debug("Starting new HTTP connection (%d): %s:%s", - self.num_connections, self.host, self.port or "80") - - conn = self.ConnectionCls(host=self.host, port=self.port, - timeout=self.timeout.connect_timeout, - strict=self.strict, **self.conn_kw) - return conn - - def _get_conn(self, timeout=None): - """ - Get a connection. Will return a pooled connection if one is available. - - If no connections are available and :prop:`.block` is ``False``, then a - fresh connection is returned. - - :param timeout: - Seconds to wait before giving up and raising - :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and - :prop:`.block` is ``True``. - """ - conn = None - try: - conn = self.pool.get(block=self.block, timeout=timeout) - - except AttributeError: # self.pool is None - raise ClosedPoolError(self, "Pool is closed.") - - except queue.Empty: - if self.block: - raise EmptyPoolError(self, - "Pool reached maximum size and no more " - "connections are allowed.") - pass # Oh well, we'll create a new connection then - - # If this is a persistent connection, check if it got disconnected - if conn and is_connection_dropped(conn): - log.debug("Resetting dropped connection: %s", self.host) - conn.close() - if getattr(conn, 'auto_open', 1) == 0: - # This is a proxied connection that has been mutated by - # httplib._tunnel() and cannot be reused (since it would - # attempt to bypass the proxy) - conn = None - - return conn or self._new_conn() - - def _put_conn(self, conn): - """ - Put a connection back into the pool. - - :param conn: - Connection object for the current host and port as returned by - :meth:`._new_conn` or :meth:`._get_conn`. - - If the pool is already full, the connection is closed and discarded - because we exceeded maxsize. If connections are discarded frequently, - then maxsize should be increased. - - If the pool is closed, then the connection will be closed and discarded. - """ - try: - self.pool.put(conn, block=False) - return # Everything is dandy, done. - except AttributeError: - # self.pool is None. - pass - except queue.Full: - # This should never happen if self.block == True - log.warning( - "Connection pool is full, discarding connection: %s", - self.host) - - # Connection never got put back into the pool, close it. - if conn: - conn.close() - - def _validate_conn(self, conn): - """ - Called right before a request is made, after the socket is created. - """ - pass - - def _prepare_proxy(self, conn): - # Nothing to do for HTTP connections. - pass - - def _get_timeout(self, timeout): - """ Helper that always returns a :class:`urllib3.util.Timeout` """ - if timeout is _Default: - return self.timeout.clone() - - if isinstance(timeout, Timeout): - return timeout.clone() - else: - # User passed us an int/float. This is for backwards compatibility, - # can be removed later - return Timeout.from_float(timeout) - - def _raise_timeout(self, err, url, timeout_value): - """Is the error actually a timeout? Will raise a ReadTimeout or pass""" - - if isinstance(err, SocketTimeout): - raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) - - # See the above comment about EAGAIN in Python 3. In Python 2 we have - # to specifically catch it and throw the timeout error - if hasattr(err, 'errno') and err.errno in _blocking_errnos: - raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) - - # Catch possible read timeouts thrown as SSL errors. If not the - # case, rethrow the original. We need to do this because of: - # http://bugs.python.org/issue10272 - if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python < 2.7.4 - raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) - - def _make_request(self, conn, method, url, timeout=_Default, chunked=False, - **httplib_request_kw): - """ - Perform a request on a given urllib connection object taken from our - pool. - - :param conn: - a connection from one of our connection pools - - :param timeout: - Socket timeout in seconds for the request. This can be a - float or integer, which will set the same timeout value for - the socket connect and the socket read, or an instance of - :class:`urllib3.util.Timeout`, which gives you more fine-grained - control over your timeouts. - """ - self.num_requests += 1 - - timeout_obj = self._get_timeout(timeout) - timeout_obj.start_connect() - conn.timeout = timeout_obj.connect_timeout - - # Trigger any extra validation we need to do. - try: - self._validate_conn(conn) - except (SocketTimeout, BaseSSLError) as e: - # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. - self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) - raise - - # conn.request() calls httplib.*.request, not the method in - # urllib3.request. It also calls makefile (recv) on the socket. - if chunked: - conn.request_chunked(method, url, **httplib_request_kw) - else: - conn.request(method, url, **httplib_request_kw) - - # Reset the timeout for the recv() on the socket - read_timeout = timeout_obj.read_timeout - - # App Engine doesn't have a sock attr - if getattr(conn, 'sock', None): - # In Python 3 socket.py will catch EAGAIN and return None when you - # try and read into the file pointer created by http.client, which - # instead raises a BadStatusLine exception. Instead of catching - # the exception and assuming all BadStatusLine exceptions are read - # timeouts, check for a zero timeout before making the request. - if read_timeout == 0: - raise ReadTimeoutError( - self, url, "Read timed out. (read timeout=%s)" % read_timeout) - if read_timeout is Timeout.DEFAULT_TIMEOUT: - conn.sock.settimeout(socket.getdefaulttimeout()) - else: # None or a value - conn.sock.settimeout(read_timeout) - - # Receive the response from the server - try: - try: # Python 2.7, use buffering of HTTP responses - httplib_response = conn.getresponse(buffering=True) - except TypeError: # Python 3 - try: - httplib_response = conn.getresponse() - except Exception as e: - # Remove the TypeError from the exception chain in Python 3; - # otherwise it looks like a programming error was the cause. - six.raise_from(e, None) - except (SocketTimeout, BaseSSLError, SocketError) as e: - self._raise_timeout(err=e, url=url, timeout_value=read_timeout) - raise - - # AppEngine doesn't have a version attr. - http_version = getattr(conn, '_http_vsn_str', 'HTTP/?') - log.debug("%s://%s:%s \"%s %s %s\" %s %s", self.scheme, self.host, self.port, - method, url, http_version, httplib_response.status, - httplib_response.length) - - try: - assert_header_parsing(httplib_response.msg) - except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 - log.warning( - 'Failed to parse headers (url=%s): %s', - self._absolute_url(url), hpe, exc_info=True) - - return httplib_response - - def _absolute_url(self, path): - return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url - - def close(self): - """ - Close all pooled connections and disable the pool. - """ - if self.pool is None: - return - # Disable access to the pool - old_pool, self.pool = self.pool, None - - try: - while True: - conn = old_pool.get(block=False) - if conn: - conn.close() - - except queue.Empty: - pass # Done. - - def is_same_host(self, url): - """ - Check if the given ``url`` is a member of the same host as this - connection pool. - """ - if url.startswith('/'): - return True - - # TODO: Add optional support for socket.gethostbyname checking. - scheme, host, port = get_host(url) - - host = _ipv6_host(host, self.scheme) - - # Use explicit default port for comparison when none is given - if self.port and not port: - port = port_by_scheme.get(scheme) - elif not self.port and port == port_by_scheme.get(scheme): - port = None - - return (scheme, host, port) == (self.scheme, self.host, self.port) - - def urlopen(self, method, url, body=None, headers=None, retries=None, - redirect=True, assert_same_host=True, timeout=_Default, - pool_timeout=None, release_conn=None, chunked=False, - body_pos=None, **response_kw): - """ - Get a connection from the pool and perform an HTTP request. This is the - lowest level call for making a request, so you'll need to specify all - the raw details. - - .. note:: - - More commonly, it's appropriate to use a convenience method provided - by :class:`.RequestMethods`, such as :meth:`request`. - - .. note:: - - `release_conn` will only behave as expected if - `preload_content=False` because we want to make - `preload_content=False` the default behaviour someday soon without - breaking backwards compatibility. - - :param method: - HTTP request method (such as GET, POST, PUT, etc.) - - :param body: - Data to send in the request body (useful for creating - POST requests, see HTTPConnectionPool.post_url for - more convenience). - - :param headers: - Dictionary of custom headers to send, such as User-Agent, - If-None-Match, etc. If None, pool headers are used. If provided, - these headers completely replace any pool-specific headers. - - :param retries: - Configure the number of retries to allow before raising a - :class:`~urllib3.exceptions.MaxRetryError` exception. - - Pass ``None`` to retry until you receive a response. Pass a - :class:`~urllib3.util.retry.Retry` object for fine-grained control - over different types of retries. - Pass an integer number to retry connection errors that many times, - but no other types of errors. Pass zero to never retry. - - If ``False``, then retries are disabled and any exception is raised - immediately. Also, instead of raising a MaxRetryError on redirects, - the redirect response will be returned. - - :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. - - :param redirect: - If True, automatically handle redirects (status codes 301, 302, - 303, 307, 308). Each redirect counts as a retry. Disabling retries - will disable redirect, too. - - :param assert_same_host: - If ``True``, will make sure that the host of the pool requests is - consistent else will raise HostChangedError. When False, you can - use the pool on an HTTP proxy and request foreign hosts. - - :param timeout: - If specified, overrides the default timeout for this one - request. It may be a float (in seconds) or an instance of - :class:`urllib3.util.Timeout`. - - :param pool_timeout: - If set and the pool is set to block=True, then this method will - block for ``pool_timeout`` seconds and raise EmptyPoolError if no - connection is available within the time period. - - :param release_conn: - If False, then the urlopen call will not release the connection - back into the pool once a response is received (but will release if - you read the entire contents of the response such as when - `preload_content=True`). This is useful if you're not preloading - the response's content immediately. You will need to call - ``r.release_conn()`` on the response ``r`` to return the connection - back into the pool. If None, it takes the value of - ``response_kw.get('preload_content', True)``. - - :param chunked: - If True, urllib3 will send the body using chunked transfer - encoding. Otherwise, urllib3 will send the body using the standard - content-length form. Defaults to False. - - :param int body_pos: - Position to seek to in file-like body in the event of a retry or - redirect. Typically this won't need to be set because urllib3 will - auto-populate the value when needed. - - :param \\**response_kw: - Additional parameters are passed to - :meth:`urllib3.response.HTTPResponse.from_httplib` - """ - if headers is None: - headers = self.headers - - if not isinstance(retries, Retry): - retries = Retry.from_int(retries, redirect=redirect, default=self.retries) - - if release_conn is None: - release_conn = response_kw.get('preload_content', True) - - # Check host - if assert_same_host and not self.is_same_host(url): - raise HostChangedError(self, url, retries) - - conn = None - - # Track whether `conn` needs to be released before - # returning/raising/recursing. Update this variable if necessary, and - # leave `release_conn` constant throughout the function. That way, if - # the function recurses, the original value of `release_conn` will be - # passed down into the recursive call, and its value will be respected. - # - # See issue #651 [1] for details. - # - # [1] <https://github.com/shazow/urllib3/issues/651> - release_this_conn = release_conn - - # Merge the proxy headers. Only do this in HTTP. We have to copy the - # headers dict so we can safely change it without those changes being - # reflected in anyone else's copy. - if self.scheme == 'http': - headers = headers.copy() - headers.update(self.proxy_headers) - - # Must keep the exception bound to a separate variable or else Python 3 - # complains about UnboundLocalError. - err = None - - # Keep track of whether we cleanly exited the except block. This - # ensures we do proper cleanup in finally. - clean_exit = False - - # Rewind body position, if needed. Record current position - # for future rewinds in the event of a redirect/retry. - body_pos = set_file_position(body, body_pos) - - try: - # Request a connection from the queue. - timeout_obj = self._get_timeout(timeout) - conn = self._get_conn(timeout=pool_timeout) - - conn.timeout = timeout_obj.connect_timeout - - is_new_proxy_conn = self.proxy is not None and not getattr(conn, 'sock', None) - if is_new_proxy_conn: - self._prepare_proxy(conn) - - # Make the request on the httplib connection object. - httplib_response = self._make_request(conn, method, url, - timeout=timeout_obj, - body=body, headers=headers, - chunked=chunked) - - # If we're going to release the connection in ``finally:``, then - # the response doesn't need to know about the connection. Otherwise - # it will also try to release it and we'll have a double-release - # mess. - response_conn = conn if not release_conn else None - - # Pass method to Response for length checking - response_kw['request_method'] = method - - # Import httplib's response into our own wrapper object - response = self.ResponseCls.from_httplib(httplib_response, - pool=self, - connection=response_conn, - retries=retries, - **response_kw) - - # Everything went great! - clean_exit = True - - except queue.Empty: - # Timed out by queue. - raise EmptyPoolError(self, "No pool connections are available.") - - except (TimeoutError, HTTPException, SocketError, ProtocolError, - BaseSSLError, SSLError, CertificateError) as e: - # Discard the connection for these exceptions. It will be - # replaced during the next _get_conn() call. - clean_exit = False - if isinstance(e, (BaseSSLError, CertificateError)): - e = SSLError(e) - elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: - e = ProxyError('Cannot connect to proxy.', e) - elif isinstance(e, (SocketError, HTTPException)): - e = ProtocolError('Connection aborted.', e) - - retries = retries.increment(method, url, error=e, _pool=self, - _stacktrace=sys.exc_info()[2]) - retries.sleep() - - # Keep track of the error for the retry warning. - err = e - - finally: - if not clean_exit: - # We hit some kind of exception, handled or otherwise. We need - # to throw the connection away unless explicitly told not to. - # Close the connection, set the variable to None, and make sure - # we put the None back in the pool to avoid leaking it. - conn = conn and conn.close() - release_this_conn = True - - if release_this_conn: - # Put the connection back to be reused. If the connection is - # expired then it will be None, which will get replaced with a - # fresh connection during _get_conn. - self._put_conn(conn) - - if not conn: - # Try again - log.warning("Retrying (%r) after connection " - "broken by '%r': %s", retries, err, url) - return self.urlopen(method, url, body, headers, retries, - redirect, assert_same_host, - timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, body_pos=body_pos, - **response_kw) - - def drain_and_release_conn(response): - try: - # discard any remaining response body, the connection will be - # released back to the pool once the entire response is read - response.read() - except (TimeoutError, HTTPException, SocketError, ProtocolError, - BaseSSLError, SSLError) as e: - pass - - # Handle redirect? - redirect_location = redirect and response.get_redirect_location() - if redirect_location: - if response.status == 303: - method = 'GET' - - try: - retries = retries.increment(method, url, response=response, _pool=self) - except MaxRetryError: - if retries.raise_on_redirect: - # Drain and release the connection for this response, since - # we're not returning it to be released manually. - drain_and_release_conn(response) - raise - return response - - # drain and return the connection to the pool before recursing - drain_and_release_conn(response) - - retries.sleep_for_retry(response) - log.debug("Redirecting %s -> %s", url, redirect_location) - return self.urlopen( - method, redirect_location, body, headers, - retries=retries, redirect=redirect, - assert_same_host=assert_same_host, - timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, body_pos=body_pos, - **response_kw) - - # Check if we should retry the HTTP response. - has_retry_after = bool(response.getheader('Retry-After')) - if retries.is_retry(method, response.status, has_retry_after): - try: - retries = retries.increment(method, url, response=response, _pool=self) - except MaxRetryError: - if retries.raise_on_status: - # Drain and release the connection for this response, since - # we're not returning it to be released manually. - drain_and_release_conn(response) - raise - return response - - # drain and return the connection to the pool before recursing - drain_and_release_conn(response) - - retries.sleep(response) - log.debug("Retry: %s", url) - return self.urlopen( - method, url, body, headers, - retries=retries, redirect=redirect, - assert_same_host=assert_same_host, - timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, - body_pos=body_pos, **response_kw) - - return response - - -class HTTPSConnectionPool(HTTPConnectionPool): - """ - Same as :class:`.HTTPConnectionPool`, but HTTPS. - - When Python is compiled with the :mod:`ssl` module, then - :class:`.VerifiedHTTPSConnection` is used, which *can* verify certificates, - instead of :class:`.HTTPSConnection`. - - :class:`.VerifiedHTTPSConnection` uses one of ``assert_fingerprint``, - ``assert_hostname`` and ``host`` in this order to verify connections. - If ``assert_hostname`` is False, no verification is done. - - The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, - ``ca_cert_dir``, and ``ssl_version`` are only used if :mod:`ssl` is - available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade - the connection socket into an SSL socket. - """ - - scheme = 'https' - ConnectionCls = HTTPSConnection - - def __init__(self, host, port=None, - strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, - block=False, headers=None, retries=None, - _proxy=None, _proxy_headers=None, - key_file=None, cert_file=None, cert_reqs=None, - ca_certs=None, ssl_version=None, - assert_hostname=None, assert_fingerprint=None, - ca_cert_dir=None, **conn_kw): - - HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize, - block, headers, retries, _proxy, _proxy_headers, - **conn_kw) - - if ca_certs and cert_reqs is None: - cert_reqs = 'CERT_REQUIRED' - - self.key_file = key_file - self.cert_file = cert_file - self.cert_reqs = cert_reqs - self.ca_certs = ca_certs - self.ca_cert_dir = ca_cert_dir - self.ssl_version = ssl_version - self.assert_hostname = assert_hostname - self.assert_fingerprint = assert_fingerprint - - def _prepare_conn(self, conn): - """ - Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` - and establish the tunnel if proxy is used. - """ - - if isinstance(conn, VerifiedHTTPSConnection): - conn.set_cert(key_file=self.key_file, - cert_file=self.cert_file, - cert_reqs=self.cert_reqs, - ca_certs=self.ca_certs, - ca_cert_dir=self.ca_cert_dir, - assert_hostname=self.assert_hostname, - assert_fingerprint=self.assert_fingerprint) - conn.ssl_version = self.ssl_version - return conn - - def _prepare_proxy(self, conn): - """ - Establish tunnel connection early, because otherwise httplib - would improperly set Host: header to proxy's IP:port. - """ - conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers) - conn.connect() - - def _new_conn(self): - """ - Return a fresh :class:`httplib.HTTPSConnection`. - """ - self.num_connections += 1 - log.debug("Starting new HTTPS connection (%d): %s:%s", - self.num_connections, self.host, self.port or "443") - - if not self.ConnectionCls or self.ConnectionCls is DummyConnection: - raise SSLError("Can't connect to HTTPS URL because the SSL " - "module is not available.") - - actual_host = self.host - actual_port = self.port - if self.proxy is not None: - actual_host = self.proxy.host - actual_port = self.proxy.port - - conn = self.ConnectionCls(host=actual_host, port=actual_port, - timeout=self.timeout.connect_timeout, - strict=self.strict, **self.conn_kw) - - return self._prepare_conn(conn) - - def _validate_conn(self, conn): - """ - Called right before a request is made, after the socket is created. - """ - super(HTTPSConnectionPool, self)._validate_conn(conn) - - # Force connect early to allow us to validate the connection. - if not getattr(conn, 'sock', None): # AppEngine might not have `.sock` - conn.connect() - - if not conn.is_verified: - warnings.warn(( - 'Unverified HTTPS request is being made. ' - 'Adding certificate verification is strongly advised. See: ' - 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' - '#ssl-warnings'), - InsecureRequestWarning) - - -def connection_from_url(url, **kw): - """ - Given a url, return an :class:`.ConnectionPool` instance of its host. - - This is a shortcut for not having to parse out the scheme, host, and port - of the url before creating an :class:`.ConnectionPool` instance. - - :param url: - Absolute URL string that must include the scheme. Port is optional. - - :param \\**kw: - Passes additional parameters to the constructor of the appropriate - :class:`.ConnectionPool`. Useful for specifying things like - timeout, maxsize, headers, etc. - - Example:: - - >>> conn = connection_from_url('http://google.com/') - >>> r = conn.request('GET', '/') - """ - scheme, host, port = get_host(url) - port = port or port_by_scheme.get(scheme, 80) - if scheme == 'https': - return HTTPSConnectionPool(host, port=port, **kw) - else: - return HTTPConnectionPool(host, port=port, **kw) - - -def _ipv6_host(host, scheme): - """ - Process IPv6 address literals - """ - - # httplib doesn't like it when we include brackets in IPv6 addresses - # Specifically, if we include brackets but also pass the port then - # httplib crazily doubles up the square brackets on the Host header. - # Instead, we need to make sure we never pass ``None`` as the port. - # However, for backward compatibility reasons we can't actually - # *assert* that. See http://bugs.python.org/issue28539 - # - # Also if an IPv6 address literal has a zone identifier, the - # percent sign might be URIencoded, convert it back into ASCII - if host.startswith('[') and host.endswith(']'): - host = host.replace('%25', '%').strip('[]') - if scheme in NORMALIZABLE_SCHEMES: - host = host.lower() - return host diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_appengine_environ.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_appengine_environ.py deleted file mode 100644 index f3e0094..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_appengine_environ.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -This module provides means to detect the App Engine environment. -""" - -import os - - -def is_appengine(): - return (is_local_appengine() or - is_prod_appengine() or - is_prod_appengine_mvms()) - - -def is_appengine_sandbox(): - return is_appengine() and not is_prod_appengine_mvms() - - -def is_local_appengine(): - return ('APPENGINE_RUNTIME' in os.environ and - 'Development/' in os.environ['SERVER_SOFTWARE']) - - -def is_prod_appengine(): - return ('APPENGINE_RUNTIME' in os.environ and - 'Google App Engine/' in os.environ['SERVER_SOFTWARE'] and - not is_prod_appengine_mvms()) - - -def is_prod_appengine_mvms(): - return os.environ.get('GAE_VM', False) == 'true' diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py deleted file mode 100644 index bcf41c0..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +++ /dev/null @@ -1,593 +0,0 @@ -""" -This module uses ctypes to bind a whole bunch of functions and constants from -SecureTransport. The goal here is to provide the low-level API to -SecureTransport. These are essentially the C-level functions and constants, and -they're pretty gross to work with. - -This code is a bastardised version of the code found in Will Bond's oscrypto -library. An enormous debt is owed to him for blazing this trail for us. For -that reason, this code should be considered to be covered both by urllib3's -license and by oscrypto's: - - Copyright (c) 2015-2016 Will Bond <will@wbond.net> - - 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. -""" -from __future__ import absolute_import - -import platform -from ctypes.util import find_library -from ctypes import ( - c_void_p, c_int32, c_char_p, c_size_t, c_byte, c_uint32, c_ulong, c_long, - c_bool -) -from ctypes import CDLL, POINTER, CFUNCTYPE - - -security_path = find_library('Security') -if not security_path: - raise ImportError('The library Security could not be found') - - -core_foundation_path = find_library('CoreFoundation') -if not core_foundation_path: - raise ImportError('The library CoreFoundation could not be found') - - -version = platform.mac_ver()[0] -version_info = tuple(map(int, version.split('.'))) -if version_info < (10, 8): - raise OSError( - 'Only OS X 10.8 and newer are supported, not %s.%s' % ( - version_info[0], version_info[1] - ) - ) - -Security = CDLL(security_path, use_errno=True) -CoreFoundation = CDLL(core_foundation_path, use_errno=True) - -Boolean = c_bool -CFIndex = c_long -CFStringEncoding = c_uint32 -CFData = c_void_p -CFString = c_void_p -CFArray = c_void_p -CFMutableArray = c_void_p -CFDictionary = c_void_p -CFError = c_void_p -CFType = c_void_p -CFTypeID = c_ulong - -CFTypeRef = POINTER(CFType) -CFAllocatorRef = c_void_p - -OSStatus = c_int32 - -CFDataRef = POINTER(CFData) -CFStringRef = POINTER(CFString) -CFArrayRef = POINTER(CFArray) -CFMutableArrayRef = POINTER(CFMutableArray) -CFDictionaryRef = POINTER(CFDictionary) -CFArrayCallBacks = c_void_p -CFDictionaryKeyCallBacks = c_void_p -CFDictionaryValueCallBacks = c_void_p - -SecCertificateRef = POINTER(c_void_p) -SecExternalFormat = c_uint32 -SecExternalItemType = c_uint32 -SecIdentityRef = POINTER(c_void_p) -SecItemImportExportFlags = c_uint32 -SecItemImportExportKeyParameters = c_void_p -SecKeychainRef = POINTER(c_void_p) -SSLProtocol = c_uint32 -SSLCipherSuite = c_uint32 -SSLContextRef = POINTER(c_void_p) -SecTrustRef = POINTER(c_void_p) -SSLConnectionRef = c_uint32 -SecTrustResultType = c_uint32 -SecTrustOptionFlags = c_uint32 -SSLProtocolSide = c_uint32 -SSLConnectionType = c_uint32 -SSLSessionOption = c_uint32 - - -try: - Security.SecItemImport.argtypes = [ - CFDataRef, - CFStringRef, - POINTER(SecExternalFormat), - POINTER(SecExternalItemType), - SecItemImportExportFlags, - POINTER(SecItemImportExportKeyParameters), - SecKeychainRef, - POINTER(CFArrayRef), - ] - Security.SecItemImport.restype = OSStatus - - Security.SecCertificateGetTypeID.argtypes = [] - Security.SecCertificateGetTypeID.restype = CFTypeID - - Security.SecIdentityGetTypeID.argtypes = [] - Security.SecIdentityGetTypeID.restype = CFTypeID - - Security.SecKeyGetTypeID.argtypes = [] - Security.SecKeyGetTypeID.restype = CFTypeID - - Security.SecCertificateCreateWithData.argtypes = [ - CFAllocatorRef, - CFDataRef - ] - Security.SecCertificateCreateWithData.restype = SecCertificateRef - - Security.SecCertificateCopyData.argtypes = [ - SecCertificateRef - ] - Security.SecCertificateCopyData.restype = CFDataRef - - Security.SecCopyErrorMessageString.argtypes = [ - OSStatus, - c_void_p - ] - Security.SecCopyErrorMessageString.restype = CFStringRef - - Security.SecIdentityCreateWithCertificate.argtypes = [ - CFTypeRef, - SecCertificateRef, - POINTER(SecIdentityRef) - ] - Security.SecIdentityCreateWithCertificate.restype = OSStatus - - Security.SecKeychainCreate.argtypes = [ - c_char_p, - c_uint32, - c_void_p, - Boolean, - c_void_p, - POINTER(SecKeychainRef) - ] - Security.SecKeychainCreate.restype = OSStatus - - Security.SecKeychainDelete.argtypes = [ - SecKeychainRef - ] - Security.SecKeychainDelete.restype = OSStatus - - Security.SecPKCS12Import.argtypes = [ - CFDataRef, - CFDictionaryRef, - POINTER(CFArrayRef) - ] - Security.SecPKCS12Import.restype = OSStatus - - SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) - SSLWriteFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)) - - Security.SSLSetIOFuncs.argtypes = [ - SSLContextRef, - SSLReadFunc, - SSLWriteFunc - ] - Security.SSLSetIOFuncs.restype = OSStatus - - Security.SSLSetPeerID.argtypes = [ - SSLContextRef, - c_char_p, - c_size_t - ] - Security.SSLSetPeerID.restype = OSStatus - - Security.SSLSetCertificate.argtypes = [ - SSLContextRef, - CFArrayRef - ] - Security.SSLSetCertificate.restype = OSStatus - - Security.SSLSetCertificateAuthorities.argtypes = [ - SSLContextRef, - CFTypeRef, - Boolean - ] - Security.SSLSetCertificateAuthorities.restype = OSStatus - - Security.SSLSetConnection.argtypes = [ - SSLContextRef, - SSLConnectionRef - ] - Security.SSLSetConnection.restype = OSStatus - - Security.SSLSetPeerDomainName.argtypes = [ - SSLContextRef, - c_char_p, - c_size_t - ] - Security.SSLSetPeerDomainName.restype = OSStatus - - Security.SSLHandshake.argtypes = [ - SSLContextRef - ] - Security.SSLHandshake.restype = OSStatus - - Security.SSLRead.argtypes = [ - SSLContextRef, - c_char_p, - c_size_t, - POINTER(c_size_t) - ] - Security.SSLRead.restype = OSStatus - - Security.SSLWrite.argtypes = [ - SSLContextRef, - c_char_p, - c_size_t, - POINTER(c_size_t) - ] - Security.SSLWrite.restype = OSStatus - - Security.SSLClose.argtypes = [ - SSLContextRef - ] - Security.SSLClose.restype = OSStatus - - Security.SSLGetNumberSupportedCiphers.argtypes = [ - SSLContextRef, - POINTER(c_size_t) - ] - Security.SSLGetNumberSupportedCiphers.restype = OSStatus - - Security.SSLGetSupportedCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - POINTER(c_size_t) - ] - Security.SSLGetSupportedCiphers.restype = OSStatus - - Security.SSLSetEnabledCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - c_size_t - ] - Security.SSLSetEnabledCiphers.restype = OSStatus - - Security.SSLGetNumberEnabledCiphers.argtype = [ - SSLContextRef, - POINTER(c_size_t) - ] - Security.SSLGetNumberEnabledCiphers.restype = OSStatus - - Security.SSLGetEnabledCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - POINTER(c_size_t) - ] - Security.SSLGetEnabledCiphers.restype = OSStatus - - Security.SSLGetNegotiatedCipher.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite) - ] - Security.SSLGetNegotiatedCipher.restype = OSStatus - - Security.SSLGetNegotiatedProtocolVersion.argtypes = [ - SSLContextRef, - POINTER(SSLProtocol) - ] - Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus - - Security.SSLCopyPeerTrust.argtypes = [ - SSLContextRef, - POINTER(SecTrustRef) - ] - Security.SSLCopyPeerTrust.restype = OSStatus - - Security.SecTrustSetAnchorCertificates.argtypes = [ - SecTrustRef, - CFArrayRef - ] - Security.SecTrustSetAnchorCertificates.restype = OSStatus - - Security.SecTrustSetAnchorCertificatesOnly.argstypes = [ - SecTrustRef, - Boolean - ] - Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus - - Security.SecTrustEvaluate.argtypes = [ - SecTrustRef, - POINTER(SecTrustResultType) - ] - Security.SecTrustEvaluate.restype = OSStatus - - Security.SecTrustGetCertificateCount.argtypes = [ - SecTrustRef - ] - Security.SecTrustGetCertificateCount.restype = CFIndex - - Security.SecTrustGetCertificateAtIndex.argtypes = [ - SecTrustRef, - CFIndex - ] - Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef - - Security.SSLCreateContext.argtypes = [ - CFAllocatorRef, - SSLProtocolSide, - SSLConnectionType - ] - Security.SSLCreateContext.restype = SSLContextRef - - Security.SSLSetSessionOption.argtypes = [ - SSLContextRef, - SSLSessionOption, - Boolean - ] - Security.SSLSetSessionOption.restype = OSStatus - - Security.SSLSetProtocolVersionMin.argtypes = [ - SSLContextRef, - SSLProtocol - ] - Security.SSLSetProtocolVersionMin.restype = OSStatus - - Security.SSLSetProtocolVersionMax.argtypes = [ - SSLContextRef, - SSLProtocol - ] - Security.SSLSetProtocolVersionMax.restype = OSStatus - - Security.SecCopyErrorMessageString.argtypes = [ - OSStatus, - c_void_p - ] - Security.SecCopyErrorMessageString.restype = CFStringRef - - Security.SSLReadFunc = SSLReadFunc - Security.SSLWriteFunc = SSLWriteFunc - Security.SSLContextRef = SSLContextRef - Security.SSLProtocol = SSLProtocol - Security.SSLCipherSuite = SSLCipherSuite - Security.SecIdentityRef = SecIdentityRef - Security.SecKeychainRef = SecKeychainRef - Security.SecTrustRef = SecTrustRef - Security.SecTrustResultType = SecTrustResultType - Security.SecExternalFormat = SecExternalFormat - Security.OSStatus = OSStatus - - Security.kSecImportExportPassphrase = CFStringRef.in_dll( - Security, 'kSecImportExportPassphrase' - ) - Security.kSecImportItemIdentity = CFStringRef.in_dll( - Security, 'kSecImportItemIdentity' - ) - - # CoreFoundation time! - CoreFoundation.CFRetain.argtypes = [ - CFTypeRef - ] - CoreFoundation.CFRetain.restype = CFTypeRef - - CoreFoundation.CFRelease.argtypes = [ - CFTypeRef - ] - CoreFoundation.CFRelease.restype = None - - CoreFoundation.CFGetTypeID.argtypes = [ - CFTypeRef - ] - CoreFoundation.CFGetTypeID.restype = CFTypeID - - CoreFoundation.CFStringCreateWithCString.argtypes = [ - CFAllocatorRef, - c_char_p, - CFStringEncoding - ] - CoreFoundation.CFStringCreateWithCString.restype = CFStringRef - - CoreFoundation.CFStringGetCStringPtr.argtypes = [ - CFStringRef, - CFStringEncoding - ] - CoreFoundation.CFStringGetCStringPtr.restype = c_char_p - - CoreFoundation.CFStringGetCString.argtypes = [ - CFStringRef, - c_char_p, - CFIndex, - CFStringEncoding - ] - CoreFoundation.CFStringGetCString.restype = c_bool - - CoreFoundation.CFDataCreate.argtypes = [ - CFAllocatorRef, - c_char_p, - CFIndex - ] - CoreFoundation.CFDataCreate.restype = CFDataRef - - CoreFoundation.CFDataGetLength.argtypes = [ - CFDataRef - ] - CoreFoundation.CFDataGetLength.restype = CFIndex - - CoreFoundation.CFDataGetBytePtr.argtypes = [ - CFDataRef - ] - CoreFoundation.CFDataGetBytePtr.restype = c_void_p - - CoreFoundation.CFDictionaryCreate.argtypes = [ - CFAllocatorRef, - POINTER(CFTypeRef), - POINTER(CFTypeRef), - CFIndex, - CFDictionaryKeyCallBacks, - CFDictionaryValueCallBacks - ] - CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef - - CoreFoundation.CFDictionaryGetValue.argtypes = [ - CFDictionaryRef, - CFTypeRef - ] - CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef - - CoreFoundation.CFArrayCreate.argtypes = [ - CFAllocatorRef, - POINTER(CFTypeRef), - CFIndex, - CFArrayCallBacks, - ] - CoreFoundation.CFArrayCreate.restype = CFArrayRef - - CoreFoundation.CFArrayCreateMutable.argtypes = [ - CFAllocatorRef, - CFIndex, - CFArrayCallBacks - ] - CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef - - CoreFoundation.CFArrayAppendValue.argtypes = [ - CFMutableArrayRef, - c_void_p - ] - CoreFoundation.CFArrayAppendValue.restype = None - - CoreFoundation.CFArrayGetCount.argtypes = [ - CFArrayRef - ] - CoreFoundation.CFArrayGetCount.restype = CFIndex - - CoreFoundation.CFArrayGetValueAtIndex.argtypes = [ - CFArrayRef, - CFIndex - ] - CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p - - CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( - CoreFoundation, 'kCFAllocatorDefault' - ) - CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks') - CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( - CoreFoundation, 'kCFTypeDictionaryKeyCallBacks' - ) - CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( - CoreFoundation, 'kCFTypeDictionaryValueCallBacks' - ) - - CoreFoundation.CFTypeRef = CFTypeRef - CoreFoundation.CFArrayRef = CFArrayRef - CoreFoundation.CFStringRef = CFStringRef - CoreFoundation.CFDictionaryRef = CFDictionaryRef - -except (AttributeError): - raise ImportError('Error initializing ctypes') - - -class CFConst(object): - """ - A class object that acts as essentially a namespace for CoreFoundation - constants. - """ - kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) - - -class SecurityConst(object): - """ - A class object that acts as essentially a namespace for Security constants. - """ - kSSLSessionOptionBreakOnServerAuth = 0 - - kSSLProtocol2 = 1 - kSSLProtocol3 = 2 - kTLSProtocol1 = 4 - kTLSProtocol11 = 7 - kTLSProtocol12 = 8 - - kSSLClientSide = 1 - kSSLStreamType = 0 - - kSecFormatPEMSequence = 10 - - kSecTrustResultInvalid = 0 - kSecTrustResultProceed = 1 - # This gap is present on purpose: this was kSecTrustResultConfirm, which - # is deprecated. - kSecTrustResultDeny = 3 - kSecTrustResultUnspecified = 4 - kSecTrustResultRecoverableTrustFailure = 5 - kSecTrustResultFatalTrustFailure = 6 - kSecTrustResultOtherError = 7 - - errSSLProtocol = -9800 - errSSLWouldBlock = -9803 - errSSLClosedGraceful = -9805 - errSSLClosedNoNotify = -9816 - errSSLClosedAbort = -9806 - - errSSLXCertChainInvalid = -9807 - errSSLCrypto = -9809 - errSSLInternal = -9810 - errSSLCertExpired = -9814 - errSSLCertNotYetValid = -9815 - errSSLUnknownRootCert = -9812 - errSSLNoRootCert = -9813 - errSSLHostNameMismatch = -9843 - errSSLPeerHandshakeFail = -9824 - errSSLPeerUserCancelled = -9839 - errSSLWeakPeerEphemeralDHKey = -9850 - errSSLServerAuthCompleted = -9841 - errSSLRecordOverflow = -9847 - - errSecVerifyFailed = -67808 - errSecNoTrustSettings = -25263 - errSecItemNotFound = -25300 - errSecInvalidTrustSettings = -25262 - - # Cipher suites. We only pick the ones our default cipher string allows. - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F - TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3 - TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F - TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2 - TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 - TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B - TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A - TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 - TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 - TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 - TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040 - TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 - TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032 - TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D - TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C - TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D - TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C - TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 - TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F - TLS_AES_128_GCM_SHA256 = 0x1301 - TLS_AES_256_GCM_SHA384 = 0x1302 - TLS_CHACHA20_POLY1305_SHA256 = 0x1303 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py deleted file mode 100644 index b13cd9e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +++ /dev/null @@ -1,346 +0,0 @@ -""" -Low-level helpers for the SecureTransport bindings. - -These are Python functions that are not directly related to the high-level APIs -but are necessary to get them to work. They include a whole bunch of low-level -CoreFoundation messing about and memory management. The concerns in this module -are almost entirely about trying to avoid memory leaks and providing -appropriate and useful assistance to the higher-level code. -""" -import base64 -import ctypes -import itertools -import re -import os -import ssl -import tempfile - -from .bindings import Security, CoreFoundation, CFConst - - -# This regular expression is used to grab PEM data out of a PEM bundle. -_PEM_CERTS_RE = re.compile( - b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL -) - - -def _cf_data_from_bytes(bytestring): - """ - Given a bytestring, create a CFData object from it. This CFData object must - be CFReleased by the caller. - """ - return CoreFoundation.CFDataCreate( - CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) - ) - - -def _cf_dictionary_from_tuples(tuples): - """ - Given a list of Python tuples, create an associated CFDictionary. - """ - dictionary_size = len(tuples) - - # We need to get the dictionary keys and values out in the same order. - keys = (t[0] for t in tuples) - values = (t[1] for t in tuples) - cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) - cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) - - return CoreFoundation.CFDictionaryCreate( - CoreFoundation.kCFAllocatorDefault, - cf_keys, - cf_values, - dictionary_size, - CoreFoundation.kCFTypeDictionaryKeyCallBacks, - CoreFoundation.kCFTypeDictionaryValueCallBacks, - ) - - -def _cf_string_to_unicode(value): - """ - Creates a Unicode string from a CFString object. Used entirely for error - reporting. - - Yes, it annoys me quite a lot that this function is this complex. - """ - value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) - - string = CoreFoundation.CFStringGetCStringPtr( - value_as_void_p, - CFConst.kCFStringEncodingUTF8 - ) - if string is None: - buffer = ctypes.create_string_buffer(1024) - result = CoreFoundation.CFStringGetCString( - value_as_void_p, - buffer, - 1024, - CFConst.kCFStringEncodingUTF8 - ) - if not result: - raise OSError('Error copying C string from CFStringRef') - string = buffer.value - if string is not None: - string = string.decode('utf-8') - return string - - -def _assert_no_error(error, exception_class=None): - """ - Checks the return code and throws an exception if there is an error to - report - """ - if error == 0: - return - - cf_error_string = Security.SecCopyErrorMessageString(error, None) - output = _cf_string_to_unicode(cf_error_string) - CoreFoundation.CFRelease(cf_error_string) - - if output is None or output == u'': - output = u'OSStatus %s' % error - - if exception_class is None: - exception_class = ssl.SSLError - - raise exception_class(output) - - -def _cert_array_from_pem(pem_bundle): - """ - Given a bundle of certs in PEM format, turns them into a CFArray of certs - that can be used to validate a cert chain. - """ - # Normalize the PEM bundle's line endings. - pem_bundle = pem_bundle.replace(b"\r\n", b"\n") - - der_certs = [ - base64.b64decode(match.group(1)) - for match in _PEM_CERTS_RE.finditer(pem_bundle) - ] - if not der_certs: - raise ssl.SSLError("No root certificates specified") - - cert_array = CoreFoundation.CFArrayCreateMutable( - CoreFoundation.kCFAllocatorDefault, - 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks) - ) - if not cert_array: - raise ssl.SSLError("Unable to allocate memory!") - - try: - for der_bytes in der_certs: - certdata = _cf_data_from_bytes(der_bytes) - if not certdata: - raise ssl.SSLError("Unable to allocate memory!") - cert = Security.SecCertificateCreateWithData( - CoreFoundation.kCFAllocatorDefault, certdata - ) - CoreFoundation.CFRelease(certdata) - if not cert: - raise ssl.SSLError("Unable to build cert object!") - - CoreFoundation.CFArrayAppendValue(cert_array, cert) - CoreFoundation.CFRelease(cert) - except Exception: - # We need to free the array before the exception bubbles further. - # We only want to do that if an error occurs: otherwise, the caller - # should free. - CoreFoundation.CFRelease(cert_array) - - return cert_array - - -def _is_cert(item): - """ - Returns True if a given CFTypeRef is a certificate. - """ - expected = Security.SecCertificateGetTypeID() - return CoreFoundation.CFGetTypeID(item) == expected - - -def _is_identity(item): - """ - Returns True if a given CFTypeRef is an identity. - """ - expected = Security.SecIdentityGetTypeID() - return CoreFoundation.CFGetTypeID(item) == expected - - -def _temporary_keychain(): - """ - This function creates a temporary Mac keychain that we can use to work with - credentials. This keychain uses a one-time password and a temporary file to - store the data. We expect to have one keychain per socket. The returned - SecKeychainRef must be freed by the caller, including calling - SecKeychainDelete. - - Returns a tuple of the SecKeychainRef and the path to the temporary - directory that contains it. - """ - # Unfortunately, SecKeychainCreate requires a path to a keychain. This - # means we cannot use mkstemp to use a generic temporary file. Instead, - # we're going to create a temporary directory and a filename to use there. - # This filename will be 8 random bytes expanded into base64. We also need - # some random bytes to password-protect the keychain we're creating, so we - # ask for 40 random bytes. - random_bytes = os.urandom(40) - filename = base64.b16encode(random_bytes[:8]).decode('utf-8') - password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8 - tempdirectory = tempfile.mkdtemp() - - keychain_path = os.path.join(tempdirectory, filename).encode('utf-8') - - # We now want to create the keychain itself. - keychain = Security.SecKeychainRef() - status = Security.SecKeychainCreate( - keychain_path, - len(password), - password, - False, - None, - ctypes.byref(keychain) - ) - _assert_no_error(status) - - # Having created the keychain, we want to pass it off to the caller. - return keychain, tempdirectory - - -def _load_items_from_file(keychain, path): - """ - Given a single file, loads all the trust objects from it into arrays and - the keychain. - Returns a tuple of lists: the first list is a list of identities, the - second a list of certs. - """ - certificates = [] - identities = [] - result_array = None - - with open(path, 'rb') as f: - raw_filedata = f.read() - - try: - filedata = CoreFoundation.CFDataCreate( - CoreFoundation.kCFAllocatorDefault, - raw_filedata, - len(raw_filedata) - ) - result_array = CoreFoundation.CFArrayRef() - result = Security.SecItemImport( - filedata, # cert data - None, # Filename, leaving it out for now - None, # What the type of the file is, we don't care - None, # what's in the file, we don't care - 0, # import flags - None, # key params, can include passphrase in the future - keychain, # The keychain to insert into - ctypes.byref(result_array) # Results - ) - _assert_no_error(result) - - # A CFArray is not very useful to us as an intermediary - # representation, so we are going to extract the objects we want - # and then free the array. We don't need to keep hold of keys: the - # keychain already has them! - result_count = CoreFoundation.CFArrayGetCount(result_array) - for index in range(result_count): - item = CoreFoundation.CFArrayGetValueAtIndex( - result_array, index - ) - item = ctypes.cast(item, CoreFoundation.CFTypeRef) - - if _is_cert(item): - CoreFoundation.CFRetain(item) - certificates.append(item) - elif _is_identity(item): - CoreFoundation.CFRetain(item) - identities.append(item) - finally: - if result_array: - CoreFoundation.CFRelease(result_array) - - CoreFoundation.CFRelease(filedata) - - return (identities, certificates) - - -def _load_client_cert_chain(keychain, *paths): - """ - Load certificates and maybe keys from a number of files. Has the end goal - of returning a CFArray containing one SecIdentityRef, and then zero or more - SecCertificateRef objects, suitable for use as a client certificate trust - chain. - """ - # Ok, the strategy. - # - # This relies on knowing that macOS will not give you a SecIdentityRef - # unless you have imported a key into a keychain. This is a somewhat - # artificial limitation of macOS (for example, it doesn't necessarily - # affect iOS), but there is nothing inside Security.framework that lets you - # get a SecIdentityRef without having a key in a keychain. - # - # So the policy here is we take all the files and iterate them in order. - # Each one will use SecItemImport to have one or more objects loaded from - # it. We will also point at a keychain that macOS can use to work with the - # private key. - # - # Once we have all the objects, we'll check what we actually have. If we - # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, - # we'll take the first certificate (which we assume to be our leaf) and - # ask the keychain to give us a SecIdentityRef with that cert's associated - # key. - # - # We'll then return a CFArray containing the trust chain: one - # SecIdentityRef and then zero-or-more SecCertificateRef objects. The - # responsibility for freeing this CFArray will be with the caller. This - # CFArray must remain alive for the entire connection, so in practice it - # will be stored with a single SSLSocket, along with the reference to the - # keychain. - certificates = [] - identities = [] - - # Filter out bad paths. - paths = (path for path in paths if path) - - try: - for file_path in paths: - new_identities, new_certs = _load_items_from_file( - keychain, file_path - ) - identities.extend(new_identities) - certificates.extend(new_certs) - - # Ok, we have everything. The question is: do we have an identity? If - # not, we want to grab one from the first cert we have. - if not identities: - new_identity = Security.SecIdentityRef() - status = Security.SecIdentityCreateWithCertificate( - keychain, - certificates[0], - ctypes.byref(new_identity) - ) - _assert_no_error(status) - identities.append(new_identity) - - # We now want to release the original certificate, as we no longer - # need it. - CoreFoundation.CFRelease(certificates.pop(0)) - - # We now need to build a new CFArray that holds the trust chain. - trust_chain = CoreFoundation.CFArrayCreateMutable( - CoreFoundation.kCFAllocatorDefault, - 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), - ) - for item in itertools.chain(identities, certificates): - # ArrayAppendValue does a CFRetain on the item. That's fine, - # because the finally block will release our other refs to them. - CoreFoundation.CFArrayAppendValue(trust_chain, item) - - return trust_chain - finally: - for obj in itertools.chain(identities, certificates): - CoreFoundation.CFRelease(obj) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/appengine.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/appengine.py deleted file mode 100644 index 9b42952..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/appengine.py +++ /dev/null @@ -1,289 +0,0 @@ -""" -This module provides a pool manager that uses Google App Engine's -`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_. - -Example usage:: - - from pip._vendor.urllib3 import PoolManager - from pip._vendor.urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox - - if is_appengine_sandbox(): - # AppEngineManager uses AppEngine's URLFetch API behind the scenes - http = AppEngineManager() - else: - # PoolManager uses a socket-level API behind the scenes - http = PoolManager() - - r = http.request('GET', 'https://google.com/') - -There are `limitations <https://cloud.google.com/appengine/docs/python/\ -urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be -the best choice for your application. There are three options for using -urllib3 on Google App Engine: - -1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is - cost-effective in many circumstances as long as your usage is within the - limitations. -2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets. - Sockets also have `limitations and restrictions - <https://cloud.google.com/appengine/docs/python/sockets/\ - #limitations-and-restrictions>`_ and have a lower free quota than URLFetch. - To use sockets, be sure to specify the following in your ``app.yaml``:: - - env_variables: - GAE_USE_SOCKETS_HTTPLIB : 'true' - -3. If you are using `App Engine Flexible -<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard -:class:`PoolManager` without any configuration or special environment variables. -""" - -from __future__ import absolute_import -import io -import logging -import warnings -from ..packages.six.moves.urllib.parse import urljoin - -from ..exceptions import ( - HTTPError, - HTTPWarning, - MaxRetryError, - ProtocolError, - TimeoutError, - SSLError -) - -from ..request import RequestMethods -from ..response import HTTPResponse -from ..util.timeout import Timeout -from ..util.retry import Retry -from . import _appengine_environ - -try: - from google.appengine.api import urlfetch -except ImportError: - urlfetch = None - - -log = logging.getLogger(__name__) - - -class AppEnginePlatformWarning(HTTPWarning): - pass - - -class AppEnginePlatformError(HTTPError): - pass - - -class AppEngineManager(RequestMethods): - """ - Connection manager for Google App Engine sandbox applications. - - This manager uses the URLFetch service directly instead of using the - emulated httplib, and is subject to URLFetch limitations as described in - the App Engine documentation `here - <https://cloud.google.com/appengine/docs/python/urlfetch>`_. - - Notably it will raise an :class:`AppEnginePlatformError` if: - * URLFetch is not available. - * If you attempt to use this on App Engine Flexible, as full socket - support is available. - * If a request size is more than 10 megabytes. - * If a response size is more than 32 megabtyes. - * If you use an unsupported request method such as OPTIONS. - - Beyond those cases, it will raise normal urllib3 errors. - """ - - def __init__(self, headers=None, retries=None, validate_certificate=True, - urlfetch_retries=True): - if not urlfetch: - raise AppEnginePlatformError( - "URLFetch is not available in this environment.") - - if is_prod_appengine_mvms(): - raise AppEnginePlatformError( - "Use normal urllib3.PoolManager instead of AppEngineManager" - "on Managed VMs, as using URLFetch is not necessary in " - "this environment.") - - warnings.warn( - "urllib3 is using URLFetch on Google App Engine sandbox instead " - "of sockets. To use sockets directly instead of URLFetch see " - "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.", - AppEnginePlatformWarning) - - RequestMethods.__init__(self, headers) - self.validate_certificate = validate_certificate - self.urlfetch_retries = urlfetch_retries - - self.retries = retries or Retry.DEFAULT - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - # Return False to re-raise any potential exceptions - return False - - def urlopen(self, method, url, body=None, headers=None, - retries=None, redirect=True, timeout=Timeout.DEFAULT_TIMEOUT, - **response_kw): - - retries = self._get_retries(retries, redirect) - - try: - follow_redirects = ( - redirect and - retries.redirect != 0 and - retries.total) - response = urlfetch.fetch( - url, - payload=body, - method=method, - headers=headers or {}, - allow_truncated=False, - follow_redirects=self.urlfetch_retries and follow_redirects, - deadline=self._get_absolute_timeout(timeout), - validate_certificate=self.validate_certificate, - ) - except urlfetch.DeadlineExceededError as e: - raise TimeoutError(self, e) - - except urlfetch.InvalidURLError as e: - if 'too large' in str(e): - raise AppEnginePlatformError( - "URLFetch request too large, URLFetch only " - "supports requests up to 10mb in size.", e) - raise ProtocolError(e) - - except urlfetch.DownloadError as e: - if 'Too many redirects' in str(e): - raise MaxRetryError(self, url, reason=e) - raise ProtocolError(e) - - except urlfetch.ResponseTooLargeError as e: - raise AppEnginePlatformError( - "URLFetch response too large, URLFetch only supports" - "responses up to 32mb in size.", e) - - except urlfetch.SSLCertificateError as e: - raise SSLError(e) - - except urlfetch.InvalidMethodError as e: - raise AppEnginePlatformError( - "URLFetch does not support method: %s" % method, e) - - http_response = self._urlfetch_response_to_http_response( - response, retries=retries, **response_kw) - - # Handle redirect? - redirect_location = redirect and http_response.get_redirect_location() - if redirect_location: - # Check for redirect response - if (self.urlfetch_retries and retries.raise_on_redirect): - raise MaxRetryError(self, url, "too many redirects") - else: - if http_response.status == 303: - method = 'GET' - - try: - retries = retries.increment(method, url, response=http_response, _pool=self) - except MaxRetryError: - if retries.raise_on_redirect: - raise MaxRetryError(self, url, "too many redirects") - return http_response - - retries.sleep_for_retry(http_response) - log.debug("Redirecting %s -> %s", url, redirect_location) - redirect_url = urljoin(url, redirect_location) - return self.urlopen( - method, redirect_url, body, headers, - retries=retries, redirect=redirect, - timeout=timeout, **response_kw) - - # Check if we should retry the HTTP response. - has_retry_after = bool(http_response.getheader('Retry-After')) - if retries.is_retry(method, http_response.status, has_retry_after): - retries = retries.increment( - method, url, response=http_response, _pool=self) - log.debug("Retry: %s", url) - retries.sleep(http_response) - return self.urlopen( - method, url, - body=body, headers=headers, - retries=retries, redirect=redirect, - timeout=timeout, **response_kw) - - return http_response - - def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw): - - if is_prod_appengine(): - # Production GAE handles deflate encoding automatically, but does - # not remove the encoding header. - content_encoding = urlfetch_resp.headers.get('content-encoding') - - if content_encoding == 'deflate': - del urlfetch_resp.headers['content-encoding'] - - transfer_encoding = urlfetch_resp.headers.get('transfer-encoding') - # We have a full response's content, - # so let's make sure we don't report ourselves as chunked data. - if transfer_encoding == 'chunked': - encodings = transfer_encoding.split(",") - encodings.remove('chunked') - urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings) - - original_response = HTTPResponse( - # In order for decoding to work, we must present the content as - # a file-like object. - body=io.BytesIO(urlfetch_resp.content), - msg=urlfetch_resp.header_msg, - headers=urlfetch_resp.headers, - status=urlfetch_resp.status_code, - **response_kw - ) - - return HTTPResponse( - body=io.BytesIO(urlfetch_resp.content), - headers=urlfetch_resp.headers, - status=urlfetch_resp.status_code, - original_response=original_response, - **response_kw - ) - - def _get_absolute_timeout(self, timeout): - if timeout is Timeout.DEFAULT_TIMEOUT: - return None # Defer to URLFetch's default. - if isinstance(timeout, Timeout): - if timeout._read is not None or timeout._connect is not None: - warnings.warn( - "URLFetch does not support granular timeout settings, " - "reverting to total or default URLFetch timeout.", - AppEnginePlatformWarning) - return timeout.total - return timeout - - def _get_retries(self, retries, redirect): - if not isinstance(retries, Retry): - retries = Retry.from_int( - retries, redirect=redirect, default=self.retries) - - if retries.connect or retries.read or retries.redirect: - warnings.warn( - "URLFetch only supports total retries and does not " - "recognize connect, read, or redirect retry parameters.", - AppEnginePlatformWarning) - - return retries - - -# Alias methods from _appengine_environ to maintain public API interface. - -is_appengine = _appengine_environ.is_appengine -is_appengine_sandbox = _appengine_environ.is_appengine_sandbox -is_local_appengine = _appengine_environ.is_local_appengine -is_prod_appengine = _appengine_environ.is_prod_appengine -is_prod_appengine_mvms = _appengine_environ.is_prod_appengine_mvms diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/ntlmpool.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/ntlmpool.py deleted file mode 100644 index 8ea127c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/ntlmpool.py +++ /dev/null @@ -1,111 +0,0 @@ -""" -NTLM authenticating pool, contributed by erikcederstran - -Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 -""" -from __future__ import absolute_import - -from logging import getLogger -from ntlm import ntlm - -from .. import HTTPSConnectionPool -from ..packages.six.moves.http_client import HTTPSConnection - - -log = getLogger(__name__) - - -class NTLMConnectionPool(HTTPSConnectionPool): - """ - Implements an NTLM authentication version of an urllib3 connection pool - """ - - scheme = 'https' - - def __init__(self, user, pw, authurl, *args, **kwargs): - """ - authurl is a random URL on the server that is protected by NTLM. - user is the Windows user, probably in the DOMAIN\\username format. - pw is the password for the user. - """ - super(NTLMConnectionPool, self).__init__(*args, **kwargs) - self.authurl = authurl - self.rawuser = user - user_parts = user.split('\\', 1) - self.domain = user_parts[0].upper() - self.user = user_parts[1] - self.pw = pw - - def _new_conn(self): - # Performs the NTLM handshake that secures the connection. The socket - # must be kept open while requests are performed. - self.num_connections += 1 - log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s', - self.num_connections, self.host, self.authurl) - - headers = {'Connection': 'Keep-Alive'} - req_header = 'Authorization' - resp_header = 'www-authenticate' - - conn = HTTPSConnection(host=self.host, port=self.port) - - # Send negotiation message - headers[req_header] = ( - 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser)) - log.debug('Request headers: %s', headers) - conn.request('GET', self.authurl, None, headers) - res = conn.getresponse() - reshdr = dict(res.getheaders()) - log.debug('Response status: %s %s', res.status, res.reason) - log.debug('Response headers: %s', reshdr) - log.debug('Response data: %s [...]', res.read(100)) - - # Remove the reference to the socket, so that it can not be closed by - # the response object (we want to keep the socket open) - res.fp = None - - # Server should respond with a challenge message - auth_header_values = reshdr[resp_header].split(', ') - auth_header_value = None - for s in auth_header_values: - if s[:5] == 'NTLM ': - auth_header_value = s[5:] - if auth_header_value is None: - raise Exception('Unexpected %s response header: %s' % - (resp_header, reshdr[resp_header])) - - # Send authentication message - ServerChallenge, NegotiateFlags = \ - ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value) - auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, - self.user, - self.domain, - self.pw, - NegotiateFlags) - headers[req_header] = 'NTLM %s' % auth_msg - log.debug('Request headers: %s', headers) - conn.request('GET', self.authurl, None, headers) - res = conn.getresponse() - log.debug('Response status: %s %s', res.status, res.reason) - log.debug('Response headers: %s', dict(res.getheaders())) - log.debug('Response data: %s [...]', res.read()[:100]) - if res.status != 200: - if res.status == 401: - raise Exception('Server rejected request: wrong ' - 'username or password') - raise Exception('Wrong server response: %s %s' % - (res.status, res.reason)) - - res.fp = None - log.debug('Connection established') - return conn - - def urlopen(self, method, url, body=None, headers=None, retries=3, - redirect=True, assert_same_host=True): - if headers is None: - headers = {} - headers['Connection'] = 'Keep-Alive' - return super(NTLMConnectionPool, self).urlopen(method, url, body, - headers, retries, - redirect, - assert_same_host) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/pyopenssl.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/pyopenssl.py deleted file mode 100644 index 363667c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/pyopenssl.py +++ /dev/null @@ -1,466 +0,0 @@ -""" -SSL with SNI_-support for Python 2. Follow these instructions if you would -like to verify SSL certificates in Python 2. Note, the default libraries do -*not* do certificate checking; you need to do additional work to validate -certificates yourself. - -This needs the following packages installed: - -* pyOpenSSL (tested with 16.0.0) -* cryptography (minimum 1.3.4, from pyopenssl) -* idna (minimum 2.0, from cryptography) - -However, pyopenssl depends on cryptography, which depends on idna, so while we -use all three directly here we end up having relatively few packages required. - -You can install them with the following command: - - pip install pyopenssl cryptography idna - -To activate certificate checking, call -:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code -before you begin making HTTP requests. This can be done in a ``sitecustomize`` -module, or at any other time before your application begins using ``urllib3``, -like this:: - - try: - import urllib3.contrib.pyopenssl - urllib3.contrib.pyopenssl.inject_into_urllib3() - except ImportError: - pass - -Now you can use :mod:`urllib3` as you normally would, and it will support SNI -when the required modules are installed. - -Activating this module also has the positive side effect of disabling SSL/TLS -compression in Python 2 (see `CRIME attack`_). - -If you want to configure the default list of supported cipher suites, you can -set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable. - -.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication -.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) -""" -from __future__ import absolute_import - -import OpenSSL.SSL -from cryptography import x509 -from cryptography.hazmat.backends.openssl import backend as openssl_backend -from cryptography.hazmat.backends.openssl.x509 import _Certificate -try: - from cryptography.x509 import UnsupportedExtension -except ImportError: - # UnsupportedExtension is gone in cryptography >= 2.1.0 - class UnsupportedExtension(Exception): - pass - -from socket import timeout, error as SocketError -from io import BytesIO - -try: # Platform-specific: Python 2 - from socket import _fileobject -except ImportError: # Platform-specific: Python 3 - _fileobject = None - from ..packages.backports.makefile import backport_makefile - -import logging -import ssl -from ..packages import six -import sys - -from .. import util - -__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] - -# SNI always works. -HAS_SNI = True - -# Map from urllib3 to PyOpenSSL compatible parameter-values. -_openssl_versions = { - ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD, - ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, -} - -if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'): - _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD - -if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'): - _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD - -try: - _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD}) -except AttributeError: - pass - -_stdlib_to_openssl_verify = { - ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE, - ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER, - ssl.CERT_REQUIRED: - OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, -} -_openssl_to_stdlib_verify = dict( - (v, k) for k, v in _stdlib_to_openssl_verify.items() -) - -# OpenSSL will only write 16K at a time -SSL_WRITE_BLOCKSIZE = 16384 - -orig_util_HAS_SNI = util.HAS_SNI -orig_util_SSLContext = util.ssl_.SSLContext - - -log = logging.getLogger(__name__) - - -def inject_into_urllib3(): - 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.' - - _validate_dependencies_met() - - util.ssl_.SSLContext = PyOpenSSLContext - util.HAS_SNI = HAS_SNI - util.ssl_.HAS_SNI = HAS_SNI - util.IS_PYOPENSSL = True - util.ssl_.IS_PYOPENSSL = True - - -def extract_from_urllib3(): - 'Undo monkey-patching by :func:`inject_into_urllib3`.' - - util.ssl_.SSLContext = orig_util_SSLContext - util.HAS_SNI = orig_util_HAS_SNI - util.ssl_.HAS_SNI = orig_util_HAS_SNI - util.IS_PYOPENSSL = False - util.ssl_.IS_PYOPENSSL = False - - -def _validate_dependencies_met(): - """ - Verifies that PyOpenSSL's package-level dependencies have been met. - Throws `ImportError` if they are not met. - """ - # Method added in `cryptography==1.1`; not available in older versions - from cryptography.x509.extensions import Extensions - if getattr(Extensions, "get_extension_for_class", None) is None: - raise ImportError("'cryptography' module missing required functionality. " - "Try upgrading to v1.3.4 or newer.") - - # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 - # attribute is only present on those versions. - from OpenSSL.crypto import X509 - x509 = X509() - if getattr(x509, "_x509", None) is None: - raise ImportError("'pyOpenSSL' module missing required functionality. " - "Try upgrading to v0.14 or newer.") - - -def _dnsname_to_stdlib(name): - """ - Converts a dNSName SubjectAlternativeName field to the form used by the - standard library on the given Python version. - - Cryptography produces a dNSName as a unicode string that was idna-decoded - from ASCII bytes. We need to idna-encode that string to get it back, and - then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib - uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8). - - If the name cannot be idna-encoded then we return None signalling that - the name given should be skipped. - """ - def idna_encode(name): - """ - Borrowed wholesale from the Python Cryptography Project. It turns out - that we can't just safely call `idna.encode`: it can explode for - wildcard names. This avoids that problem. - """ - from pip._vendor import idna - - try: - for prefix in [u'*.', u'.']: - if name.startswith(prefix): - name = name[len(prefix):] - return prefix.encode('ascii') + idna.encode(name) - return idna.encode(name) - except idna.core.IDNAError: - return None - - name = idna_encode(name) - if name is None: - return None - elif sys.version_info >= (3, 0): - name = name.decode('utf-8') - return name - - -def get_subj_alt_name(peer_cert): - """ - Given an PyOpenSSL certificate, provides all the subject alternative names. - """ - # Pass the cert to cryptography, which has much better APIs for this. - if hasattr(peer_cert, "to_cryptography"): - cert = peer_cert.to_cryptography() - else: - # This is technically using private APIs, but should work across all - # relevant versions before PyOpenSSL got a proper API for this. - cert = _Certificate(openssl_backend, peer_cert._x509) - - # We want to find the SAN extension. Ask Cryptography to locate it (it's - # faster than looping in Python) - try: - ext = cert.extensions.get_extension_for_class( - x509.SubjectAlternativeName - ).value - except x509.ExtensionNotFound: - # No such extension, return the empty list. - return [] - except (x509.DuplicateExtension, UnsupportedExtension, - x509.UnsupportedGeneralNameType, UnicodeError) as e: - # A problem has been found with the quality of the certificate. Assume - # no SAN field is present. - log.warning( - "A problem was encountered with the certificate that prevented " - "urllib3 from finding the SubjectAlternativeName field. This can " - "affect certificate validation. The error was %s", - e, - ) - return [] - - # We want to return dNSName and iPAddress fields. We need to cast the IPs - # back to strings because the match_hostname function wants them as - # strings. - # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 - # decoded. This is pretty frustrating, but that's what the standard library - # does with certificates, and so we need to attempt to do the same. - # We also want to skip over names which cannot be idna encoded. - names = [ - ('DNS', name) for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName)) - if name is not None - ] - names.extend( - ('IP Address', str(name)) - for name in ext.get_values_for_type(x509.IPAddress) - ) - - return names - - -class WrappedSocket(object): - '''API-compatibility wrapper for Python OpenSSL's Connection-class. - - Note: _makefile_refs, _drop() and _reuse() are needed for the garbage - collector of pypy. - ''' - - def __init__(self, connection, socket, suppress_ragged_eofs=True): - self.connection = connection - self.socket = socket - self.suppress_ragged_eofs = suppress_ragged_eofs - self._makefile_refs = 0 - self._closed = False - - def fileno(self): - return self.socket.fileno() - - # Copy-pasted from Python 3.5 source code - def _decref_socketios(self): - if self._makefile_refs > 0: - self._makefile_refs -= 1 - if self._closed: - self.close() - - def recv(self, *args, **kwargs): - try: - data = self.connection.recv(*args, **kwargs) - except OpenSSL.SSL.SysCallError as e: - if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): - return b'' - else: - raise SocketError(str(e)) - except OpenSSL.SSL.ZeroReturnError as e: - if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: - return b'' - else: - raise - except OpenSSL.SSL.WantReadError: - if not util.wait_for_read(self.socket, self.socket.gettimeout()): - raise timeout('The read operation timed out') - else: - return self.recv(*args, **kwargs) - else: - return data - - def recv_into(self, *args, **kwargs): - try: - return self.connection.recv_into(*args, **kwargs) - except OpenSSL.SSL.SysCallError as e: - if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): - return 0 - else: - raise SocketError(str(e)) - except OpenSSL.SSL.ZeroReturnError as e: - if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: - return 0 - else: - raise - except OpenSSL.SSL.WantReadError: - if not util.wait_for_read(self.socket, self.socket.gettimeout()): - raise timeout('The read operation timed out') - else: - return self.recv_into(*args, **kwargs) - - def settimeout(self, timeout): - return self.socket.settimeout(timeout) - - def _send_until_done(self, data): - while True: - try: - return self.connection.send(data) - except OpenSSL.SSL.WantWriteError: - if not util.wait_for_write(self.socket, self.socket.gettimeout()): - raise timeout() - continue - except OpenSSL.SSL.SysCallError as e: - raise SocketError(str(e)) - - def sendall(self, data): - total_sent = 0 - while total_sent < len(data): - sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) - total_sent += sent - - def shutdown(self): - # FIXME rethrow compatible exceptions should we ever use this - self.connection.shutdown() - - def close(self): - if self._makefile_refs < 1: - try: - self._closed = True - return self.connection.close() - except OpenSSL.SSL.Error: - return - else: - self._makefile_refs -= 1 - - def getpeercert(self, binary_form=False): - x509 = self.connection.get_peer_certificate() - - if not x509: - return x509 - - if binary_form: - return OpenSSL.crypto.dump_certificate( - OpenSSL.crypto.FILETYPE_ASN1, - x509) - - return { - 'subject': ( - (('commonName', x509.get_subject().CN),), - ), - 'subjectAltName': get_subj_alt_name(x509) - } - - def _reuse(self): - self._makefile_refs += 1 - - def _drop(self): - if self._makefile_refs < 1: - self.close() - else: - self._makefile_refs -= 1 - - -if _fileobject: # Platform-specific: Python 2 - def makefile(self, mode, bufsize=-1): - self._makefile_refs += 1 - return _fileobject(self, mode, bufsize, close=True) -else: # Platform-specific: Python 3 - makefile = backport_makefile - -WrappedSocket.makefile = makefile - - -class PyOpenSSLContext(object): - """ - I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible - for translating the interface of the standard library ``SSLContext`` object - to calls into PyOpenSSL. - """ - def __init__(self, protocol): - self.protocol = _openssl_versions[protocol] - self._ctx = OpenSSL.SSL.Context(self.protocol) - self._options = 0 - self.check_hostname = False - - @property - def options(self): - return self._options - - @options.setter - def options(self, value): - self._options = value - self._ctx.set_options(value) - - @property - def verify_mode(self): - return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()] - - @verify_mode.setter - def verify_mode(self, value): - self._ctx.set_verify( - _stdlib_to_openssl_verify[value], - _verify_callback - ) - - def set_default_verify_paths(self): - self._ctx.set_default_verify_paths() - - def set_ciphers(self, ciphers): - if isinstance(ciphers, six.text_type): - ciphers = ciphers.encode('utf-8') - self._ctx.set_cipher_list(ciphers) - - def load_verify_locations(self, cafile=None, capath=None, cadata=None): - if cafile is not None: - cafile = cafile.encode('utf-8') - if capath is not None: - capath = capath.encode('utf-8') - self._ctx.load_verify_locations(cafile, capath) - if cadata is not None: - self._ctx.load_verify_locations(BytesIO(cadata)) - - def load_cert_chain(self, certfile, keyfile=None, password=None): - self._ctx.use_certificate_chain_file(certfile) - if password is not None: - self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password) - self._ctx.use_privatekey_file(keyfile or certfile) - - def wrap_socket(self, sock, server_side=False, - do_handshake_on_connect=True, suppress_ragged_eofs=True, - server_hostname=None): - cnx = OpenSSL.SSL.Connection(self._ctx, sock) - - if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3 - server_hostname = server_hostname.encode('utf-8') - - if server_hostname is not None: - cnx.set_tlsext_host_name(server_hostname) - - cnx.set_connect_state() - - while True: - try: - cnx.do_handshake() - except OpenSSL.SSL.WantReadError: - if not util.wait_for_read(sock, sock.gettimeout()): - raise timeout('select timed out') - continue - except OpenSSL.SSL.Error as e: - raise ssl.SSLError('bad handshake: %r' % e) - break - - return WrappedSocket(cnx, sock) - - -def _verify_callback(cnx, x509, err_no, err_depth, return_code): - return err_no == 0 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/securetransport.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/securetransport.py deleted file mode 100644 index 77cb59e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/securetransport.py +++ /dev/null @@ -1,804 +0,0 @@ -""" -SecureTranport support for urllib3 via ctypes. - -This makes platform-native TLS available to urllib3 users on macOS without the -use of a compiler. This is an important feature because the Python Package -Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL -that ships with macOS is not capable of doing TLSv1.2. The only way to resolve -this is to give macOS users an alternative solution to the problem, and that -solution is to use SecureTransport. - -We use ctypes here because this solution must not require a compiler. That's -because pip is not allowed to require a compiler either. - -This is not intended to be a seriously long-term solution to this problem. -The hope is that PEP 543 will eventually solve this issue for us, at which -point we can retire this contrib module. But in the short term, we need to -solve the impending tire fire that is Python on Mac without this kind of -contrib module. So...here we are. - -To use this module, simply import and inject it:: - - import urllib3.contrib.securetransport - urllib3.contrib.securetransport.inject_into_urllib3() - -Happy TLSing! -""" -from __future__ import absolute_import - -import contextlib -import ctypes -import errno -import os.path -import shutil -import socket -import ssl -import threading -import weakref - -from .. import util -from ._securetransport.bindings import ( - Security, SecurityConst, CoreFoundation -) -from ._securetransport.low_level import ( - _assert_no_error, _cert_array_from_pem, _temporary_keychain, - _load_client_cert_chain -) - -try: # Platform-specific: Python 2 - from socket import _fileobject -except ImportError: # Platform-specific: Python 3 - _fileobject = None - from ..packages.backports.makefile import backport_makefile - -__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] - -# SNI always works -HAS_SNI = True - -orig_util_HAS_SNI = util.HAS_SNI -orig_util_SSLContext = util.ssl_.SSLContext - -# This dictionary is used by the read callback to obtain a handle to the -# calling wrapped socket. This is a pretty silly approach, but for now it'll -# do. I feel like I should be able to smuggle a handle to the wrapped socket -# directly in the SSLConnectionRef, but for now this approach will work I -# guess. -# -# We need to lock around this structure for inserts, but we don't do it for -# reads/writes in the callbacks. The reasoning here goes as follows: -# -# 1. It is not possible to call into the callbacks before the dictionary is -# populated, so once in the callback the id must be in the dictionary. -# 2. The callbacks don't mutate the dictionary, they only read from it, and -# so cannot conflict with any of the insertions. -# -# This is good: if we had to lock in the callbacks we'd drastically slow down -# the performance of this code. -_connection_refs = weakref.WeakValueDictionary() -_connection_ref_lock = threading.Lock() - -# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over -# for no better reason than we need *a* limit, and this one is right there. -SSL_WRITE_BLOCKSIZE = 16384 - -# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to -# individual cipher suites. We need to do this because this is how -# SecureTransport wants them. -CIPHER_SUITES = [ - SecurityConst.TLS_AES_256_GCM_SHA384, - SecurityConst.TLS_CHACHA20_POLY1305_SHA256, - SecurityConst.TLS_AES_128_GCM_SHA256, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, - SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, - SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, - SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256, - SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA, -] - -# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of -# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. -_protocol_to_min_max = { - ssl.PROTOCOL_SSLv23: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), -} - -if hasattr(ssl, "PROTOCOL_SSLv2"): - _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( - SecurityConst.kSSLProtocol2, SecurityConst.kSSLProtocol2 - ) -if hasattr(ssl, "PROTOCOL_SSLv3"): - _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( - SecurityConst.kSSLProtocol3, SecurityConst.kSSLProtocol3 - ) -if hasattr(ssl, "PROTOCOL_TLSv1"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( - SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol1 - ) -if hasattr(ssl, "PROTOCOL_TLSv1_1"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( - SecurityConst.kTLSProtocol11, SecurityConst.kTLSProtocol11 - ) -if hasattr(ssl, "PROTOCOL_TLSv1_2"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( - SecurityConst.kTLSProtocol12, SecurityConst.kTLSProtocol12 - ) -if hasattr(ssl, "PROTOCOL_TLS"): - _protocol_to_min_max[ssl.PROTOCOL_TLS] = _protocol_to_min_max[ssl.PROTOCOL_SSLv23] - - -def inject_into_urllib3(): - """ - Monkey-patch urllib3 with SecureTransport-backed SSL-support. - """ - util.ssl_.SSLContext = SecureTransportContext - util.HAS_SNI = HAS_SNI - util.ssl_.HAS_SNI = HAS_SNI - util.IS_SECURETRANSPORT = True - util.ssl_.IS_SECURETRANSPORT = True - - -def extract_from_urllib3(): - """ - Undo monkey-patching by :func:`inject_into_urllib3`. - """ - util.ssl_.SSLContext = orig_util_SSLContext - util.HAS_SNI = orig_util_HAS_SNI - util.ssl_.HAS_SNI = orig_util_HAS_SNI - util.IS_SECURETRANSPORT = False - util.ssl_.IS_SECURETRANSPORT = False - - -def _read_callback(connection_id, data_buffer, data_length_pointer): - """ - SecureTransport read callback. This is called by ST to request that data - be returned from the socket. - """ - wrapped_socket = None - try: - wrapped_socket = _connection_refs.get(connection_id) - if wrapped_socket is None: - return SecurityConst.errSSLInternal - base_socket = wrapped_socket.socket - - requested_length = data_length_pointer[0] - - timeout = wrapped_socket.gettimeout() - error = None - read_count = 0 - - try: - while read_count < requested_length: - if timeout is None or timeout >= 0: - if not util.wait_for_read(base_socket, timeout): - raise socket.error(errno.EAGAIN, 'timed out') - - remaining = requested_length - read_count - buffer = (ctypes.c_char * remaining).from_address( - data_buffer + read_count - ) - chunk_size = base_socket.recv_into(buffer, remaining) - read_count += chunk_size - if not chunk_size: - if not read_count: - return SecurityConst.errSSLClosedGraceful - break - except (socket.error) as e: - error = e.errno - - if error is not None and error != errno.EAGAIN: - data_length_pointer[0] = read_count - if error == errno.ECONNRESET or error == errno.EPIPE: - return SecurityConst.errSSLClosedAbort - raise - - data_length_pointer[0] = read_count - - if read_count != requested_length: - return SecurityConst.errSSLWouldBlock - - return 0 - except Exception as e: - if wrapped_socket is not None: - wrapped_socket._exception = e - return SecurityConst.errSSLInternal - - -def _write_callback(connection_id, data_buffer, data_length_pointer): - """ - SecureTransport write callback. This is called by ST to request that data - actually be sent on the network. - """ - wrapped_socket = None - try: - wrapped_socket = _connection_refs.get(connection_id) - if wrapped_socket is None: - return SecurityConst.errSSLInternal - base_socket = wrapped_socket.socket - - bytes_to_write = data_length_pointer[0] - data = ctypes.string_at(data_buffer, bytes_to_write) - - timeout = wrapped_socket.gettimeout() - error = None - sent = 0 - - try: - while sent < bytes_to_write: - if timeout is None or timeout >= 0: - if not util.wait_for_write(base_socket, timeout): - raise socket.error(errno.EAGAIN, 'timed out') - chunk_sent = base_socket.send(data) - sent += chunk_sent - - # This has some needless copying here, but I'm not sure there's - # much value in optimising this data path. - data = data[chunk_sent:] - except (socket.error) as e: - error = e.errno - - if error is not None and error != errno.EAGAIN: - data_length_pointer[0] = sent - if error == errno.ECONNRESET or error == errno.EPIPE: - return SecurityConst.errSSLClosedAbort - raise - - data_length_pointer[0] = sent - - if sent != bytes_to_write: - return SecurityConst.errSSLWouldBlock - - return 0 - except Exception as e: - if wrapped_socket is not None: - wrapped_socket._exception = e - return SecurityConst.errSSLInternal - - -# We need to keep these two objects references alive: if they get GC'd while -# in use then SecureTransport could attempt to call a function that is in freed -# memory. That would be...uh...bad. Yeah, that's the word. Bad. -_read_callback_pointer = Security.SSLReadFunc(_read_callback) -_write_callback_pointer = Security.SSLWriteFunc(_write_callback) - - -class WrappedSocket(object): - """ - API-compatibility wrapper for Python's OpenSSL wrapped socket object. - - Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage - collector of PyPy. - """ - def __init__(self, socket): - self.socket = socket - self.context = None - self._makefile_refs = 0 - self._closed = False - self._exception = None - self._keychain = None - self._keychain_dir = None - self._client_cert_chain = None - - # We save off the previously-configured timeout and then set it to - # zero. This is done because we use select and friends to handle the - # timeouts, but if we leave the timeout set on the lower socket then - # Python will "kindly" call select on that socket again for us. Avoid - # that by forcing the timeout to zero. - self._timeout = self.socket.gettimeout() - self.socket.settimeout(0) - - @contextlib.contextmanager - def _raise_on_error(self): - """ - A context manager that can be used to wrap calls that do I/O from - SecureTransport. If any of the I/O callbacks hit an exception, this - context manager will correctly propagate the exception after the fact. - This avoids silently swallowing those exceptions. - - It also correctly forces the socket closed. - """ - self._exception = None - - # We explicitly don't catch around this yield because in the unlikely - # event that an exception was hit in the block we don't want to swallow - # it. - yield - if self._exception is not None: - exception, self._exception = self._exception, None - self.close() - raise exception - - def _set_ciphers(self): - """ - Sets up the allowed ciphers. By default this matches the set in - util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done - custom and doesn't allow changing at this time, mostly because parsing - OpenSSL cipher strings is going to be a freaking nightmare. - """ - ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES) - result = Security.SSLSetEnabledCiphers( - self.context, ciphers, len(CIPHER_SUITES) - ) - _assert_no_error(result) - - def _custom_validate(self, verify, trust_bundle): - """ - Called when we have set custom validation. We do this in two cases: - first, when cert validation is entirely disabled; and second, when - using a custom trust DB. - """ - # If we disabled cert validation, just say: cool. - if not verify: - return - - # We want data in memory, so load it up. - if os.path.isfile(trust_bundle): - with open(trust_bundle, 'rb') as f: - trust_bundle = f.read() - - cert_array = None - trust = Security.SecTrustRef() - - try: - # Get a CFArray that contains the certs we want. - cert_array = _cert_array_from_pem(trust_bundle) - - # Ok, now the hard part. We want to get the SecTrustRef that ST has - # created for this connection, shove our CAs into it, tell ST to - # ignore everything else it knows, and then ask if it can build a - # chain. This is a buuuunch of code. - result = Security.SSLCopyPeerTrust( - self.context, ctypes.byref(trust) - ) - _assert_no_error(result) - if not trust: - raise ssl.SSLError("Failed to copy trust reference") - - result = Security.SecTrustSetAnchorCertificates(trust, cert_array) - _assert_no_error(result) - - result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) - _assert_no_error(result) - - trust_result = Security.SecTrustResultType() - result = Security.SecTrustEvaluate( - trust, ctypes.byref(trust_result) - ) - _assert_no_error(result) - finally: - if trust: - CoreFoundation.CFRelease(trust) - - if cert_array is not None: - CoreFoundation.CFRelease(cert_array) - - # Ok, now we can look at what the result was. - successes = ( - SecurityConst.kSecTrustResultUnspecified, - SecurityConst.kSecTrustResultProceed - ) - if trust_result.value not in successes: - raise ssl.SSLError( - "certificate verify failed, error code: %d" % - trust_result.value - ) - - def handshake(self, - server_hostname, - verify, - trust_bundle, - min_version, - max_version, - client_cert, - client_key, - client_key_passphrase): - """ - Actually performs the TLS handshake. This is run automatically by - wrapped socket, and shouldn't be needed in user code. - """ - # First, we do the initial bits of connection setup. We need to create - # a context, set its I/O funcs, and set the connection reference. - self.context = Security.SSLCreateContext( - None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType - ) - result = Security.SSLSetIOFuncs( - self.context, _read_callback_pointer, _write_callback_pointer - ) - _assert_no_error(result) - - # Here we need to compute the handle to use. We do this by taking the - # id of self modulo 2**31 - 1. If this is already in the dictionary, we - # just keep incrementing by one until we find a free space. - with _connection_ref_lock: - handle = id(self) % 2147483647 - while handle in _connection_refs: - handle = (handle + 1) % 2147483647 - _connection_refs[handle] = self - - result = Security.SSLSetConnection(self.context, handle) - _assert_no_error(result) - - # If we have a server hostname, we should set that too. - if server_hostname: - if not isinstance(server_hostname, bytes): - server_hostname = server_hostname.encode('utf-8') - - result = Security.SSLSetPeerDomainName( - self.context, server_hostname, len(server_hostname) - ) - _assert_no_error(result) - - # Setup the ciphers. - self._set_ciphers() - - # Set the minimum and maximum TLS versions. - result = Security.SSLSetProtocolVersionMin(self.context, min_version) - _assert_no_error(result) - result = Security.SSLSetProtocolVersionMax(self.context, max_version) - _assert_no_error(result) - - # If there's a trust DB, we need to use it. We do that by telling - # SecureTransport to break on server auth. We also do that if we don't - # want to validate the certs at all: we just won't actually do any - # authing in that case. - if not verify or trust_bundle is not None: - result = Security.SSLSetSessionOption( - self.context, - SecurityConst.kSSLSessionOptionBreakOnServerAuth, - True - ) - _assert_no_error(result) - - # If there's a client cert, we need to use it. - if client_cert: - self._keychain, self._keychain_dir = _temporary_keychain() - self._client_cert_chain = _load_client_cert_chain( - self._keychain, client_cert, client_key - ) - result = Security.SSLSetCertificate( - self.context, self._client_cert_chain - ) - _assert_no_error(result) - - while True: - with self._raise_on_error(): - result = Security.SSLHandshake(self.context) - - if result == SecurityConst.errSSLWouldBlock: - raise socket.timeout("handshake timed out") - elif result == SecurityConst.errSSLServerAuthCompleted: - self._custom_validate(verify, trust_bundle) - continue - else: - _assert_no_error(result) - break - - def fileno(self): - return self.socket.fileno() - - # Copy-pasted from Python 3.5 source code - def _decref_socketios(self): - if self._makefile_refs > 0: - self._makefile_refs -= 1 - if self._closed: - self.close() - - def recv(self, bufsiz): - buffer = ctypes.create_string_buffer(bufsiz) - bytes_read = self.recv_into(buffer, bufsiz) - data = buffer[:bytes_read] - return data - - def recv_into(self, buffer, nbytes=None): - # Read short on EOF. - if self._closed: - return 0 - - if nbytes is None: - nbytes = len(buffer) - - buffer = (ctypes.c_char * nbytes).from_buffer(buffer) - processed_bytes = ctypes.c_size_t(0) - - with self._raise_on_error(): - result = Security.SSLRead( - self.context, buffer, nbytes, ctypes.byref(processed_bytes) - ) - - # There are some result codes that we want to treat as "not always - # errors". Specifically, those are errSSLWouldBlock, - # errSSLClosedGraceful, and errSSLClosedNoNotify. - if (result == SecurityConst.errSSLWouldBlock): - # If we didn't process any bytes, then this was just a time out. - # However, we can get errSSLWouldBlock in situations when we *did* - # read some data, and in those cases we should just read "short" - # and return. - if processed_bytes.value == 0: - # Timed out, no data read. - raise socket.timeout("recv timed out") - elif result in (SecurityConst.errSSLClosedGraceful, SecurityConst.errSSLClosedNoNotify): - # The remote peer has closed this connection. We should do so as - # well. Note that we don't actually return here because in - # principle this could actually be fired along with return data. - # It's unlikely though. - self.close() - else: - _assert_no_error(result) - - # Ok, we read and probably succeeded. We should return whatever data - # was actually read. - return processed_bytes.value - - def settimeout(self, timeout): - self._timeout = timeout - - def gettimeout(self): - return self._timeout - - def send(self, data): - processed_bytes = ctypes.c_size_t(0) - - with self._raise_on_error(): - result = Security.SSLWrite( - self.context, data, len(data), ctypes.byref(processed_bytes) - ) - - if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: - # Timed out - raise socket.timeout("send timed out") - else: - _assert_no_error(result) - - # We sent, and probably succeeded. Tell them how much we sent. - return processed_bytes.value - - def sendall(self, data): - total_sent = 0 - while total_sent < len(data): - sent = self.send(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) - total_sent += sent - - def shutdown(self): - with self._raise_on_error(): - Security.SSLClose(self.context) - - def close(self): - # TODO: should I do clean shutdown here? Do I have to? - if self._makefile_refs < 1: - self._closed = True - if self.context: - CoreFoundation.CFRelease(self.context) - self.context = None - if self._client_cert_chain: - CoreFoundation.CFRelease(self._client_cert_chain) - self._client_cert_chain = None - if self._keychain: - Security.SecKeychainDelete(self._keychain) - CoreFoundation.CFRelease(self._keychain) - shutil.rmtree(self._keychain_dir) - self._keychain = self._keychain_dir = None - return self.socket.close() - else: - self._makefile_refs -= 1 - - def getpeercert(self, binary_form=False): - # Urgh, annoying. - # - # Here's how we do this: - # - # 1. Call SSLCopyPeerTrust to get hold of the trust object for this - # connection. - # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. - # 3. To get the CN, call SecCertificateCopyCommonName and process that - # string so that it's of the appropriate type. - # 4. To get the SAN, we need to do something a bit more complex: - # a. Call SecCertificateCopyValues to get the data, requesting - # kSecOIDSubjectAltName. - # b. Mess about with this dictionary to try to get the SANs out. - # - # This is gross. Really gross. It's going to be a few hundred LoC extra - # just to repeat something that SecureTransport can *already do*. So my - # operating assumption at this time is that what we want to do is - # instead to just flag to urllib3 that it shouldn't do its own hostname - # validation when using SecureTransport. - if not binary_form: - raise ValueError( - "SecureTransport only supports dumping binary certs" - ) - trust = Security.SecTrustRef() - certdata = None - der_bytes = None - - try: - # Grab the trust store. - result = Security.SSLCopyPeerTrust( - self.context, ctypes.byref(trust) - ) - _assert_no_error(result) - if not trust: - # Probably we haven't done the handshake yet. No biggie. - return None - - cert_count = Security.SecTrustGetCertificateCount(trust) - if not cert_count: - # Also a case that might happen if we haven't handshaked. - # Handshook? Handshaken? - return None - - leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) - assert leaf - - # Ok, now we want the DER bytes. - certdata = Security.SecCertificateCopyData(leaf) - assert certdata - - data_length = CoreFoundation.CFDataGetLength(certdata) - data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) - der_bytes = ctypes.string_at(data_buffer, data_length) - finally: - if certdata: - CoreFoundation.CFRelease(certdata) - if trust: - CoreFoundation.CFRelease(trust) - - return der_bytes - - def _reuse(self): - self._makefile_refs += 1 - - def _drop(self): - if self._makefile_refs < 1: - self.close() - else: - self._makefile_refs -= 1 - - -if _fileobject: # Platform-specific: Python 2 - def makefile(self, mode, bufsize=-1): - self._makefile_refs += 1 - return _fileobject(self, mode, bufsize, close=True) -else: # Platform-specific: Python 3 - def makefile(self, mode="r", buffering=None, *args, **kwargs): - # We disable buffering with SecureTransport because it conflicts with - # the buffering that ST does internally (see issue #1153 for more). - buffering = 0 - return backport_makefile(self, mode, buffering, *args, **kwargs) - -WrappedSocket.makefile = makefile - - -class SecureTransportContext(object): - """ - I am a wrapper class for the SecureTransport library, to translate the - interface of the standard library ``SSLContext`` object to calls into - SecureTransport. - """ - def __init__(self, protocol): - self._min_version, self._max_version = _protocol_to_min_max[protocol] - self._options = 0 - self._verify = False - self._trust_bundle = None - self._client_cert = None - self._client_key = None - self._client_key_passphrase = None - - @property - def check_hostname(self): - """ - SecureTransport cannot have its hostname checking disabled. For more, - see the comment on getpeercert() in this file. - """ - return True - - @check_hostname.setter - def check_hostname(self, value): - """ - SecureTransport cannot have its hostname checking disabled. For more, - see the comment on getpeercert() in this file. - """ - pass - - @property - def options(self): - # TODO: Well, crap. - # - # So this is the bit of the code that is the most likely to cause us - # trouble. Essentially we need to enumerate all of the SSL options that - # users might want to use and try to see if we can sensibly translate - # them, or whether we should just ignore them. - return self._options - - @options.setter - def options(self, value): - # TODO: Update in line with above. - self._options = value - - @property - def verify_mode(self): - return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE - - @verify_mode.setter - def verify_mode(self, value): - self._verify = True if value == ssl.CERT_REQUIRED else False - - def set_default_verify_paths(self): - # So, this has to do something a bit weird. Specifically, what it does - # is nothing. - # - # This means that, if we had previously had load_verify_locations - # called, this does not undo that. We need to do that because it turns - # out that the rest of the urllib3 code will attempt to load the - # default verify paths if it hasn't been told about any paths, even if - # the context itself was sometime earlier. We resolve that by just - # ignoring it. - pass - - def load_default_certs(self): - return self.set_default_verify_paths() - - def set_ciphers(self, ciphers): - # For now, we just require the default cipher string. - if ciphers != util.ssl_.DEFAULT_CIPHERS: - raise ValueError( - "SecureTransport doesn't support custom cipher strings" - ) - - def load_verify_locations(self, cafile=None, capath=None, cadata=None): - # OK, we only really support cadata and cafile. - if capath is not None: - raise ValueError( - "SecureTransport does not support cert directories" - ) - - self._trust_bundle = cafile or cadata - - def load_cert_chain(self, certfile, keyfile=None, password=None): - self._client_cert = certfile - self._client_key = keyfile - self._client_cert_passphrase = password - - def wrap_socket(self, sock, server_side=False, - do_handshake_on_connect=True, suppress_ragged_eofs=True, - server_hostname=None): - # So, what do we do here? Firstly, we assert some properties. This is a - # stripped down shim, so there is some functionality we don't support. - # See PEP 543 for the real deal. - assert not server_side - assert do_handshake_on_connect - assert suppress_ragged_eofs - - # Ok, we're good to go. Now we want to create the wrapped socket object - # and store it in the appropriate place. - wrapped_socket = WrappedSocket(sock) - - # Now we can handshake - wrapped_socket.handshake( - server_hostname, self._verify, self._trust_bundle, - self._min_version, self._max_version, self._client_cert, - self._client_key, self._client_key_passphrase - ) - return wrapped_socket diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/socks.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/socks.py deleted file mode 100644 index 811e312..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/contrib/socks.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: utf-8 -*- -""" -This module contains provisional support for SOCKS proxies from within -urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and -SOCKS5. To enable its functionality, either install PySocks or install this -module with the ``socks`` extra. - -The SOCKS implementation supports the full range of urllib3 features. It also -supports the following SOCKS features: - -- SOCKS4 -- SOCKS4a -- SOCKS5 -- Usernames and passwords for the SOCKS proxy - -Known Limitations: - -- Currently PySocks does not support contacting remote websites via literal - IPv6 addresses. Any such connection attempt will fail. You must use a domain - name. -- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any - such connection attempt will fail. -""" -from __future__ import absolute_import - -try: - import socks -except ImportError: - import warnings - from ..exceptions import DependencyWarning - - warnings.warn(( - 'SOCKS support in urllib3 requires the installation of optional ' - 'dependencies: specifically, PySocks. For more information, see ' - 'https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies' - ), - DependencyWarning - ) - raise - -from socket import error as SocketError, timeout as SocketTimeout - -from ..connection import ( - HTTPConnection, HTTPSConnection -) -from ..connectionpool import ( - HTTPConnectionPool, HTTPSConnectionPool -) -from ..exceptions import ConnectTimeoutError, NewConnectionError -from ..poolmanager import PoolManager -from ..util.url import parse_url - -try: - import ssl -except ImportError: - ssl = None - - -class SOCKSConnection(HTTPConnection): - """ - A plain-text HTTP connection that connects via a SOCKS proxy. - """ - def __init__(self, *args, **kwargs): - self._socks_options = kwargs.pop('_socks_options') - super(SOCKSConnection, self).__init__(*args, **kwargs) - - def _new_conn(self): - """ - Establish a new connection via the SOCKS proxy. - """ - extra_kw = {} - if self.source_address: - extra_kw['source_address'] = self.source_address - - if self.socket_options: - extra_kw['socket_options'] = self.socket_options - - try: - conn = socks.create_connection( - (self.host, self.port), - proxy_type=self._socks_options['socks_version'], - proxy_addr=self._socks_options['proxy_host'], - proxy_port=self._socks_options['proxy_port'], - proxy_username=self._socks_options['username'], - proxy_password=self._socks_options['password'], - proxy_rdns=self._socks_options['rdns'], - timeout=self.timeout, - **extra_kw - ) - - except SocketTimeout as e: - raise ConnectTimeoutError( - self, "Connection to %s timed out. (connect timeout=%s)" % - (self.host, self.timeout)) - - except socks.ProxyError as e: - # This is fragile as hell, but it seems to be the only way to raise - # useful errors here. - if e.socket_err: - error = e.socket_err - if isinstance(error, SocketTimeout): - raise ConnectTimeoutError( - self, - "Connection to %s timed out. (connect timeout=%s)" % - (self.host, self.timeout) - ) - else: - raise NewConnectionError( - self, - "Failed to establish a new connection: %s" % error - ) - else: - raise NewConnectionError( - self, - "Failed to establish a new connection: %s" % e - ) - - except SocketError as e: # Defensive: PySocks should catch all these. - raise NewConnectionError( - self, "Failed to establish a new connection: %s" % e) - - return conn - - -# We don't need to duplicate the Verified/Unverified distinction from -# urllib3/connection.py here because the HTTPSConnection will already have been -# correctly set to either the Verified or Unverified form by that module. This -# means the SOCKSHTTPSConnection will automatically be the correct type. -class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): - pass - - -class SOCKSHTTPConnectionPool(HTTPConnectionPool): - ConnectionCls = SOCKSConnection - - -class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): - ConnectionCls = SOCKSHTTPSConnection - - -class SOCKSProxyManager(PoolManager): - """ - A version of the urllib3 ProxyManager that routes connections via the - defined SOCKS proxy. - """ - pool_classes_by_scheme = { - 'http': SOCKSHTTPConnectionPool, - 'https': SOCKSHTTPSConnectionPool, - } - - def __init__(self, proxy_url, username=None, password=None, - num_pools=10, headers=None, **connection_pool_kw): - parsed = parse_url(proxy_url) - - if username is None and password is None and parsed.auth is not None: - split = parsed.auth.split(':') - if len(split) == 2: - username, password = split - if parsed.scheme == 'socks5': - socks_version = socks.PROXY_TYPE_SOCKS5 - rdns = False - elif parsed.scheme == 'socks5h': - socks_version = socks.PROXY_TYPE_SOCKS5 - rdns = True - elif parsed.scheme == 'socks4': - socks_version = socks.PROXY_TYPE_SOCKS4 - rdns = False - elif parsed.scheme == 'socks4a': - socks_version = socks.PROXY_TYPE_SOCKS4 - rdns = True - else: - raise ValueError( - "Unable to determine SOCKS version from %s" % proxy_url - ) - - self.proxy_url = proxy_url - - socks_options = { - 'socks_version': socks_version, - 'proxy_host': parsed.host, - 'proxy_port': parsed.port, - 'username': username, - 'password': password, - 'rdns': rdns - } - connection_pool_kw['_socks_options'] = socks_options - - super(SOCKSProxyManager, self).__init__( - num_pools, headers, **connection_pool_kw - ) - - self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/exceptions.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/exceptions.py deleted file mode 100644 index 7bbaa98..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/exceptions.py +++ /dev/null @@ -1,246 +0,0 @@ -from __future__ import absolute_import -from .packages.six.moves.http_client import ( - IncompleteRead as httplib_IncompleteRead -) -# Base Exceptions - - -class HTTPError(Exception): - "Base exception used by this module." - pass - - -class HTTPWarning(Warning): - "Base warning used by this module." - pass - - -class PoolError(HTTPError): - "Base exception for errors caused within a pool." - def __init__(self, pool, message): - self.pool = pool - HTTPError.__init__(self, "%s: %s" % (pool, message)) - - def __reduce__(self): - # For pickling purposes. - return self.__class__, (None, None) - - -class RequestError(PoolError): - "Base exception for PoolErrors that have associated URLs." - def __init__(self, pool, url, message): - self.url = url - PoolError.__init__(self, pool, message) - - def __reduce__(self): - # For pickling purposes. - return self.__class__, (None, self.url, None) - - -class SSLError(HTTPError): - "Raised when SSL certificate fails in an HTTPS connection." - pass - - -class ProxyError(HTTPError): - "Raised when the connection to a proxy fails." - pass - - -class DecodeError(HTTPError): - "Raised when automatic decoding based on Content-Type fails." - pass - - -class ProtocolError(HTTPError): - "Raised when something unexpected happens mid-request/response." - pass - - -#: Renamed to ProtocolError but aliased for backwards compatibility. -ConnectionError = ProtocolError - - -# Leaf Exceptions - -class MaxRetryError(RequestError): - """Raised when the maximum number of retries is exceeded. - - :param pool: The connection pool - :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` - :param string url: The requested Url - :param exceptions.Exception reason: The underlying error - - """ - - def __init__(self, pool, url, reason=None): - self.reason = reason - - message = "Max retries exceeded with url: %s (Caused by %r)" % ( - url, reason) - - RequestError.__init__(self, pool, url, message) - - -class HostChangedError(RequestError): - "Raised when an existing pool gets a request for a foreign host." - - def __init__(self, pool, url, retries=3): - message = "Tried to open a foreign host with url: %s" % url - RequestError.__init__(self, pool, url, message) - self.retries = retries - - -class TimeoutStateError(HTTPError): - """ Raised when passing an invalid state to a timeout """ - pass - - -class TimeoutError(HTTPError): - """ Raised when a socket timeout error occurs. - - Catching this error will catch both :exc:`ReadTimeoutErrors - <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`. - """ - pass - - -class ReadTimeoutError(TimeoutError, RequestError): - "Raised when a socket timeout occurs while receiving data from a server" - pass - - -# This timeout error does not have a URL attached and needs to inherit from the -# base HTTPError -class ConnectTimeoutError(TimeoutError): - "Raised when a socket timeout occurs while connecting to a server" - pass - - -class NewConnectionError(ConnectTimeoutError, PoolError): - "Raised when we fail to establish a new connection. Usually ECONNREFUSED." - pass - - -class EmptyPoolError(PoolError): - "Raised when a pool runs out of connections and no more are allowed." - pass - - -class ClosedPoolError(PoolError): - "Raised when a request enters a pool after the pool has been closed." - pass - - -class LocationValueError(ValueError, HTTPError): - "Raised when there is something wrong with a given URL input." - pass - - -class LocationParseError(LocationValueError): - "Raised when get_host or similar fails to parse the URL input." - - def __init__(self, location): - message = "Failed to parse: %s" % location - HTTPError.__init__(self, message) - - self.location = location - - -class ResponseError(HTTPError): - "Used as a container for an error reason supplied in a MaxRetryError." - GENERIC_ERROR = 'too many error responses' - SPECIFIC_ERROR = 'too many {status_code} error responses' - - -class SecurityWarning(HTTPWarning): - "Warned when performing security reducing actions" - pass - - -class SubjectAltNameWarning(SecurityWarning): - "Warned when connecting to a host with a certificate missing a SAN." - pass - - -class InsecureRequestWarning(SecurityWarning): - "Warned when making an unverified HTTPS request." - pass - - -class SystemTimeWarning(SecurityWarning): - "Warned when system time is suspected to be wrong" - pass - - -class InsecurePlatformWarning(SecurityWarning): - "Warned when certain SSL configuration is not available on a platform." - pass - - -class SNIMissingWarning(HTTPWarning): - "Warned when making a HTTPS request without SNI available." - pass - - -class DependencyWarning(HTTPWarning): - """ - Warned when an attempt is made to import a module with missing optional - dependencies. - """ - pass - - -class ResponseNotChunked(ProtocolError, ValueError): - "Response needs to be chunked in order to read it as chunks." - pass - - -class BodyNotHttplibCompatible(HTTPError): - """ - Body should be httplib.HTTPResponse like (have an fp attribute which - returns raw chunks) for read_chunked(). - """ - pass - - -class IncompleteRead(HTTPError, httplib_IncompleteRead): - """ - Response length doesn't match expected Content-Length - - Subclass of http_client.IncompleteRead to allow int value - for `partial` to avoid creating large objects on streamed - reads. - """ - def __init__(self, partial, expected): - super(IncompleteRead, self).__init__(partial, expected) - - def __repr__(self): - return ('IncompleteRead(%i bytes read, ' - '%i more expected)' % (self.partial, self.expected)) - - -class InvalidHeader(HTTPError): - "The header provided was somehow invalid." - pass - - -class ProxySchemeUnknown(AssertionError, ValueError): - "ProxyManager does not support the supplied scheme" - # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. - - def __init__(self, scheme): - message = "Not supported proxy scheme %s" % scheme - super(ProxySchemeUnknown, self).__init__(message) - - -class HeaderParsingError(HTTPError): - "Raised by assert_header_parsing, but we convert it to a log.warning statement." - def __init__(self, defects, unparsed_data): - message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data) - super(HeaderParsingError, self).__init__(message) - - -class UnrewindableBodyError(HTTPError): - "urllib3 encountered an error when trying to rewind a body" - pass diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/fields.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/fields.py deleted file mode 100644 index 37fe64a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/fields.py +++ /dev/null @@ -1,178 +0,0 @@ -from __future__ import absolute_import -import email.utils -import mimetypes - -from .packages import six - - -def guess_content_type(filename, default='application/octet-stream'): - """ - Guess the "Content-Type" of a file. - - :param filename: - The filename to guess the "Content-Type" of using :mod:`mimetypes`. - :param default: - If no "Content-Type" can be guessed, default to `default`. - """ - if filename: - return mimetypes.guess_type(filename)[0] or default - return default - - -def format_header_param(name, value): - """ - Helper function to format and quote a single header parameter. - - Particularly useful for header parameters which might contain - non-ASCII values, like file names. This follows RFC 2231, as - suggested by RFC 2388 Section 4.4. - - :param name: - The name of the parameter, a string expected to be ASCII only. - :param value: - The value of the parameter, provided as a unicode string. - """ - if not any(ch in value for ch in '"\\\r\n'): - result = '%s="%s"' % (name, value) - try: - result.encode('ascii') - except (UnicodeEncodeError, UnicodeDecodeError): - pass - else: - return result - if not six.PY3 and isinstance(value, six.text_type): # Python 2: - value = value.encode('utf-8') - value = email.utils.encode_rfc2231(value, 'utf-8') - value = '%s*=%s' % (name, value) - return value - - -class RequestField(object): - """ - A data container for request body parameters. - - :param name: - The name of this request field. - :param data: - The data/value body. - :param filename: - An optional filename of the request field. - :param headers: - An optional dict-like object of headers to initially use for the field. - """ - def __init__(self, name, data, filename=None, headers=None): - self._name = name - self._filename = filename - self.data = data - self.headers = {} - if headers: - self.headers = dict(headers) - - @classmethod - def from_tuples(cls, fieldname, value): - """ - A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. - - Supports constructing :class:`~urllib3.fields.RequestField` from - parameter of key/value strings AND key/filetuple. A filetuple is a - (filename, data, MIME type) tuple where the MIME type is optional. - For example:: - - 'foo': 'bar', - 'fakefile': ('foofile.txt', 'contents of foofile'), - 'realfile': ('barfile.txt', open('realfile').read()), - 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), - 'nonamefile': 'contents of nonamefile field', - - Field names and filenames must be unicode. - """ - if isinstance(value, tuple): - if len(value) == 3: - filename, data, content_type = value - else: - filename, data = value - content_type = guess_content_type(filename) - else: - filename = None - content_type = None - data = value - - request_param = cls(fieldname, data, filename=filename) - request_param.make_multipart(content_type=content_type) - - return request_param - - def _render_part(self, name, value): - """ - Overridable helper function to format a single header parameter. - - :param name: - The name of the parameter, a string expected to be ASCII only. - :param value: - The value of the parameter, provided as a unicode string. - """ - return format_header_param(name, value) - - def _render_parts(self, header_parts): - """ - Helper function to format and quote a single header. - - Useful for single headers that are composed of multiple items. E.g., - 'Content-Disposition' fields. - - :param header_parts: - A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format - as `k1="v1"; k2="v2"; ...`. - """ - parts = [] - iterable = header_parts - if isinstance(header_parts, dict): - iterable = header_parts.items() - - for name, value in iterable: - if value is not None: - parts.append(self._render_part(name, value)) - - return '; '.join(parts) - - def render_headers(self): - """ - Renders the headers for this request field. - """ - lines = [] - - sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location'] - for sort_key in sort_keys: - if self.headers.get(sort_key, False): - lines.append('%s: %s' % (sort_key, self.headers[sort_key])) - - for header_name, header_value in self.headers.items(): - if header_name not in sort_keys: - if header_value: - lines.append('%s: %s' % (header_name, header_value)) - - lines.append('\r\n') - return '\r\n'.join(lines) - - def make_multipart(self, content_disposition=None, content_type=None, - content_location=None): - """ - Makes this request field into a multipart request field. - - This method overrides "Content-Disposition", "Content-Type" and - "Content-Location" headers to the request parameter. - - :param content_type: - The 'Content-Type' of the request body. - :param content_location: - The 'Content-Location' of the request body. - - """ - self.headers['Content-Disposition'] = content_disposition or 'form-data' - self.headers['Content-Disposition'] += '; '.join([ - '', self._render_parts( - (('name', self._name), ('filename', self._filename)) - ) - ]) - self.headers['Content-Type'] = content_type - self.headers['Content-Location'] = content_location diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/filepost.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/filepost.py deleted file mode 100644 index 78f1e19..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/filepost.py +++ /dev/null @@ -1,98 +0,0 @@ -from __future__ import absolute_import -import binascii -import codecs -import os - -from io import BytesIO - -from .packages import six -from .packages.six import b -from .fields import RequestField - -writer = codecs.lookup('utf-8')[3] - - -def choose_boundary(): - """ - Our embarrassingly-simple replacement for mimetools.choose_boundary. - """ - boundary = binascii.hexlify(os.urandom(16)) - if six.PY3: - boundary = boundary.decode('ascii') - return boundary - - -def iter_field_objects(fields): - """ - Iterate over fields. - - Supports list of (k, v) tuples and dicts, and lists of - :class:`~urllib3.fields.RequestField`. - - """ - if isinstance(fields, dict): - i = six.iteritems(fields) - else: - i = iter(fields) - - for field in i: - if isinstance(field, RequestField): - yield field - else: - yield RequestField.from_tuples(*field) - - -def iter_fields(fields): - """ - .. deprecated:: 1.6 - - Iterate over fields. - - The addition of :class:`~urllib3.fields.RequestField` makes this function - obsolete. Instead, use :func:`iter_field_objects`, which returns - :class:`~urllib3.fields.RequestField` objects. - - Supports list of (k, v) tuples and dicts. - """ - if isinstance(fields, dict): - return ((k, v) for k, v in six.iteritems(fields)) - - return ((k, v) for k, v in fields) - - -def encode_multipart_formdata(fields, boundary=None): - """ - Encode a dictionary of ``fields`` using the multipart/form-data MIME format. - - :param fields: - Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). - - :param boundary: - If not specified, then a random boundary will be generated using - :func:`urllib3.filepost.choose_boundary`. - """ - body = BytesIO() - if boundary is None: - boundary = choose_boundary() - - for field in iter_field_objects(fields): - body.write(b('--%s\r\n' % (boundary))) - - writer(body).write(field.render_headers()) - data = field.data - - if isinstance(data, int): - data = str(data) # Backwards compatibility - - if isinstance(data, six.text_type): - writer(body).write(data) - else: - body.write(data) - - body.write(b'\r\n') - - body.write(b('--%s--\r\n' % (boundary))) - - content_type = str('multipart/form-data; boundary=%s' % boundary) - - return body.getvalue(), content_type diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/__init__.py deleted file mode 100644 index 170e974..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from __future__ import absolute_import - -from . import ssl_match_hostname - -__all__ = ('ssl_match_hostname', ) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/backports/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/backports/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/backports/makefile.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/backports/makefile.py deleted file mode 100644 index 740db37..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/backports/makefile.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -""" -backports.makefile -~~~~~~~~~~~~~~~~~~ - -Backports the Python 3 ``socket.makefile`` method for use with anything that -wants to create a "fake" socket object. -""" -import io - -from socket import SocketIO - - -def backport_makefile(self, mode="r", buffering=None, encoding=None, - errors=None, newline=None): - """ - Backport of ``socket.makefile`` from Python 3.5. - """ - if not set(mode) <= {"r", "w", "b"}: - raise ValueError( - "invalid mode %r (only r, w, b allowed)" % (mode,) - ) - writing = "w" in mode - reading = "r" in mode or not writing - assert reading or writing - binary = "b" in mode - rawmode = "" - if reading: - rawmode += "r" - if writing: - rawmode += "w" - raw = SocketIO(self, rawmode) - self._makefile_refs += 1 - if buffering is None: - buffering = -1 - if buffering < 0: - buffering = io.DEFAULT_BUFFER_SIZE - if buffering == 0: - if not binary: - raise ValueError("unbuffered streams must be binary") - return raw - if reading and writing: - buffer = io.BufferedRWPair(raw, raw, buffering) - elif reading: - buffer = io.BufferedReader(raw, buffering) - else: - assert writing - buffer = io.BufferedWriter(raw, buffering) - if binary: - return buffer - text = io.TextIOWrapper(buffer, encoding, errors, newline) - text.mode = mode - return text diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/six.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/six.py deleted file mode 100644 index 190c023..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/six.py +++ /dev/null @@ -1,868 +0,0 @@ -"""Utilities for writing code that runs on Python 2 and 3""" - -# Copyright (c) 2010-2015 Benjamin Peterson -# -# 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. - -from __future__ import absolute_import - -import functools -import itertools -import operator -import sys -import types - -__author__ = "Benjamin Peterson <benjamin@python.org>" -__version__ = "1.10.0" - - -# Useful for very coarse version differentiation. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -PY34 = sys.version_info[0:2] >= (3, 4) - -if PY3: - string_types = str, - integer_types = int, - class_types = type, - text_type = str - binary_type = bytes - - MAXSIZE = sys.maxsize -else: - string_types = basestring, - integer_types = (int, long) - class_types = (type, types.ClassType) - text_type = unicode - binary_type = str - - if sys.platform.startswith("java"): - # Jython always uses 32 bits. - MAXSIZE = int((1 << 31) - 1) - else: - # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): - - def __len__(self): - return 1 << 31 - try: - len(X()) - except OverflowError: - # 32-bit - MAXSIZE = int((1 << 31) - 1) - else: - # 64-bit - MAXSIZE = int((1 << 63) - 1) - del X - - -def _add_doc(func, doc): - """Add documentation to a function.""" - func.__doc__ = doc - - -def _import_module(name): - """Import module, returning the module after the last dot.""" - __import__(name) - return sys.modules[name] - - -class _LazyDescr(object): - - def __init__(self, name): - self.name = name - - def __get__(self, obj, tp): - result = self._resolve() - setattr(obj, self.name, result) # Invokes __set__. - try: - # This is a bit ugly, but it avoids running this again by - # removing this descriptor. - delattr(obj.__class__, self.name) - except AttributeError: - pass - return result - - -class MovedModule(_LazyDescr): - - def __init__(self, name, old, new=None): - super(MovedModule, self).__init__(name) - if PY3: - if new is None: - new = name - self.mod = new - else: - self.mod = old - - def _resolve(self): - return _import_module(self.mod) - - def __getattr__(self, attr): - _module = self._resolve() - value = getattr(_module, attr) - setattr(self, attr, value) - return value - - -class _LazyModule(types.ModuleType): - - def __init__(self, name): - super(_LazyModule, self).__init__(name) - self.__doc__ = self.__class__.__doc__ - - def __dir__(self): - attrs = ["__doc__", "__name__"] - attrs += [attr.name for attr in self._moved_attributes] - return attrs - - # Subclasses should override this - _moved_attributes = [] - - -class MovedAttribute(_LazyDescr): - - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): - super(MovedAttribute, self).__init__(name) - if PY3: - if new_mod is None: - new_mod = name - self.mod = new_mod - if new_attr is None: - if old_attr is None: - new_attr = name - else: - new_attr = old_attr - self.attr = new_attr - else: - self.mod = old_mod - if old_attr is None: - old_attr = name - self.attr = old_attr - - def _resolve(self): - module = _import_module(self.mod) - return getattr(module, self.attr) - - -class _SixMetaPathImporter(object): - - """ - A meta path importer to import six.moves and its submodules. - - This class implements a PEP302 finder and loader. It should be compatible - with Python 2.5 and all existing versions of Python3 - """ - - def __init__(self, six_module_name): - self.name = six_module_name - self.known_modules = {} - - def _add_module(self, mod, *fullnames): - for fullname in fullnames: - self.known_modules[self.name + "." + fullname] = mod - - def _get_module(self, fullname): - return self.known_modules[self.name + "." + fullname] - - def find_module(self, fullname, path=None): - if fullname in self.known_modules: - return self - return None - - def __get_module(self, fullname): - try: - return self.known_modules[fullname] - except KeyError: - raise ImportError("This loader does not know module " + fullname) - - def load_module(self, fullname): - try: - # in case of a reload - return sys.modules[fullname] - except KeyError: - pass - mod = self.__get_module(fullname) - if isinstance(mod, MovedModule): - mod = mod._resolve() - else: - mod.__loader__ = self - sys.modules[fullname] = mod - return mod - - def is_package(self, fullname): - """ - Return true, if the named module is a package. - - We need this method to get correct spec objects with - Python 3.4 (see PEP451) - """ - return hasattr(self.__get_module(fullname), "__path__") - - def get_code(self, fullname): - """Return None - - Required, if is_package is implemented""" - self.__get_module(fullname) # eventually raises ImportError - return None - get_source = get_code # same as get_code - -_importer = _SixMetaPathImporter(__name__) - - -class _MovedItems(_LazyModule): - - """Lazy loading of moved objects""" - __path__ = [] # mark as package - - -_moved_attributes = [ - MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), - MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), - MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), - MovedAttribute("intern", "__builtin__", "sys"), - MovedAttribute("map", "itertools", "builtins", "imap", "map"), - MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), - MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), - MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), - MovedAttribute("reduce", "__builtin__", "functools"), - MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), - MovedAttribute("StringIO", "StringIO", "io"), - MovedAttribute("UserDict", "UserDict", "collections"), - MovedAttribute("UserList", "UserList", "collections"), - MovedAttribute("UserString", "UserString", "collections"), - MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), - MovedModule("builtins", "__builtin__"), - MovedModule("configparser", "ConfigParser"), - MovedModule("copyreg", "copy_reg"), - MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), - MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), - MovedModule("http_cookies", "Cookie", "http.cookies"), - MovedModule("html_entities", "htmlentitydefs", "html.entities"), - MovedModule("html_parser", "HTMLParser", "html.parser"), - MovedModule("http_client", "httplib", "http.client"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), - MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), - MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), - MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), - MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), - MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), - MovedModule("cPickle", "cPickle", "pickle"), - MovedModule("queue", "Queue"), - MovedModule("reprlib", "repr"), - MovedModule("socketserver", "SocketServer"), - MovedModule("_thread", "thread", "_thread"), - MovedModule("tkinter", "Tkinter"), - MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), - MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), - MovedModule("tkinter_tix", "Tix", "tkinter.tix"), - MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), - MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), - MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), - MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), - MovedModule("tkinter_font", "tkFont", "tkinter.font"), - MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), - MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), - MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), - MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), -] -# Add windows specific modules. -if sys.platform == "win32": - _moved_attributes += [ - MovedModule("winreg", "_winreg"), - ] - -for attr in _moved_attributes: - setattr(_MovedItems, attr.name, attr) - if isinstance(attr, MovedModule): - _importer._add_module(attr, "moves." + attr.name) -del attr - -_MovedItems._moved_attributes = _moved_attributes - -moves = _MovedItems(__name__ + ".moves") -_importer._add_module(moves, "moves") - - -class Module_six_moves_urllib_parse(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_parse""" - - -_urllib_parse_moved_attributes = [ - MovedAttribute("ParseResult", "urlparse", "urllib.parse"), - MovedAttribute("SplitResult", "urlparse", "urllib.parse"), - MovedAttribute("parse_qs", "urlparse", "urllib.parse"), - MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), - MovedAttribute("urldefrag", "urlparse", "urllib.parse"), - MovedAttribute("urljoin", "urlparse", "urllib.parse"), - MovedAttribute("urlparse", "urlparse", "urllib.parse"), - MovedAttribute("urlsplit", "urlparse", "urllib.parse"), - MovedAttribute("urlunparse", "urlparse", "urllib.parse"), - MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), - MovedAttribute("quote", "urllib", "urllib.parse"), - MovedAttribute("quote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote", "urllib", "urllib.parse"), - MovedAttribute("unquote_plus", "urllib", "urllib.parse"), - MovedAttribute("urlencode", "urllib", "urllib.parse"), - MovedAttribute("splitquery", "urllib", "urllib.parse"), - MovedAttribute("splittag", "urllib", "urllib.parse"), - MovedAttribute("splituser", "urllib", "urllib.parse"), - MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), - MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), - MovedAttribute("uses_params", "urlparse", "urllib.parse"), - MovedAttribute("uses_query", "urlparse", "urllib.parse"), - MovedAttribute("uses_relative", "urlparse", "urllib.parse"), -] -for attr in _urllib_parse_moved_attributes: - setattr(Module_six_moves_urllib_parse, attr.name, attr) -del attr - -Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes - -_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), - "moves.urllib_parse", "moves.urllib.parse") - - -class Module_six_moves_urllib_error(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_error""" - - -_urllib_error_moved_attributes = [ - MovedAttribute("URLError", "urllib2", "urllib.error"), - MovedAttribute("HTTPError", "urllib2", "urllib.error"), - MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), -] -for attr in _urllib_error_moved_attributes: - setattr(Module_six_moves_urllib_error, attr.name, attr) -del attr - -Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes - -_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), - "moves.urllib_error", "moves.urllib.error") - - -class Module_six_moves_urllib_request(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_request""" - - -_urllib_request_moved_attributes = [ - MovedAttribute("urlopen", "urllib2", "urllib.request"), - MovedAttribute("install_opener", "urllib2", "urllib.request"), - MovedAttribute("build_opener", "urllib2", "urllib.request"), - MovedAttribute("pathname2url", "urllib", "urllib.request"), - MovedAttribute("url2pathname", "urllib", "urllib.request"), - MovedAttribute("getproxies", "urllib", "urllib.request"), - MovedAttribute("Request", "urllib2", "urllib.request"), - MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), - MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), - MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), - MovedAttribute("BaseHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), - MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), - MovedAttribute("FileHandler", "urllib2", "urllib.request"), - MovedAttribute("FTPHandler", "urllib2", "urllib.request"), - MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), - MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), - MovedAttribute("urlretrieve", "urllib", "urllib.request"), - MovedAttribute("urlcleanup", "urllib", "urllib.request"), - MovedAttribute("URLopener", "urllib", "urllib.request"), - MovedAttribute("FancyURLopener", "urllib", "urllib.request"), - MovedAttribute("proxy_bypass", "urllib", "urllib.request"), -] -for attr in _urllib_request_moved_attributes: - setattr(Module_six_moves_urllib_request, attr.name, attr) -del attr - -Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes - -_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), - "moves.urllib_request", "moves.urllib.request") - - -class Module_six_moves_urllib_response(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_response""" - - -_urllib_response_moved_attributes = [ - MovedAttribute("addbase", "urllib", "urllib.response"), - MovedAttribute("addclosehook", "urllib", "urllib.response"), - MovedAttribute("addinfo", "urllib", "urllib.response"), - MovedAttribute("addinfourl", "urllib", "urllib.response"), -] -for attr in _urllib_response_moved_attributes: - setattr(Module_six_moves_urllib_response, attr.name, attr) -del attr - -Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes - -_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), - "moves.urllib_response", "moves.urllib.response") - - -class Module_six_moves_urllib_robotparser(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_robotparser""" - - -_urllib_robotparser_moved_attributes = [ - MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), -] -for attr in _urllib_robotparser_moved_attributes: - setattr(Module_six_moves_urllib_robotparser, attr.name, attr) -del attr - -Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes - -_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), - "moves.urllib_robotparser", "moves.urllib.robotparser") - - -class Module_six_moves_urllib(types.ModuleType): - - """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" - __path__ = [] # mark as package - parse = _importer._get_module("moves.urllib_parse") - error = _importer._get_module("moves.urllib_error") - request = _importer._get_module("moves.urllib_request") - response = _importer._get_module("moves.urllib_response") - robotparser = _importer._get_module("moves.urllib_robotparser") - - def __dir__(self): - return ['parse', 'error', 'request', 'response', 'robotparser'] - -_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), - "moves.urllib") - - -def add_move(move): - """Add an item to six.moves.""" - setattr(_MovedItems, move.name, move) - - -def remove_move(name): - """Remove item from six.moves.""" - try: - delattr(_MovedItems, name) - except AttributeError: - try: - del moves.__dict__[name] - except KeyError: - raise AttributeError("no such move, %r" % (name,)) - - -if PY3: - _meth_func = "__func__" - _meth_self = "__self__" - - _func_closure = "__closure__" - _func_code = "__code__" - _func_defaults = "__defaults__" - _func_globals = "__globals__" -else: - _meth_func = "im_func" - _meth_self = "im_self" - - _func_closure = "func_closure" - _func_code = "func_code" - _func_defaults = "func_defaults" - _func_globals = "func_globals" - - -try: - advance_iterator = next -except NameError: - def advance_iterator(it): - return it.next() -next = advance_iterator - - -try: - callable = callable -except NameError: - def callable(obj): - return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) - - -if PY3: - def get_unbound_function(unbound): - return unbound - - create_bound_method = types.MethodType - - def create_unbound_method(func, cls): - return func - - Iterator = object -else: - def get_unbound_function(unbound): - return unbound.im_func - - def create_bound_method(func, obj): - return types.MethodType(func, obj, obj.__class__) - - def create_unbound_method(func, cls): - return types.MethodType(func, None, cls) - - class Iterator(object): - - def next(self): - return type(self).__next__(self) - - callable = callable -_add_doc(get_unbound_function, - """Get the function out of a possibly unbound function""") - - -get_method_function = operator.attrgetter(_meth_func) -get_method_self = operator.attrgetter(_meth_self) -get_function_closure = operator.attrgetter(_func_closure) -get_function_code = operator.attrgetter(_func_code) -get_function_defaults = operator.attrgetter(_func_defaults) -get_function_globals = operator.attrgetter(_func_globals) - - -if PY3: - def iterkeys(d, **kw): - return iter(d.keys(**kw)) - - def itervalues(d, **kw): - return iter(d.values(**kw)) - - def iteritems(d, **kw): - return iter(d.items(**kw)) - - def iterlists(d, **kw): - return iter(d.lists(**kw)) - - viewkeys = operator.methodcaller("keys") - - viewvalues = operator.methodcaller("values") - - viewitems = operator.methodcaller("items") -else: - def iterkeys(d, **kw): - return d.iterkeys(**kw) - - def itervalues(d, **kw): - return d.itervalues(**kw) - - def iteritems(d, **kw): - return d.iteritems(**kw) - - def iterlists(d, **kw): - return d.iterlists(**kw) - - viewkeys = operator.methodcaller("viewkeys") - - viewvalues = operator.methodcaller("viewvalues") - - viewitems = operator.methodcaller("viewitems") - -_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") -_add_doc(itervalues, "Return an iterator over the values of a dictionary.") -_add_doc(iteritems, - "Return an iterator over the (key, value) pairs of a dictionary.") -_add_doc(iterlists, - "Return an iterator over the (key, [values]) pairs of a dictionary.") - - -if PY3: - def b(s): - return s.encode("latin-1") - - def u(s): - return s - unichr = chr - import struct - int2byte = struct.Struct(">B").pack - del struct - byte2int = operator.itemgetter(0) - indexbytes = operator.getitem - iterbytes = iter - import io - StringIO = io.StringIO - BytesIO = io.BytesIO - _assertCountEqual = "assertCountEqual" - if sys.version_info[1] <= 1: - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" - else: - _assertRaisesRegex = "assertRaisesRegex" - _assertRegex = "assertRegex" -else: - def b(s): - return s - # Workaround for standalone backslash - - def u(s): - return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") - unichr = unichr - int2byte = chr - - def byte2int(bs): - return ord(bs[0]) - - def indexbytes(buf, i): - return ord(buf[i]) - iterbytes = functools.partial(itertools.imap, ord) - import StringIO - StringIO = BytesIO = StringIO.StringIO - _assertCountEqual = "assertItemsEqual" - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" -_add_doc(b, """Byte literal""") -_add_doc(u, """Text literal""") - - -def assertCountEqual(self, *args, **kwargs): - return getattr(self, _assertCountEqual)(*args, **kwargs) - - -def assertRaisesRegex(self, *args, **kwargs): - return getattr(self, _assertRaisesRegex)(*args, **kwargs) - - -def assertRegex(self, *args, **kwargs): - return getattr(self, _assertRegex)(*args, **kwargs) - - -if PY3: - exec_ = getattr(moves.builtins, "exec") - - def reraise(tp, value, tb=None): - if value is None: - value = tp() - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - -else: - def exec_(_code_, _globs_=None, _locs_=None): - """Execute code in a namespace.""" - if _globs_ is None: - frame = sys._getframe(1) - _globs_ = frame.f_globals - if _locs_ is None: - _locs_ = frame.f_locals - del frame - elif _locs_ is None: - _locs_ = _globs_ - exec("""exec _code_ in _globs_, _locs_""") - - exec_("""def reraise(tp, value, tb=None): - raise tp, value, tb -""") - - -if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, from_value): - if from_value is None: - raise value - raise value from from_value -""") -elif sys.version_info[:2] > (3, 2): - exec_("""def raise_from(value, from_value): - raise value from from_value -""") -else: - def raise_from(value, from_value): - raise value - - -print_ = getattr(moves.builtins, "print", None) -if print_ is None: - def print_(*args, **kwargs): - """The new-style print function for Python 2.4 and 2.5.""" - fp = kwargs.pop("file", sys.stdout) - if fp is None: - return - - def write(data): - if not isinstance(data, basestring): - data = str(data) - # If the file has an encoding, encode unicode with it. - if (isinstance(fp, file) and - isinstance(data, unicode) and - fp.encoding is not None): - errors = getattr(fp, "errors", None) - if errors is None: - errors = "strict" - data = data.encode(fp.encoding, errors) - fp.write(data) - want_unicode = False - sep = kwargs.pop("sep", None) - if sep is not None: - if isinstance(sep, unicode): - want_unicode = True - elif not isinstance(sep, str): - raise TypeError("sep must be None or a string") - end = kwargs.pop("end", None) - if end is not None: - if isinstance(end, unicode): - want_unicode = True - elif not isinstance(end, str): - raise TypeError("end must be None or a string") - if kwargs: - raise TypeError("invalid keyword arguments to print()") - if not want_unicode: - for arg in args: - if isinstance(arg, unicode): - want_unicode = True - break - if want_unicode: - newline = unicode("\n") - space = unicode(" ") - else: - newline = "\n" - space = " " - if sep is None: - sep = space - if end is None: - end = newline - for i, arg in enumerate(args): - if i: - write(sep) - write(arg) - write(end) -if sys.version_info[:2] < (3, 3): - _print = print_ - - def print_(*args, **kwargs): - fp = kwargs.get("file", sys.stdout) - flush = kwargs.pop("flush", False) - _print(*args, **kwargs) - if flush and fp is not None: - fp.flush() - -_add_doc(reraise, """Reraise an exception.""") - -if sys.version_info[0:2] < (3, 4): - def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES): - def wrapper(f): - f = functools.wraps(wrapped, assigned, updated)(f) - f.__wrapped__ = wrapped - return f - return wrapper -else: - wraps = functools.wraps - - -def with_metaclass(meta, *bases): - """Create a base class with a metaclass.""" - # This requires a bit of explanation: the basic idea is to make a dummy - # metaclass for one level of class instantiation that replaces itself with - # the actual metaclass. - class metaclass(meta): - - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) - - -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - - -def python_2_unicode_compatible(klass): - """ - A decorator that defines __unicode__ and __str__ methods under Python 2. - Under Python 3 it does nothing. - - To support Python 2 and 3 with a single code base, define a __str__ method - returning text and apply this decorator to the class. - """ - if PY2: - if '__str__' not in klass.__dict__: - raise ValueError("@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % - klass.__name__) - klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode('utf-8') - return klass - - -# Complete the moves implementation. -# This code is at the end of this module to speed up module loading. -# Turn this module into a package. -__path__ = [] # required for PEP 302 and PEP 451 -__package__ = __name__ # see PEP 366 @ReservedAssignment -if globals().get("__spec__") is not None: - __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable -# Remove other six meta path importers, since they cause problems. This can -# happen if six is removed from sys.modules and then reloaded. (Setuptools does -# this for some reason.) -if sys.meta_path: - for i, importer in enumerate(sys.meta_path): - # Here's some real nastiness: Another "instance" of the six module might - # be floating around. Therefore, we can't use isinstance() to check for - # the six meta path importer, since the other six instance will have - # inserted an importer with different class. - if (type(importer).__name__ == "_SixMetaPathImporter" and - importer.name == __name__): - del sys.meta_path[i] - break - del i, importer -# Finally, add the importer to the meta path import hook. -sys.meta_path.append(_importer) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py deleted file mode 100644 index d6594eb..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -try: - # Our match_hostname function is the same as 3.5's, so we only want to - # import the match_hostname function if it's at least that good. - if sys.version_info < (3, 5): - raise ImportError("Fallback to vendored code") - - from ssl import CertificateError, match_hostname -except ImportError: - try: - # Backport of the function from a pypi module - from backports.ssl_match_hostname import CertificateError, match_hostname - except ImportError: - # Our vendored copy - from ._implementation import CertificateError, match_hostname - -# Not needed, but documenting what we provide. -__all__ = ('CertificateError', 'match_hostname') diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py deleted file mode 100644 index 970cf65..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py +++ /dev/null @@ -1,156 +0,0 @@ -"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" - -# Note: This file is under the PSF license as the code comes from the python -# stdlib. http://docs.python.org/3/license.html - -import re -import sys - -# ipaddress has been backported to 2.6+ in pypi. If it is installed on the -# system, use it to handle IPAddress ServerAltnames (this was added in -# python-3.5) otherwise only do DNS matching. This allows -# backports.ssl_match_hostname to continue to be used in Python 2.7. -try: - from pip._vendor import ipaddress -except ImportError: - ipaddress = None - -__version__ = '3.5.0.1' - - -class CertificateError(ValueError): - pass - - -def _dnsname_match(dn, hostname, max_wildcards=1): - """Matching according to RFC 6125, section 6.4.3 - - http://tools.ietf.org/html/rfc6125#section-6.4.3 - """ - pats = [] - if not dn: - return False - - # Ported from python3-syntax: - # leftmost, *remainder = dn.split(r'.') - parts = dn.split(r'.') - leftmost = parts[0] - remainder = parts[1:] - - wildcards = leftmost.count('*') - if wildcards > max_wildcards: - # Issue #17980: avoid denials of service by refusing more - # than one wildcard per fragment. A survey of established - # policy among SSL implementations showed it to be a - # reasonable choice. - raise CertificateError( - "too many wildcards in certificate DNS name: " + repr(dn)) - - # speed up common case w/o wildcards - if not wildcards: - return dn.lower() == hostname.lower() - - # RFC 6125, section 6.4.3, subitem 1. - # The client SHOULD NOT attempt to match a presented identifier in which - # the wildcard character comprises a label other than the left-most label. - if leftmost == '*': - # When '*' is a fragment by itself, it matches a non-empty dotless - # fragment. - pats.append('[^.]+') - elif leftmost.startswith('xn--') or hostname.startswith('xn--'): - # RFC 6125, section 6.4.3, subitem 3. - # The client SHOULD NOT attempt to match a presented identifier - # where the wildcard character is embedded within an A-label or - # U-label of an internationalized domain name. - pats.append(re.escape(leftmost)) - else: - # Otherwise, '*' matches any dotless string, e.g. www* - pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) - - # add the remaining fragments, ignore any wildcards - for frag in remainder: - pats.append(re.escape(frag)) - - pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) - return pat.match(hostname) - - -def _to_unicode(obj): - if isinstance(obj, str) and sys.version_info < (3,): - obj = unicode(obj, encoding='ascii', errors='strict') - return obj - -def _ipaddress_match(ipname, host_ip): - """Exact matching of IP addresses. - - RFC 6125 explicitly doesn't define an algorithm for this - (section 1.7.2 - "Out of Scope"). - """ - # OpenSSL may add a trailing newline to a subjectAltName's IP address - # Divergence from upstream: ipaddress can't handle byte str - ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) - return ip == host_ip - - -def match_hostname(cert, hostname): - """Verify that *cert* (in decoded format as returned by - SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 - rules are followed, but IP addresses are not accepted for *hostname*. - - CertificateError is raised on failure. On success, the function - returns nothing. - """ - if not cert: - raise ValueError("empty or no certificate, match_hostname needs a " - "SSL socket or SSL context with either " - "CERT_OPTIONAL or CERT_REQUIRED") - try: - # Divergence from upstream: ipaddress can't handle byte str - host_ip = ipaddress.ip_address(_to_unicode(hostname)) - except ValueError: - # Not an IP address (common case) - host_ip = None - except UnicodeError: - # Divergence from upstream: Have to deal with ipaddress not taking - # byte strings. addresses should be all ascii, so we consider it not - # an ipaddress in this case - host_ip = None - except AttributeError: - # Divergence from upstream: Make ipaddress library optional - if ipaddress is None: - host_ip = None - else: - raise - dnsnames = [] - san = cert.get('subjectAltName', ()) - for key, value in san: - if key == 'DNS': - if host_ip is None and _dnsname_match(value, hostname): - return - dnsnames.append(value) - elif key == 'IP Address': - if host_ip is not None and _ipaddress_match(value, host_ip): - return - dnsnames.append(value) - if not dnsnames: - # The subject is only checked when there is no dNSName entry - # in subjectAltName - for sub in cert.get('subject', ()): - for key, value in sub: - # XXX according to RFC 2818, the most specific Common Name - # must be used. - if key == 'commonName': - if _dnsname_match(value, hostname): - return - dnsnames.append(value) - if len(dnsnames) > 1: - raise CertificateError("hostname %r " - "doesn't match either of %s" - % (hostname, ', '.join(map(repr, dnsnames)))) - elif len(dnsnames) == 1: - raise CertificateError("hostname %r " - "doesn't match %r" - % (hostname, dnsnames[0])) - else: - raise CertificateError("no appropriate commonName or " - "subjectAltName fields were found") diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/poolmanager.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/poolmanager.py deleted file mode 100644 index fe5491c..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/poolmanager.py +++ /dev/null @@ -1,450 +0,0 @@ -from __future__ import absolute_import -import collections -import functools -import logging - -from ._collections import RecentlyUsedContainer -from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool -from .connectionpool import port_by_scheme -from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown -from .packages.six.moves.urllib.parse import urljoin -from .request import RequestMethods -from .util.url import parse_url -from .util.retry import Retry - - -__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url'] - - -log = logging.getLogger(__name__) - -SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs', - 'ssl_version', 'ca_cert_dir', 'ssl_context') - -# All known keyword arguments that could be provided to the pool manager, its -# pools, or the underlying connections. This is used to construct a pool key. -_key_fields = ( - 'key_scheme', # str - 'key_host', # str - 'key_port', # int - 'key_timeout', # int or float or Timeout - 'key_retries', # int or Retry - 'key_strict', # bool - 'key_block', # bool - 'key_source_address', # str - 'key_key_file', # str - 'key_cert_file', # str - 'key_cert_reqs', # str - 'key_ca_certs', # str - 'key_ssl_version', # str - 'key_ca_cert_dir', # str - 'key_ssl_context', # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext - 'key_maxsize', # int - 'key_headers', # dict - 'key__proxy', # parsed proxy url - 'key__proxy_headers', # dict - 'key_socket_options', # list of (level (int), optname (int), value (int or str)) tuples - 'key__socks_options', # dict - 'key_assert_hostname', # bool or string - 'key_assert_fingerprint', # str - 'key_server_hostname', #str -) - -#: The namedtuple class used to construct keys for the connection pool. -#: All custom key schemes should include the fields in this key at a minimum. -PoolKey = collections.namedtuple('PoolKey', _key_fields) - - -def _default_key_normalizer(key_class, request_context): - """ - Create a pool key out of a request context dictionary. - - According to RFC 3986, both the scheme and host are case-insensitive. - Therefore, this function normalizes both before constructing the pool - key for an HTTPS request. If you wish to change this behaviour, provide - alternate callables to ``key_fn_by_scheme``. - - :param key_class: - The class to use when constructing the key. This should be a namedtuple - with the ``scheme`` and ``host`` keys at a minimum. - :type key_class: namedtuple - :param request_context: - A dictionary-like object that contain the context for a request. - :type request_context: dict - - :return: A namedtuple that can be used as a connection pool key. - :rtype: PoolKey - """ - # Since we mutate the dictionary, make a copy first - context = request_context.copy() - context['scheme'] = context['scheme'].lower() - context['host'] = context['host'].lower() - - # These are both dictionaries and need to be transformed into frozensets - for key in ('headers', '_proxy_headers', '_socks_options'): - if key in context and context[key] is not None: - context[key] = frozenset(context[key].items()) - - # The socket_options key may be a list and needs to be transformed into a - # tuple. - socket_opts = context.get('socket_options') - if socket_opts is not None: - context['socket_options'] = tuple(socket_opts) - - # Map the kwargs to the names in the namedtuple - this is necessary since - # namedtuples can't have fields starting with '_'. - for key in list(context.keys()): - context['key_' + key] = context.pop(key) - - # Default to ``None`` for keys missing from the context - for field in key_class._fields: - if field not in context: - context[field] = None - - return key_class(**context) - - -#: A dictionary that maps a scheme to a callable that creates a pool key. -#: This can be used to alter the way pool keys are constructed, if desired. -#: Each PoolManager makes a copy of this dictionary so they can be configured -#: globally here, or individually on the instance. -key_fn_by_scheme = { - 'http': functools.partial(_default_key_normalizer, PoolKey), - 'https': functools.partial(_default_key_normalizer, PoolKey), -} - -pool_classes_by_scheme = { - 'http': HTTPConnectionPool, - 'https': HTTPSConnectionPool, -} - - -class PoolManager(RequestMethods): - """ - Allows for arbitrary requests while transparently keeping track of - necessary connection pools for you. - - :param num_pools: - Number of connection pools to cache before discarding the least - recently used pool. - - :param headers: - Headers to include with all requests, unless other headers are given - explicitly. - - :param \\**connection_pool_kw: - Additional parameters are used to create fresh - :class:`urllib3.connectionpool.ConnectionPool` instances. - - Example:: - - >>> manager = PoolManager(num_pools=2) - >>> r = manager.request('GET', 'http://google.com/') - >>> r = manager.request('GET', 'http://google.com/mail') - >>> r = manager.request('GET', 'http://yahoo.com/') - >>> len(manager.pools) - 2 - - """ - - proxy = None - - def __init__(self, num_pools=10, headers=None, **connection_pool_kw): - RequestMethods.__init__(self, headers) - self.connection_pool_kw = connection_pool_kw - self.pools = RecentlyUsedContainer(num_pools, - dispose_func=lambda p: p.close()) - - # Locally set the pool classes and keys so other PoolManagers can - # override them. - self.pool_classes_by_scheme = pool_classes_by_scheme - self.key_fn_by_scheme = key_fn_by_scheme.copy() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.clear() - # Return False to re-raise any potential exceptions - return False - - def _new_pool(self, scheme, host, port, request_context=None): - """ - Create a new :class:`ConnectionPool` based on host, port, scheme, and - any additional pool keyword arguments. - - If ``request_context`` is provided, it is provided as keyword arguments - to the pool class used. This method is used to actually create the - connection pools handed out by :meth:`connection_from_url` and - companion methods. It is intended to be overridden for customization. - """ - pool_cls = self.pool_classes_by_scheme[scheme] - if request_context is None: - request_context = self.connection_pool_kw.copy() - - # Although the context has everything necessary to create the pool, - # this function has historically only used the scheme, host, and port - # in the positional args. When an API change is acceptable these can - # be removed. - for key in ('scheme', 'host', 'port'): - request_context.pop(key, None) - - if scheme == 'http': - for kw in SSL_KEYWORDS: - request_context.pop(kw, None) - - return pool_cls(host, port, **request_context) - - def clear(self): - """ - Empty our store of pools and direct them all to close. - - This will not affect in-flight connections, but they will not be - re-used after completion. - """ - self.pools.clear() - - def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): - """ - Get a :class:`ConnectionPool` based on the host, port, and scheme. - - If ``port`` isn't given, it will be derived from the ``scheme`` using - ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is - provided, it is merged with the instance's ``connection_pool_kw`` - variable and used to create the new connection pool, if one is - needed. - """ - - if not host: - raise LocationValueError("No host specified.") - - request_context = self._merge_pool_kwargs(pool_kwargs) - request_context['scheme'] = scheme or 'http' - if not port: - port = port_by_scheme.get(request_context['scheme'].lower(), 80) - request_context['port'] = port - request_context['host'] = host - - return self.connection_from_context(request_context) - - def connection_from_context(self, request_context): - """ - Get a :class:`ConnectionPool` based on the request context. - - ``request_context`` must at least contain the ``scheme`` key and its - value must be a key in ``key_fn_by_scheme`` instance variable. - """ - scheme = request_context['scheme'].lower() - pool_key_constructor = self.key_fn_by_scheme[scheme] - pool_key = pool_key_constructor(request_context) - - return self.connection_from_pool_key(pool_key, request_context=request_context) - - def connection_from_pool_key(self, pool_key, request_context=None): - """ - Get a :class:`ConnectionPool` based on the provided pool key. - - ``pool_key`` should be a namedtuple that only contains immutable - objects. At a minimum it must have the ``scheme``, ``host``, and - ``port`` fields. - """ - with self.pools.lock: - # If the scheme, host, or port doesn't match existing open - # connections, open a new ConnectionPool. - pool = self.pools.get(pool_key) - if pool: - return pool - - # Make a fresh ConnectionPool of the desired type - scheme = request_context['scheme'] - host = request_context['host'] - port = request_context['port'] - pool = self._new_pool(scheme, host, port, request_context=request_context) - self.pools[pool_key] = pool - - return pool - - def connection_from_url(self, url, pool_kwargs=None): - """ - Similar to :func:`urllib3.connectionpool.connection_from_url`. - - If ``pool_kwargs`` is not provided and a new pool needs to be - constructed, ``self.connection_pool_kw`` is used to initialize - the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs`` - is provided, it is used instead. Note that if a new pool does not - need to be created for the request, the provided ``pool_kwargs`` are - not used. - """ - u = parse_url(url) - return self.connection_from_host(u.host, port=u.port, scheme=u.scheme, - pool_kwargs=pool_kwargs) - - def _merge_pool_kwargs(self, override): - """ - Merge a dictionary of override values for self.connection_pool_kw. - - This does not modify self.connection_pool_kw and returns a new dict. - Any keys in the override dictionary with a value of ``None`` are - removed from the merged dictionary. - """ - base_pool_kwargs = self.connection_pool_kw.copy() - if override: - for key, value in override.items(): - if value is None: - try: - del base_pool_kwargs[key] - except KeyError: - pass - else: - base_pool_kwargs[key] = value - return base_pool_kwargs - - def urlopen(self, method, url, redirect=True, **kw): - """ - Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen` - with custom cross-host redirect logic and only sends the request-uri - portion of the ``url``. - - The given ``url`` parameter must be absolute, such that an appropriate - :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it. - """ - u = parse_url(url) - conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) - - kw['assert_same_host'] = False - kw['redirect'] = False - - if 'headers' not in kw: - kw['headers'] = self.headers.copy() - - if self.proxy is not None and u.scheme == "http": - response = conn.urlopen(method, url, **kw) - else: - response = conn.urlopen(method, u.request_uri, **kw) - - redirect_location = redirect and response.get_redirect_location() - if not redirect_location: - return response - - # Support relative URLs for redirecting. - redirect_location = urljoin(url, redirect_location) - - # RFC 7231, Section 6.4.4 - if response.status == 303: - method = 'GET' - - retries = kw.get('retries') - if not isinstance(retries, Retry): - retries = Retry.from_int(retries, redirect=redirect) - - # Strip headers marked as unsafe to forward to the redirected location. - # Check remove_headers_on_redirect to avoid a potential network call within - # conn.is_same_host() which may use socket.gethostbyname() in the future. - if (retries.remove_headers_on_redirect - and not conn.is_same_host(redirect_location)): - for header in retries.remove_headers_on_redirect: - kw['headers'].pop(header, None) - - try: - retries = retries.increment(method, url, response=response, _pool=conn) - except MaxRetryError: - if retries.raise_on_redirect: - raise - return response - - kw['retries'] = retries - kw['redirect'] = redirect - - log.info("Redirecting %s -> %s", url, redirect_location) - return self.urlopen(method, redirect_location, **kw) - - -class ProxyManager(PoolManager): - """ - Behaves just like :class:`PoolManager`, but sends all requests through - the defined proxy, using the CONNECT method for HTTPS URLs. - - :param proxy_url: - The URL of the proxy to be used. - - :param proxy_headers: - A dictionary containing headers that will be sent to the proxy. In case - of HTTP they are being sent with each request, while in the - HTTPS/CONNECT case they are sent only once. Could be used for proxy - authentication. - - Example: - >>> proxy = urllib3.ProxyManager('http://localhost:3128/') - >>> r1 = proxy.request('GET', 'http://google.com/') - >>> r2 = proxy.request('GET', 'http://httpbin.org/') - >>> len(proxy.pools) - 1 - >>> r3 = proxy.request('GET', 'https://httpbin.org/') - >>> r4 = proxy.request('GET', 'https://twitter.com/') - >>> len(proxy.pools) - 3 - - """ - - def __init__(self, proxy_url, num_pools=10, headers=None, - proxy_headers=None, **connection_pool_kw): - - if isinstance(proxy_url, HTTPConnectionPool): - proxy_url = '%s://%s:%i' % (proxy_url.scheme, proxy_url.host, - proxy_url.port) - proxy = parse_url(proxy_url) - if not proxy.port: - port = port_by_scheme.get(proxy.scheme, 80) - proxy = proxy._replace(port=port) - - if proxy.scheme not in ("http", "https"): - raise ProxySchemeUnknown(proxy.scheme) - - self.proxy = proxy - self.proxy_headers = proxy_headers or {} - - connection_pool_kw['_proxy'] = self.proxy - connection_pool_kw['_proxy_headers'] = self.proxy_headers - - super(ProxyManager, self).__init__( - num_pools, headers, **connection_pool_kw) - - def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): - if scheme == "https": - return super(ProxyManager, self).connection_from_host( - host, port, scheme, pool_kwargs=pool_kwargs) - - return super(ProxyManager, self).connection_from_host( - self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs) - - def _set_proxy_headers(self, url, headers=None): - """ - Sets headers needed by proxies: specifically, the Accept and Host - headers. Only sets headers not provided by the user. - """ - headers_ = {'Accept': '*/*'} - - netloc = parse_url(url).netloc - if netloc: - headers_['Host'] = netloc - - if headers: - headers_.update(headers) - return headers_ - - def urlopen(self, method, url, redirect=True, **kw): - "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." - u = parse_url(url) - - if u.scheme == "http": - # For proxied HTTPS requests, httplib sets the necessary headers - # on the CONNECT to the proxy. For HTTP, we'll definitely - # need to set 'Host' at the very least. - headers = kw.get('headers', self.headers) - kw['headers'] = self._set_proxy_headers(url, headers) - - return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) - - -def proxy_from_url(url, **kw): - return ProxyManager(proxy_url=url, **kw) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/request.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/request.py deleted file mode 100644 index 8f2f44b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/request.py +++ /dev/null @@ -1,150 +0,0 @@ -from __future__ import absolute_import - -from .filepost import encode_multipart_formdata -from .packages.six.moves.urllib.parse import urlencode - - -__all__ = ['RequestMethods'] - - -class RequestMethods(object): - """ - Convenience mixin for classes who implement a :meth:`urlopen` method, such - as :class:`~urllib3.connectionpool.HTTPConnectionPool` and - :class:`~urllib3.poolmanager.PoolManager`. - - Provides behavior for making common types of HTTP request methods and - decides which type of request field encoding to use. - - Specifically, - - :meth:`.request_encode_url` is for sending requests whose fields are - encoded in the URL (such as GET, HEAD, DELETE). - - :meth:`.request_encode_body` is for sending requests whose fields are - encoded in the *body* of the request using multipart or www-form-urlencoded - (such as for POST, PUT, PATCH). - - :meth:`.request` is for making any kind of request, it will look up the - appropriate encoding format and use one of the above two methods to make - the request. - - Initializer parameters: - - :param headers: - Headers to include with all requests, unless other headers are given - explicitly. - """ - - _encode_url_methods = {'DELETE', 'GET', 'HEAD', 'OPTIONS'} - - def __init__(self, headers=None): - self.headers = headers or {} - - def urlopen(self, method, url, body=None, headers=None, - encode_multipart=True, multipart_boundary=None, - **kw): # Abstract - raise NotImplementedError("Classes extending RequestMethods must implement " - "their own ``urlopen`` method.") - - def request(self, method, url, fields=None, headers=None, **urlopen_kw): - """ - Make a request using :meth:`urlopen` with the appropriate encoding of - ``fields`` based on the ``method`` used. - - This is a convenience method that requires the least amount of manual - effort. It can be used in most situations, while still having the - option to drop down to more specific methods when necessary, such as - :meth:`request_encode_url`, :meth:`request_encode_body`, - or even the lowest level :meth:`urlopen`. - """ - method = method.upper() - - urlopen_kw['request_url'] = url - - if method in self._encode_url_methods: - return self.request_encode_url(method, url, fields=fields, - headers=headers, - **urlopen_kw) - else: - return self.request_encode_body(method, url, fields=fields, - headers=headers, - **urlopen_kw) - - def request_encode_url(self, method, url, fields=None, headers=None, - **urlopen_kw): - """ - Make a request using :meth:`urlopen` with the ``fields`` encoded in - the url. This is useful for request methods like GET, HEAD, DELETE, etc. - """ - if headers is None: - headers = self.headers - - extra_kw = {'headers': headers} - extra_kw.update(urlopen_kw) - - if fields: - url += '?' + urlencode(fields) - - return self.urlopen(method, url, **extra_kw) - - def request_encode_body(self, method, url, fields=None, headers=None, - encode_multipart=True, multipart_boundary=None, - **urlopen_kw): - """ - Make a request using :meth:`urlopen` with the ``fields`` encoded in - the body. This is useful for request methods like POST, PUT, PATCH, etc. - - When ``encode_multipart=True`` (default), then - :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode - the payload with the appropriate content type. Otherwise - :meth:`urllib.urlencode` is used with the - 'application/x-www-form-urlencoded' content type. - - Multipart encoding must be used when posting files, and it's reasonably - safe to use it in other times too. However, it may break request - signing, such as with OAuth. - - Supports an optional ``fields`` parameter of key/value strings AND - key/filetuple. A filetuple is a (filename, data, MIME type) tuple where - the MIME type is optional. For example:: - - fields = { - 'foo': 'bar', - 'fakefile': ('foofile.txt', 'contents of foofile'), - 'realfile': ('barfile.txt', open('realfile').read()), - 'typedfile': ('bazfile.bin', open('bazfile').read(), - 'image/jpeg'), - 'nonamefile': 'contents of nonamefile field', - } - - When uploading a file, providing a filename (the first parameter of the - tuple) is optional but recommended to best mimic behavior of browsers. - - Note that if ``headers`` are supplied, the 'Content-Type' header will - be overwritten because it depends on the dynamic random boundary string - which is used to compose the body of the request. The random boundary - string can be explicitly set with the ``multipart_boundary`` parameter. - """ - if headers is None: - headers = self.headers - - extra_kw = {'headers': {}} - - if fields: - if 'body' in urlopen_kw: - raise TypeError( - "request got values for both 'fields' and 'body', can only specify one.") - - if encode_multipart: - body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary) - else: - body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' - - extra_kw['body'] = body - extra_kw['headers'] = {'Content-Type': content_type} - - extra_kw['headers'].update(headers) - extra_kw.update(urlopen_kw) - - return self.urlopen(method, url, **extra_kw) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/response.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/response.py deleted file mode 100644 index c112690..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/response.py +++ /dev/null @@ -1,705 +0,0 @@ -from __future__ import absolute_import -from contextlib import contextmanager -import zlib -import io -import logging -from socket import timeout as SocketTimeout -from socket import error as SocketError - -from ._collections import HTTPHeaderDict -from .exceptions import ( - BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError, - ResponseNotChunked, IncompleteRead, InvalidHeader -) -from .packages.six import string_types as basestring, PY3 -from .packages.six.moves import http_client as httplib -from .connection import HTTPException, BaseSSLError -from .util.response import is_fp_closed, is_response_to_head - -log = logging.getLogger(__name__) - - -class DeflateDecoder(object): - - def __init__(self): - self._first_try = True - self._data = b'' - self._obj = zlib.decompressobj() - - def __getattr__(self, name): - return getattr(self._obj, name) - - def decompress(self, data): - if not data: - return data - - if not self._first_try: - return self._obj.decompress(data) - - self._data += data - try: - decompressed = self._obj.decompress(data) - if decompressed: - self._first_try = False - self._data = None - return decompressed - except zlib.error: - self._first_try = False - self._obj = zlib.decompressobj(-zlib.MAX_WBITS) - try: - return self.decompress(self._data) - finally: - self._data = None - - -class GzipDecoderState(object): - - FIRST_MEMBER = 0 - OTHER_MEMBERS = 1 - SWALLOW_DATA = 2 - - -class GzipDecoder(object): - - def __init__(self): - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - self._state = GzipDecoderState.FIRST_MEMBER - - def __getattr__(self, name): - return getattr(self._obj, name) - - def decompress(self, data): - ret = bytearray() - if self._state == GzipDecoderState.SWALLOW_DATA or not data: - return bytes(ret) - while True: - try: - ret += self._obj.decompress(data) - except zlib.error: - previous_state = self._state - # Ignore data after the first error - self._state = GzipDecoderState.SWALLOW_DATA - if previous_state == GzipDecoderState.OTHER_MEMBERS: - # Allow trailing garbage acceptable in other gzip clients - return bytes(ret) - raise - data = self._obj.unused_data - if not data: - return bytes(ret) - self._state = GzipDecoderState.OTHER_MEMBERS - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - - -class MultiDecoder(object): - """ - From RFC7231: - If one or more encodings have been applied to a representation, the - sender that applied the encodings MUST generate a Content-Encoding - header field that lists the content codings in the order in which - they were applied. - """ - - def __init__(self, modes): - self._decoders = [_get_decoder(m.strip()) for m in modes.split(',')] - - def flush(self): - return self._decoders[0].flush() - - def decompress(self, data): - for d in reversed(self._decoders): - data = d.decompress(data) - return data - - -def _get_decoder(mode): - if ',' in mode: - return MultiDecoder(mode) - - if mode == 'gzip': - return GzipDecoder() - - return DeflateDecoder() - - -class HTTPResponse(io.IOBase): - """ - HTTP Response container. - - Backwards-compatible to httplib's HTTPResponse but the response ``body`` is - loaded and decoded on-demand when the ``data`` property is accessed. This - class is also compatible with the Python standard library's :mod:`io` - module, and can hence be treated as a readable object in the context of that - framework. - - Extra parameters for behaviour not present in httplib.HTTPResponse: - - :param preload_content: - If True, the response's body will be preloaded during construction. - - :param decode_content: - If True, will attempt to decode the body based on the - 'content-encoding' header. - - :param original_response: - When this HTTPResponse wrapper is generated from an httplib.HTTPResponse - object, it's convenient to include the original for debug purposes. It's - otherwise unused. - - :param retries: - The retries contains the last :class:`~urllib3.util.retry.Retry` that - was used during the request. - - :param enforce_content_length: - Enforce content length checking. Body returned by server must match - value of Content-Length header, if present. Otherwise, raise error. - """ - - CONTENT_DECODERS = ['gzip', 'deflate'] - REDIRECT_STATUSES = [301, 302, 303, 307, 308] - - def __init__(self, body='', headers=None, status=0, version=0, reason=None, - strict=0, preload_content=True, decode_content=True, - original_response=None, pool=None, connection=None, msg=None, - retries=None, enforce_content_length=False, - request_method=None, request_url=None): - - if isinstance(headers, HTTPHeaderDict): - self.headers = headers - else: - self.headers = HTTPHeaderDict(headers) - self.status = status - self.version = version - self.reason = reason - self.strict = strict - self.decode_content = decode_content - self.retries = retries - self.enforce_content_length = enforce_content_length - - self._decoder = None - self._body = None - self._fp = None - self._original_response = original_response - self._fp_bytes_read = 0 - self.msg = msg - self._request_url = request_url - - if body and isinstance(body, (basestring, bytes)): - self._body = body - - self._pool = pool - self._connection = connection - - if hasattr(body, 'read'): - self._fp = body - - # Are we using the chunked-style of transfer encoding? - self.chunked = False - self.chunk_left = None - tr_enc = self.headers.get('transfer-encoding', '').lower() - # Don't incur the penalty of creating a list and then discarding it - encodings = (enc.strip() for enc in tr_enc.split(",")) - if "chunked" in encodings: - self.chunked = True - - # Determine length of response - self.length_remaining = self._init_length(request_method) - - # If requested, preload the body. - if preload_content and not self._body: - self._body = self.read(decode_content=decode_content) - - def get_redirect_location(self): - """ - Should we redirect and where to? - - :returns: Truthy redirect location string if we got a redirect status - code and valid location. ``None`` if redirect status and no - location. ``False`` if not a redirect status code. - """ - if self.status in self.REDIRECT_STATUSES: - return self.headers.get('location') - - return False - - def release_conn(self): - if not self._pool or not self._connection: - return - - self._pool._put_conn(self._connection) - self._connection = None - - @property - def data(self): - # For backwords-compat with earlier urllib3 0.4 and earlier. - if self._body: - return self._body - - if self._fp: - return self.read(cache_content=True) - - @property - def connection(self): - return self._connection - - def isclosed(self): - return is_fp_closed(self._fp) - - def tell(self): - """ - Obtain the number of bytes pulled over the wire so far. May differ from - the amount of content returned by :meth:``HTTPResponse.read`` if bytes - are encoded on the wire (e.g, compressed). - """ - return self._fp_bytes_read - - def _init_length(self, request_method): - """ - Set initial length value for Response content if available. - """ - length = self.headers.get('content-length') - - if length is not None: - if self.chunked: - # This Response will fail with an IncompleteRead if it can't be - # received as chunked. This method falls back to attempt reading - # the response before raising an exception. - log.warning("Received response with both Content-Length and " - "Transfer-Encoding set. This is expressly forbidden " - "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " - "attempting to process response as Transfer-Encoding: " - "chunked.") - return None - - try: - # RFC 7230 section 3.3.2 specifies multiple content lengths can - # be sent in a single Content-Length header - # (e.g. Content-Length: 42, 42). This line ensures the values - # are all valid ints and that as long as the `set` length is 1, - # all values are the same. Otherwise, the header is invalid. - lengths = set([int(val) for val in length.split(',')]) - if len(lengths) > 1: - raise InvalidHeader("Content-Length contained multiple " - "unmatching values (%s)" % length) - length = lengths.pop() - except ValueError: - length = None - else: - if length < 0: - length = None - - # Convert status to int for comparison - # In some cases, httplib returns a status of "_UNKNOWN" - try: - status = int(self.status) - except ValueError: - status = 0 - - # Check for responses that shouldn't include a body - if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD': - length = 0 - - return length - - def _init_decoder(self): - """ - Set-up the _decoder attribute if necessary. - """ - # Note: content-encoding value should be case-insensitive, per RFC 7230 - # Section 3.2 - content_encoding = self.headers.get('content-encoding', '').lower() - if self._decoder is None: - if content_encoding in self.CONTENT_DECODERS: - self._decoder = _get_decoder(content_encoding) - elif ',' in content_encoding: - encodings = [e.strip() for e in content_encoding.split(',') if e.strip() in self.CONTENT_DECODERS] - if len(encodings): - self._decoder = _get_decoder(content_encoding) - - def _decode(self, data, decode_content, flush_decoder): - """ - Decode the data passed in and potentially flush the decoder. - """ - try: - if decode_content and self._decoder: - data = self._decoder.decompress(data) - except (IOError, zlib.error) as e: - content_encoding = self.headers.get('content-encoding', '').lower() - raise DecodeError( - "Received response with content-encoding: %s, but " - "failed to decode it." % content_encoding, e) - - if flush_decoder and decode_content: - data += self._flush_decoder() - - return data - - def _flush_decoder(self): - """ - Flushes the decoder. Should only be called if the decoder is actually - being used. - """ - if self._decoder: - buf = self._decoder.decompress(b'') - return buf + self._decoder.flush() - - return b'' - - @contextmanager - def _error_catcher(self): - """ - Catch low-level python exceptions, instead re-raising urllib3 - variants, so that low-level exceptions are not leaked in the - high-level api. - - On exit, release the connection back to the pool. - """ - clean_exit = False - - try: - try: - yield - - except SocketTimeout: - # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but - # there is yet no clean way to get at it from this context. - raise ReadTimeoutError(self._pool, None, 'Read timed out.') - - except BaseSSLError as e: - # FIXME: Is there a better way to differentiate between SSLErrors? - if 'read operation timed out' not in str(e): # Defensive: - # This shouldn't happen but just in case we're missing an edge - # case, let's avoid swallowing SSL errors. - raise - - raise ReadTimeoutError(self._pool, None, 'Read timed out.') - - except (HTTPException, SocketError) as e: - # This includes IncompleteRead. - raise ProtocolError('Connection broken: %r' % e, e) - - # If no exception is thrown, we should avoid cleaning up - # unnecessarily. - clean_exit = True - finally: - # If we didn't terminate cleanly, we need to throw away our - # connection. - if not clean_exit: - # The response may not be closed but we're not going to use it - # anymore so close it now to ensure that the connection is - # released back to the pool. - if self._original_response: - self._original_response.close() - - # Closing the response may not actually be sufficient to close - # everything, so if we have a hold of the connection close that - # too. - if self._connection: - self._connection.close() - - # If we hold the original response but it's closed now, we should - # return the connection back to the pool. - if self._original_response and self._original_response.isclosed(): - self.release_conn() - - def read(self, amt=None, decode_content=None, cache_content=False): - """ - Similar to :meth:`httplib.HTTPResponse.read`, but with two additional - parameters: ``decode_content`` and ``cache_content``. - - :param amt: - How much of the content to read. If specified, caching is skipped - because it doesn't make sense to cache partial content as the full - response. - - :param decode_content: - If True, will attempt to decode the body based on the - 'content-encoding' header. - - :param cache_content: - If True, will save the returned data such that the same result is - returned despite of the state of the underlying file object. This - is useful if you want the ``.data`` property to continue working - after having ``.read()`` the file object. (Overridden if ``amt`` is - set.) - """ - self._init_decoder() - if decode_content is None: - decode_content = self.decode_content - - if self._fp is None: - return - - flush_decoder = False - data = None - - with self._error_catcher(): - if amt is None: - # cStringIO doesn't like amt=None - data = self._fp.read() - flush_decoder = True - else: - cache_content = False - data = self._fp.read(amt) - if amt != 0 and not data: # Platform-specific: Buggy versions of Python. - # Close the connection when no data is returned - # - # This is redundant to what httplib/http.client _should_ - # already do. However, versions of python released before - # December 15, 2012 (http://bugs.python.org/issue16298) do - # not properly close the connection in all cases. There is - # no harm in redundantly calling close. - self._fp.close() - flush_decoder = True - if self.enforce_content_length and self.length_remaining not in (0, None): - # This is an edge case that httplib failed to cover due - # to concerns of backward compatibility. We're - # addressing it here to make sure IncompleteRead is - # raised during streaming, so all calls with incorrect - # Content-Length are caught. - raise IncompleteRead(self._fp_bytes_read, self.length_remaining) - - if data: - self._fp_bytes_read += len(data) - if self.length_remaining is not None: - self.length_remaining -= len(data) - - data = self._decode(data, decode_content, flush_decoder) - - if cache_content: - self._body = data - - return data - - def stream(self, amt=2**16, decode_content=None): - """ - A generator wrapper for the read() method. A call will block until - ``amt`` bytes have been read from the connection or until the - connection is closed. - - :param amt: - How much of the content to read. The generator will return up to - much data per iteration, but may return less. This is particularly - likely when using compressed data. However, the empty string will - never be returned. - - :param decode_content: - If True, will attempt to decode the body based on the - 'content-encoding' header. - """ - if self.chunked and self.supports_chunked_reads(): - for line in self.read_chunked(amt, decode_content=decode_content): - yield line - else: - while not is_fp_closed(self._fp): - data = self.read(amt=amt, decode_content=decode_content) - - if data: - yield data - - @classmethod - def from_httplib(ResponseCls, r, **response_kw): - """ - Given an :class:`httplib.HTTPResponse` instance ``r``, return a - corresponding :class:`urllib3.response.HTTPResponse` object. - - Remaining parameters are passed to the HTTPResponse constructor, along - with ``original_response=r``. - """ - headers = r.msg - - if not isinstance(headers, HTTPHeaderDict): - if PY3: # Python 3 - headers = HTTPHeaderDict(headers.items()) - else: # Python 2 - headers = HTTPHeaderDict.from_httplib(headers) - - # HTTPResponse objects in Python 3 don't have a .strict attribute - strict = getattr(r, 'strict', 0) - resp = ResponseCls(body=r, - headers=headers, - status=r.status, - version=r.version, - reason=r.reason, - strict=strict, - original_response=r, - **response_kw) - return resp - - # Backwards-compatibility methods for httplib.HTTPResponse - def getheaders(self): - return self.headers - - def getheader(self, name, default=None): - return self.headers.get(name, default) - - # Backwards compatibility for http.cookiejar - def info(self): - return self.headers - - # Overrides from io.IOBase - def close(self): - if not self.closed: - self._fp.close() - - if self._connection: - self._connection.close() - - @property - def closed(self): - if self._fp is None: - return True - elif hasattr(self._fp, 'isclosed'): - return self._fp.isclosed() - elif hasattr(self._fp, 'closed'): - return self._fp.closed - else: - return True - - def fileno(self): - if self._fp is None: - raise IOError("HTTPResponse has no file to get a fileno from") - elif hasattr(self._fp, "fileno"): - return self._fp.fileno() - else: - raise IOError("The file-like object this HTTPResponse is wrapped " - "around has no file descriptor") - - def flush(self): - if self._fp is not None and hasattr(self._fp, 'flush'): - return self._fp.flush() - - def readable(self): - # This method is required for `io` module compatibility. - return True - - def readinto(self, b): - # This method is required for `io` module compatibility. - temp = self.read(len(b)) - if len(temp) == 0: - return 0 - else: - b[:len(temp)] = temp - return len(temp) - - def supports_chunked_reads(self): - """ - Checks if the underlying file-like object looks like a - httplib.HTTPResponse object. We do this by testing for the fp - attribute. If it is present we assume it returns raw chunks as - processed by read_chunked(). - """ - return hasattr(self._fp, 'fp') - - def _update_chunk_length(self): - # First, we'll figure out length of a chunk and then - # we'll try to read it from socket. - if self.chunk_left is not None: - return - line = self._fp.fp.readline() - line = line.split(b';', 1)[0] - try: - self.chunk_left = int(line, 16) - except ValueError: - # Invalid chunked protocol response, abort. - self.close() - raise httplib.IncompleteRead(line) - - def _handle_chunk(self, amt): - returned_chunk = None - if amt is None: - chunk = self._fp._safe_read(self.chunk_left) - returned_chunk = chunk - self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. - self.chunk_left = None - elif amt < self.chunk_left: - value = self._fp._safe_read(amt) - self.chunk_left = self.chunk_left - amt - returned_chunk = value - elif amt == self.chunk_left: - value = self._fp._safe_read(amt) - self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. - self.chunk_left = None - returned_chunk = value - else: # amt > self.chunk_left - returned_chunk = self._fp._safe_read(self.chunk_left) - self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. - self.chunk_left = None - return returned_chunk - - def read_chunked(self, amt=None, decode_content=None): - """ - Similar to :meth:`HTTPResponse.read`, but with an additional - parameter: ``decode_content``. - - :param amt: - How much of the content to read. If specified, caching is skipped - because it doesn't make sense to cache partial content as the full - response. - - :param decode_content: - If True, will attempt to decode the body based on the - 'content-encoding' header. - """ - self._init_decoder() - # FIXME: Rewrite this method and make it a class with a better structured logic. - if not self.chunked: - raise ResponseNotChunked( - "Response is not chunked. " - "Header 'transfer-encoding: chunked' is missing.") - if not self.supports_chunked_reads(): - raise BodyNotHttplibCompatible( - "Body should be httplib.HTTPResponse like. " - "It should have have an fp attribute which returns raw chunks.") - - with self._error_catcher(): - # Don't bother reading the body of a HEAD request. - if self._original_response and is_response_to_head(self._original_response): - self._original_response.close() - return - - # If a response is already read and closed - # then return immediately. - if self._fp.fp is None: - return - - while True: - self._update_chunk_length() - if self.chunk_left == 0: - break - chunk = self._handle_chunk(amt) - decoded = self._decode(chunk, decode_content=decode_content, - flush_decoder=False) - if decoded: - yield decoded - - if decode_content: - # On CPython and PyPy, we should never need to flush the - # decoder. However, on Jython we *might* need to, so - # lets defensively do it anyway. - decoded = self._flush_decoder() - if decoded: # Platform-specific: Jython. - yield decoded - - # Chunk content ends with \r\n: discard it. - while True: - line = self._fp.fp.readline() - if not line: - # Some sites may not end with '\r\n'. - break - if line == b'\r\n': - break - - # We read everything; close the "file". - if self._original_response: - self._original_response.close() - - def geturl(self): - """ - Returns the URL that was the source of this response. - If the request that generated this response redirected, this method - will return the final redirect location. - """ - if self.retries is not None and len(self.retries.history): - return self.retries.history[-1].redirect_location - else: - return self._request_url diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/__init__.py deleted file mode 100644 index 2f2770b..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -from __future__ import absolute_import -# For backwards compatibility, provide imports that used to be here. -from .connection import is_connection_dropped -from .request import make_headers -from .response import is_fp_closed -from .ssl_ import ( - SSLContext, - HAS_SNI, - IS_PYOPENSSL, - IS_SECURETRANSPORT, - assert_fingerprint, - resolve_cert_reqs, - resolve_ssl_version, - ssl_wrap_socket, -) -from .timeout import ( - current_time, - Timeout, -) - -from .retry import Retry -from .url import ( - get_host, - parse_url, - split_first, - Url, -) -from .wait import ( - wait_for_read, - wait_for_write -) - -__all__ = ( - 'HAS_SNI', - 'IS_PYOPENSSL', - 'IS_SECURETRANSPORT', - 'SSLContext', - 'Retry', - 'Timeout', - 'Url', - 'assert_fingerprint', - 'current_time', - 'is_connection_dropped', - 'is_fp_closed', - 'get_host', - 'parse_url', - 'make_headers', - 'resolve_cert_reqs', - 'resolve_ssl_version', - 'split_first', - 'ssl_wrap_socket', - 'wait_for_read', - 'wait_for_write' -) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/connection.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/connection.py deleted file mode 100644 index 5ad70b2..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/connection.py +++ /dev/null @@ -1,134 +0,0 @@ -from __future__ import absolute_import -import socket -from .wait import NoWayToWaitForSocketError, wait_for_read -from ..contrib import _appengine_environ - - -def is_connection_dropped(conn): # Platform-specific - """ - Returns True if the connection is dropped and should be closed. - - :param conn: - :class:`httplib.HTTPConnection` object. - - Note: For platforms like AppEngine, this will always return ``False`` to - let the platform handle connection recycling transparently for us. - """ - sock = getattr(conn, 'sock', False) - if sock is False: # Platform-specific: AppEngine - return False - if sock is None: # Connection already closed (such as by httplib). - return True - try: - # Returns True if readable, which here means it's been dropped - return wait_for_read(sock, timeout=0.0) - except NoWayToWaitForSocketError: # Platform-specific: AppEngine - return False - - -# This function is copied from socket.py in the Python 2.7 standard -# library test suite. Added to its signature is only `socket_options`. -# One additional modification is that we avoid binding to IPv6 servers -# discovered in DNS if the system doesn't have IPv6 functionality. -def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - source_address=None, socket_options=None): - """Connect to *address* and return the socket object. - - Convenience function. Connect to *address* (a 2-tuple ``(host, - port)``) and return the socket object. Passing the optional - *timeout* parameter will set the timeout on the socket instance - before attempting to connect. If no *timeout* is supplied, the - global default timeout setting returned by :func:`getdefaulttimeout` - is used. If *source_address* is set it must be a tuple of (host, port) - for the socket to bind as a source address before making the connection. - An host of '' or port 0 tells the OS to use the default. - """ - - host, port = address - if host.startswith('['): - host = host.strip('[]') - err = None - - # Using the value from allowed_gai_family() in the context of getaddrinfo lets - # us select whether to work with IPv4 DNS records, IPv6 records, or both. - # The original create_connection function always returns all records. - family = allowed_gai_family() - - for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): - af, socktype, proto, canonname, sa = res - sock = None - try: - sock = socket.socket(af, socktype, proto) - - # If provided, set socket level options before connecting. - _set_socket_options(sock, socket_options) - - if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: - sock.settimeout(timeout) - if source_address: - sock.bind(source_address) - sock.connect(sa) - return sock - - except socket.error as e: - err = e - if sock is not None: - sock.close() - sock = None - - if err is not None: - raise err - - raise socket.error("getaddrinfo returns an empty list") - - -def _set_socket_options(sock, options): - if options is None: - return - - for opt in options: - sock.setsockopt(*opt) - - -def allowed_gai_family(): - """This function is designed to work in the context of - getaddrinfo, where family=socket.AF_UNSPEC is the default and - will perform a DNS search for both IPv6 and IPv4 records.""" - - family = socket.AF_INET - if HAS_IPV6: - family = socket.AF_UNSPEC - return family - - -def _has_ipv6(host): - """ Returns True if the system can bind an IPv6 address. """ - sock = None - has_ipv6 = False - - # App Engine doesn't support IPV6 sockets and actually has a quota on the - # number of sockets that can be used, so just early out here instead of - # creating a socket needlessly. - # See https://github.com/urllib3/urllib3/issues/1446 - if _appengine_environ.is_appengine_sandbox(): - return False - - if socket.has_ipv6: - # has_ipv6 returns true if cPython was compiled with IPv6 support. - # It does not tell us if the system has IPv6 support enabled. To - # determine that we must bind to an IPv6 address. - # https://github.com/shazow/urllib3/pull/611 - # https://bugs.python.org/issue658327 - try: - sock = socket.socket(socket.AF_INET6) - sock.bind((host, 0)) - has_ipv6 = True - except Exception: - pass - - if sock: - sock.close() - return has_ipv6 - - -HAS_IPV6 = _has_ipv6('::1') diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/queue.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/queue.py deleted file mode 100644 index d3d379a..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/queue.py +++ /dev/null @@ -1,21 +0,0 @@ -import collections -from ..packages import six -from ..packages.six.moves import queue - -if six.PY2: - # Queue is imported for side effects on MS Windows. See issue #229. - import Queue as _unused_module_Queue # noqa: F401 - - -class LifoQueue(queue.Queue): - def _init(self, _): - self.queue = collections.deque() - - def _qsize(self, len=len): - return len(self.queue) - - def _put(self, item): - self.queue.append(item) - - def _get(self): - return self.queue.pop() diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/request.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/request.py deleted file mode 100644 index 3ddfcd5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/request.py +++ /dev/null @@ -1,118 +0,0 @@ -from __future__ import absolute_import -from base64 import b64encode - -from ..packages.six import b, integer_types -from ..exceptions import UnrewindableBodyError - -ACCEPT_ENCODING = 'gzip,deflate' -_FAILEDTELL = object() - - -def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, - basic_auth=None, proxy_basic_auth=None, disable_cache=None): - """ - Shortcuts for generating request headers. - - :param keep_alive: - If ``True``, adds 'connection: keep-alive' header. - - :param accept_encoding: - Can be a boolean, list, or string. - ``True`` translates to 'gzip,deflate'. - List will get joined by comma. - String will be used as provided. - - :param user_agent: - String representing the user-agent you want, such as - "python-urllib3/0.6" - - :param basic_auth: - Colon-separated username:password string for 'authorization: basic ...' - auth header. - - :param proxy_basic_auth: - Colon-separated username:password string for 'proxy-authorization: basic ...' - auth header. - - :param disable_cache: - If ``True``, adds 'cache-control: no-cache' header. - - Example:: - - >>> make_headers(keep_alive=True, user_agent="Batman/1.0") - {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} - >>> make_headers(accept_encoding=True) - {'accept-encoding': 'gzip,deflate'} - """ - headers = {} - if accept_encoding: - if isinstance(accept_encoding, str): - pass - elif isinstance(accept_encoding, list): - accept_encoding = ','.join(accept_encoding) - else: - accept_encoding = ACCEPT_ENCODING - headers['accept-encoding'] = accept_encoding - - if user_agent: - headers['user-agent'] = user_agent - - if keep_alive: - headers['connection'] = 'keep-alive' - - if basic_auth: - headers['authorization'] = 'Basic ' + \ - b64encode(b(basic_auth)).decode('utf-8') - - if proxy_basic_auth: - headers['proxy-authorization'] = 'Basic ' + \ - b64encode(b(proxy_basic_auth)).decode('utf-8') - - if disable_cache: - headers['cache-control'] = 'no-cache' - - return headers - - -def set_file_position(body, pos): - """ - If a position is provided, move file to that point. - Otherwise, we'll attempt to record a position for future use. - """ - if pos is not None: - rewind_body(body, pos) - elif getattr(body, 'tell', None) is not None: - try: - pos = body.tell() - except (IOError, OSError): - # This differentiates from None, allowing us to catch - # a failed `tell()` later when trying to rewind the body. - pos = _FAILEDTELL - - return pos - - -def rewind_body(body, body_pos): - """ - Attempt to rewind body to a certain position. - Primarily used for request redirects and retries. - - :param body: - File-like object that supports seek. - - :param int pos: - Position to seek to in file. - """ - body_seek = getattr(body, 'seek', None) - if body_seek is not None and isinstance(body_pos, integer_types): - try: - body_seek(body_pos) - except (IOError, OSError): - raise UnrewindableBodyError("An error occurred when rewinding request " - "body for redirect/retry.") - elif body_pos is _FAILEDTELL: - raise UnrewindableBodyError("Unable to record file position for rewinding " - "request body during a redirect/retry.") - else: - raise ValueError("body_pos must be of type integer, " - "instead it was %s." % type(body_pos)) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/response.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/response.py deleted file mode 100644 index 3d54864..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/response.py +++ /dev/null @@ -1,87 +0,0 @@ -from __future__ import absolute_import -from ..packages.six.moves import http_client as httplib - -from ..exceptions import HeaderParsingError - - -def is_fp_closed(obj): - """ - Checks whether a given file-like object is closed. - - :param obj: - The file-like object to check. - """ - - try: - # Check `isclosed()` first, in case Python3 doesn't set `closed`. - # GH Issue #928 - return obj.isclosed() - except AttributeError: - pass - - try: - # Check via the official file-like-object way. - return obj.closed - except AttributeError: - pass - - try: - # Check if the object is a container for another file-like object that - # gets released on exhaustion (e.g. HTTPResponse). - return obj.fp is None - except AttributeError: - pass - - raise ValueError("Unable to determine whether fp is closed.") - - -def assert_header_parsing(headers): - """ - Asserts whether all headers have been successfully parsed. - Extracts encountered errors from the result of parsing headers. - - Only works on Python 3. - - :param headers: Headers to verify. - :type headers: `httplib.HTTPMessage`. - - :raises urllib3.exceptions.HeaderParsingError: - If parsing errors are found. - """ - - # This will fail silently if we pass in the wrong kind of parameter. - # To make debugging easier add an explicit check. - if not isinstance(headers, httplib.HTTPMessage): - raise TypeError('expected httplib.Message, got {0}.'.format( - type(headers))) - - defects = getattr(headers, 'defects', None) - get_payload = getattr(headers, 'get_payload', None) - - unparsed_data = None - if get_payload: - # get_payload is actually email.message.Message.get_payload; - # we're only interested in the result if it's not a multipart message - if not headers.is_multipart(): - payload = get_payload() - - if isinstance(payload, (bytes, str)): - unparsed_data = payload - - if defects or unparsed_data: - raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) - - -def is_response_to_head(response): - """ - Checks whether the request of a response has been a HEAD-request. - Handles the quirks of AppEngine. - - :param conn: - :type conn: :class:`httplib.HTTPResponse` - """ - # FIXME: Can we do this somehow without accessing private httplib _method? - method = response._method - if isinstance(method, int): # Platform-specific: Appengine - return method == 3 - return method.upper() == 'HEAD' diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/retry.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/retry.py deleted file mode 100644 index e7d0abd..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/retry.py +++ /dev/null @@ -1,411 +0,0 @@ -from __future__ import absolute_import -import time -import logging -from collections import namedtuple -from itertools import takewhile -import email -import re - -from ..exceptions import ( - ConnectTimeoutError, - MaxRetryError, - ProtocolError, - ReadTimeoutError, - ResponseError, - InvalidHeader, -) -from ..packages import six - - -log = logging.getLogger(__name__) - - -# Data structure for representing the metadata of requests that result in a retry. -RequestHistory = namedtuple('RequestHistory', ["method", "url", "error", - "status", "redirect_location"]) - - -class Retry(object): - """ Retry configuration. - - Each retry attempt will create a new Retry object with updated values, so - they can be safely reused. - - Retries can be defined as a default for a pool:: - - retries = Retry(connect=5, read=2, redirect=5) - http = PoolManager(retries=retries) - response = http.request('GET', 'http://example.com/') - - Or per-request (which overrides the default for the pool):: - - response = http.request('GET', 'http://example.com/', retries=Retry(10)) - - Retries can be disabled by passing ``False``:: - - response = http.request('GET', 'http://example.com/', retries=False) - - Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless - retries are disabled, in which case the causing exception will be raised. - - :param int total: - Total number of retries to allow. Takes precedence over other counts. - - Set to ``None`` to remove this constraint and fall back on other - counts. It's a good idea to set this to some sensibly-high value to - account for unexpected edge cases and avoid infinite retry loops. - - Set to ``0`` to fail on the first retry. - - Set to ``False`` to disable and imply ``raise_on_redirect=False``. - - :param int connect: - How many connection-related errors to retry on. - - These are errors raised before the request is sent to the remote server, - which we assume has not triggered the server to process the request. - - Set to ``0`` to fail on the first retry of this type. - - :param int read: - How many times to retry on read errors. - - These errors are raised after the request was sent to the server, so the - request may have side-effects. - - Set to ``0`` to fail on the first retry of this type. - - :param int redirect: - How many redirects to perform. Limit this to avoid infinite redirect - loops. - - A redirect is a HTTP response with a status code 301, 302, 303, 307 or - 308. - - Set to ``0`` to fail on the first retry of this type. - - Set to ``False`` to disable and imply ``raise_on_redirect=False``. - - :param int status: - How many times to retry on bad status codes. - - These are retries made on responses, where status code matches - ``status_forcelist``. - - Set to ``0`` to fail on the first retry of this type. - - :param iterable method_whitelist: - Set of uppercased HTTP method verbs that we should retry on. - - By default, we only retry on methods which are considered to be - idempotent (multiple requests with the same parameters end with the - same state). See :attr:`Retry.DEFAULT_METHOD_WHITELIST`. - - Set to a ``False`` value to retry on any verb. - - :param iterable status_forcelist: - A set of integer HTTP status codes that we should force a retry on. - A retry is initiated if the request method is in ``method_whitelist`` - and the response status code is in ``status_forcelist``. - - By default, this is disabled with ``None``. - - :param float backoff_factor: - A backoff factor to apply between attempts after the second try - (most errors are resolved immediately by a second try without a - delay). urllib3 will sleep for:: - - {backoff factor} * (2 ** ({number of total retries} - 1)) - - seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep - for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer - than :attr:`Retry.BACKOFF_MAX`. - - By default, backoff is disabled (set to 0). - - :param bool raise_on_redirect: Whether, if the number of redirects is - exhausted, to raise a MaxRetryError, or to return a response with a - response code in the 3xx range. - - :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: - whether we should raise an exception, or return a response, - if status falls in ``status_forcelist`` range and retries have - been exhausted. - - :param tuple history: The history of the request encountered during - each call to :meth:`~Retry.increment`. The list is in the order - the requests occurred. Each list item is of class :class:`RequestHistory`. - - :param bool respect_retry_after_header: - Whether to respect Retry-After header on status codes defined as - :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. - - :param iterable remove_headers_on_redirect: - Sequence of headers to remove from the request when a response - indicating a redirect is returned before firing off the redirected - request. - """ - - DEFAULT_METHOD_WHITELIST = frozenset([ - 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) - - RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - - DEFAULT_REDIRECT_HEADERS_BLACKLIST = frozenset(['Authorization']) - - #: Maximum backoff time. - BACKOFF_MAX = 120 - - def __init__(self, total=10, connect=None, read=None, redirect=None, status=None, - method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, - backoff_factor=0, raise_on_redirect=True, raise_on_status=True, - history=None, respect_retry_after_header=True, - remove_headers_on_redirect=DEFAULT_REDIRECT_HEADERS_BLACKLIST): - - self.total = total - self.connect = connect - self.read = read - self.status = status - - if redirect is False or total is False: - redirect = 0 - raise_on_redirect = False - - self.redirect = redirect - self.status_forcelist = status_forcelist or set() - self.method_whitelist = method_whitelist - self.backoff_factor = backoff_factor - self.raise_on_redirect = raise_on_redirect - self.raise_on_status = raise_on_status - self.history = history or tuple() - self.respect_retry_after_header = respect_retry_after_header - self.remove_headers_on_redirect = remove_headers_on_redirect - - def new(self, **kw): - params = dict( - total=self.total, - connect=self.connect, read=self.read, redirect=self.redirect, status=self.status, - method_whitelist=self.method_whitelist, - status_forcelist=self.status_forcelist, - backoff_factor=self.backoff_factor, - raise_on_redirect=self.raise_on_redirect, - raise_on_status=self.raise_on_status, - history=self.history, - remove_headers_on_redirect=self.remove_headers_on_redirect - ) - params.update(kw) - return type(self)(**params) - - @classmethod - def from_int(cls, retries, redirect=True, default=None): - """ Backwards-compatibility for the old retries format.""" - if retries is None: - retries = default if default is not None else cls.DEFAULT - - if isinstance(retries, Retry): - return retries - - redirect = bool(redirect) and None - new_retries = cls(retries, redirect=redirect) - log.debug("Converted retries value: %r -> %r", retries, new_retries) - return new_retries - - def get_backoff_time(self): - """ Formula for computing the current backoff - - :rtype: float - """ - # We want to consider only the last consecutive errors sequence (Ignore redirects). - consecutive_errors_len = len(list(takewhile(lambda x: x.redirect_location is None, - reversed(self.history)))) - if consecutive_errors_len <= 1: - return 0 - - backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1)) - return min(self.BACKOFF_MAX, backoff_value) - - def parse_retry_after(self, retry_after): - # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 - if re.match(r"^\s*[0-9]+\s*$", retry_after): - seconds = int(retry_after) - else: - retry_date_tuple = email.utils.parsedate(retry_after) - if retry_date_tuple is None: - raise InvalidHeader("Invalid Retry-After header: %s" % retry_after) - retry_date = time.mktime(retry_date_tuple) - seconds = retry_date - time.time() - - if seconds < 0: - seconds = 0 - - return seconds - - def get_retry_after(self, response): - """ Get the value of Retry-After in seconds. """ - - retry_after = response.getheader("Retry-After") - - if retry_after is None: - return None - - return self.parse_retry_after(retry_after) - - def sleep_for_retry(self, response=None): - retry_after = self.get_retry_after(response) - if retry_after: - time.sleep(retry_after) - return True - - return False - - def _sleep_backoff(self): - backoff = self.get_backoff_time() - if backoff <= 0: - return - time.sleep(backoff) - - def sleep(self, response=None): - """ Sleep between retry attempts. - - This method will respect a server's ``Retry-After`` response header - and sleep the duration of the time requested. If that is not present, it - will use an exponential backoff. By default, the backoff factor is 0 and - this method will return immediately. - """ - - if response: - slept = self.sleep_for_retry(response) - if slept: - return - - self._sleep_backoff() - - def _is_connection_error(self, err): - """ Errors when we're fairly sure that the server did not receive the - request, so it should be safe to retry. - """ - return isinstance(err, ConnectTimeoutError) - - def _is_read_error(self, err): - """ Errors that occur after the request has been started, so we should - assume that the server began processing it. - """ - return isinstance(err, (ReadTimeoutError, ProtocolError)) - - def _is_method_retryable(self, method): - """ Checks if a given HTTP method should be retried upon, depending if - it is included on the method whitelist. - """ - if self.method_whitelist and method.upper() not in self.method_whitelist: - return False - - return True - - def is_retry(self, method, status_code, has_retry_after=False): - """ Is this method/status code retryable? (Based on whitelists and control - variables such as the number of total retries to allow, whether to - respect the Retry-After header, whether this header is present, and - whether the returned status code is on the list of status codes to - be retried upon on the presence of the aforementioned header) - """ - if not self._is_method_retryable(method): - return False - - if self.status_forcelist and status_code in self.status_forcelist: - return True - - return (self.total and self.respect_retry_after_header and - has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES)) - - def is_exhausted(self): - """ Are we out of retries? """ - retry_counts = (self.total, self.connect, self.read, self.redirect, self.status) - retry_counts = list(filter(None, retry_counts)) - if not retry_counts: - return False - - return min(retry_counts) < 0 - - def increment(self, method=None, url=None, response=None, error=None, - _pool=None, _stacktrace=None): - """ Return a new Retry object with incremented retry counters. - - :param response: A response object, or None, if the server did not - return a response. - :type response: :class:`~urllib3.response.HTTPResponse` - :param Exception error: An error encountered during the request, or - None if the response was received successfully. - - :return: A new ``Retry`` object. - """ - if self.total is False and error: - # Disabled, indicate to re-raise the error. - raise six.reraise(type(error), error, _stacktrace) - - total = self.total - if total is not None: - total -= 1 - - connect = self.connect - read = self.read - redirect = self.redirect - status_count = self.status - cause = 'unknown' - status = None - redirect_location = None - - if error and self._is_connection_error(error): - # Connect retry? - if connect is False: - raise six.reraise(type(error), error, _stacktrace) - elif connect is not None: - connect -= 1 - - elif error and self._is_read_error(error): - # Read retry? - if read is False or not self._is_method_retryable(method): - raise six.reraise(type(error), error, _stacktrace) - elif read is not None: - read -= 1 - - elif response and response.get_redirect_location(): - # Redirect retry? - if redirect is not None: - redirect -= 1 - cause = 'too many redirects' - redirect_location = response.get_redirect_location() - status = response.status - - else: - # Incrementing because of a server error like a 500 in - # status_forcelist and a the given method is in the whitelist - cause = ResponseError.GENERIC_ERROR - if response and response.status: - if status_count is not None: - status_count -= 1 - cause = ResponseError.SPECIFIC_ERROR.format( - status_code=response.status) - status = response.status - - history = self.history + (RequestHistory(method, url, error, status, redirect_location),) - - new_retry = self.new( - total=total, - connect=connect, read=read, redirect=redirect, status=status_count, - history=history) - - if new_retry.is_exhausted(): - raise MaxRetryError(_pool, url, error or ResponseError(cause)) - - log.debug("Incremented Retry for (url='%s'): %r", url, new_retry) - - return new_retry - - def __repr__(self): - return ('{cls.__name__}(total={self.total}, connect={self.connect}, ' - 'read={self.read}, redirect={self.redirect}, status={self.status})').format( - cls=type(self), self=self) - - -# For backwards compatibility (equivalent to pre-v1.9): -Retry.DEFAULT = Retry(3) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/ssl_.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/ssl_.py deleted file mode 100644 index dfc553f..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/ssl_.py +++ /dev/null @@ -1,381 +0,0 @@ -from __future__ import absolute_import -import errno -import warnings -import hmac -import socket - -from binascii import hexlify, unhexlify -from hashlib import md5, sha1, sha256 - -from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning -from ..packages import six - - -SSLContext = None -HAS_SNI = False -IS_PYOPENSSL = False -IS_SECURETRANSPORT = False - -# Maps the length of a digest to a possible hash function producing this digest -HASHFUNC_MAP = { - 32: md5, - 40: sha1, - 64: sha256, -} - - -def _const_compare_digest_backport(a, b): - """ - Compare two digests of equal length in constant time. - - The digests must be of type str/bytes. - Returns True if the digests match, and False otherwise. - """ - result = abs(len(a) - len(b)) - for l, r in zip(bytearray(a), bytearray(b)): - result |= l ^ r - return result == 0 - - -_const_compare_digest = getattr(hmac, 'compare_digest', - _const_compare_digest_backport) - - -try: # Test for SSL features - import ssl - from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 - from ssl import HAS_SNI # Has SNI? -except ImportError: - pass - - -try: - from ssl import OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION -except ImportError: - OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 - OP_NO_COMPRESSION = 0x20000 - - -# Python 2.7 doesn't have inet_pton on non-Linux so we fallback on inet_aton in -# those cases. This means that we can only detect IPv4 addresses in this case. -if hasattr(socket, 'inet_pton'): - inet_pton = socket.inet_pton -else: - # Maybe we can use ipaddress if the user has urllib3[secure]? - try: - from pip._vendor import ipaddress - - def inet_pton(_, host): - if isinstance(host, bytes): - host = host.decode('ascii') - return ipaddress.ip_address(host) - - except ImportError: # Platform-specific: Non-Linux - def inet_pton(_, host): - return socket.inet_aton(host) - - -# A secure default. -# Sources for more information on TLS ciphers: -# -# - https://wiki.mozilla.org/Security/Server_Side_TLS -# - https://www.ssllabs.com/projects/best-practices/index.html -# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ -# -# The general intent is: -# - Prefer TLS 1.3 cipher suites -# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), -# - prefer ECDHE over DHE for better performance, -# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and -# security, -# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common, -# - disable NULL authentication, MD5 MACs and DSS for security reasons. -DEFAULT_CIPHERS = ':'.join([ - 'TLS13-AES-256-GCM-SHA384', - 'TLS13-CHACHA20-POLY1305-SHA256', - 'TLS13-AES-128-GCM-SHA256', - 'ECDH+AESGCM', - 'ECDH+CHACHA20', - 'DH+AESGCM', - 'DH+CHACHA20', - 'ECDH+AES256', - 'DH+AES256', - 'ECDH+AES128', - 'DH+AES', - 'RSA+AESGCM', - 'RSA+AES', - '!aNULL', - '!eNULL', - '!MD5', -]) - -try: - from ssl import SSLContext # Modern SSL? -except ImportError: - import sys - - class SSLContext(object): # Platform-specific: Python 2 - def __init__(self, protocol_version): - self.protocol = protocol_version - # Use default values from a real SSLContext - self.check_hostname = False - self.verify_mode = ssl.CERT_NONE - self.ca_certs = None - self.options = 0 - self.certfile = None - self.keyfile = None - self.ciphers = None - - def load_cert_chain(self, certfile, keyfile): - self.certfile = certfile - self.keyfile = keyfile - - def load_verify_locations(self, cafile=None, capath=None): - self.ca_certs = cafile - - if capath is not None: - raise SSLError("CA directories not supported in older Pythons") - - def set_ciphers(self, cipher_suite): - self.ciphers = cipher_suite - - def wrap_socket(self, socket, server_hostname=None, server_side=False): - warnings.warn( - 'A true SSLContext object is not available. This prevents ' - 'urllib3 from configuring SSL appropriately and may cause ' - 'certain SSL connections to fail. You can upgrade to a newer ' - 'version of Python to solve this. For more information, see ' - 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' - '#ssl-warnings', - InsecurePlatformWarning - ) - kwargs = { - 'keyfile': self.keyfile, - 'certfile': self.certfile, - 'ca_certs': self.ca_certs, - 'cert_reqs': self.verify_mode, - 'ssl_version': self.protocol, - 'server_side': server_side, - } - return wrap_socket(socket, ciphers=self.ciphers, **kwargs) - - -def assert_fingerprint(cert, fingerprint): - """ - Checks if given fingerprint matches the supplied certificate. - - :param cert: - Certificate as bytes object. - :param fingerprint: - Fingerprint as string of hexdigits, can be interspersed by colons. - """ - - fingerprint = fingerprint.replace(':', '').lower() - digest_length = len(fingerprint) - hashfunc = HASHFUNC_MAP.get(digest_length) - if not hashfunc: - raise SSLError( - 'Fingerprint of invalid length: {0}'.format(fingerprint)) - - # We need encode() here for py32; works on py2 and p33. - fingerprint_bytes = unhexlify(fingerprint.encode()) - - cert_digest = hashfunc(cert).digest() - - if not _const_compare_digest(cert_digest, fingerprint_bytes): - raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".' - .format(fingerprint, hexlify(cert_digest))) - - -def resolve_cert_reqs(candidate): - """ - Resolves the argument to a numeric constant, which can be passed to - the wrap_socket function/method from the ssl module. - Defaults to :data:`ssl.CERT_NONE`. - If given a string it is assumed to be the name of the constant in the - :mod:`ssl` module or its abbreviation. - (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. - If it's neither `None` nor a string we assume it is already the numeric - constant which can directly be passed to wrap_socket. - """ - if candidate is None: - return CERT_NONE - - if isinstance(candidate, str): - res = getattr(ssl, candidate, None) - if res is None: - res = getattr(ssl, 'CERT_' + candidate) - return res - - return candidate - - -def resolve_ssl_version(candidate): - """ - like resolve_cert_reqs - """ - if candidate is None: - return PROTOCOL_SSLv23 - - if isinstance(candidate, str): - res = getattr(ssl, candidate, None) - if res is None: - res = getattr(ssl, 'PROTOCOL_' + candidate) - return res - - return candidate - - -def create_urllib3_context(ssl_version=None, cert_reqs=None, - options=None, ciphers=None): - """All arguments have the same meaning as ``ssl_wrap_socket``. - - By default, this function does a lot of the same work that - ``ssl.create_default_context`` does on Python 3.4+. It: - - - Disables SSLv2, SSLv3, and compression - - Sets a restricted set of server ciphers - - If you wish to enable SSLv3, you can do:: - - from pip._vendor.urllib3.util import ssl_ - context = ssl_.create_urllib3_context() - context.options &= ~ssl_.OP_NO_SSLv3 - - You can do the same to enable compression (substituting ``COMPRESSION`` - for ``SSLv3`` in the last line above). - - :param ssl_version: - The desired protocol version to use. This will default to - PROTOCOL_SSLv23 which will negotiate the highest protocol that both - the server and your installation of OpenSSL support. - :param cert_reqs: - Whether to require the certificate verification. This defaults to - ``ssl.CERT_REQUIRED``. - :param options: - Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, - ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``. - :param ciphers: - Which cipher suites to allow the server to select. - :returns: - Constructed SSLContext object with specified options - :rtype: SSLContext - """ - context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23) - - context.set_ciphers(ciphers or DEFAULT_CIPHERS) - - # Setting the default here, as we may have no ssl module on import - cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs - - if options is None: - options = 0 - # SSLv2 is easily broken and is considered harmful and dangerous - options |= OP_NO_SSLv2 - # SSLv3 has several problems and is now dangerous - options |= OP_NO_SSLv3 - # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ - # (issue #309) - options |= OP_NO_COMPRESSION - - context.options |= options - - context.verify_mode = cert_reqs - if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2 - # We do our own verification, including fingerprints and alternative - # hostnames. So disable it here - context.check_hostname = False - return context - - -def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, - ca_certs=None, server_hostname=None, - ssl_version=None, ciphers=None, ssl_context=None, - ca_cert_dir=None): - """ - All arguments except for server_hostname, ssl_context, and ca_cert_dir have - the same meaning as they do when using :func:`ssl.wrap_socket`. - - :param server_hostname: - When SNI is supported, the expected hostname of the certificate - :param ssl_context: - A pre-made :class:`SSLContext` object. If none is provided, one will - be created using :func:`create_urllib3_context`. - :param ciphers: - A string of ciphers we wish the client to support. - :param ca_cert_dir: - A directory containing CA certificates in multiple separate files, as - supported by OpenSSL's -CApath flag or the capath argument to - SSLContext.load_verify_locations(). - """ - context = ssl_context - if context is None: - # Note: This branch of code and all the variables in it are no longer - # used by urllib3 itself. We should consider deprecating and removing - # this code. - context = create_urllib3_context(ssl_version, cert_reqs, - ciphers=ciphers) - - if ca_certs or ca_cert_dir: - try: - context.load_verify_locations(ca_certs, ca_cert_dir) - except IOError as e: # Platform-specific: Python 2.7 - raise SSLError(e) - # Py33 raises FileNotFoundError which subclasses OSError - # These are not equivalent unless we check the errno attribute - except OSError as e: # Platform-specific: Python 3.3 and beyond - if e.errno == errno.ENOENT: - raise SSLError(e) - raise - elif getattr(context, 'load_default_certs', None) is not None: - # try to load OS default certs; works well on Windows (require Python3.4+) - context.load_default_certs() - - if certfile: - context.load_cert_chain(certfile, keyfile) - - # If we detect server_hostname is an IP address then the SNI - # extension should not be used according to RFC3546 Section 3.1 - # We shouldn't warn the user if SNI isn't available but we would - # not be using SNI anyways due to IP address for server_hostname. - if ((server_hostname is not None and not is_ipaddress(server_hostname)) - or IS_SECURETRANSPORT): - if HAS_SNI and server_hostname is not None: - return context.wrap_socket(sock, server_hostname=server_hostname) - - warnings.warn( - 'An HTTPS request has been made, but the SNI (Server Name ' - 'Indication) extension to TLS is not available on this platform. ' - 'This may cause the server to present an incorrect TLS ' - 'certificate, which can cause validation failures. You can upgrade to ' - 'a newer version of Python to solve this. For more information, see ' - 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' - '#ssl-warnings', - SNIMissingWarning - ) - - return context.wrap_socket(sock) - - -def is_ipaddress(hostname): - """Detects whether the hostname given is an IP address. - - :param str hostname: Hostname to examine. - :return: True if the hostname is an IP address, False otherwise. - """ - if six.PY3 and isinstance(hostname, bytes): - # IDN A-label bytes are ASCII compatible. - hostname = hostname.decode('ascii') - - families = [socket.AF_INET] - if hasattr(socket, 'AF_INET6'): - families.append(socket.AF_INET6) - - for af in families: - try: - inet_pton(af, hostname) - except (socket.error, ValueError, OSError): - pass - else: - return True - return False diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/timeout.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/timeout.py deleted file mode 100644 index cec817e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/timeout.py +++ /dev/null @@ -1,242 +0,0 @@ -from __future__ import absolute_import -# The default socket timeout, used by httplib to indicate that no timeout was -# specified by the user -from socket import _GLOBAL_DEFAULT_TIMEOUT -import time - -from ..exceptions import TimeoutStateError - -# A sentinel value to indicate that no timeout was specified by the user in -# urllib3 -_Default = object() - - -# Use time.monotonic if available. -current_time = getattr(time, "monotonic", time.time) - - -class Timeout(object): - """ Timeout configuration. - - Timeouts can be defined as a default for a pool:: - - timeout = Timeout(connect=2.0, read=7.0) - http = PoolManager(timeout=timeout) - response = http.request('GET', 'http://example.com/') - - Or per-request (which overrides the default for the pool):: - - response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) - - Timeouts can be disabled by setting all the parameters to ``None``:: - - no_timeout = Timeout(connect=None, read=None) - response = http.request('GET', 'http://example.com/, timeout=no_timeout) - - - :param total: - This combines the connect and read timeouts into one; the read timeout - will be set to the time leftover from the connect attempt. In the - event that both a connect timeout and a total are specified, or a read - timeout and a total are specified, the shorter timeout will be applied. - - Defaults to None. - - :type total: integer, float, or None - - :param connect: - The maximum amount of time to wait for a connection attempt to a server - to succeed. Omitting the parameter will default the connect timeout to - the system default, probably `the global default timeout in socket.py - <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. - None will set an infinite timeout for connection attempts. - - :type connect: integer, float, or None - - :param read: - The maximum amount of time to wait between consecutive - read operations for a response from the server. Omitting - the parameter will default the read timeout to the system - default, probably `the global default timeout in socket.py - <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. - None will set an infinite timeout. - - :type read: integer, float, or None - - .. note:: - - Many factors can affect the total amount of time for urllib3 to return - an HTTP response. - - For example, Python's DNS resolver does not obey the timeout specified - on the socket. Other factors that can affect total request time include - high CPU load, high swap, the program running at a low priority level, - or other behaviors. - - In addition, the read and total timeouts only measure the time between - read operations on the socket connecting the client and the server, - not the total amount of time for the request to return a complete - response. For most requests, the timeout is raised because the server - has not sent the first byte in the specified time. This is not always - the case; if a server streams one byte every fifteen seconds, a timeout - of 20 seconds will not trigger, even though the request will take - several minutes to complete. - - If your goal is to cut off any request after a set amount of wall clock - time, consider having a second "watcher" thread to cut off a slow - request. - """ - - #: A sentinel object representing the default timeout value - DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT - - def __init__(self, total=None, connect=_Default, read=_Default): - self._connect = self._validate_timeout(connect, 'connect') - self._read = self._validate_timeout(read, 'read') - self.total = self._validate_timeout(total, 'total') - self._start_connect = None - - def __str__(self): - return '%s(connect=%r, read=%r, total=%r)' % ( - type(self).__name__, self._connect, self._read, self.total) - - @classmethod - def _validate_timeout(cls, value, name): - """ Check that a timeout attribute is valid. - - :param value: The timeout value to validate - :param name: The name of the timeout attribute to validate. This is - used to specify in error messages. - :return: The validated and casted version of the given value. - :raises ValueError: If it is a numeric value less than or equal to - zero, or the type is not an integer, float, or None. - """ - if value is _Default: - return cls.DEFAULT_TIMEOUT - - if value is None or value is cls.DEFAULT_TIMEOUT: - return value - - if isinstance(value, bool): - raise ValueError("Timeout cannot be a boolean value. It must " - "be an int, float or None.") - try: - float(value) - except (TypeError, ValueError): - raise ValueError("Timeout value %s was %s, but it must be an " - "int, float or None." % (name, value)) - - try: - if value <= 0: - raise ValueError("Attempted to set %s timeout to %s, but the " - "timeout cannot be set to a value less " - "than or equal to 0." % (name, value)) - except TypeError: # Python 3 - raise ValueError("Timeout value %s was %s, but it must be an " - "int, float or None." % (name, value)) - - return value - - @classmethod - def from_float(cls, timeout): - """ Create a new Timeout from a legacy timeout value. - - The timeout value used by httplib.py sets the same timeout on the - connect(), and recv() socket requests. This creates a :class:`Timeout` - object that sets the individual timeouts to the ``timeout`` value - passed to this function. - - :param timeout: The legacy timeout value. - :type timeout: integer, float, sentinel default object, or None - :return: Timeout object - :rtype: :class:`Timeout` - """ - return Timeout(read=timeout, connect=timeout) - - def clone(self): - """ Create a copy of the timeout object - - Timeout properties are stored per-pool but each request needs a fresh - Timeout object to ensure each one has its own start/stop configured. - - :return: a copy of the timeout object - :rtype: :class:`Timeout` - """ - # We can't use copy.deepcopy because that will also create a new object - # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to - # detect the user default. - return Timeout(connect=self._connect, read=self._read, - total=self.total) - - def start_connect(self): - """ Start the timeout clock, used during a connect() attempt - - :raises urllib3.exceptions.TimeoutStateError: if you attempt - to start a timer that has been started already. - """ - if self._start_connect is not None: - raise TimeoutStateError("Timeout timer has already been started.") - self._start_connect = current_time() - return self._start_connect - - def get_connect_duration(self): - """ Gets the time elapsed since the call to :meth:`start_connect`. - - :return: Elapsed time. - :rtype: float - :raises urllib3.exceptions.TimeoutStateError: if you attempt - to get duration for a timer that hasn't been started. - """ - if self._start_connect is None: - raise TimeoutStateError("Can't get connect duration for timer " - "that has not started.") - return current_time() - self._start_connect - - @property - def connect_timeout(self): - """ Get the value to use when setting a connection timeout. - - This will be a positive float or integer, the value None - (never timeout), or the default system timeout. - - :return: Connect timeout. - :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None - """ - if self.total is None: - return self._connect - - if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: - return self.total - - return min(self._connect, self.total) - - @property - def read_timeout(self): - """ Get the value for the read timeout. - - This assumes some time has elapsed in the connection timeout and - computes the read timeout appropriately. - - If self.total is set, the read timeout is dependent on the amount of - time taken by the connect timeout. If the connection time has not been - established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be - raised. - - :return: Value to use for the read timeout. - :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None - :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` - has not yet been called on this object. - """ - if (self.total is not None and - self.total is not self.DEFAULT_TIMEOUT and - self._read is not None and - self._read is not self.DEFAULT_TIMEOUT): - # In case the connect timeout has not yet been established. - if self._start_connect is None: - return self._read - return max(0, min(self.total - self.get_connect_duration(), - self._read)) - elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: - return max(0, self.total - self.get_connect_duration()) - else: - return self._read diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/url.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/url.py deleted file mode 100644 index 6b6f996..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/url.py +++ /dev/null @@ -1,230 +0,0 @@ -from __future__ import absolute_import -from collections import namedtuple - -from ..exceptions import LocationParseError - - -url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] - -# We only want to normalize urls with an HTTP(S) scheme. -# urllib3 infers URLs without a scheme (None) to be http. -NORMALIZABLE_SCHEMES = ('http', 'https', None) - - -class Url(namedtuple('Url', url_attrs)): - """ - Datastructure for representing an HTTP URL. Used as a return value for - :func:`parse_url`. Both the scheme and host are normalized as they are - both case-insensitive according to RFC 3986. - """ - __slots__ = () - - def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, - query=None, fragment=None): - if path and not path.startswith('/'): - path = '/' + path - if scheme: - scheme = scheme.lower() - if host and scheme in NORMALIZABLE_SCHEMES: - host = host.lower() - return super(Url, cls).__new__(cls, scheme, auth, host, port, path, - query, fragment) - - @property - def hostname(self): - """For backwards-compatibility with urlparse. We're nice like that.""" - return self.host - - @property - def request_uri(self): - """Absolute path including the query string.""" - uri = self.path or '/' - - if self.query is not None: - uri += '?' + self.query - - return uri - - @property - def netloc(self): - """Network location including host and port""" - if self.port: - return '%s:%d' % (self.host, self.port) - return self.host - - @property - def url(self): - """ - Convert self into a url - - This function should more or less round-trip with :func:`.parse_url`. The - returned url may not be exactly the same as the url inputted to - :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls - with a blank port will have : removed). - - Example: :: - - >>> U = parse_url('http://google.com/mail/') - >>> U.url - 'http://google.com/mail/' - >>> Url('http', 'username:password', 'host.com', 80, - ... '/path', 'query', 'fragment').url - 'http://username:password@host.com:80/path?query#fragment' - """ - scheme, auth, host, port, path, query, fragment = self - url = '' - - # We use "is not None" we want things to happen with empty strings (or 0 port) - if scheme is not None: - url += scheme + '://' - if auth is not None: - url += auth + '@' - if host is not None: - url += host - if port is not None: - url += ':' + str(port) - if path is not None: - url += path - if query is not None: - url += '?' + query - if fragment is not None: - url += '#' + fragment - - return url - - def __str__(self): - return self.url - - -def split_first(s, delims): - """ - Given a string and an iterable of delimiters, split on the first found - delimiter. Return two split parts and the matched delimiter. - - If not found, then the first part is the full input string. - - Example:: - - >>> split_first('foo/bar?baz', '?/=') - ('foo', 'bar?baz', '/') - >>> split_first('foo/bar?baz', '123') - ('foo/bar?baz', '', None) - - Scales linearly with number of delims. Not ideal for large number of delims. - """ - min_idx = None - min_delim = None - for d in delims: - idx = s.find(d) - if idx < 0: - continue - - if min_idx is None or idx < min_idx: - min_idx = idx - min_delim = d - - if min_idx is None or min_idx < 0: - return s, '', None - - return s[:min_idx], s[min_idx + 1:], min_delim - - -def parse_url(url): - """ - Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is - performed to parse incomplete urls. Fields not provided will be None. - - Partly backwards-compatible with :mod:`urlparse`. - - Example:: - - >>> parse_url('http://google.com/mail/') - Url(scheme='http', host='google.com', port=None, path='/mail/', ...) - >>> parse_url('google.com:80') - Url(scheme=None, host='google.com', port=80, path=None, ...) - >>> parse_url('/foo?bar') - Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) - """ - - # While this code has overlap with stdlib's urlparse, it is much - # simplified for our needs and less annoying. - # Additionally, this implementations does silly things to be optimal - # on CPython. - - if not url: - # Empty - return Url() - - scheme = None - auth = None - host = None - port = None - path = None - fragment = None - query = None - - # Scheme - if '://' in url: - scheme, url = url.split('://', 1) - - # Find the earliest Authority Terminator - # (http://tools.ietf.org/html/rfc3986#section-3.2) - url, path_, delim = split_first(url, ['/', '?', '#']) - - if delim: - # Reassemble the path - path = delim + path_ - - # Auth - if '@' in url: - # Last '@' denotes end of auth part - auth, url = url.rsplit('@', 1) - - # IPv6 - if url and url[0] == '[': - host, url = url.split(']', 1) - host += ']' - - # Port - if ':' in url: - _host, port = url.split(':', 1) - - if not host: - host = _host - - if port: - # If given, ports must be integers. No whitespace, no plus or - # minus prefixes, no non-integer digits such as ^2 (superscript). - if not port.isdigit(): - raise LocationParseError(url) - try: - port = int(port) - except ValueError: - raise LocationParseError(url) - else: - # Blank ports are cool, too. (rfc3986#section-3.2.3) - port = None - - elif not host and url: - host = url - - if not path: - return Url(scheme, auth, host, port, path, query, fragment) - - # Fragment - if '#' in path: - path, fragment = path.split('#', 1) - - # Query - if '?' in path: - path, query = path.split('?', 1) - - return Url(scheme, auth, host, port, path, query, fragment) - - -def get_host(url): - """ - Deprecated. Use :func:`parse_url` instead. - """ - p = parse_url(url) - return p.scheme or 'http', p.hostname, p.port diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/wait.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/wait.py deleted file mode 100644 index 4db71ba..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/urllib3/util/wait.py +++ /dev/null @@ -1,150 +0,0 @@ -import errno -from functools import partial -import select -import sys -try: - from time import monotonic -except ImportError: - from time import time as monotonic - -__all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"] - - -class NoWayToWaitForSocketError(Exception): - pass - - -# How should we wait on sockets? -# -# There are two types of APIs you can use for waiting on sockets: the fancy -# modern stateful APIs like epoll/kqueue, and the older stateless APIs like -# select/poll. The stateful APIs are more efficient when you have a lots of -# sockets to keep track of, because you can set them up once and then use them -# lots of times. But we only ever want to wait on a single socket at a time -# and don't want to keep track of state, so the stateless APIs are actually -# more efficient. So we want to use select() or poll(). -# -# Now, how do we choose between select() and poll()? On traditional Unixes, -# select() has a strange calling convention that makes it slow, or fail -# altogether, for high-numbered file descriptors. The point of poll() is to fix -# that, so on Unixes, we prefer poll(). -# -# On Windows, there is no poll() (or at least Python doesn't provide a wrapper -# for it), but that's OK, because on Windows, select() doesn't have this -# strange calling convention; plain select() works fine. -# -# So: on Windows we use select(), and everywhere else we use poll(). We also -# fall back to select() in case poll() is somehow broken or missing. - -if sys.version_info >= (3, 5): - # Modern Python, that retries syscalls by default - def _retry_on_intr(fn, timeout): - return fn(timeout) -else: - # Old and broken Pythons. - def _retry_on_intr(fn, timeout): - if timeout is None: - deadline = float("inf") - else: - deadline = monotonic() + timeout - - while True: - try: - return fn(timeout) - # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7 - except (OSError, select.error) as e: - # 'e.args[0]' incantation works for both OSError and select.error - if e.args[0] != errno.EINTR: - raise - else: - timeout = deadline - monotonic() - if timeout < 0: - timeout = 0 - if timeout == float("inf"): - timeout = None - continue - - -def select_wait_for_socket(sock, read=False, write=False, timeout=None): - if not read and not write: - raise RuntimeError("must specify at least one of read=True, write=True") - rcheck = [] - wcheck = [] - if read: - rcheck.append(sock) - if write: - wcheck.append(sock) - # When doing a non-blocking connect, most systems signal success by - # marking the socket writable. Windows, though, signals success by marked - # it as "exceptional". We paper over the difference by checking the write - # sockets for both conditions. (The stdlib selectors module does the same - # thing.) - fn = partial(select.select, rcheck, wcheck, wcheck) - rready, wready, xready = _retry_on_intr(fn, timeout) - return bool(rready or wready or xready) - - -def poll_wait_for_socket(sock, read=False, write=False, timeout=None): - if not read and not write: - raise RuntimeError("must specify at least one of read=True, write=True") - mask = 0 - if read: - mask |= select.POLLIN - if write: - mask |= select.POLLOUT - poll_obj = select.poll() - poll_obj.register(sock, mask) - - # For some reason, poll() takes timeout in milliseconds - def do_poll(t): - if t is not None: - t *= 1000 - return poll_obj.poll(t) - - return bool(_retry_on_intr(do_poll, timeout)) - - -def null_wait_for_socket(*args, **kwargs): - raise NoWayToWaitForSocketError("no select-equivalent available") - - -def _have_working_poll(): - # Apparently some systems have a select.poll that fails as soon as you try - # to use it, either due to strange configuration or broken monkeypatching - # from libraries like eventlet/greenlet. - try: - poll_obj = select.poll() - _retry_on_intr(poll_obj.poll, 0) - except (AttributeError, OSError): - return False - else: - return True - - -def wait_for_socket(*args, **kwargs): - # We delay choosing which implementation to use until the first time we're - # called. We could do it at import time, but then we might make the wrong - # decision if someone goes wild with monkeypatching select.poll after - # we're imported. - global wait_for_socket - if _have_working_poll(): - wait_for_socket = poll_wait_for_socket - elif hasattr(select, "select"): - wait_for_socket = select_wait_for_socket - else: # Platform-specific: Appengine. - wait_for_socket = null_wait_for_socket - return wait_for_socket(*args, **kwargs) - - -def wait_for_read(sock, timeout=None): - """ Waits for reading to be available on a given socket. - Returns True if the socket is readable, or False if the timeout expired. - """ - return wait_for_socket(sock, read=True, timeout=timeout) - - -def wait_for_write(sock, timeout=None): - """ Waits for writing to be available on a given socket. - Returns True if the socket is readable, or False if the timeout expired. - """ - return wait_for_socket(sock, write=True, timeout=timeout) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/__init__.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/__init__.py deleted file mode 100644 index d21d697..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/__init__.py +++ /dev/null @@ -1,342 +0,0 @@ -# coding: utf-8 -""" - - webencodings - ~~~~~~~~~~~~ - - This is a Python implementation of the `WHATWG Encoding standard - <http://encoding.spec.whatwg.org/>`. See README for details. - - :copyright: Copyright 2012 by Simon Sapin - :license: BSD, see LICENSE for details. - -""" - -from __future__ import unicode_literals - -import codecs - -from .labels import LABELS - - -VERSION = '0.5.1' - - -# Some names in Encoding are not valid Python aliases. Remap these. -PYTHON_NAMES = { - 'iso-8859-8-i': 'iso-8859-8', - 'x-mac-cyrillic': 'mac-cyrillic', - 'macintosh': 'mac-roman', - 'windows-874': 'cp874'} - -CACHE = {} - - -def ascii_lower(string): - r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. - - :param string: An Unicode string. - :returns: A new Unicode string. - - This is used for `ASCII case-insensitive - <http://encoding.spec.whatwg.org/#ascii-case-insensitive>`_ - matching of encoding labels. - The same matching is also used, among other things, - for `CSS keywords <http://dev.w3.org/csswg/css-values/#keywords>`_. - - This is different from the :meth:`~py:str.lower` method of Unicode strings - which also affect non-ASCII characters, - sometimes mapping them into the ASCII range: - - >>> keyword = u'Bac\N{KELVIN SIGN}ground' - >>> assert keyword.lower() == u'background' - >>> assert ascii_lower(keyword) != keyword.lower() - >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' - - """ - # This turns out to be faster than unicode.translate() - return string.encode('utf8').lower().decode('utf8') - - -def lookup(label): - """ - Look for an encoding by its label. - This is the spec’s `get an encoding - <http://encoding.spec.whatwg.org/#concept-encoding-get>`_ algorithm. - Supported labels are listed there. - - :param label: A string. - :returns: - An :class:`Encoding` object, or :obj:`None` for an unknown label. - - """ - # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. - label = ascii_lower(label.strip('\t\n\f\r ')) - name = LABELS.get(label) - if name is None: - return None - encoding = CACHE.get(name) - if encoding is None: - if name == 'x-user-defined': - from .x_user_defined import codec_info - else: - python_name = PYTHON_NAMES.get(name, name) - # Any python_name value that gets to here should be valid. - codec_info = codecs.lookup(python_name) - encoding = Encoding(name, codec_info) - CACHE[name] = encoding - return encoding - - -def _get_encoding(encoding_or_label): - """ - Accept either an encoding object or label. - - :param encoding: An :class:`Encoding` object or a label string. - :returns: An :class:`Encoding` object. - :raises: :exc:`~exceptions.LookupError` for an unknown label. - - """ - if hasattr(encoding_or_label, 'codec_info'): - return encoding_or_label - - encoding = lookup(encoding_or_label) - if encoding is None: - raise LookupError('Unknown encoding label: %r' % encoding_or_label) - return encoding - - -class Encoding(object): - """Reresents a character encoding such as UTF-8, - that can be used for decoding or encoding. - - .. attribute:: name - - Canonical name of the encoding - - .. attribute:: codec_info - - The actual implementation of the encoding, - a stdlib :class:`~codecs.CodecInfo` object. - See :func:`codecs.register`. - - """ - def __init__(self, name, codec_info): - self.name = name - self.codec_info = codec_info - - def __repr__(self): - return '<Encoding %s>' % self.name - - -#: The UTF-8 encoding. Should be used for new content and formats. -UTF8 = lookup('utf-8') - -_UTF16LE = lookup('utf-16le') -_UTF16BE = lookup('utf-16be') - - -def decode(input, fallback_encoding, errors='replace'): - """ - Decode a single string. - - :param input: A byte string - :param fallback_encoding: - An :class:`Encoding` object or a label string. - The encoding to use if :obj:`input` does note have a BOM. - :param errors: Type of error handling. See :func:`codecs.register`. - :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. - :return: - A ``(output, encoding)`` tuple of an Unicode string - and an :obj:`Encoding`. - - """ - # Fail early if `encoding` is an invalid label. - fallback_encoding = _get_encoding(fallback_encoding) - bom_encoding, input = _detect_bom(input) - encoding = bom_encoding or fallback_encoding - return encoding.codec_info.decode(input, errors)[0], encoding - - -def _detect_bom(input): - """Return (bom_encoding, input), with any BOM removed from the input.""" - if input.startswith(b'\xFF\xFE'): - return _UTF16LE, input[2:] - if input.startswith(b'\xFE\xFF'): - return _UTF16BE, input[2:] - if input.startswith(b'\xEF\xBB\xBF'): - return UTF8, input[3:] - return None, input - - -def encode(input, encoding=UTF8, errors='strict'): - """ - Encode a single string. - - :param input: An Unicode string. - :param encoding: An :class:`Encoding` object or a label string. - :param errors: Type of error handling. See :func:`codecs.register`. - :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. - :return: A byte string. - - """ - return _get_encoding(encoding).codec_info.encode(input, errors)[0] - - -def iter_decode(input, fallback_encoding, errors='replace'): - """ - "Pull"-based decoder. - - :param input: - An iterable of byte strings. - - The input is first consumed just enough to determine the encoding - based on the precense of a BOM, - then consumed on demand when the return value is. - :param fallback_encoding: - An :class:`Encoding` object or a label string. - The encoding to use if :obj:`input` does note have a BOM. - :param errors: Type of error handling. See :func:`codecs.register`. - :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. - :returns: - An ``(output, encoding)`` tuple. - :obj:`output` is an iterable of Unicode strings, - :obj:`encoding` is the :obj:`Encoding` that is being used. - - """ - - decoder = IncrementalDecoder(fallback_encoding, errors) - generator = _iter_decode_generator(input, decoder) - encoding = next(generator) - return generator, encoding - - -def _iter_decode_generator(input, decoder): - """Return a generator that first yields the :obj:`Encoding`, - then yields output chukns as Unicode strings. - - """ - decode = decoder.decode - input = iter(input) - for chunck in input: - output = decode(chunck) - if output: - assert decoder.encoding is not None - yield decoder.encoding - yield output - break - else: - # Input exhausted without determining the encoding - output = decode(b'', final=True) - assert decoder.encoding is not None - yield decoder.encoding - if output: - yield output - return - - for chunck in input: - output = decode(chunck) - if output: - yield output - output = decode(b'', final=True) - if output: - yield output - - -def iter_encode(input, encoding=UTF8, errors='strict'): - """ - “Pull”-based encoder. - - :param input: An iterable of Unicode strings. - :param encoding: An :class:`Encoding` object or a label string. - :param errors: Type of error handling. See :func:`codecs.register`. - :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. - :returns: An iterable of byte strings. - - """ - # Fail early if `encoding` is an invalid label. - encode = IncrementalEncoder(encoding, errors).encode - return _iter_encode_generator(input, encode) - - -def _iter_encode_generator(input, encode): - for chunck in input: - output = encode(chunck) - if output: - yield output - output = encode('', final=True) - if output: - yield output - - -class IncrementalDecoder(object): - """ - “Push”-based decoder. - - :param fallback_encoding: - An :class:`Encoding` object or a label string. - The encoding to use if :obj:`input` does note have a BOM. - :param errors: Type of error handling. See :func:`codecs.register`. - :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. - - """ - def __init__(self, fallback_encoding, errors='replace'): - # Fail early if `encoding` is an invalid label. - self._fallback_encoding = _get_encoding(fallback_encoding) - self._errors = errors - self._buffer = b'' - self._decoder = None - #: The actual :class:`Encoding` that is being used, - #: or :obj:`None` if that is not determined yet. - #: (Ie. if there is not enough input yet to determine - #: if there is a BOM.) - self.encoding = None # Not known yet. - - def decode(self, input, final=False): - """Decode one chunk of the input. - - :param input: A byte string. - :param final: - Indicate that no more input is available. - Must be :obj:`True` if this is the last call. - :returns: An Unicode string. - - """ - decoder = self._decoder - if decoder is not None: - return decoder(input, final) - - input = self._buffer + input - encoding, input = _detect_bom(input) - if encoding is None: - if len(input) < 3 and not final: # Not enough data yet. - self._buffer = input - return '' - else: # No BOM - encoding = self._fallback_encoding - decoder = encoding.codec_info.incrementaldecoder(self._errors).decode - self._decoder = decoder - self.encoding = encoding - return decoder(input, final) - - -class IncrementalEncoder(object): - """ - “Push”-based encoder. - - :param encoding: An :class:`Encoding` object or a label string. - :param errors: Type of error handling. See :func:`codecs.register`. - :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. - - .. method:: encode(input, final=False) - - :param input: An Unicode string. - :param final: - Indicate that no more input is available. - Must be :obj:`True` if this is the last call. - :returns: A byte string. - - """ - def __init__(self, encoding=UTF8, errors='strict'): - encoding = _get_encoding(encoding) - self.encode = encoding.codec_info.incrementalencoder(errors).encode diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/labels.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/labels.py deleted file mode 100644 index 29cbf91..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/labels.py +++ /dev/null @@ -1,231 +0,0 @@ -""" - - webencodings.labels - ~~~~~~~~~~~~~~~~~~~ - - Map encoding labels to their name. - - :copyright: Copyright 2012 by Simon Sapin - :license: BSD, see LICENSE for details. - -""" - -# XXX Do not edit! -# This file is automatically generated by mklabels.py - -LABELS = { - 'unicode-1-1-utf-8': 'utf-8', - 'utf-8': 'utf-8', - 'utf8': 'utf-8', - '866': 'ibm866', - 'cp866': 'ibm866', - 'csibm866': 'ibm866', - 'ibm866': 'ibm866', - 'csisolatin2': 'iso-8859-2', - 'iso-8859-2': 'iso-8859-2', - 'iso-ir-101': 'iso-8859-2', - 'iso8859-2': 'iso-8859-2', - 'iso88592': 'iso-8859-2', - 'iso_8859-2': 'iso-8859-2', - 'iso_8859-2:1987': 'iso-8859-2', - 'l2': 'iso-8859-2', - 'latin2': 'iso-8859-2', - 'csisolatin3': 'iso-8859-3', - 'iso-8859-3': 'iso-8859-3', - 'iso-ir-109': 'iso-8859-3', - 'iso8859-3': 'iso-8859-3', - 'iso88593': 'iso-8859-3', - 'iso_8859-3': 'iso-8859-3', - 'iso_8859-3:1988': 'iso-8859-3', - 'l3': 'iso-8859-3', - 'latin3': 'iso-8859-3', - 'csisolatin4': 'iso-8859-4', - 'iso-8859-4': 'iso-8859-4', - 'iso-ir-110': 'iso-8859-4', - 'iso8859-4': 'iso-8859-4', - 'iso88594': 'iso-8859-4', - 'iso_8859-4': 'iso-8859-4', - 'iso_8859-4:1988': 'iso-8859-4', - 'l4': 'iso-8859-4', - 'latin4': 'iso-8859-4', - 'csisolatincyrillic': 'iso-8859-5', - 'cyrillic': 'iso-8859-5', - 'iso-8859-5': 'iso-8859-5', - 'iso-ir-144': 'iso-8859-5', - 'iso8859-5': 'iso-8859-5', - 'iso88595': 'iso-8859-5', - 'iso_8859-5': 'iso-8859-5', - 'iso_8859-5:1988': 'iso-8859-5', - 'arabic': 'iso-8859-6', - 'asmo-708': 'iso-8859-6', - 'csiso88596e': 'iso-8859-6', - 'csiso88596i': 'iso-8859-6', - 'csisolatinarabic': 'iso-8859-6', - 'ecma-114': 'iso-8859-6', - 'iso-8859-6': 'iso-8859-6', - 'iso-8859-6-e': 'iso-8859-6', - 'iso-8859-6-i': 'iso-8859-6', - 'iso-ir-127': 'iso-8859-6', - 'iso8859-6': 'iso-8859-6', - 'iso88596': 'iso-8859-6', - 'iso_8859-6': 'iso-8859-6', - 'iso_8859-6:1987': 'iso-8859-6', - 'csisolatingreek': 'iso-8859-7', - 'ecma-118': 'iso-8859-7', - 'elot_928': 'iso-8859-7', - 'greek': 'iso-8859-7', - 'greek8': 'iso-8859-7', - 'iso-8859-7': 'iso-8859-7', - 'iso-ir-126': 'iso-8859-7', - 'iso8859-7': 'iso-8859-7', - 'iso88597': 'iso-8859-7', - 'iso_8859-7': 'iso-8859-7', - 'iso_8859-7:1987': 'iso-8859-7', - 'sun_eu_greek': 'iso-8859-7', - 'csiso88598e': 'iso-8859-8', - 'csisolatinhebrew': 'iso-8859-8', - 'hebrew': 'iso-8859-8', - 'iso-8859-8': 'iso-8859-8', - 'iso-8859-8-e': 'iso-8859-8', - 'iso-ir-138': 'iso-8859-8', - 'iso8859-8': 'iso-8859-8', - 'iso88598': 'iso-8859-8', - 'iso_8859-8': 'iso-8859-8', - 'iso_8859-8:1988': 'iso-8859-8', - 'visual': 'iso-8859-8', - 'csiso88598i': 'iso-8859-8-i', - 'iso-8859-8-i': 'iso-8859-8-i', - 'logical': 'iso-8859-8-i', - 'csisolatin6': 'iso-8859-10', - 'iso-8859-10': 'iso-8859-10', - 'iso-ir-157': 'iso-8859-10', - 'iso8859-10': 'iso-8859-10', - 'iso885910': 'iso-8859-10', - 'l6': 'iso-8859-10', - 'latin6': 'iso-8859-10', - 'iso-8859-13': 'iso-8859-13', - 'iso8859-13': 'iso-8859-13', - 'iso885913': 'iso-8859-13', - 'iso-8859-14': 'iso-8859-14', - 'iso8859-14': 'iso-8859-14', - 'iso885914': 'iso-8859-14', - 'csisolatin9': 'iso-8859-15', - 'iso-8859-15': 'iso-8859-15', - 'iso8859-15': 'iso-8859-15', - 'iso885915': 'iso-8859-15', - 'iso_8859-15': 'iso-8859-15', - 'l9': 'iso-8859-15', - 'iso-8859-16': 'iso-8859-16', - 'cskoi8r': 'koi8-r', - 'koi': 'koi8-r', - 'koi8': 'koi8-r', - 'koi8-r': 'koi8-r', - 'koi8_r': 'koi8-r', - 'koi8-u': 'koi8-u', - 'csmacintosh': 'macintosh', - 'mac': 'macintosh', - 'macintosh': 'macintosh', - 'x-mac-roman': 'macintosh', - 'dos-874': 'windows-874', - 'iso-8859-11': 'windows-874', - 'iso8859-11': 'windows-874', - 'iso885911': 'windows-874', - 'tis-620': 'windows-874', - 'windows-874': 'windows-874', - 'cp1250': 'windows-1250', - 'windows-1250': 'windows-1250', - 'x-cp1250': 'windows-1250', - 'cp1251': 'windows-1251', - 'windows-1251': 'windows-1251', - 'x-cp1251': 'windows-1251', - 'ansi_x3.4-1968': 'windows-1252', - 'ascii': 'windows-1252', - 'cp1252': 'windows-1252', - 'cp819': 'windows-1252', - 'csisolatin1': 'windows-1252', - 'ibm819': 'windows-1252', - 'iso-8859-1': 'windows-1252', - 'iso-ir-100': 'windows-1252', - 'iso8859-1': 'windows-1252', - 'iso88591': 'windows-1252', - 'iso_8859-1': 'windows-1252', - 'iso_8859-1:1987': 'windows-1252', - 'l1': 'windows-1252', - 'latin1': 'windows-1252', - 'us-ascii': 'windows-1252', - 'windows-1252': 'windows-1252', - 'x-cp1252': 'windows-1252', - 'cp1253': 'windows-1253', - 'windows-1253': 'windows-1253', - 'x-cp1253': 'windows-1253', - 'cp1254': 'windows-1254', - 'csisolatin5': 'windows-1254', - 'iso-8859-9': 'windows-1254', - 'iso-ir-148': 'windows-1254', - 'iso8859-9': 'windows-1254', - 'iso88599': 'windows-1254', - 'iso_8859-9': 'windows-1254', - 'iso_8859-9:1989': 'windows-1254', - 'l5': 'windows-1254', - 'latin5': 'windows-1254', - 'windows-1254': 'windows-1254', - 'x-cp1254': 'windows-1254', - 'cp1255': 'windows-1255', - 'windows-1255': 'windows-1255', - 'x-cp1255': 'windows-1255', - 'cp1256': 'windows-1256', - 'windows-1256': 'windows-1256', - 'x-cp1256': 'windows-1256', - 'cp1257': 'windows-1257', - 'windows-1257': 'windows-1257', - 'x-cp1257': 'windows-1257', - 'cp1258': 'windows-1258', - 'windows-1258': 'windows-1258', - 'x-cp1258': 'windows-1258', - 'x-mac-cyrillic': 'x-mac-cyrillic', - 'x-mac-ukrainian': 'x-mac-cyrillic', - 'chinese': 'gbk', - 'csgb2312': 'gbk', - 'csiso58gb231280': 'gbk', - 'gb2312': 'gbk', - 'gb_2312': 'gbk', - 'gb_2312-80': 'gbk', - 'gbk': 'gbk', - 'iso-ir-58': 'gbk', - 'x-gbk': 'gbk', - 'gb18030': 'gb18030', - 'hz-gb-2312': 'hz-gb-2312', - 'big5': 'big5', - 'big5-hkscs': 'big5', - 'cn-big5': 'big5', - 'csbig5': 'big5', - 'x-x-big5': 'big5', - 'cseucpkdfmtjapanese': 'euc-jp', - 'euc-jp': 'euc-jp', - 'x-euc-jp': 'euc-jp', - 'csiso2022jp': 'iso-2022-jp', - 'iso-2022-jp': 'iso-2022-jp', - 'csshiftjis': 'shift_jis', - 'ms_kanji': 'shift_jis', - 'shift-jis': 'shift_jis', - 'shift_jis': 'shift_jis', - 'sjis': 'shift_jis', - 'windows-31j': 'shift_jis', - 'x-sjis': 'shift_jis', - 'cseuckr': 'euc-kr', - 'csksc56011987': 'euc-kr', - 'euc-kr': 'euc-kr', - 'iso-ir-149': 'euc-kr', - 'korean': 'euc-kr', - 'ks_c_5601-1987': 'euc-kr', - 'ks_c_5601-1989': 'euc-kr', - 'ksc5601': 'euc-kr', - 'ksc_5601': 'euc-kr', - 'windows-949': 'euc-kr', - 'csiso2022kr': 'iso-2022-kr', - 'iso-2022-kr': 'iso-2022-kr', - 'utf-16be': 'utf-16be', - 'utf-16': 'utf-16le', - 'utf-16le': 'utf-16le', - 'x-user-defined': 'x-user-defined', -} diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/mklabels.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/mklabels.py deleted file mode 100644 index 295dc92..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/mklabels.py +++ /dev/null @@ -1,59 +0,0 @@ -""" - - webencodings.mklabels - ~~~~~~~~~~~~~~~~~~~~~ - - Regenarate the webencodings.labels module. - - :copyright: Copyright 2012 by Simon Sapin - :license: BSD, see LICENSE for details. - -""" - -import json -try: - from urllib import urlopen -except ImportError: - from urllib.request import urlopen - - -def assert_lower(string): - assert string == string.lower() - return string - - -def generate(url): - parts = ['''\ -""" - - webencodings.labels - ~~~~~~~~~~~~~~~~~~~ - - Map encoding labels to their name. - - :copyright: Copyright 2012 by Simon Sapin - :license: BSD, see LICENSE for details. - -""" - -# XXX Do not edit! -# This file is automatically generated by mklabels.py - -LABELS = { -'''] - labels = [ - (repr(assert_lower(label)).lstrip('u'), - repr(encoding['name']).lstrip('u')) - for category in json.loads(urlopen(url).read().decode('ascii')) - for encoding in category['encodings'] - for label in encoding['labels']] - max_len = max(len(label) for label, name in labels) - parts.extend( - ' %s:%s %s,\n' % (label, ' ' * (max_len - len(label)), name) - for label, name in labels) - parts.append('}') - return ''.join(parts) - - -if __name__ == '__main__': - print(generate('http://encoding.spec.whatwg.org/encodings.json')) diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/tests.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/tests.py deleted file mode 100644 index e12c10d..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/tests.py +++ /dev/null @@ -1,153 +0,0 @@ -# coding: utf-8 -""" - - webencodings.tests - ~~~~~~~~~~~~~~~~~~ - - A basic test suite for Encoding. - - :copyright: Copyright 2012 by Simon Sapin - :license: BSD, see LICENSE for details. - -""" - -from __future__ import unicode_literals - -from . import (lookup, LABELS, decode, encode, iter_decode, iter_encode, - IncrementalDecoder, IncrementalEncoder, UTF8) - - -def assert_raises(exception, function, *args, **kwargs): - try: - function(*args, **kwargs) - except exception: - return - else: # pragma: no cover - raise AssertionError('Did not raise %s.' % exception) - - -def test_labels(): - assert lookup('utf-8').name == 'utf-8' - assert lookup('Utf-8').name == 'utf-8' - assert lookup('UTF-8').name == 'utf-8' - assert lookup('utf8').name == 'utf-8' - assert lookup('utf8').name == 'utf-8' - assert lookup('utf8 ').name == 'utf-8' - assert lookup(' \r\nutf8\t').name == 'utf-8' - assert lookup('u8') is None # Python label. - assert lookup('utf-8 ') is None # Non-ASCII white space. - - assert lookup('US-ASCII').name == 'windows-1252' - assert lookup('iso-8859-1').name == 'windows-1252' - assert lookup('latin1').name == 'windows-1252' - assert lookup('LATIN1').name == 'windows-1252' - assert lookup('latin-1') is None - assert lookup('LATİN1') is None # ASCII-only case insensitivity. - - -def test_all_labels(): - for label in LABELS: - assert decode(b'', label) == ('', lookup(label)) - assert encode('', label) == b'' - for repeat in [0, 1, 12]: - output, _ = iter_decode([b''] * repeat, label) - assert list(output) == [] - assert list(iter_encode([''] * repeat, label)) == [] - decoder = IncrementalDecoder(label) - assert decoder.decode(b'') == '' - assert decoder.decode(b'', final=True) == '' - encoder = IncrementalEncoder(label) - assert encoder.encode('') == b'' - assert encoder.encode('', final=True) == b'' - # All encoding names are valid labels too: - for name in set(LABELS.values()): - assert lookup(name).name == name - - -def test_invalid_label(): - assert_raises(LookupError, decode, b'\xEF\xBB\xBF\xc3\xa9', 'invalid') - assert_raises(LookupError, encode, 'é', 'invalid') - assert_raises(LookupError, iter_decode, [], 'invalid') - assert_raises(LookupError, iter_encode, [], 'invalid') - assert_raises(LookupError, IncrementalDecoder, 'invalid') - assert_raises(LookupError, IncrementalEncoder, 'invalid') - - -def test_decode(): - assert decode(b'\x80', 'latin1') == ('€', lookup('latin1')) - assert decode(b'\x80', lookup('latin1')) == ('€', lookup('latin1')) - assert decode(b'\xc3\xa9', 'utf8') == ('é', lookup('utf8')) - assert decode(b'\xc3\xa9', UTF8) == ('é', lookup('utf8')) - assert decode(b'\xc3\xa9', 'ascii') == ('é', lookup('ascii')) - assert decode(b'\xEF\xBB\xBF\xc3\xa9', 'ascii') == ('é', lookup('utf8')) # UTF-8 with BOM - - assert decode(b'\xFE\xFF\x00\xe9', 'ascii') == ('é', lookup('utf-16be')) # UTF-16-BE with BOM - assert decode(b'\xFF\xFE\xe9\x00', 'ascii') == ('é', lookup('utf-16le')) # UTF-16-LE with BOM - assert decode(b'\xFE\xFF\xe9\x00', 'ascii') == ('\ue900', lookup('utf-16be')) - assert decode(b'\xFF\xFE\x00\xe9', 'ascii') == ('\ue900', lookup('utf-16le')) - - assert decode(b'\x00\xe9', 'UTF-16BE') == ('é', lookup('utf-16be')) - assert decode(b'\xe9\x00', 'UTF-16LE') == ('é', lookup('utf-16le')) - assert decode(b'\xe9\x00', 'UTF-16') == ('é', lookup('utf-16le')) - - assert decode(b'\xe9\x00', 'UTF-16BE') == ('\ue900', lookup('utf-16be')) - assert decode(b'\x00\xe9', 'UTF-16LE') == ('\ue900', lookup('utf-16le')) - assert decode(b'\x00\xe9', 'UTF-16') == ('\ue900', lookup('utf-16le')) - - -def test_encode(): - assert encode('é', 'latin1') == b'\xe9' - assert encode('é', 'utf8') == b'\xc3\xa9' - assert encode('é', 'utf8') == b'\xc3\xa9' - assert encode('é', 'utf-16') == b'\xe9\x00' - assert encode('é', 'utf-16le') == b'\xe9\x00' - assert encode('é', 'utf-16be') == b'\x00\xe9' - - -def test_iter_decode(): - def iter_decode_to_string(input, fallback_encoding): - output, _encoding = iter_decode(input, fallback_encoding) - return ''.join(output) - assert iter_decode_to_string([], 'latin1') == '' - assert iter_decode_to_string([b''], 'latin1') == '' - assert iter_decode_to_string([b'\xe9'], 'latin1') == 'é' - assert iter_decode_to_string([b'hello'], 'latin1') == 'hello' - assert iter_decode_to_string([b'he', b'llo'], 'latin1') == 'hello' - assert iter_decode_to_string([b'hell', b'o'], 'latin1') == 'hello' - assert iter_decode_to_string([b'\xc3\xa9'], 'latin1') == 'é' - assert iter_decode_to_string([b'\xEF\xBB\xBF\xc3\xa9'], 'latin1') == 'é' - assert iter_decode_to_string([ - b'\xEF\xBB\xBF', b'\xc3', b'\xa9'], 'latin1') == 'é' - assert iter_decode_to_string([ - b'\xEF\xBB\xBF', b'a', b'\xc3'], 'latin1') == 'a\uFFFD' - assert iter_decode_to_string([ - b'', b'\xEF', b'', b'', b'\xBB\xBF\xc3', b'\xa9'], 'latin1') == 'é' - assert iter_decode_to_string([b'\xEF\xBB\xBF'], 'latin1') == '' - assert iter_decode_to_string([b'\xEF\xBB'], 'latin1') == 'ï»' - assert iter_decode_to_string([b'\xFE\xFF\x00\xe9'], 'latin1') == 'é' - assert iter_decode_to_string([b'\xFF\xFE\xe9\x00'], 'latin1') == 'é' - assert iter_decode_to_string([ - b'', b'\xFF', b'', b'', b'\xFE\xe9', b'\x00'], 'latin1') == 'é' - assert iter_decode_to_string([ - b'', b'h\xe9', b'llo'], 'x-user-defined') == 'h\uF7E9llo' - - -def test_iter_encode(): - assert b''.join(iter_encode([], 'latin1')) == b'' - assert b''.join(iter_encode([''], 'latin1')) == b'' - assert b''.join(iter_encode(['é'], 'latin1')) == b'\xe9' - assert b''.join(iter_encode(['', 'é', '', ''], 'latin1')) == b'\xe9' - assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16')) == b'\xe9\x00' - assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16le')) == b'\xe9\x00' - assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16be')) == b'\x00\xe9' - assert b''.join(iter_encode([ - '', 'h\uF7E9', '', 'llo'], 'x-user-defined')) == b'h\xe9llo' - - -def test_x_user_defined(): - encoded = b'2,\x0c\x0b\x1aO\xd9#\xcb\x0f\xc9\xbbt\xcf\xa8\xca' - decoded = '2,\x0c\x0b\x1aO\uf7d9#\uf7cb\x0f\uf7c9\uf7bbt\uf7cf\uf7a8\uf7ca' - encoded = b'aa' - decoded = 'aa' - assert decode(encoded, 'x-user-defined') == (decoded, lookup('x-user-defined')) - assert encode(decoded, 'x-user-defined') == encoded diff --git a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/x_user_defined.py b/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/x_user_defined.py deleted file mode 100644 index d16e326..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.0.3-py3.8.egg/pip/_vendor/webencodings/x_user_defined.py +++ /dev/null @@ -1,325 +0,0 @@ -# coding: utf-8 -""" - - webencodings.x_user_defined - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - An implementation of the x-user-defined encoding. - - :copyright: Copyright 2012 by Simon Sapin - :license: BSD, see LICENSE for details. - -""" - -from __future__ import unicode_literals - -import codecs - - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self, input, errors='strict'): - return codecs.charmap_encode(input, errors, encoding_table) - - def decode(self, input, errors='strict'): - return codecs.charmap_decode(input, errors, decoding_table) - - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input, self.errors, encoding_table)[0] - - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input, self.errors, decoding_table)[0] - - -class StreamWriter(Codec, codecs.StreamWriter): - pass - - -class StreamReader(Codec, codecs.StreamReader): - pass - - -### encodings module API - -codec_info = codecs.CodecInfo( - name='x-user-defined', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, -) - - -### Decoding Table - -# Python 3: -# for c in range(256): print(' %r' % chr(c if c < 128 else c + 0xF700)) -decoding_table = ( - '\x00' - '\x01' - '\x02' - '\x03' - '\x04' - '\x05' - '\x06' - '\x07' - '\x08' - '\t' - '\n' - '\x0b' - '\x0c' - '\r' - '\x0e' - '\x0f' - '\x10' - '\x11' - '\x12' - '\x13' - '\x14' - '\x15' - '\x16' - '\x17' - '\x18' - '\x19' - '\x1a' - '\x1b' - '\x1c' - '\x1d' - '\x1e' - '\x1f' - ' ' - '!' - '"' - '#' - '$' - '%' - '&' - "'" - '(' - ')' - '*' - '+' - ',' - '-' - '.' - '/' - '0' - '1' - '2' - '3' - '4' - '5' - '6' - '7' - '8' - '9' - ':' - ';' - '<' - '=' - '>' - '?' - '@' - 'A' - 'B' - 'C' - 'D' - 'E' - 'F' - 'G' - 'H' - 'I' - 'J' - 'K' - 'L' - 'M' - 'N' - 'O' - 'P' - 'Q' - 'R' - 'S' - 'T' - 'U' - 'V' - 'W' - 'X' - 'Y' - 'Z' - '[' - '\\' - ']' - '^' - '_' - '`' - 'a' - 'b' - 'c' - 'd' - 'e' - 'f' - 'g' - 'h' - 'i' - 'j' - 'k' - 'l' - 'm' - 'n' - 'o' - 'p' - 'q' - 'r' - 's' - 't' - 'u' - 'v' - 'w' - 'x' - 'y' - 'z' - '{' - '|' - '}' - '~' - '\x7f' - '\uf780' - '\uf781' - '\uf782' - '\uf783' - '\uf784' - '\uf785' - '\uf786' - '\uf787' - '\uf788' - '\uf789' - '\uf78a' - '\uf78b' - '\uf78c' - '\uf78d' - '\uf78e' - '\uf78f' - '\uf790' - '\uf791' - '\uf792' - '\uf793' - '\uf794' - '\uf795' - '\uf796' - '\uf797' - '\uf798' - '\uf799' - '\uf79a' - '\uf79b' - '\uf79c' - '\uf79d' - '\uf79e' - '\uf79f' - '\uf7a0' - '\uf7a1' - '\uf7a2' - '\uf7a3' - '\uf7a4' - '\uf7a5' - '\uf7a6' - '\uf7a7' - '\uf7a8' - '\uf7a9' - '\uf7aa' - '\uf7ab' - '\uf7ac' - '\uf7ad' - '\uf7ae' - '\uf7af' - '\uf7b0' - '\uf7b1' - '\uf7b2' - '\uf7b3' - '\uf7b4' - '\uf7b5' - '\uf7b6' - '\uf7b7' - '\uf7b8' - '\uf7b9' - '\uf7ba' - '\uf7bb' - '\uf7bc' - '\uf7bd' - '\uf7be' - '\uf7bf' - '\uf7c0' - '\uf7c1' - '\uf7c2' - '\uf7c3' - '\uf7c4' - '\uf7c5' - '\uf7c6' - '\uf7c7' - '\uf7c8' - '\uf7c9' - '\uf7ca' - '\uf7cb' - '\uf7cc' - '\uf7cd' - '\uf7ce' - '\uf7cf' - '\uf7d0' - '\uf7d1' - '\uf7d2' - '\uf7d3' - '\uf7d4' - '\uf7d5' - '\uf7d6' - '\uf7d7' - '\uf7d8' - '\uf7d9' - '\uf7da' - '\uf7db' - '\uf7dc' - '\uf7dd' - '\uf7de' - '\uf7df' - '\uf7e0' - '\uf7e1' - '\uf7e2' - '\uf7e3' - '\uf7e4' - '\uf7e5' - '\uf7e6' - '\uf7e7' - '\uf7e8' - '\uf7e9' - '\uf7ea' - '\uf7eb' - '\uf7ec' - '\uf7ed' - '\uf7ee' - '\uf7ef' - '\uf7f0' - '\uf7f1' - '\uf7f2' - '\uf7f3' - '\uf7f4' - '\uf7f5' - '\uf7f6' - '\uf7f7' - '\uf7f8' - '\uf7f9' - '\uf7fa' - '\uf7fb' - '\uf7fc' - '\uf7fd' - '\uf7fe' - '\uf7ff' -) - -### Encoding table -encoding_table = codecs.charmap_build(decoding_table) diff --git a/venv/lib/python3.8/site-packages/setuptools-40.8.0-py3.8.egg b/venv/lib/python3.8/site-packages/setuptools-40.8.0-py3.8.egg deleted file mode 100644 index 6d257c133f47f9ce3d9735e02f5e9643a43339eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 571890 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%0AqWw4Jo21d;*5Hqad~W%_bw{i zGctc0BwcQ#t-JyddjTGm5B{qj61nZ_A>jE{XVgEz{+?lx3EwDcL;@{;f;Bz*O+Tnb zuoqqJJu~9HS~dndUMxsIa2%xFv+LnoS^hWwHyHSN)9{<VhxQ$0TYuNtUn~CJ^h`JN zZxD5MV4&Tj!Vz6vXG8iSIn<O6@F353w}_40F~lqUHQU-SHvY$3aW%0Avz0IqFo~>a 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ÝdUUfWfwZc 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%0AaCsRM0n%G z4C>o~+y6iY`6lJ~AT*TDg%oa@00T~D7GC~dy4-Xk@b?4oD_g>b=2sqldI)}H?=J{# z{KC_eUzvgK0q|=BP(6Kv{0ip&_xTlq!;t)nlm`#aCV+B)LVz^@%K^*)X;1%9{0bJv zi&*Jb01g10c>2GCUx|6v$FH<LGbFz<`x(+F7<oquJQo7&c;@f$D;WF6_!W}xe~Mp` z@@@khIsm!=`T&&Rtp*4OxaHX&ieI5^WPtzE0G0z3Kl=mmE56OK>@4AJrDOrcyoYcE z{Xm^{J8;)e#tnD&%elyILyC+Y1Ej?+luwfJy@E?g4X&|~Swf|f9x<yfk|X9&%5l)6 zge>7Bl+L+|;mBzMG948PsIvvj<9PoJ$Rt9sQOyrXWtBbdClqk&<CNtX@wop1`cJRs zIGD!?!|=spfeb_GV>c`m5Ty*{B}O2Ha9q+h<k1NHW7j(*?|)3<7f7=VG&G;8-s@y1 z?NzbkaclYayG608K;1*sLgcuD(G+*8a@C-F(S&FN!Zm)*Yq+1d#F@xWN@DuCAmKAu zs`lUuIY5GS2NtLDEVro>#mr2qbm)(8+8^tjiI`Z<eLQeXamqz9%*wI_p*$E$g{jP0 z;%Mzfq9l{ZwS<w}uZZk(S?<ivrDlwnE{;}{Tv>MkD#4(#9O^B&7vCI&S&|#^pAWh? ztiQ~Tj?dMy+PF!mJsa=Z2E`sNaH(SJkwPb|Yo~DT$KLC}++-Rlq(HN81Vr;!uZ^1U zj^Pb&&Awo>@cCisIJgp(a@W2>CJ@=yY4IlQ7G3On@wqC^V~3VPccf?8hLJ0~9fTW( z*gy`Mw0e@nu8UhGV<+$qd?D9=t>i8*IU{J#!R~$h5%0}oe`IhBCJ<Fcq$FJKRFJhz z7Fe351|xai^a&<-8Pjw9l3@bB^)KCxm#>dZsP8#F^$34>8q+C?`XlyGz9HvPo^dIo z8gEDLvWD@r`z)$t*VJ#xp`SoSIvL?)XnVy)G%&`U^I#m$kra!eGIDN`Q(#yv+C1h) zW!SnrstnsV9z}+&TO1vMOh$++G8k5K&lur}T|Rz!&n~ZEkI%pq-C)%p&&uAiLLWwO z$lx3Bi@)TaM+H<vB*TME-3Iue=AdkNj916m#OUL!b|I@;I0P0>buhHAXS6VC0E-Fm z=!&2k8wU2)ai)k6#GQ1eXxr&GQ+RLh-z+uKHE!rD8W1@yN_b}{k-~jpXW;eznLB;_ zoSc`8)9k=`su=>j61jX&fQdy(*-z~G_*E)yF7RBvyQy*pd>=nx-cWN;(zb>|Iby2H zJE_DFae+2=BFUUe`AYMsJ0(tSriOBG+WE;&<Oa_J9#G1GpNW3<cCN0fJ4J?RCCfq) zg|A^Xn4OZyw1{S(h6{B+qjz!1)gcts1Hbs)ly`Miwm3zD#*J4(_}On`ws?MqcOGz` zNJ)Hxh+?@;jT43Ax>KQTS30+<7%m<#?8MAt&nH7u5WmQQwji4TSa6Ul_ku?Ot%208 zFoOuGTmTlxy-J-yD~_466EbK`oJ|JLcD}NO=USnFH*isDBniG~f@sbWVl+jxp+6W} zvo%Q33EZ}`vQ6YRFKCYzsV!0Aj$NWx={jq1tKSZ=-N}!vIz%dUsAB9O`<>2u10?eN zx#7zoS7jR=3#XhHCpTR5c34x2N-4`0n!cyas=U_X(eN<dvmP$=JSGkpFi;OH1=Koh zp;C*&5h~QxDUR-=l3m2eS11MxYtRH5Jtn<>gWoafY=4n-nEfJL#ui|WGF-;fJd@=z zUVy=p4c%`#;i_zPRi4uu)tc(nWX}oh2)Io`I;zN?NGCORm9tWiam!JuC{Aa%-E$xD zGV<JoX5%>=`M}iTOxGezf17AzN!9mkT~XCf&aN}uDRZT>>pKKu!|*T=6mino_3hcf zXkLJ%cqFY7&+@3m19;kY6l^sMn^5#0qWjCFpiEn3TYP03+u~NvMR9~Sq4a*TYmkLX zk^Qp+WVi9TC-k4P6S1Jk42*#iS#<S-;5Dw?R^YKF;%j{6IW8RO2wyCM4?8c*CKLJ| zmWB+V6Ae+!1CjL2c%i&i_~Q=p-L!g!!-y2wAl`J^B}4Q!o+q*nt!`_*?`ZpN7W*t< zJy4;rn?}(v;pp&&oc52epirvh8{+jnd_|<)tilhJ>qQm{tt@F9+Cx0S?w=!JS)eHk z23V|x|FU%O->MkNNYoNE5|xccqE>@fS%CrmD>cJ^8`i*oTgxF}9U6`*L&H%U(QwqZ zayL08_L`4+o`*91EJ#JVD!Tv;qKQV$H$K51K{KDnqK`pM&<Qjx#h)4eA$Knii}Fe5 z#ceK=pufb9ioS%G<!=#v7NJZ+%~5tEpNn_Z6lbH)xH3BwEz!XLcJf>YU)c!}F28`L zrZV)WxH&x^IUBStQ=7LX+91rNQh*1f&TNBkAllewUYbrUebEv;<9*G>p8-bT@{2s+ zt00-8rai1;7uh8uOL-{08KJopC}OCkYL9ZYn(Ft79222$y6mEeLP4{Hg?yk8<e56J zauOe9fjbG?+MmFA0naSi<Ak@5=d>GU2%&?L@47lU-{e^%(NYtE+{h+ksS0v40i&gO z?VRYLUYdOj(v4<e0p7lVdUk5|g;1Y4MALwFfoRgQDxl(&`cC#w(VdX{LI2%VLZK4& zK0cmPag&9@y1-r3P8Y$DRLXNpJf~(aR8?y6ZR6Qhx$W&xOx6HZw2x9nt598#*=$q5 zze32xP`HTfheuvSl|n$AHWC6ji=Ts>2Qn~70T6Bcd&((gJmBNinVg84#V`$O5hKzm zdD*DrJ${Z3JlG7ONkO)R?xitmx>*C!)s=vVSq>0w*PdI<Le>E?|7;k?2Rr7)C2}LN ziOoW(!l&}g*`!26f81Hh)$p+D#>qTgz}>Xqa=R0n#1<laxr3-IcX54WLs|a`ZYMWE z6HdeMF{@p1RQv3!wWI}Merw;3t86T9RO_2?_XTKAA}s`O$Dj>`a8cS-Zeo|4g;!C> zPVWL6tUQy7=?1C-@*gYwvDT{@L3pzk1=Ml=ybUI+Y_o8<l^U~a^6I`-{X|lbOUsON zaaXAb33lPq6(Y=g*l+2Iz-d*D8mfEBh=vVf+e!aP#WMI(y*qs2xPqYmxalt<(JkQi zUKn5H)n4svl@aY8RVT=PpE9ByH%=wZ(p2L#-`M^XK|^pJpn2YTO^w%YNTh{N<8@zc z?)Oc`ekKRV%h!M6rSMVtbzhV5d!O=ar8~3NrdXPe2W(klIYC&cB03+V@C2p|=Z{{Q zW}mT_9j4i5y3)|98r~3~{2IR%zx}NYm|%t<WlhK!R;u?W{r=zf>5zw?9@<tH!rl^E z&rWqV$(+rygfH#E37>D2%fCoyhNnh&YD#DYzPw$=oryh~(8>-&%|4=C-t!UPu)@dN z<0K@_J6lSzS+z)_bE5)TsrI)Bfr)d{8xICfDv1vcF(=iMBx?3gS!7DmpWHBB*fc0H zLlb-M;f-A=?i>!Nq)T5n(1kdsc;-U8q91^&P=*vuxf=O8;TKAxR$Sl6X$MVd8fSg~ zkiy>H+2eaJPvupF4YN}=pNO9~YLg3r5p1QaIu31{XwJ$K&*EWe6T1wxn%`bam-9aG zNQN-3*K8BTyD=7woVjjb$j!n<$;5l*$at=gC3@E`Vmc_n*{sAuxINMgiF8>vMySUK zo=$R9uqaA9{0Q#0bHm_W*>mxbmdWV3D5+t}j|x}Nr;CcSD<H_rXL&*vI^q~M*idtn z`(_~w?C6Fx->NgypS;6!#aNO5n7;&6G<@3eiEHq#W}HoS0EHOgdou&wGdhZL^Xldx z3?|HbpwKdU6QSiw?bhkg$b6$vMkg3pgCq1GZk+@l|59NE^2?`lT$vG`o18GSSAGVA z3x!mi--=th_%O`Ic}1?NzJlNXDNXeya+%zqKf-+g%tU-83KNb%H5;Z#C<+#v4>dJU zV!4@Gv^c)JorBEur!^0k$WgnacB|5+@U&CfGtz74imgL5Zv`S$Zf`|XR&L{0?1yz` zS@nDD>AK+wD!Ve_*oNO34A6+2;CVZ~GGc2S#zyN;hW4A})BqNy`kJN^fNH241_@OO z$21QDVJ6bV7d<Dbz$Oxp+6>_K0gDgtO7uDXr<!UJ#^Ae1+18xjYM`>pmr+)EwmW5l zO5eP3lrSB27aztW&H-7?7xvMUOn;iTm0C7Jl{}j2y^t*`?IDBx0#dS(^aywtgV&Gn zD~JH9(uYmWdG^O!=lhjES1Nyu@DeIL?yC{me+v)^o^llmbRQ2Q-ib2YBzteU>{#?V zM-ZZtyir8%pe0*)<}?wEZWSI!HEqV0oc1@!RvmD{mHuMUq~EDnbR>Sf!!8px0oVrM zCV^AZbCIkWYvwkhF!Y5i6fV6TBeggWN1*krN69%LMu>n2Z6t!4DEY+*BI<5hP=mUg z*5ipKd<)3&MG$sCOE?0GxsDvGLW7OS5XM6MY++;#InQo#TaWli^P7vVA$1yAM5Ipn zOqk_#MD~;lo)W3kHRRMX;#yLtepB>Eg@AA-PSIztnxdP1Q}j($fwSzBjv=P#M+Z&O zAHWp-z9TSkE=}yYj~GnX!rCwzXWymLEP5Bw%dYj@BbLJ=+KJvvy%RMMhF8cWi*xh@ z;l~c|!S{_$*An^VnSxdnR6;zlsG&xK1AK6uGGtyNJF&W+9p|N>KH{6AgD^ouue_%P zX{mvCm`}+xpUtDO*;6o1Q{zL}Va^7n!5PnRJy`~u(k$d`r~2?=dPdE+wqe4@&}p6# zW+4x6O`^tn)Y^{f-8s*cVBXm0w~&TYu}xQQ7gTqm@X)rvh78~4+ZQU$;$yO*44{-V zY>8RISOvA-?yBqn65fCeV{CogY8lbp+Pep<pbv^fLNrvE13mRT@oD7NVCO}}Pb4I1 zq!4?B9MRt^jNImJX|J-<_}pGi&2FlC?2alF)u36hpSU7udTta1g_9s14Qg~n(Drw6 zoq*}<(P-khPgskpReSZ{<!o6RKZ#xJp8bwES5QO4<v=0a1fp69TEZ1U2v9y%iLadt z+_MkFPvSa>*2jA)Y&K=Kq^x&a6(u4Y*-X!3g6C%pDnhN4_k8MJAlEl*9-0ejh#pss z6E|SYHl>s{*_&2VeG{%MnSE~c0oO=W*<n(-#*s>58*SpbKAS9y=+83b7|cSsgKF4< z=3WVO>uZvKws7fvX^gR9ROWNe7E02Zdimz)CWW!1Hp0;J(S)NtXQm!Whm~;#-96Vh zO<kg}yV6S=W(!vwv`O$>pil5P$RR}zw5hSHy%0%a@O|Is3m<Sszogw!x+sTCM-n+k z7qqY7xJ=Cwe)XCU@0%eYD_bxOM!5RN6yat`vL)Al79m&W9?2)A;*COXhS0VpaGVxz zxoWlmMA$5z>%!g01eDAdP{~$Kjwea8?@V{fT@#h;ctf2w;Vk<j&HkgBeeX3~R1H5C zZ&Gu^(>xP3`_IH@s@X6@fo7iy!V6#yX$BX=M_@5yy<Fyqz(TLSqj#70jvmm*?)l=1 zMz4y~{3xIj>VOi;;9G#G=9hWpYT40sp(qo3oIO>2lueg}Z9T(VviZh_&$U^@Tlmm- zQ7<ar!1u%+S9B__I4_B)BK1^klk<?W>LO}M<szpMWvOS;k#VZ3FOaq14zF6h0(EoG z?@MT8=fYI<b;9TDE!A!8mnga0$c_fD3*Z$DUgtcIuUbuUp5G7Y!1<m!edvhOPU8+O zq2DseKKWUgL(+a6*f*yi@XaB*xbf_#yh*J;&bII}_<G)pi(pS?q%RdlX$WsQ(D9M5 zWZ=<~t$(@8*x|}-(|5vjEIuIZe?Q=VQdSEDE0%tFi%LI-9F^T7y#E01q6=?5;6sLN zbSL|eX-^N54)3zB+R3j=Q=%@3aN%K^3+F4&W2^d>u=ZwGZm0gNrdkELbT`N~HKLNP zOLx~9qU80bduxsTns@5cY|0!qGL0L-AL=>1R|fO`XZ@~BE!rJ}PYSgs(*SOYFqM`y z>;dmQNI#98o9S9Mn?H0$aGA9F2D<_XROE)oZz04gPTiA)Gn;)p??>cOCACf=IoHe} zW;eH>0t<~RWyB1WXgI8OEgLbD*C<YQCn?idwr*jN<4P!7jK^8)YE`_(Aeywz#!e)i zn^Hyug~sLfvx|96-J%iGFk&)B{E;`Jqq1KHk>xb<v{0ZLFy?fOISyln`(>%1v8IP+ z;La=F2IE7-*}>xInHTB(`5)u*ViNSnH4l|5@ZOwO^OJSx7a}utx>JIc-Hbz1jd~-Y zT%f(jAPIe(4dYE+j`&b6$e~ht6b{{Yd~O%a<cdaDuGVGj)VFAyD9H&dW1Vc?cun=I z@G>uqRo5z#lb~_Q9XyDiraw|K)}17C#D#L9Nf^?k2=#E#?w%6SsI@Vat#=#6K)k&N z#PDPU+M8kTp%<3Z*l<Us7|I@OQiSm#btbWPQE-rFnm)IS3nl^2+GI8nSTX3M7NSO8 zOT3j3KN<JB@Rs}nJZBrthtS#^u#R$1P@N2L=NqGqUDyFoM@<dZ5Ze%U8SbkaUVU^^ zaB@3Zx&TH%v+pR-F1^Zaqo8p6i2F4Ah8r9QTPLBkiBLC6v+tPZ9T&a=7ZxUL+2~yx zJP#xRKciH%cnrP)6O{~fcWrvmmSJ_HcunoH5z~@U*QxhydUAA&=cb;PCv38%gcj;Q zOKJv8RdjCG8M3nuqq57!NGb<9$X%>XXuR28rIk}Q;`zC$1LpoNy-|(#P%<AN+sYlz z-hNFDFC+cc?xZe1HufkitdBJ)fC%YyEgBQ!X@XHP0!BrF^ZLU=Bt5Uy>{k^yufWLo z5Vw?_SHf6LfophjvcUkI-~KuoJDtvketkp5BzKye<QnFz2O3{%3ngdvIE;v1C!<y_ z4HP+EvKwlktRMp=(>qXR6gVq;L)m|~g)J{|DR8j#;$XptEATLl4{1sXo*wGC4F^vM zja)-UPd~Qtlkbr>rv56LNwRMUq4HNx1g~+kBb432ID|&XJ*onpA+e&#-OhGmypUjL z3tC0?(>Ts|I$6o#0b+X*(#X9fnwp$`<UBgsSN0S0ZD^#+rY-EnT|l1mlW{O|bmqQ| z^Pjm<Pg8*A@hL(iDL|0>;?Z5YI`&#J4!zQ`A<8(!QyGVYgex#<Cmc<J3H&5Wa(kWi z8Pk2uEKL5K?q;A6L|mX|gsoTnG$U+febs)D<a4cKt-r96OhnP=ew%|aupV_AwGK2O z@5*hh&FybCp2o=;m}qvGE4QV|C~7^S%|?_JWNLFox3SeMXu^n%EH715YM013?E%zy zSaXCM+0(!nLKrS6-q^}29VXF%7T6Tgjd(g)Pn2P?3)0wGY3y|2Yy~+-9w7?*Dgtir z-%~+v@8f2bE3?-#uDe0Ssvu_ua{j8>h?XJ^c-+*>8^di{v@>%zz-<5%0klrR!0m~z z>?M?br)QEhoqI-0v%g0ztr>WYx)Z*sHz8wY>Y;<UX`pW)rtG)r*%(;=XX=~T$%(iL z1I#X@NMs-<O^pE>xY^i2GP?sFl=v_m9!NP86A^P(lgI>vvqpbNQ=_2?Wb_+uhPe=@ zz-D#~AEp9w8t7hA1Wbb=5Q1^`8rYkvOkMD#tTI7$WsK9*sr(g+9<YjGm0f#v-f)#C z9P%aVuwL4$Wkaa1R(Sp*F$UHva^nS?-P_P6I}Vr#h(TroJXcA?9eteTsQz`4>u?)S z!^{VqbT5v%4~aQykt+du673|_Pdx(jY&47=89S}Y+KZzZlS3*<dyRy%`ME>gdFc1f zqUY~NY3SeHk6YpGtdb#SR7V?7H)tc5@^>>pTV}iOCz~E^R1`{onR`uGeLvO~rEopZ z!$JTnnMpKwhT#%`LsNyZ=L)kwL9HtMX*{R@Hi!==HUe`RT7z?78FU<#p|;qo!pS+l zJj$VS)SA9`SieuJHHlQwVs`^9`@e&c0WBnF@3+aFr^IY1=6RK5K2Xp%bK`^$%0;m% z4wX8wCJ1f+NEF+@h3^*E>^`$Nw>Gy=*!7K<H6QP&>>JMkFDyI(E7e@#*<g|x49-TN zo8}6sD)0O6yNx0s5CaIji(leF#sCAYQj6F1TBkO1LBmX1k7Ae+H6u=K);F*zi8#F2 zTN4=rI5)$aoW9BFo01`Rbd(G?vB}sk^Nhu>T?XTvjDum|C-*2|`sgug@%z+Nzkzx` zjiSMoD`;x=l4Y;=AQ?CfiTL4as`rx*38#XM`UXu+HHp&!%i@EZiEOZZ!w4V%HpDo4 zgETb-sPXb0V}Goerm3C|FKL>ZrQkFh1+gC;@)fp^C(6P|W5k^xE6ngiY;y+jxCK1C z)*Us~KgCv7kj=}v!W~_tiAexQmJB(&9tMb}<~NXQRi*ItTkkSl4%WQ=0^`FIkHPVF z`Gaf8;e%516Ewaim4D#4RKBJ<StQgwc0ct5G@z)OorrP}F{dI-L-Dc1e)x|Y2N6I0 z5I=<%N~JrJd{cWqR4ozf%0*__<Pc?f@PL*xl<+5gkVJ|}q(Po1pm`8=X-WdLqnpj{ zltfZ#6!P$<cR+eYZ+vCPw(~H^j|@nv;BY6xDp7T+yG;F#i`!yUL&ZR9Rol?6t-l!J z_-tF~v07DJ?)Tgj_ySby1Wa@d85pHQrQ<8<l)|4PgJ}zyR5tiNVrg2jDR5S)`Vwav zDkKm|j~oZ6u%DNZZ}{5fz$`IWIQ21ZL+<_#;?3nx`c;C=CNAX&Ndc}cyfESl%0HG! z0y*6-t`$%DRP=0cqA;w)yHwMKe`m3eeYC@xjaoPibg{-I(+w-ItCt=h8ZUU)=9|dT z@&$cAJ5M-Rj53p+cVoNbxmGqhp1Z(KgmoJyJX2eM5Q{rSMQX#f3BNc`)^f;vc!}4Z zR(d)f1#>FE(OMjM1pL?aJ{<4G1K>{xc4$ksPZAOrwh*oO;dpM_LS}HNiOMDyGJ|k7 z?&CX!N<4eudIheG?5grjs|I%Ih+4$h^QijfJ5DG3$NE4PyTn(1`$ZX1mvaG+GaK3W zdE68`1zh&=EZfR#Ask2$+Z{lY2%&0nQUzZdwc&G_DyX+5WDAL3O9nPCa~0Xb!Y8S< zI0f!S{k4Q{KC1~Pnri%t3)wCMla(#3ZydC#^V=eV72Wb_X&4l`lZLuC%AsnWP;vm@ zv_TF<nL0(=tSq5$xMae2W(ICM;r)diqHVu}tfQ1->l4=WOB7pY`&kmuCp`WHML7sj zPAHMWQK<)!_j;Q~%Q6cG4h=%8uTVm{Pe{j1dKHzuIl=}TJwxt*sW!St(Fs&U$7IyY z-6h6A)$D_F*++9h3r0fjFsT+AXGxc`s<NvUQdS=JOcHc9>~Ad(%nhe@sW9@R-+SwV zZ^b1<_AZCm!$p)<lu+d%1J-=VDRg%1d5OOVa?6$5B|P4Q*7pQ5C%ZCH4GWt?CQqPJ zA80}?LQ{|7bbUo+lZZ%&Ho9}dx0>1}Xqas(7zz*m0iNDMawr4M%+02fv((~3AFP*S zg}fr)Zo~2-Y#s7-6UE$E3L1>SbH?5paZBhnrT(&A$v1k?Km#54!YeO(=SX($6IlAD z;B9AXx;LKUB?3n!q>?-!zK!vrfO^Jb&l6r&xQwkF7sL%0J}C4OBIG(}m*;K$ciZmY z0>xIW&lsTXxBbz7okF`c==*cLs0LZbKnc{0YT6Uf0aFjTGP`gRyj9rf%U;-4IABr1 z6%4pe<+{juPB%Thg02)W)9`?zJ|etP`$yir(k!A_^=2#>OVA3V3;mcPj|q?6$o8Rh z+ZDbzksRb;v64+rwOI%%lw`{%41MXf*(b@0VzES48{@je>5i9Nimi^RONx@$XKVIt zR%+g<ulf>6tuwt<-ywO!n!yDRc0RaB%uGiY=$A?80_BqESg3UHq3%U@M%9gUd{*T+ zCaWFkxh2qdyW^PLBRDL|ZJw}!5XTfp4es`HA%w-rZNx5^#?+%8b_3&QIgyCC!qoeh zg21WQUO>Jz+nD8^P(CalB^p)4{E75^6w(8ZZ1^sK%Yw;pG#Vt<ZXE+u$X1|Lm7E$_ zF&Qed23{sk_(cKPg>x1J&alG^d^7B;FfNHvF?X6QZX6rb#OU}2c=u%4QdVWTjk`0< z!nuWz3%8pmyOBsaUS^}+sqo?Pr~TH(&n7o~796*7q>>9>oCdRPD|~tnp(@C#{<~s< zEOVmCYQAZGeUP(WS>Q4r)9kOuQ~Y&>^c4RDo*`(7W;dW@j3?Y_O81r+r7O30Ydl_e zmT2k$)7*7tW%nU1r>Y$Z(^-fosCJwaI45IolCxPE&-HFO2ARa=itJ3tDfT@aL(YCh zrIPRWC~S(=`VTABkU}NSPXc^AZ7>bu9;0BhVw1Uz7ht{HjcRpJnG&6mIte|YCOiZk zz9M&m?-h1p4WP!uvW0uBC^@j)S*ZdJB13o~9gRdHd4k6Y6LCxI0+1^xqG?3-2VRtz zU2cab7}6-Y5cK;1)lgr+!`csEo*5w=&i77Fc)8VYx-|I75tvXY4yMm{Ho*esuIzmA z#ex@IrgKD`#ARybP2n%t<Sye8z86}{B;fgKZig%P@G6hiEZp^oh{ll7rX(Md14~N> zEH*CggmA0?Z-KT#{{(~YRG>g%IL-FqBh1V9-<-Vz$VWVygv!CN`NPNFV<jLI#&Gx3 z<z(Gjy7jS^NRS-dMTDLf<hUwN$LDt7Nll0F!Y(8;(Tg{p!+Xp&SV&<~Moeo_s=WzD zMu?0LCYbJ-M~~u?g^q_s@p<WO4qz?L#oOY--wFun?3$G0ifFgWiS&^xg0DQnhwyWe zWVi(Ar?zJjePC@sUCgLc@tuw<iR|PoAz~M~G~VW3B$JVn+_P0KQ(N7LgyY-=RK;j& z@kGZhm$A1yHpvsXTO6AdiQE(zQD))KJ4w<Opeuv;Fih(*wkR4Laf$3n-q;dtY~#6e zie6V`y=O9Mj8`CmnV7_zD~t`2G-<OYsBZiu?$3(K(<mDjXO(({hfb6s`gkM*De$At zaZM5)U+e3gr?IV}31|<s7ZFbAFxkv_-OM-PVcH3Emay&3K}&w)8cI0aEsO({a8$tH z@XR#>SI9HoR0{{Ea{E$!z5_b26VfyV>r!+05a<seKZV*=V(lb8CO-EZ)pd*_;Lr%C zqK~B0_E8*3&l0*J-{{IV$Xe0ESDy3C<&E`FSMhErSO(>uIXI}?(Y|umqllh_Zv14f zDL(fww~ntojcuBpCH!n~%JZv9%EC3D8yE<e9~cz=77fRNISB?PMEP|8peVa(6h#kA zitq&r`WQ}8J1Mnxk~A!FkN5t3?3s!4$WdqqQa>F+Za$%YU<mcCUKRVN6~g^#K7j>^ zGLI5ISwr^w4zCGZB^IsmtrD3%M)eh3`p=RjHBRDn#&~(1->yLh(YXeR8qbWqTJGk( zGImn8Q7va9gl%hZq~LatU|Hka{W#;l;2_xt6NuXcQ$?R}VS!{fkDDRfu_ka$*}wWK zC6Tf9p8H{u?!-gOaVS3~*yKnBVVrEQ!pFtgbt5(V4r%uFcBkAuQOQn8svDVbmL09x z_btliHOCv(+-P@_h-P5J;&b~v3iMI9OnpfSXSv4J0a_`Ieb+g$^wTODpG)<*KPi)B zemewafluY<^Z_cXnH*oJp%6`V2{A}QuqL*sk&DrPN3@V~vxLd31KZ=5tFCGfD)KQ6 zl4ccX_Gv_umYmg|S<sy#pQwZyvB`B~p;AH6)}G}J7gZ4Jy@KJ#@WhtCv;ZO$=*zWs zHT-|m#^3@)dAMgTJdd%*!2b~&Zv&t4o+!<JJcE~aCr#9{VUUAsB5sQ8Kk89v_8-GM zcn((!2pJ|C)f59C0!BVlU3ZfghwK3yXjFni8bKkAppZsTNFyku5fsvH2nEdNBsZl1 zzM5eueO==Lax!r2kcDnSy|Y!Gh5?=40rTZma)eW_aW~5=zloe?z4NH}w^yAFvYwBe zU(4!@>hIyLSr!+<;sL*$Z|+-t6g8_3{yp_A!yEuO3D5@64KM<T#3+Dy0LuUh0m=ck z1MC2J4&ZfwCV&qB+5q|hw0)2czyPoczz(n-;HLmj0=xw94!{QhtpFVW{Q&Ck872Z? zIzSA70U!%tEr1>1Nr2Y@P5^uX&<8N4AIbu_3t$nzN&q{+Ljb!0UIN$$&;-x|&;if~ zaFfU|Hv`NDNCj99U<23yPz~@Xz^?(`1ULrJ0`M1rK7c47rDFgL087c{aNw^a!oYl% zWMJ~|Gcf(jff!z6@P*y?8w2x;afYkX6j+Lit@%2(Ot;R;>a3fJSY2LOzExLXFDucN z+spE-6&15W{p01?trphmAEujD!N5Nzxr{5$*OiuGKGr<+1wTtEdK46u=IhLx*}}3? z63DTZwZ&G5f;tAKPAMlLvmk^a@4j?p<<?RX>-LH~dr>(%t9<iDD93IDM9mZfhACkx zm^`M8u`^cqo5kca#qh^4Gni6_BhR;zy3Q!&ii_zZ9s~qq6KWYnFcU1-Dvd^C5dP-G zFlG{27iV4`qGIljiODvHKqYm!zB8&dg=^r)Fq_IZ!A}J-m=H##0!IaZ_{!{^k_4Tc zM9PuL70RIC5Y@2I;p(sv8turNMum?aGd5z}_z95{Cr#E(xp`{TwCT6Zxb?Q^nYYin zBj(P#VrS2pdv{!Xf_`4&kM1!f%}-7-rY=ZZc<+6SOpBM8)0bu}%goANp7U=jR_3l+ zy~eUOFW*|QuCU0qzPO~cto(j^1<P&NxM}kPKi*QgbsO2%HI`zRn#+nxS*sn#0%L^n zvl#wg#KbapL5rop(;|XziZw89YH>xX-D*WQ!^&n^iaGMU!0$P!xVS72)7rUGwy4Ca zv)b)tb{)fnLFX=8v?L>g`rs>*v2gJMzgH$@i79E};sKwfb7Nv>hlM7U>MZ5u#YK4* zwg`qyp`}7sVu4|40e_aYmXxzN6pPC&FeD4Dx@4WV?Bb%ec8h(pt_bREw_Eer;?1){ z&Bazrg%t*NDQn4NNeaK*Z>i8#aOLG?b_lUrN^}K)d`X$z3VFa|35hd{VoULh4GX<p zmo$I|2YH(^7B2Gpa@fM63Z12*!dkMnc(X2_vlo@F)0IM28>}=|QE3rdWGOCsfMg%K z4CBK$f+$%brEV>^4&HT}%Q(9~uCsItSsg?zDXU<iuIsIkJ66YTt>B8`b1Bf}S&ECX zFlZ^n>Gr&`l5+Ct&bTA5*nX?7fGf=-ZA$R83?Nln!P>bz7Ag<_NMK5FvB^?I>yGul z3+qij@6s}EU7@a`+>&P{%>@I%QXJ4={_S<=p!V|B-AX%e=`z~hY#|_BR+?v>b>r>f z#VrQQz?=}jfdcZS@VnwLoGT@>P9O?}R!cd>7USK0ojPtTDjU>q1L@`tnXZD(zfQV2 zn68|I+HWYbvz(=Ppo6d{Nkoh{d&vA(mzCnQeFroY&fa8V_2qwOd|<uFe2RTt2JiXS z4Mll=aiuo0ZYqcG21X3FjQ_Waaqb=zrv!#w5nBjrLOzay^@HON-7Zq1d<$!V=wY<W z2Y>W->;0Uy0t>>CvQ+xWp&~Fll@yiYLR5tPjl-QQ<tnfNH(GwcPaf(J6F+1ftfkOv zWu+z7QWj!k+_)j*TI}mMj9B5zmwZnJFp07F!ItBk>q85(!0C;SV1_Xj<=M+B$_iLr zRuQRXa&)w>Jr>bP595VG>{+vBG4o)3UT24@m0BPISGvBmY-8z<pj;`55xZ$hXsDS+ zOVCO50B|bx!=>km@T`=cANPB9!?Q|y{;A*d!+y^@{GNCEJ@4{+e#GxN*x`84QRRRI zS@EFb!R?OlpdeV0Yieo$p_mwl*-;Ct>x^6C%-IfDZ(&h3oAK(6Zib`Q0jU^RmJ16D zRjQCp<>ed8%LCTqfBjIm+~B_%zQ3!(uKr5{O6huk)z|n7j8WzHC%eHv|Mc7a{^U3K z=S{2oXE*=<fZx@9TKL~R0%QY!H~I@00kVNV`3?RJjDUai@9)(g|H9$V|II(_hN~>q zJMjHR>pM{I!9Fs=FgmKXJF9CR{7J2=j(^Dg(}#EL-1W$#k3Igg-A_FE^QV6C^fS-y zdG7faUVQ17dw=!omtXnKtG|8icmMwT*WcK;|G>dF-}=Mb@4Q>zaH#R{ADfzw96fgY z#Gg){I(_E7v*+Ib;KP=WK0bfp&!2qSdhxT*+y3K=FNOBMcsl<2)z_Vu{&u<Ro9>?8 zE8l+C_kF+k4>LqVGdwrM5dE|3|IaS}znmc*I{be``=_NPl$0dkt^vd3!*8a}1V0@< zY=$3WGTo7%f5&D*OPNg!lVl=1G4OGO9cC7nZSXxW0d5H&GpyyT*E5M*$5pTlb1zp+ z^0*ghWptCu?M1jJVY1ls@cMqLb*-I~XtsMTrQ{LH!Td2_%oFp%d@v74w;A)m^q3aY zFc}t>v*%k#9;x;s^0cgwvsXxd+1C70tMsyrqfe%?QsR-pNv?&(w3rU#V?2z5;S4bO z(jH4TuwrE!Ggv|xqkm?F)xKn{4S0Zs0~9mvctF@9O9h*hhg_w(teh(+e)OGY!<ZmP z%R1})vQ0@$W`=QT>|L``7A+z;LD7H#AOiRRT8JHKAE+|a92x-H0h$9^1sVt12$~97 z3>yx9$x9Y5$y^r2%mSVl-@W@uv(}Pqz`rD)xGSNo&A?TZEG;Wz>FSvF53H<sKzO># zfRd;T6UQ*G6*0`SPh2}LN*kejPIA5P7a|M+;YS9A|6yuic&%Ufx6=$vKLR}0gL_VT z#_)&y;uX#@FvW8W*TrL$J}~_Bpzw=>!cPneU!Q33)%ET~!;s~4{^<I6Of?K0Zb~vR zMM>9BpS$4tct+oM{q#RyeEsl0n+NLF;rHA!DBd$m2f|)nI&^zja{|lr&u91w12cKW z(BZidW*HP-KPdkLs{+IQ`!#K~fmyx!`t?0%8#+C@$BM6?{^aKCr~jnt`r+?x4-6mN zpRYf5{q&~Y*AH*obA9|*yc8Hd`1_o)mxkjn_m_qt%enCC_3`LEbp3k%{Fs4RdBs;0 zGX^)YTbXPA{&lwUkDaY7l`XKATJ09rnoM`hl39DPaf7uK){G_yWAPLs8Mn*5ClRH} zY)cWFT4v8EDqUA>r7I-!7?VuSOr&VAO#W7pVP*X?O|z8d7X$t94d!Yp%jb%%sYS)s z#g-B)#QvBu;%<Dhy@)N!vlM4o$^Ib2bjcT4EgP&?`F}f*3(Yti<~wCZu@z{Fo8{7~ zo|K<&CpZVm{0~#gF>P{LNeLueR8$JZ&%+e3^xIjk92ff}rW3KJIVYEK*cv~gaq_7r zv@GU=HCVQ}+{(NQlufafy$aF0mCL-lc)k|=H7TF7+o6@co@vU=(n6ARzHw6?5L=KK zGA9QVla+wWkij3w7gnTL*K+IDS?y-1E_U6QGKoeZTVODn<Y`t*IXUEDo+HonKw~Ar z#EeyD{wQCFJ%AgW*8GK~d3I|F83hgg{y>Fz{WCCaQnHz0!m(wR7)|)x3fN>>ii`5e zm;nli`H^y&-&x8$e3MR7?!jl@iAy5B5fr<y?ftNS)vvvlksZ~AK;!&OnGJ1C#t_pj zUsPtvm$nFDG`$HpdpExa^+-}_enxpwDectzWLThaV23k<#ZwFzzV&46UlqVC8X`qD zQ?1M{%C{yLTI|cpOt@n_e=}=k4qZDR7_BdmexP3s!&sDAbZ?xrK#n4vv)VVCt#(3q zmgdnx2)%8?wq910w_X~RFJC>Dpm8$DSS94&vLg7tD#$p6C+11TQnom=bR$ry%&!Or zORcm!R(UaydZ(IxCG`7+o_*Z!9X>q3dA=;Qn5!tnyytTT1y(zZ?Jwkul1-L!T21JQ z$qHXvEGzRi5F_}<g0?WwZwue>Yl3vifj$tYos4O62tz+n=1UwWSi0{h?`2Y>4Cr;> zXqe>UvI=Q-U>>5QMZ!OcdD5>oOE|WiV@VwYVr4VI_~rS1^P8nv4hv0UG8mXd$}M)Q zueMo%K7e%#;^^1^Sr&T{9#kYT_ZgQiHZB6bAio%xrc%XH7}sPlGw;(h`AZ7u`*isL zmxA?!ncX}0B(YG?T8_0=Bwc%b{MYZF|ErHq^0_j9kp}J6aq(W!)lv_E;qo64w}1Wq z_x~1uVR-9z<K9jA3-H%Cc8Wg(`WgV`JsqL{_xa*DMHw~km{dqEo}uA&Pm~BmQ9v}T zf@1t304PtYlH6gE8!Ckj_X`^%rA1dG<*SwaMgrU<0s2po{O3sTNz!|=^lp~YES3B- zBsW{iKSwINSn|h>6&(Ofw8XZ(UBWe3itmtcu9DpCQn*tJua@$`3wJ1r^R)E7N5ba? zsk~oG{`)2TPD<e)O5qV9v@N`C=52F-m-$cn4;B8OjXzZQ|K6W=$R7>Y4f*@0qWy#Y zhCXzl;X`kV|8w#FA%FkBj{)iT|M*ZS91V1sT&a2i7OXYfH*cRJ`M>ljb@#kT-KuAB zmj}3$tq$Vuh4>B6fBd{|h<vO1scVqjH*PR~lH~4#_@|z0du}}QAI}NTtr$B0t$WB5 z>S{{=c-6-`X7$ImkMFuV{@IpKTCXt7om*+j;=j^8yJRW+ziRH@F+S-BeU~v;<BIm7 zy}v?_f$99(z?5GyFtw3M%<l12u_?OP*P`^pwY66;khSy#xVUCN3ofqVDsb^5zVM}i zti`W@i}Xb;xTC;b2`<t!QQ(dPx9<xBGalT-;7$PdA#jma$Om^4xGCUH2DkM;41|{0 z3oeec*V+uk3YQk#O^7_Wcy`tKxq-p2rxjcrY!|@A&CnCzuG)QLfb<vAQJ62*$;)0~ z``DoGcV9Lzj{@ufcnF{tpc=pdunC|Xpb%gsfEgeSU>-mmz-)jRfSCX@0HOeN0FeMr zK(W675dh%;S^zbG5}@~Q&?f-G-)Q_+a9aRQ0~`kU1HfwlF919X@D#uffGq&!0K=36 zeU5!P3)>X>{GnU_K5UbIX_9rCS%bz8wv#UCk#Worzrp;KqnxJiyhQh>%^AyvN_s;- zbIL!K{xsA}JBf~Kub=-je&hYpn8&fG2f&#Z#|2vEK*g-*04@WJgo?!gEC#@fDc&>* z45f=VGDI$pK^;$cll*T0c)9Wp024s*{{jN=@5!mi2mKV%&zruu%fRFVtOQurWw>hm z{2x$D0|XQR000O8gqlT8*bb}oi<tlb044zd6#xJLb7gdOaCC2PY;!MXb!ja&G%jU$ zW$e9scvRKZFn%U8lT2=$1Q-Z68DLN}iqY|sFi_`^iJp;(#)^uHij5*xtTZ_XumUEY ziOpm?mA1Ck*0$E_>#fySYq=^W1ag6J35wiQ;(ZSz7(kP7J-@Zqo=GMV`o7=qdA|QX z9x`X2eO-I+wbyO0y-(?F%O$HMNjCU1O-WiMiGM!nfBv@{{sxU*Ge~+neapC2mf)6g zGw0o3=~__n(0vtmKj<pI`)5CUNOS$<URQ<wGuQn;bNR2o(e>a%_uM-<J3GT2uVccU zFZ}7gt2VVH{(Q&YY`KTRn_H&9bMJ!LE#>fh_`&O1is^Y*%Y*a`w4~GX_LjNu{PF$e z^RRpZwz3jQy6175G~!KmLn5wInjmGSq)XC=@G@V-wdKQ4j_9&QiicAq$&No#-&0y( z5rZU>s}hA0j~~AG3re<Ji!>>D@a9+~N5=nRkpHKDoszUX<?P9mwR;z9@I3iJ93bqw zt$!XDKr^}Gp1ZZXVgAn-bxIe&-`@WDeDHs=$R>SpITnO58HV*)2Ii}uyg+26K0;rm zEO?ImK|bIAK~MkRzyAyW)bMP#Lk-V&=cr-Lou`JExLwLj<tF83)%eC0WS^==tLdo^ zu#;<W@{YW&cDG0T=@vEeu&I`}@G_WJPnYLlu>9L5X}lVlWeKv*8gtpb^4Kb@Uy)a2 zU08K&wr(?<V&_#I8?U=+x|R*~v!=IZt86nn&3_6tsMh`YT}{^6s@WJz@pM5U+l8vR z5ncn{gSExxl2uS>a8jYmMIn{VcdIJX++`|T;-1xH9p6-JkyJL@?F+Cb)!5)t?o{qj zW;eDa{$YRfZc(ehnFEVJW%hRlLw?T&H5_u6QOq8dHOMQ{RdzhostsALn)Ox3F4k>L zK67@RBh;!NQX?TZl8RvD3AZl=pMJMbjm&fx0BCC1?{@L)bAduEaTiE(&Fc~ceY54z z-*LGAL*Z?r@L(t`23?InK^Sq$)7`F`Evnh7T3f1$X6p_J!c%jKRBuZ~W)t*;BK25O zwb&34_#nX64AtYD@cr46MANw%S1x}d0|9%A^2G)xB~)SpdtX_FZz^k1Sr1>EiNR)- zJs}3n)5aYLF?-fsh40lHaAfalOd9XA;};G$bv4KisO&_f%s~hS-Qe9or#+_1jw<1$ zlDsYx(5l4qg&NM|_d;_u^_o*2>z5#9h6T`smr<nNDX++fS6}F$cDqkrw}lsq%=VI+ zFSLNK>J%bkb8HWU#_Pj;UCkDKkf$CJ<)`X>mmc)9j&`%g)CLDxGosp7-j<Gt*6lH| z%IAHxlU2auKlaP=N+L^Bs-&1DQlPv9CZZ`2zN`rgoeRM8H**M#+~o;)pUV;OR(SzQ zt}#uMkahq*p8<zq)F#!m>VsMKW8*ARO{?bc>@b~Id<2vm=MAz?>O=PU_~#(LcR;GA z9!GSK8VR}=_#@ZM^Xv$}<L)FX;D;vRXBPg<;U79ADRK)e^6V!7G{Bn$^B|Y$JhTr{ zb~fY%1X~b<x>YRT!)YzVpMnxkYYAX3d*9OvuagkvEL8NhebnJe{J0&l&H36V_)zEY z3L653_|qd1{vf1xH8OxhWkGkDvB?bEe+RXg&b#&@q6M+}rwDG-=}%PqcTw$yiE2lk zrP`3_@WA-CGvn(mh^vAUMg^v>#qI>ysX#dgT=jmevLk@8u)Kni8!SslUdyI#5*d%Y z9xxjq$!~2Bdbce3Dp0-&hJ}w!BRJbWmZVa)5f)XDb@0J*V$DO%qFSgka=*E>AjoW= z1j@HSk>5d)fVGW(ISApO`bnHfn2oe%{MINGTe5us9tGG2LLopP>ZI?+Ta=p>M2J}_ zL;%-j_Y%MYBuMOtAIVU#{20*>Wt9XS_OzPL<9m|nQh`{g5r5Xjh)xBnw_#zPJXWeI zoUG+g$tK7S6wAAQQLKrk0?JZJ&kiWd>{C9*fxx2SYfNVMz-#!LG`<TYP`2CXG4=6$ zn^jOqpkmGwAH^qjIzSmIwnmRx1l1~lr+^X&RQMlml!o}2Hz2XRMUA|Zh3RZFpHbVF zT{SnU=6cn;t5TL%q=f1<$J7kXHZ@z1Hl;{NF)35T`RGSjHA+|9J%|?YL;(C&f+U_P zY+?2?hzKhVd4>I22-PZC*nc->xfH4BvE#711&J?I*=`{8eBm)%@LUDVb@6BlHMSSm z77$kK<DF10Qj!wQrY7EYmq8YoO?NQ-f?LH|f_@_VD2ZHn<r)XF*+_{6*>MB$uq}vF z<9kfgIBf}pZSDXJyJMM4H5wh}R+VM)R7g{eW(UTo#vuz#L680w%?3ZvZJKKZEopWH zy!$b2={R|8h~$L;%ld>jLl(fhqzp^GHh{20(*jntISn&w7X;V`01jXCB8-D2-p{>a zB7<xrUkI6Kd}G5(*v5F~hfm_*v~cBwX$D!m!%TEoWnzMn{UEv``w3^zI!1g}?o#f& z>-J;<s50mMqb(B4z6*X8qLI-aY5-8a3>LZS2!?%m!LaJO@n%@<u-0Lcj(PU6qpVT& zZkB&n?`_o2<IB&Lq-GL!kwUlxne*)MwDSL&C`m?(8FeC_L6P?pMeaCjk;-_H&m_d} zd)x~+BJ=XDYw~<@&F_djZR1}}fJ{B6c7f4z8t|?hR`w>f;g~%bu{WP@k&MsAst@d# z6|fEkEYF^pVUc3F5Ez|-@(<7s`}2^gYkJ|M`b4Z{B-Y}@CBYihh90}|DHLyo;#u`w zN@0~Yp1(fvY~XGHWzE=XdXMTCAYi3KaD|q#HX`&h-SaSVjuRp~RkjP3nluzTgOUHj zAwd>a2-N3Jnin-<58EwLqwhwfs?0vyYmwGMek9^)t5CIy*}aW&un|Bd%nsX&APcvh zi*VVq^Pzi?)eWKoh+E+?qcQR8iImuRfk;eSH4;&3v8NT#Z4|VohKE{IV|{^YGyuBC zEE<S+_VtiE_9gZq;v5W_N+PN?0OUC0oHxk=cwQeLrU0|8$Ds<cp_YJg+|)AR_q1j& zt=XZcHm95h1{pBxvHE}!wdn64rQ6`b&LXeozXXM<YML8WAI;8l&%?>hz8WC~Rvm4C zZncTAAjX_MA4DzHyQg9b3{+<thIcQT417af_1dfS?*cWyUF|-gHXOGSLPW2M1aouv zRM2DPH4o&;u?#gbqri0D_yI`+2#BcPI5t#edzZ>aLk=I5ocmhHJ+UvhfExzoQ!6&V zsp3ii<z51%Wl_Go=I42`n!hOtp6=*CVBUZ}L(N75)cpSYy;2F*3s5YT<uw&~1jpkd zBZ2U0Z^k&h_qcsRKIVVF07q>%&h4loh|ruIRC%0hEt7YR2P6x+ePKX|#@;^k|2KDT zf_?$|2aFy^#f|cc9f8%B_`iVsMmt3ND$Y^6_ZXk1X{o{d1~r@m!geWZ2^bw$1sbBM zdXacZgBPooJ9qBf<;&G@E@D-{Y}LOj1$Z)Qb5*k;V7BO8jq+HZgqh%fp!%3JT9PUY zFn{<4kT7n@fpQ=?-LM<}I-oo}IQ(_OUyr^!_S9UGZ&kT57yh6G{D>kD*o{9_2%a2& zI`OAR-`-i3<(8r|0V&Vi{~+5_npv;8VG6s}r)iVwfc@3la^=wHI5_5dfLu$16#c7M zR)94&s$m;+a6OD|O2FWbigN?2&C~R6S<niy%l3eA#4Po+2UbgBD630r+O^hzQSXpL z4C;(mAL^@qap;R$cdn+#U+-5Ncn;;#eiDzmS>(7e{(4Pc4qrU#GLhqw`0K>p3}fRl zLqvug@haC$#bt{9v2Id5J7BJJDoVN<(zFbit=e435<3k2b5)E;o}lmzc`)KGOsM=C zy5yoENRQ7smZ*0?l%*n#W<7QkTWE{pZwbqT^%i8Uit%}m(k0n~tX&(TFrTBeyv)|U zJ7{eO8W)_<9w=|TmJQ8OS#b_i9jbMPqf4>MT9&**u^Jtn>eD#To=pMPO4uEJ2Bacd zOQlQ!UIhv5JPh6IrvL~(hB7orbCZJMpxaf7vgUdf<Y}HViE<V;3jH7mdGc<$`4*v= zfplnmQ-GZJWl3<}r)l9F1KH5Cqm&(Eo5C~Q3smoMEhFeXqRT<=dQDzUto0q#ZQ=EB z(7Q>`Qj4B)FNbLTGg##Du=Zildq5;The^#M3B%gjp!YM8^xv5D50Qjn?K#mqw!d(Q zmPwj$BZ`)XtGrY63jqpk9L%Xze$0!~;OZ1f$WqYP0BC4KfXsMysF6o3F$d<gDz(E@ z)Hsh|g~PRbQAOK32{QrgcC<naud`0QSj(O|TT7ohSqFY`G-gvH51{T=I7Hv3dJkw9 z2Vn#z20_}&-xe%-f_f)E{%Ug5+xXK|tIAGc%g3?h;VM9IgX-<B2*OBc<AQ8!yaF79 zg+K2tyoKLRg<(*%GBy7bwdh$Ii-p&rwt;*VbG7lyAy@2Ts!Pq^kGZI#NtCO%F1fcZ zn^HT}?WvFc8gj8sF&hxi1wqh@&|ZV11Awkyh(m+`XD8+jV}@fRgA&uV5GuM!!Wsu9 zrfDJ74Va-%<adri9J>dk!nG(=^vM&T!dHw&St&LckYpFX95SvRkF4GSvI(d!ivcwY zP?RIB<<2`A`}8smm09B(P-{SrJ}$(5l^sTLuu4#OwR?AfHI$CpS2|%ggn=iNj@p5m zD$v@XyRdY^c8YCQF&2b!TpE)C6bl1ZI;viUSYXDx6r;n6>iyo6LOGv<`qVrCt?aHJ zFqkC%;?2GvfYNi-hK8KE-3_LxryOlm8(MRsf9uEVo0L3YU_0cR$56ev{Bo3Fih&3$ zuO|s?h{|eLQD_Fx-fVj&^51rC7^^}Pca42XIyB<o=^o4iaN5fqkfW&Bp^YL!QcKyg zZ^CTp{J{BCy#tfFsD>2XX;7Y&rs6zU7DwfWQjW@xT9SDv!Rj-nEgFHNT)syK@a(sP zfGMxE%`!S1v71q2aCvs{bIE`KYNN3#3-Vf)4MWE5A^{Er!Yi+kBtP37gYs2q{qoBz zN6!MX=%`xaE|jz^ELvbZhv1x22ml|+PcRdLHWB?oXy(9>0dA#?O5j!>S_#>e4<AXg zb?hd!rd9h8=bR?K04;8WBB<m*k!HWU5TJe(p6YZg_!m$kjQQ?D3){Uo1FZ}NO&}nW zE>{3T@S|6dcyDZ&^B?64lmT=Q(Sksi*CtpZGMce<mg#jv(}7J)S+C!MEb2N?Jg-%| z8&Fl!KfN|GG<|OMXQn*2`go7Ls9j|i;0ozL<n)asVF2q1tV!_Rg}{M2&7gHhz_UJ3 z)2KB7pq~0h70}n%Z8nB>Xy=8xv<Yg%fgA{rg7ENoScY(>2--qjdMy@9%(aW{;nx?@ zl)0`XLG_=fU}Op|fdy(xaS2g1JCgE)$olIoXoxx5Dg?3-AUQs?h0KMf^H4m}#x|SV z`{Nb1wGt)(Qk>f$8^o_hbct5D@I{2@j>Rwtp_LaA0k}mhp5tVuwPMXFST88C-u)E^ zag`QeD|ZRLCbFZFLIt3f;UGc6%F0CCNHN<JC8NnD+mgzv#<aR~P>I>2<v~v$g)q<X zk|n@_fd335E}uer?JqXtBYOrs_%i4iG<6%i?}zc^bw!vqW-Miy=7L9T(3v`5Oq+ns zffN(T9*K4Tc?vZqBaXK!k+KxinF8_HrvZH>+K8r`yks`+D`6dMub&;G@#Mo`JeM2O z{*rBxEOO{1L^a#%@C8Et+KG=sux6iJvyDh;cGVbwz;iK%J5h`%0C?rlUq#~Wm^h3Q zd&qDdWL*dYupN%?g{twbgUr3E_jE-T-#;0$7NzMav9B;<w#sC_Yck38yb+(_H1mC^ zHxuh!ClcWGJ5byC8<UYU9o6kYFV~=<quAp~s(2RkHW&vaRs*w<wTWiqAYc}M=M)-X zoarL!I7Yn!QOnULoFNA06fh)s)z59VFUu0+p#Y(9@Gl@i0Y07u1>k8qCp4q<1*5+J z`2n&jUoWcy<RM}d{po3xzab1$W{J**H>6Ph$aG8edP-^|D?3E7_0ee<Bi008eNo)d zzMCJIhQZDJ`S^3tQ1PsbzyBis+%ZKwy9(p)h1AVQ0R{O_E+WPF>tnsz9m#vbw5e8q z^IU=;n$Fvs05w*X-X=+Ni|k+R1itkXwcI}9LmaxxKZJMH+EiVL+p1coXJ1%|BC+dM zXQp5YH7_}~&{&1kaL}TpIJakC(bH&hm4DZmh|B3shBhjojrVX=V6<N^CWFAZqG?&c z_;fp8eHoCT(Ku7TyfjXX_`gp;4`*GR$oW|Y<$Mxz;zlRGqc<nRoaX=mU(TPCG5^CE zt4Co%DkPZBSsQ7T9tItqS1A;(fy($2Upz0N$ll{n$^FyfQRx`f3{e1W+X-ClS{iHN z|He!$Qzgk4TH>BBuLL<+S&dtuez{~*kkz9oxRu{`5X$u+uGZ|+u~-ve7vBRvv5~CD zc!!1r*gK@Gg2*<$715P7$Ly<2G8qXGFTifk3$RL8fPH>fLT~5qO&3Z)bTA<r*|}!H zLY$YUh8MWd=GBirl(L5%rEFY){k*U=|LZQrHn$YTsRKb4m1{ndXb&c=wgkhz?L|M5 zAI~Sl=$%=txF_iCkRN*q=d1W6hK)Z#*m%Sy$sv?14X;HT0VIwryliK{+H7tI@==S3 zv8+<5UMiJWKG>m80-D#IhcxdTK-xnP;;&pzG;h!vVQJrDI(I=dn_*MpIsjC*jlVw~ z6R-BM8*QcKrL==F3En3Kth>mrzJ+Lk>12&CQ6EBP6GY+09Pf`Re;WM}%(|yOHaEZ? zc6km4^39^j3ui*Na@dUTg5FOnek8hAd4=jdR*|K8dn(hEt`eI|zu53fS~~Q~+oMg0 z4M*$OV(8hMmOwbw593g3ZC1?f=0<91a>aiWz_?-JgSjdQum|8-slt3ElZ*uYUgFLn z`y)z+oXcp>=HsU0SjeG2AiC9mgI3%60@b@)w*mY^`0FBO4#q5^#!UOq(kxPUaURNH zdU-H1aR-`i%6kIF)RU5)zZ#tY__c#!@WQr}Xi)*iR_r3#Gi)VWY`EABqGD`BfMuO* zE_P#q=3)mvKp2HwnbkA$QgY)PPO+2(FJia_gj)@?Qw0pRfJmCW<|la|;O(s(4XP?{ z03udho@X91O{3fmh&loO%5$UvvO(AMJQ%6nAQ>9J$bnU@m{ROqW4gm!oUO8yT8C<; z$SWFR4tZTG|LQ`rlj^o~Yb?dI#%rqCu`D=nF9&N5uwwz%$@co{qNp6P4}Eo8%+0(8 zFv7UX)ND2T9{oDrpZUmAG!P&A$pr)IQ@VTzs;E?DQ7tQAEGCdGxv?t&3Qt|BBwB)I z&OtfZ+z2h{!}&BAQKRqzJy#^Zc@;Nd$pQdd&H@1KT_>yQ)!%Fvn>bxZrNkyqON!X{ z+JjQ>JQRIk1uhP-?WHV=dwYJ?0gst})(H>V^25D9e$P?UEb;6Jc=zfG|2rU`XWu~4 zn#{s{<seBad{(IPvI=TrEiQH;yQ59}6o|8mvCZr%&hrH$+0Sk>O}S=`BzV){Y!a0g z0l12{S(}7L=?TH|ddOJ04GlCcpmmK!D|hJw^|MN?q1LKm5W+KpY&~QtgDf!Kg^%jz zW9f6S^awJHuSaWmLyuip#Gh)wQeD#vt2Bl08g%x)#In!c7lk!PFG)ka6$a(Fw$fL3 zv4VSJGu=M?@hc4U$EV0NqD(m;hYqBQT}8B+C~MJ>t(wh>_lO!6<XnEDB^5VyI;PHA zG+33_ZJaKzd&1EPBVl|h$E*t5q?WH&%UjjR&=yE~DkJARNoqK5gSKX~O^SDi9C{eQ zF`^*2)jHyVixYuZB57|T@LVGB2WZwfW|3>ALcj+N8$I{PPcDPSD~GC5aP25^2(>b! zr&tbc#}Vi$kwcRy<{CLPkpeer4;nqQ<j@!NcAGZb=($@CIq9uj4j~_isx~CaB~rlH z=m>b%YZt3*76kTc=PL4=FEZu#q{_k1fWB3Rgd=}_drx#Ql)%v}i#llIYE0>2sOPX1 zhOm1>0dx-5k-X-c%mBMXD)DwJtZ6msY_h)r+kiYd4(tXR*P)$6)vD|tlXaLdE_y`z zL0x?%wF^t+m8CtnEm$9yg#4wfk^jL*^R7T2#z3XBh|mpD>PmXx&5v)jp?HaB=@~5r zka3$F(|lDMU5e4>D}l+6rz`BJ9JvTLsMe)o_6KO(@0Fi$S}}0nvTa7s{c`9q4gSyM z(7!40kR19W1r})c8a<VA=zE|KMvpFs+9-OlT(c7@T6G?Rcca-d*I$&YrGv7V0+8$9 zs`;DM_G7VeFfuqIN4}*IiDj5A{=!@hXlMgwJDk562!%h&2s#v;aFpa#sFfnUP)L|6 z34QVK9NP^|es{1yiQI6c*6%Kj-KdacglT>(lpdQFU`uKG`GwOGLnwz9pTu>$!KK;f zhOdmJgs)7DX>>l$Gz^uHk${`3h$(VK8a}crGfLyw6q`)5hII^uU!Rs%D!*6K6B`cm z2ag<zOD!#ju&soZ^w4{DsdxQSN1%H*!sZYaXHdlz))H0^)3el}tfRTjRE#gWOT0%* z<m-?6fsxI@?H`!C_i!0^?;h1UVG|6Js<5q!xmEFQdejbeYc3!StUds1w)-&1c9H1? zMo-Z)t72`gwW{Xk*mm^x!77yZ0Bg<sM%8S@_S0cp{jz~p6-2T0DsO=t%A|ei%_bx@ zSqq}5o9TmmRj2OLl{k<^aR8O-)96aH?0hA%?hdldY~v5(9w<<Mvecq13K|6Kj-@K= z{w|3{3A)ts;}VS~5P?%_c^BqKYQ@XO3EW@oM;|1R*Mvo|2`yu|i~TZD@Av({^jzk4 zg`M=&SAUJR6m5*(+X(^$%Pxhgxr6Efkw`^#-&0S}kM#EF!yv~5%<+{gIY*WEBHclg zgVtPN57$p2q`~3w7tM6fl51w*7~y1If&=HMOhXL32<EG6gGI~1mweJ0KzLGPxe%M8 zQ5IK>!!#oIoQZsNUcTn`=XXPT7O-3BsxQbk0?T#r54ug0B5(kL7`uxP?IC=1Xv5*x z)~`ST|2q_bs{Nk&A|N-K?(JFjbCt#XKuE~Hpgu)-2cUqitisi9Zc~koDSZ0W#EQ@_ zWx|3AR9!na$o%ekaS)!M;{3PW#Ecd1as4F%KQ@6Lz?0D1CN`oMqFp#__lWFJj}K~J zG7_QIhW6{`!7j>zJPuI=sq+xpW6vO<5}ZtBf?1)|0jqH~Fx`F4Fc`$okOKmzt8pJQ zO@HB2y=?Od!8ZR!Y?C!%L`!^Y{?Gxm3qI?1S!s)Ydwh#NVb=u&320N`cb=9Hzw@<h z_+6y`p6GP!$*Qa7>lw&J;WaB(1%x6ex(F5$1YFUdL7*;;Xw}p!^r2OcS}xNEsYY`O zMMbZN<f$HtzqB|0J2`qK#@_>+6Q4kG&%-AW+OhZq$~qjMi{+4vPvCcH@I($Zo6y!L zuh>HTiuYWBevjTJZ5(ZZ(>^7Ll6>m-rU?TDQ2VAFl0zwEpH9v&>U)}r=rcgep|=<4 zBTAS~%Mu8Z9Qgx8m$2^WlkhB#WUWAk?T={c_UKYdITF<q1;;3H>IjpLBApz$?KBOJ zt$TM&25gua$*RKg5x=?}GeoC|qApE=-wE0!@SCrVhu@2|A@Exu*W`&B98o!5RWwxu zEYVYF0fDhiiyl2iQ7O>_r^Mhaz@J(8GZTN*680JNK`?ewZGUV}-T*-9*%dd}&I7*h zD}0-fDY~eOY$Lro>jDt87v}}Tb6mXw@A5dG2F>mj;F8PN%tGZl@{<<a3E6MQy_el3 z9y8!=)*UF0K9WNE{O=qVV8U(TYz@uib}17LO1mqIOKKl+1dL2mX(~?7C<#B31rdet zQj`HdQ!u6sVuAsqaTbW#*C!XQXk^*vLIiN#CGMZdp#V)atYv6h4tdGRbDm8tF9=w_ zUn>ElEXtFEc|@(eo8?G^G{ehJf_6rIK={WB_@M&reo)U&Gy6tJR;(Ms_IDr<h%nLi zo=W8hfGbtyg;i&UJiu(H`@r7F><^(zXf}HrmxKUO#>|1&SQ-F>@d`5)@BU@WRO3gc z_5l2z*6s!6SF&h#;==)pi48KH!MBA79|)FzjXq`|d;<?1Tl&BkAhx@K2&AIp5r|BZ z0<wZ508^H;28}O#?**b{ngYBoD@L=l6Uk(A02SvZhxf#i$4VH~3Z!Gd`oO+fs&&lH zRCJi|ny3+aPiv`FGaOa1N1KWr)e0;u6Iry;@ck;lAG5^!wd`*(ozMSE7%tKK<ysul z5;95u_Ftm;E7h<^UQuuKr07_iFP3ifSall&9cpAo9M;KkSnXzURxAg%6((a|wb_bp zABwp_MXQ2om7ll)P1)JQQqfJ(^)FPxVphnHrkdr#R0FDK<)i?6q@a|Q7xtO}diQE; zTJ?$if|RrFYg}a!`x;iJj22tBpbuu-dnEFuss5$|a0f~*pw*!P^H}v17R%a?{0*&@ zAdBQ!1aHD;uk&V^>1=*W=q`>F!Jd7<RiJf#>QNz0coC*TB4orT=a7_up;<w6x{J#R zR4r@7cbBJ?uZGew7qT2~7t)ESzwiBJS~B7trRU)`3HN0*65_*RN78iWzJ-=jw%c@? zZ;HjQn$B<DB)eZ$%|6``QB!!&Wtep<#IC_wXsTDeNn8g<=JvDb@1SKzK{#30g);h{ z0P9iN5$?+q-5wc)4uitHSt#h}SBHCp=Jwb`+F|C#W!T}_1M{G2Iq&ojU3!fT1!PA6 zuDbIJM3De%_eXpVZ-$m{)(5QHjh>4tjzpA$Mo;dd)K#FIN{!VGe%#te6flkrQsk@a z8`Y;3=5Mey3VYuo0j!>`M(kgI2_tS(jrtsN1EBO<lF~OP(uY!d?>>wtDbGv2dBS;o zWF8VJ=aXN?w{e1zvK$aNyomhalwLolGuTDY(fF{j#YA)GJ)U0ook>OZ+rF2ig)TIu zx4eO*`>z~?1HX67^zU&FPRQ4s@}AOLlB^$qQGJ^oefCUfY(XCI2bVCKVS`6tHi0pj z<d}wY!S7G)ZTf;D`+iWV7mmlKOZzq5{2eu|$k&`yyeIYg<i?la?Dau_)~&O{&_!EK z1cQpQ*%t2V>-)uOji~_?w+bk>!n%7Mq4-N23WcCJ3Q&Bfc)!!v{SQ!_-B;PuMTmSr zf$<NrPYE-3B7eE>hrqNQO#m~cA24qpO#t(~;{9G<o9vn1C=k2Xtr&OHuDnrrNjJc1 z>M_yPz;sr<PHS{HzY#ZJZ~@PKovfNCKp_lUdu@Jw`&TrK1)i?Rbr$|pkPMbb?zG}^ z@{YM|h(%g@f3W;>V8afpMY`6Q+97FW*RrgRE+x;<a`;;w;V+qLHbGTx<HXP<mq6xy zAcA2o;f?m^f70evlZgD3D<=Awj#&ZkGYt3VlG%vO#hxT@7XEb#`7erPtU>?LFJX3L ze_sR_Q}S@)_qeT7Q}nC4l{^QUv#(%9`48vRn9DBWqtOAF-I(KN&CvPJK*<5=L}tZ# zq56kqqvKS#I4_oF%*b;YTOr?!9HZPp&1&dVpV@zJvd>o#7)Bb$Q&_PJ`A=!TQL`h1 zI7ePno;Rq{Nqa{iszZ~1_ev75$a*r?Cia1}xXn2jzQ>){=lA1hhf6$Ph$+DSFZY;q zX2aNKdZ)dfYmwy0<0!h6e+z@V%tAB4CGDrzvZ1_dI?TizwvE^AGR@_Xey4@TnbQ<q zt{A5+`cPhk)B~96MBtx(XxtqeRZ`QX4}(l8FpncevLgGtaXV3E&OEAR=mDsB^)5V* zfB=yKAf^e8S6DX``A&?RI6e_%_W-Nv^(AQ(E=non8`n37I0$)S{RSfw|ItC`nalwD z$autI(I=|qO(YALO)7}fKp<c3L?)C4Y%h}!8c$ml7eVyDK10^sm;(ZVclVOU_*Mnk zad9329$$Rrs^!h9wLW0DH=vZT@67a5jf@%Bfel@B8&=FtsO(C$rb`=TJnFD$FuAZ| zx4()hTlo_7P%+L!hwU8IduquC@g43g>OrdMeCbsI8y*n&{LIE>vOL;f-wzqBttx}= znG^F~m85~=L<B}H-?L6Qn@!6kL&b2OH$svk*Nx$PSYp#{SO;SL3DpYn$3-{oN7KWS zQ?M{>tSR=$YCH?c8_5lx=#k7P!%H(A6NFK@jSND3F8nMP<@Aeb8W5|Wb_u$I;VRtP zJKED*v@4bq2+uwx#nLhLCnpFGvls41=|FuYv784^${meKd;aBn)X20K@EnPCpK46q zFX_1)EpN~yh#I-P{S$;bYk%Lugt7YK<@i|9A`<RNI0u)a-`VsIwfnH@ZLV~4l|1hU zN_bhcU)fE&Qg^8G8^;9t)R?O5@4+=|b}T|O%U_PeD3>{aqMObOUJ*?DB4gU`kE1F+ z0$r}(8B1fcS*_Wpz13{Ries<hOR9KDknVy$zkvbr5HeAKTn?Qe5O&C+BVrqn?Lp_3 zaY~&O0@(=dT9WGBB|rWSsbsfWYAsFHDR^X$wU<KA6{V_30?`o{#A(_1J>;rOQO)&e z8*8kZBI#cSSS#OMC`na?7i&YR3TJDBMCQr|#Zf?X!kL4EI3hMUo^oTIh03dD1JtfZ zG0Qy6a!H*9pvs>*SsNeEI;qJz89n(DMe_z0ja*|<y-f>qno3~s{~J_?wdjNv%WbkE z22S9A#wgk>7%*QT7`+Kve1Z@DK)~zIAAGnk)J{69!j37dllSZq-cpnN@``;*Xo+=< zJ{Fd?lRT(YR*Up(y1deM>x3qx*htt3A9}r|K=_WETM&XWY<w0vBH)~|^{ic4ZKJ7f z0f324wzVZ9$&n;_o1lTHcTnH>tyjh!LQ!~kfI3l2lbRhlgbU}T|3W!;%;Il_+Axcp z=4XoYS+n@AN-2JT%vj<slQabn8p5<<1%9Dp6o^xbxJL_Artpv`0OCT>U556rS*Tjf z0iB@+>WYm|Y{h`$Zu?fK4D@Q$!?4<aeTeqF4p1%j+YbsIV!6ma`w;rHTndrts7%-| zgpeS`_V(SP*?AD&5)Ushoo~H}hYX&De1e<2K1rN+`pt{NpXU`Efu-<bOj~#miCu=s z_xL1Cm<<VQ(i0lT)i099fxw<cE{26N8Wz|(3#mTn#_8F??`ub!&^|S?G)IZdNLA#O zjsEZ*Hu!VEU)J2CuK`8+F&;b0KUHTNE6~_DWYLePk;oXRX$|(V&Q?@w0qj<d1DJC5 zJ;Xl$k19Kj%*tK8+lLD%<}eG`aE3uQ-28$ht;Onb8+w|BHWwjfL2Zgz53AYRSn++G z-+glvjHL^YcikL2UtV#G1yH-*?_IxWn3BIe!0NA!1Z@k@|K%+ge|S3`K1!)e3)SoI zv#Ya6xkLlm0z?&dwGGrMfhquxHGWhT%|>`U_D@%lp6in!AG<k=9Dgt$<Uwa3;qFWa z99bhQRn*1qnR@0TDFcfrbO0q@YVuU!X@L-^z}i5i?y_36tg7^!y3kN;5BD9cDcazw zbQi`z(b{SpsaRT5wLm(U40C<JXiULVC;EG_tB@O9HwFgcuS&${GI~ZVazK5N>8@Co zf^UPME?^e}>M_?tP2Tq_=+rIEkf)9RW~WK!1)RhFo*?lvpXg8YF`eM;Nw|Yv4SY}= zq8h7kQ%b^PFi)eCY3ygKQQ73(J;W~mDjZL7XuM-Gfe~tc<RGIv4XddSg9Y4-M*$g~ z`fJhb{Nz!jXZBC=KwtQmtHf%1|6{Sj3OWtRLdYoEK-;!TTKfzae|#5~Bsy9sFjV-Q ziZiO{S=#o2X&MuE9zy;1#A$tEv%Tq%Skb1__k4mT-k3}iV<pCkQ~Ka$`?I|{2SLu* z2gZq$`cNXW&GxEz8uQs=YtP_@n(#tR-g8IDpl9I^;;V&x&W`W^dXwy9J>Et=8^tj@ zh-1+_I^2EH#~-0LrOILfwoyUnc&VsR4xNVrtF<j){RZ7RjAQnSXtl{t;Z`P|w5~Rz z6ee$}m7uNO^*2x%8s*T}lCaN^_IznPvWX(E8;vF(q$+&G7SOJi*}`{b`HO(K%a2Fm zr1;#z+3s_-iwb91v`O-cLV1O1@g7^`%-;reUO5H;s>-khtRDpO+w|`Nu$00){e3lZ z^*O6gBlB@M0@e+b#;&tfM_+(tp-nQPHf^*K&DL@hZyShqjj@rdY&P62U4?tQv8+`# z2OjBKl?!j-tF!#!xsI4Me5XT=EXx5hw;DG{fWAdLaA?LH`UZMjvl6#CTg>Q(1ABH= z8+xP7e-K7?%p-Uf*m_V|gIujN;y;*!-UEes+9idzTC@x06}j>X#p2z*2scYE9i!A) z73&9z!-BD;);90<h2P*#Y2gTc8y@2*wSH8Z|AD?12Cn*B>>EO=xs7jaTAuN3ww8s4 zfst!P-`0x0trdM+OMSaDOO4!|6NoH1XroTaE7Oq3%|$cG`V<_ugCwgTM<EZ<wGbEa zmUgj0Qbp`-gRj@){fstn6wp9~0JWam(#X2WbI3dWFSzJH`dbHYe%9eFw#lI<VZ>Iu za64)CAriAeghR{p65>3+7t6FoSw&gC1f?|W#k2mbjXTh+&p2eRaZ~1BVdhT5V(KH~ zFQ6%{---K3ZQ3Ay@>|nH`|-p#cH)}<i^y%YbUjWE=5kFs)Y4^d*$Ycfu0e%Ckb>Ip z(5tQ37Pe=^(2dLyw%aL?6}C$l*oEe{V8njQKLH_*+n0_|%Qwj@{WEgrD&de?3*5+D zk6B`$iLBMf5lxm3hirBJ5u>NqhAgfNdNX~BYGbvD%YNxdwR~G$Xaw?3%vF#Nxk#;y zeF7_d_#W(lWa_yfb7$-k{j~F;&`&iy=Gbo0J<*BABhdMLbU->6M&O?xVCIiBJe<hC zfN|%ye1p0Pijgt92Zr@q1-;XHEefE5l%bwFi}chx$Yy6u%SMq~AG-P!I&mI`-)4LF zVL`A+gP%0e2BEU*Ni<b^&`$R-$Sswqz<3+92UTW}-528THVP$uw#t}`B3iX!MiFW^ zUP2ItHSppeVKpqTe~uAJIrfm_DZ@&+B`N;<gBUgn;*DK{jZKHdLX4=6A`#*3l!vJh z^&a7T{x<%uh(p&6e0^QKVm17E5uQbMYr6|2AmBJ7jn#Og48nD{mtesRT*u6jM`n?W z1!TV)WxS$mI<>(nld&%u*cUr5#eBx2J;({!^^T+z52ZA_NVa+xuk+~B6_Gnd2OmVa z8CC*twCcpD+60HIb`5yX8}MGx?>(Z-65GRS#7Xj3QCTOlpd3)SFiVO>H5LPmz*5Q_ zNpW-t&7y;jUX8u(G^%hcEM!MRt&JR#j8?PLZ%OY5q~GG`2c&q<8}MGx?>!mF!9N7j zZ^`%pkQ6r%NWZ0a4xwj5vJGo5mQZl~rv_PW(7Qvs7?0MmP5h6*0ZJipYye&+(w6TO zJW~^~Kl>r>Vr_@jc$_F-W0FlP?n51=mUbs(o*zRAEw5MR8N^#D{b_uS<*z2y`}DUc z_(WJe5k==8psW05I@7XSWcc_{lGL(&tB_iH?U&}njn7C@8;Gdp#I?`RSq2ELekOiS zk7du@h30!x%Ql^uZe-7d2$S4&&4XgkbKvoYi2a7YBQ>pl4%%;4MkB&ES7Vnj)Kra| zB*jhD-S~jamu;uat9prRK6Qy1f*4D2YUPA}h#qB9dU$QUFf`z{p8c;MVkL$c1sV*V zgPzBt#GZp<OQRrJmk=<U&L;rxSoSigfc2Qprl)%i&1yuotU-SOuJDAlNAs}k8?i06 z-E=-rc{fAsFp&4Y!;LlPe_@<4!(oQ4u{8c{lmsl0c^;>{$@>BEIsduYYe{lM)Es`% zmZT}7bwQrXy@D|vAPL~E8(`AZC}y6ainqz)ZI*a*iMM&;ZLoM-Al_`^ZLxUkqV6%G zY83IMh<Hv=Bjay^c-i?Dh!?Z*%Y!sWOvu|PPeZ{m#At^@kvUtF#Ozf5JC0L91+V)i zF^zsvMPeGYd^7?bJpnCyr)>vjq>Y4%?!%+i-X3j`ag~H;8G+^=>z&pV^dSarbp;pG zTR6bh%<tX?OsMSuS(xVlXZa^hQRW{|ZH{~(jP5E;u~3X}{i=7KFJajad=Q`KHNPiY z={e|yvYF0Pn9g;-@11AiO`OIzpCkdPZ*L%3eV(J1A7cklH}D16cK${S2r7}gEK2nW zTosGRg5rx?P~?@ihog8{g>}=OX2WTRPhPQ=|Hv8FC=nQ6?b~Ep@YTNK4&%BCx$BTj z_#@X^VnZ;tR>X!WmTgk$sQFBHVK8o#V9HR^S`{0CCG=KMWrenSuz<{Q!wUWGSwg`m ziz^tO`q)U2W!wuUYy|aVR@|;r7S~~L%XUtHJ<#93pJc+EgfD+sO%M!#YA;{$scEtq zd1`rQSHolaaQ?~XD0tvG1=?BwdHOOG!y0^AHeXL^WbXRRV|F!Iv=QM)99<1LawtrT zzc|PE^t2kbhG*ol;yg$*I=(epQo_Y~uaIN;#oV*5*BKpX>cn+@j_8>n=H5SqHaSQP zYRBD&V%imvL#T_eeB2Gme;`MVOt(NItk`X~c)tx7JC=>`vyD)E-8iHpv0IE*7eElb z3ca&Wo7x29^l9xJ5TjMr1RSaUD|DWXJN~xLQmt9*V`+e(dCkyI#o^M1dv>s`plqjb zCmxakM3qC|(#GtJoI04aT1#x$yOy|8RRCGpMqW%!dr!$V8zHB>0*zO+D%kwKT_9I~ zzkLwT=eu2WrBy*Na(Qh#RB_C+FTk3-4lNUHHT5~hiQyH8;YT(;K*1dET;wJiCVDJF zCKplPOeKWLHl`Idp|~8nn-oG6n&r?RNe-Hp2g;K2?ohfM$Da9ToUd&Gwv&gh5Eo+& zv{&+d`{@AGvHj?hh8m`)waI>{gH+=Qzo7;%fvR49mMmU7AlsS~NU=R<tFVqL%zhbi z@;?qnLkFzbo~aA3hREMyWX)ib86NwLV4Oh}2Ma$@sFP}bJC`m$OVt;X!-9S2vuM@W ziL@$k*;%sMFl%|E$X05tzn=M<9DL;2vhVzaM&UPq!coX^S?HFP+9Fs3C9A(f2TkWg zzb0!5Qm#wMZ{$L?e4lECi41<?;BV$4NHafih?>!2qy`!2a=@7Eze$+Zg+M<)F3{hZ zIF}=4caWDRTpJ#re>&Z#k1?hNH^5|rz>o9HUjW)D_E7$a8>dNkV$gxw$hCR=d)i!~ zb7ITTpc1yf|0UT!H_%r7KHVNE&Woku`HH0bNCxhC^<DFKm_OPiwn`XOz<-2Zk*ot= zHGI9en<#p~yFq?TxC!<I@=pdM4><zHDTn+Rp6S8;<wxl#T4%t!v2x}bIxym0ugcT6 ztJdwRcY8%H=6SCJnYrq1)JKBowhxqMm+Jkn;%ZF$JNC-ks1>OVrd5rM?m-vDzjRUm zj(&k{Y~@eVE2PeFa6=?*r=(A?I=*3JuSF?I!|H#F8u>*K9l%Y|?%igK7~>=vEHb8; z%)is7zIe8?nn^wh$>m0gazp=5%QXVCe=mauH<Q2mz33!e&-ATDkM-XK?svaY!)kG8 z&!JiI1aP@JRkgNw>Z^<Jte&2=MjX()Ay0m){%B)cuw0o6Ya+;Y1g#B<ywW$cL|!>7 z_1Z{K$}6ear=7!Y$O1{cB7-Ro>w1v1D`W*t$_<lByqhaN!xn@PpJ*S(GRPW&k?gnr zj0ZSc6MNC)OY<9mM`KJa3TJqVmHFHad~El2qr(yx+b8wThX?19)ozcAPd2kXCh^A# zrTC2&;!c|Ec2tO;_>QLi{7>SE>ru`=ldYW{VaNE*-wWe9;%}oIsw3&Y7NxRax&0M7 zsoY*PMH_-H-^ThJwV}hNS{o2wqjU*S;<eHSxvT;9e!%;_94aPXr|FJTtn&&ye_-_3 z_3U8yHir`Nos3QtQ5NBaIGh@NjU1`N|H22m)@B@Y$Tghca5}f3_&j6_+66b2vQ2(( z`_c;n4WHUTf=5slG$S|Ul!j+pdRX??ZIIjkCHz`jAm@_3)l+^YN%d?kU7L~BY~a&C z?!K^k%5q3a#8qS5PpYT<Iw=kpZ|u72DZfpMtHHP_)l(u#ad=Nb?A+=pPbS5oCqQg) z^_1UWT!x54`HB4&Lv%VoF}H^au2>ok4lIQ*4Mg<w)4~*XmVJus8&KU3Xa86{ZWNE1 zAJNtd;C;3N!RS**5Eo`AyTBxlHnKhBy0F00#oCPnDRKzSP!xDxiU+C^f#npi%AsFU zz^0WN2U4{QjpG*WF8<Wsgb7C-r}euT>(xENQrS-4o)cf9`w6q3gGa(EeL?h9VJ`cV zNPDVZ+OI^~B9XQrIW4C1XR&Xrlav~4<pIK?<)l!sO@O_zO_Ee}s|_vs4LQBYx*l%> z<^5hO?U*eE)_vq|M=86|9UBYHcJ8HSqkEH@<;91Q^m8EW7Cp^VAMKLxQiFqfh7u{Y z^79)(TLm@40iACJYQ5Yz;n0Q|Co;8M<AhDi3gRh1KTPC;*d;->jxLa)yCIGL!mtF{ z^&x(?0uiG5ar}J(QNvC}FtLbb<2h~CPUjHpmQ9G`xER#(P2`#IICbB+r^O-cdIc<d zcPmu!K401i1So8C19)iw-UT2XyoVU*-LGe}-;-PWHpSc-v$M_c@b1?#5N<obtq%@{ z30BCO<_{Bep8CYO%|ejDeLp<2nZ0KZpdvg!?e{dkDKwp_b#&ncokkxyZ8)xuOj-@5 zvoVaDu>1VD$0Y8$D2&(l${s0kFB++**-t|R|JS#Ic;?WN2|U`-ckVLjo-vhKstf5v zZN9NM&!$ggKG!st{kJ1D=d^M77&L7>KGLR1zGp0YD*xqin92S$80hPpBnSPWw!fV* z?$K8?ZQ;jwjEdh9L&O}T(hZLGwNH@9q00W<RbJPk^eV5Ud0-OGukw!9(>?VyCa@mX zBd^Hh3qK{^AhzKfW80@fb_mp2L-qR6{)+us{56efhw)T00I`G47L3`~M$QQ!@{GbY z0;nKOodz7Y8C8$dblK)?tA$$lI&zJLBq+Qo@n5v{)B}9v);3}C0#Y<40%3&zUMyXo zhA-113oKf(T7GDa*hk*N7h}<I8kVU*e^-=0TX<^zS>(<;K8RnoSl*;sVTdICd1z@u z8<{=$d%H1p;*d5%>+_^$`}g~LExl**F95`N3GbMATonA{W~8MS+|WOxUt*t(H{U&{ zlpPMR9>us9nb&84WlFO}c$)0cfIO!Jj13OYL7cZ-n74zz72{#*V1gKr72(ykXkkdJ zv(~1mX0yD)gDG42-}cj_4jGt%?&0myMgj5or?2X?OG|~{bp3CbC%x$!Q;Oj!DNh$( zflJqq0rqJ2DsQ?@H!vNh_{~IqzR(<j@KiT~r<ken{ooj8GaIVBv$ZY+`HIjceN0W4 zHb{*WTdE4jLp5x7EE8v;rVCN9vppKiHCwU$)TXrAc(MdQu4&a{h#uPYHC?)6s!O|O zYPwbo19GLju7z(vr2z_z!V~Frh`7`@EEw-*ER)V#nT;4nV_-H$Z#6|RXh(`?j}A4_ zsQHCv4;XGY<V-!&mA}c7D(yYeVTm~EckL0Vzw2w%WTsW^?9=B|wyVir@gb3zvJj%y z7^Ej^c-kN74wij5vXX8^mwNQdpwmHwp}n_Ozl+L7Ir3mUWQqUAs@}tuv(@q-D!s?d z${W<k(8H>?y+TDJt^EVBf}s0_!HBK1uU_(fjn{e~Z6?w6OVjqZpggeIQ|}Lt*#=>9 zk?-fiBK&90;$Q1y*}vO~)bon~`$&ms?i9t_reA70-=hwrexhYH+aKI1)=zAl>HOY6 zx$3T+;<%)LE65Q$<Hup~Ome{ck?u5|kM@=)mN$g>?1{Plq6yky)p{BN=jq*vz#(*) zEX1DzHUEU#4&1WQv%?>`-r{LRcg9JW<T9P(vC?v`c)!sUq#7UYAa0I8UeZ?umZJ(h ztw87|#V;-R%D{668}v-vGW_!gC|G}o^xwJBK+u|EmENsdI`m$y2@=JA(Ma?_4o$%$ zONB1H`>r0IdQbe>ncoO%dU+?-86aSKu*ZX_;@MC^R3dNKCcJJE2wM9&M4?Qlk1B7D zPZX-QFk5pFUFXrBB`Q_qHUvBbP>M7^^q?s;NF|NFFX-z8y2@9$AtBneH2dieSHRd* zBl-U7_#N%U2koQ&P3+!XAgS+N`uzTjp2<hGvRTVgySJl%(7#d2jo)GN^<zQ{hu{Z~ z5eE)<_L<IEN#VC2BU1zlDI(%ej|m_C!XW4fs|4Od%!J+QDo?z*pm%=|m|HMB=2ve6 z&UC*Ip(ox>DEwzo%98H`tNvy;bhy-0Uy2?qfEjq9)g=D=>o9Etro{`#?|Y<y1i2;; z@AAnBG&dj<k2&IbmiJ{A^(W4c7{^ZQ+5Et^gv~GZ<C@mRlfBs?82rj}$-C3J{C(Pj zNj8}=+j@DO-{CMie6jKTwQXl|PNb_&>bJ(tvW0P5M8ZddU+}N^-CyX<mh8PY5x<gg zCZDzV^<HfQeLXtf`u|(gf4GkgZ-m>UzJkY@HF@sxI$RZ@9ok(lr|Cxns}lEV_1)E_ zvYb-Zg05yk>n62(N5In_nDD;FRaVvm<!%6uc1`>$ts)3t91oAfE4D;1Bh;m@24ZLd zAqRd>)9)$zJxRYO==V7N9;4qL<m#8a6~89iq84Sp1Bx*4EFpi*_2ZG6n{Fl(xaXia zrb1U*?bL?^y&D$}QoUQWl<@gLyk5Xg!<*GeHv`o@cwBy=o40R?`!XhbF`{VY;$O9) zD`V^-HGU|S%-DS9n@9=(zm=i~hRQWt(Ehkm93Cap)Ld`F!l3H?9tfoO)WYl_YZh1A zJo_pr=;d1w4e<*id=><m<SU#n?B9JB?j)~=Iq30#brnNhi>7k-mbfqG4}mQLV5u@W zq|%m8UxjqEvo=-revH1ZNKE1xzdkL{Dq(q#euxoq^L_Xq^ibFgn{eoXW(v@@Py48} zq2bwqH`x;(Hl4v`pe1b7h82l&at$67#WsHvw#I&CIzvm5)%-%P>BdHWI6g~Wf$=GB zJ8K7LZSL*heFNdX86*09Ha``{!NNvk;xl+-*AIOH_5j!JShVClA>y^Fa>+5kvs<^) zo9^P}Ajhvh2dC+hXu{-p7cIi<%eK-rmUxV#VF_9FPz}AX$ezCyH&Ib?z2PXyec7?s zc*W*~12(^}H;8;{FwZ}V=RY_1`F0Q3Q~!a#ENu+4V+dgeiWzvfVC<)O?_V1K4PZuW zwrU*jSX2x^KDi~qHiY^?00)s}ec1=|Lq+yQkWVW^nE!l)V9r;K6CDe2ho3Wu;csm^ zJAC|io8qTeUVem5uT0y7r&nS-`I1D!lOn-Q3E1tm0{~Azu)q3LfbP?K@uEtQD=$GO zz-v0x?xO*3edPpxIaV`nNwQ%fK9)0D$s>GPKz?I48pRxZ%tT?KMh?A|H=a%y2()3U z_e5nb-v1fNO2a{D<hd_l>VV@b{q}7OjBRH8D9Hr=dMko4yFVCo^l(FqX=XOZuBKBQ zQ~0Si+Aw52T)sf)Fy3Z5X2K`Y<ydy8H8w<LGbWL11^;+6;%WIL$tcg0gcy<VK=1WO z4aNZiXrMGqLQSjuyL!Cnn-6R4wZ070tnvXc)*L$*0P|_7#@%^RERVnb0vWP5b0;3j z?7>j}i<l1^?l%Umq`P!h6^w$Oe)3b?o#+6u<Ar}n371$Gq<9W`%o4^?X)50X3)NSG z_lyI%{W_JjCw(&i6#z4?kl)vGhS{WHT-q#*MQ^9#(mH|H*hTCoLBR<$oVF{**JH0` zS)D;ZnX=Lc%vnmECKvirx_sMDgW8lr%9BM;SJ=kx?Jrxj<w}=dcDS@`&knYkwz&Ry z4qe>%Z8u`L96C&AE$z=j{ns*ECuC1^RLP;exUbVJZ19npD9Y8=6VbO<Y(`_!Py`~t zvSj(GM$`HF!@}?P1t<k7L^|kma_A2!D6%m~f^G&u6vs=1N@@<up+zYuXn`dEF78re z<{E=!>6z}by37(#^^Rqzk&7IgDQ>5v$WJvX#**P>lIBwC{KJE_LH8ZvgA28O_iV+u z2a*uX*|7j#^|YD#rd<|b8`b>AfOUh4yJx@JW)WP=FN)$<HZH$__NC>}LQDf~a&+SI zu=gn^ADYN;lSLp_VO+{Ymv+=-W}~#~PjCPbRVUdcswys`7cYk4<~TS)T_FE=#7{Mn zeIDL4$g&zx8442oIHG>G(R6;aNQ~%oD8x=E`6sPQ+`gju?x6exs=73AC7`Z`-jMp$ z>Z_fPcMxQ^wMw+}6!b?*zQZ<pt2doh@w&f4LmNzuWyvF^-|Yhx^<G3CLZK9WxV+K| zQ!&@*$(V~bZQvxRMq^4+mMi3yI7ai%MLv&rmDKzet87jI$g~k`%UoCiejZ39>x<21 zY=|`~`5P4PM)@%d5GGh{!653jxN%xz$~CL3h(vPe7kKB*3A<c#F9i6N8xtZc4?-}U z7u|i*H0!KX)NH<%1;585<Z|#@=7&(TKaKAA!P;Xln$DpM@nZzB-_!fw0F7U3L4?oh zr1b#^zX?6M_XXHDgpS*3cmY*U;#Wj&%=VMbIr6sKl}3k*H;Nuqo?C}{{KlyndS>k~ z#cWdXe*@kXo{GWhW9AS^s@P8S5=99t?q^N@{CWUkQVY6|YIyqw^nvyX@n#UrlUQA* z^L?GnMVDLgXlJ|zHNR6W$0HNoCiw~6er6ljAVMUD^*W$vQQ>|uTE~7zpQ9TcPN&E< zA0&D<9(qQl&epd}<dx7lV`B=UfG*Ds4^xb$6qWuO=x=T~m0qiloyKl%Jaadd=Kn=E zztIFvUJF2<wX1ti{h+J3<sV%S@zkg5&|#VmMANs6faWDSGr3=9vOrR{h+eFxzq#?( z>f<j1)vahrUg_kfk>5fG4{&|o1og9q)#!WuO#XV$j`kiuC;|z1#i}pWZ~!{7M^ykE zp8M=u_~l!n|5=#31pO1TT}^#tK=tQ0i4oabNfV!G1&-|Zc0KxT%mMXQ;&j5R{A3HD zKRYFQ3-m$po{}F+#nE`<B-#P8Wa2JVr}$=y>HKB9N<1d)*%y8CBx1<%3c`@bu)57W zXFb%g4A0v|?6n({c!E#MRH~-BN6H~QfX82Mz~x9cZN3XZ!zD#kh|fPIKKX^b5dD^& zFABfq+EJv&BJ=EjVRzr24Dt5lo8?Pb2Y&9Wd=EPGkLEW+GafTs$S-Q>byxu|iTLa> zz5C@S{)UG6F>5z~v~7rwqZ|d^iA*yXnf4Au8()o8ALyDjgW0;}b-@CM@u@}6=cnsU ztaVp?qE@<$Hc5Io_#W}&*n==U--BGW94qMZ7dR|hZVB5EU^^iJ?+0Q%F(-erw;uii z)eLe9-n|1v5JZskDIJ=dch=^XiRMrWnTO)of_}H0CuAWSuK0&&3e@srhIv{a!UxwU z4-HxYK|ZR*Z_9b7J>Q4}^E?gAewB5rG%yqY4$;QvWAXls0JD7u1CvJsGm&q6uNTCD z0@dDiVn}|$w(-y0c=i&CcKP#QNb(_Sh8r7cF`a+;IXNz5n9ipb5dBT@>;w70$;0m< z3FklQZNk`$H>Cb(BHi~sfd|gs_MPi`$44C61x!lXlP~L23*0>Ay)zjq#QopvNM>G$ zlJ+jV^Z5uFhtOTD>Up8l7AnRg4oM$T1<M7fK(VQ*<kpoqKQcv)+-TxAqP)i!Wy&j3 zro#w~v7!I|W;K5k45FI9hsp|#Hc<|1N<d#0zY92u-<>$iIsLK{RORvJNctARo>K1? zeNaIB?9^S*i66n6HXPm-4#q^gzxMnXFZFKJuYwRi_3jyTdh$f#gWpA+p1#y3ZXS7H zQh-$!;3k$hvCqWyP2!7B^Zphe7uw0#TvGIaLw5z)wjgWbvvPspfj+8gZ}uCbzpI96 z>ci`h9nz^YWy(fvG95jO#m?;?orTd_DtR(|8StLcQvrPZN{V-<Tw}Lj1Cue?wCJ}6 zBX^^*GwA)iVx+uc5IJV?^Y9KT(7GL}xmEQZt^7)18}ge#3cjGE_Ch!R?j6%ygVu&{ zjsUgaw6OKjqog<kyr4RsvMjt_jcEC&RdyQc!d7I_N<&j`E89?;`ieE>H$x*Xf9>Sn zdO^&ItK+N6aO34^sM=pUKi`af<gd-=_rG%n&0fsOvbAWIg=*x`-KT}=A^~Ewj3OF9 zs0E2OWy!5-<mW$xZ`@hn%Ln*)=i2^bAct)6JNXmv(kR5!o;x)l?Mb|5*mqMBnVzFY z(BUn7N0}PdXQ|<(b3iNl)nAePZ&br2d4A?}ual&8DMY7B*`8pyG{+w<0rq$#e3Jw4 z*&q3t>G$r^uMbA-)r*iRZdoHfCMWDEOOT<?e-Ir7wX71h(;vQQ$Gegg8)Z6wG#}Zl zv+-TB+xunzhyJkh-|wQ{bVrV#l`immw=KI|VXXm_Ik)%<3$=`Zb)$Eie%NR=71og7 zpyY2<ybVh;{1MgS50@^8r2;n(mq5u6<<M+YRJ^<7(2e*JHAKTIQe9pokIrtt_iH^( zWmZ3%W9$AiE|gMehqaB`(F?ipnM1MeG@UQZNB@l;zZX=Asi<<T?G!d-Sy}h-$LObr zU)x=FyEq0O=<db|t_aSE1h2}0)xBu48c}4`+px$=?#dmV{I=Ob2gQ$nsvtLqzJxJr zPHSt!1BX2CQ17Nonm=4XNB%KWJuV{{m>?_3q5Uxc*Pk@bCm+Cp_cq8Oyi$+dB+;ck zXjWvUjuKq!&8Bnz19U)GE$>vkopNX#)p-+M2>Dq?rI*#9y-x9h?2`s5kmE_T7(sb* zdSxYxMLi1J5to*pg!-cUs8Hv!If;|-T{HwY0PVSghTwu948bk8$A<tn;Jv%GvCUTM z{t!Ompeb&5*&XmEMxZeVfs9!L7`a>fS#O5`5V}DERejT$5+4EWD$x-DCrtYQTjO^Y z6?hx;%-&&%WhZ(?oq^#ro!9@AK5`bB(djR`M7MM6T9l`*kH3At28eD`bPK72-9h%X z-`kBlIDkeAhWf+0gT0IBRb%R@5XlzX6t<PmbKw|sJU@iygyrN`v~)2}BOcb8itA-x zFjBgJZD-r))_XdfTH_M-EpMaNiqj4Q5M=dGVQ&`GY56IlW(y#{&F|f;r?C@JJPiV2 zftt&H5`YDS7Q$Q6e*~m`MAb!?sgYY@I`%Be=)+~z_#Bv2BVTtbPR!>tF}SBVF+MRl zyeih~^xZcrr8eA`w|Vx(jMDN3;rRW?Q@9^^hb;~@OcuIAOu}s^0rs``0}(5+fp}r_ zn6b%XvS0*kFikimY?p$UECE*YN5{f^EQN#)Pd#2i?(a#=%_M%`YSWC36Q$#AVQCnm zpjZ)~%|l0DbVWRh$F;Wd%b^7D9lSU6q~<_>#0jf~-KaEA^=#qe{)k-!ddPqtGN6Z% zdtC|n?F`?jS%4;bI`<Dec#pz*xC9ljkb4zD^la~yvt>8{=r~>oiRgMl2j*EQ{`n=^ zN1X((&r!K%_M!O3@Nv@wA!J@$2$_@QIKBXQeh%>aytw1I*gZ&gjY8U90JI(GyRHIl zhd$ZgdL}{J9e$P_Torc;^6V>Roql#a$fA)&7DS|JFd69F`_G>Xc($3&75Cv;RLv2d zHWbRmt}vZT=3-*DeN}>jZ}o?>yH_ImZIwgk3OtlUV<@mqu0ek~rqA;p)zk2{QntX> zeaB*$w^^mEY19sZ*FbX#N36R{=Y{tna(DQ>p9^ZFyh|uOPhAzq*+&5(7Tr1n@109v z_T>pelhK<?CVKPr&AlYI0643-f47(9zQ_g1g$`!<!;_HY#;ka=3Fc(P95x_sqYE;B z_ScBs1U8Xjww3mT<5YOzTpA~5kd@ByqwDZ4`liI9xhO;nN^(9>lGj$C_!h0D3BPv% zv<3at9XK$+l7{vlCp@t^esuf}bPyVE@-}I1m?8uLh(;ep;ANwQ@faZ36-24CWKJAZ z1p#S`Q|(XhB`W7Vfy-hWKL>$nf<@rKMKJmgv<Q5#2ta5C#EIOSle`G}uYozeYrrS2 zSK}vtPix@0_!@XQvEhVkppXtyh^-eve8sg6;&wImp>Qaee2Nf%;E9QTpX8V`U`Mv! z_wUsFcKNZt2>(n+#ohREo-6POL}r~WBVe|W*xJ>QqRDd^L>N3_MCfX;Y1tymMlm-0 z9AHD#uHPU6R&A&X=_)1CCjmS0Yk{TczlUFj!|wq?8`J=PA&@>7H&^^iz?byBKp^pz z)3L%Jo0;Lj57DV%r6Y)+31t3^PK@oL?*=NJLHuUm2hiBqD4v8$u5Y<oeH=IBEB?L8 zg&S6RwhTGXpW#!h8;~>t7~iPXQOvQ*N8^(v+6&5!=|TMPV2}kfaxf|nUIRH8mxpmK zjGKgCB*gd*jOQ3H05e-KwlhdyC44nd&9Q|*bq_vd1A!D@DqMY<z#Y(k_*)*ZwhWvg z)oe}75lxV4L{pL`i6#i*Y`v3|n4q%02{NJ%98(%NOWy>gi3yUDn)qMNk3XXad)x^% z;{<`Ue?tz&!oUp`%_xpwI9K0E(^F{<=r7F=P@_d+eqb)DlBY?`PeaoD1mo@D`1auV zc48dIIGlt4$G8rR+l_JC0WO*$oW2`!FrFY26NJ;8`=91#4QeKMey#%+OrLLJz`;}B z5(jDcsW&N*$G;N+7mta+B>tHQ6!1M1$mH!J!pB=gK;`d=Kp9^l0<-u(MPLqpK?LUU zKZ!sg|BVPN;9(J1%&Xq)J$1)55k|7f=ZP?q4?bIjk*x5tH+v7|alZ)D9oU5;jO>?R zD8k66xl4qRSM#AFjO2zpL>TSK{N#UAcsGVSMYsdQUx+Zec=O#NjNcyTZ6b`<JMelD zM!kr?Ey8$EioYzvbjbQy5yqpse7OkYF<u@LVLE)hScK`+^n4M<bJu*12%{?npDDt4 z_?oLCjJ9+>^}lH&S@@FHv})7)<~d#UW}p8YeY$oSm6+jxn6V<pCSr0R#wlWsypgDh za0Z!U63*m7#_#@08C%~Fr~)wuM9fMNGYMikM9hmK1~_u|ha%>;BBl^x+C)sXi19(p zdJ*%Gh*2SCm590HjlS*)pOb<hYsHRcqmjsg%l|@ut%d*NA7{Vtss1&(@X6RvaC;-( zYn9%2(N4_{-LBN;#@<uvq<~pZ<ULf61`RZZV6qI!{JMW6ZkT!wxb(k!VJT(1OKV#7 zL8|!KL6)DZ5WL|C-e63$`)ku<ycbaGe*koN5}-lW9%So5#5eUkrOp~K8<pCWfVm!^ zyO0iOABedJ#Aji=mP(&8{sNn}megiI!*b1B{DLZ0mFchb=bB2yR~CD^$s%$6wRp#( z4~oyuihiA8fM>jRcDV0)H5u+!F_ucLC6F|j2XJ@>!C0mwnvDG$25ZxQ^8cYv@gWNt zB|gA6Wxam0n4nt{-`@Lbd7t~wfY0!4PWlYrdwrkZ3tD&J_xFg+ix2QM$K=Gv_dNB; zG?xGGzrn|nzT9^P_=yXS$1V(=yS&aa#g?I8C?p7o(+|a2n?4qAXOl&GR$Rh3j9>Q~ zRgV=fhfFEjmCzs63ps9AnF320*pwcGU=9Xz^l1>x!(g61nZA4rGRzj_TM7R8r$qTt z2@&TIa?qF|KCK=9V_CVX+@i{@AZ&})lh0O_qcVgpZiS!@_TU#`P;|}Z7roMF8*VXU zw=g<o>vvDZ&k~^3dCu)57ZzgnA*OT0ZM5r=&RY1TP&C#`7dAA4X7Unl-p4<39{+lG z)jbZ!DKvQ%{?Nz#f3r_9hQI!De4nD`<zzU?8ZR~~UPOERn8E)*4*HBVV54HlKhC^S zaUs9yW!gEI{PNj$4*clIfkX0h7_b@H{dOt__wH2uk!*-Pv0?m+mwLA<j=h9+t75ML zx0F=Y9J_#jM$vrjOJ{4c{l7$$XWgw3=M+r4M8{9}h|fwLML_XOQs@?B%*b=ZKOYqv z0xvfF&J;w@7Cn9Hw3u!>ReNuO?X#07{4!8iRnYC?03K0%b{)Ab0P+-#dHWS~zM|7& zk!*85dL)ErC47G5&=cem;QVlYe8b}2TgV4h4powM=KpK&P2i$BvW4;L1!$V38wCZ| zPQ=87sJJB4*c!W~iH$af2r9{B0ih8hLZ`V`F>yf~67kB6Nt`T`MYB7T%)~E~sBsbp zTo8AXxJ@=m%yLPaNEWw5z5jEn>NX8RChs@%zIp%mP2=^{UZ<)~Rh_Cjb*fo*ZKan% zU!VaFxaz_Rsh+n9vzYfa%)313?WW#?xVMpcj|_TWPra3y%scQlZm1sv_u))Qqi_X; zZktO(D+$MVupMvHdu*CN;4%|d;OEw}JA+}T)>D0Z?dzGSYoXhAT(}csy!bX1&N{lD zmQ;T9ZFWtw_KYwQa~Y=`aWQqI>`ev-z2Q&AZt0$uqyCoDsPjiTgxfS{pfhO1aMPBr z69P9vs--l$gTiQe;@j-b$uOmb@97Kz|690!FL^NcH_$sN?4iaX>+wB3?qPOH`?K(H z@(2x~J`(0d>0$O{B0nmm_ho8#S6Te$wM%0B=XGKqDJ<~`sE1Kfm>FPQj1g@^WYY^h z9{D6c&rXi0{z9%x{VMt6=X;Fs{d2rS^<oN(C%?oL7Dvn?{8{XMRKa)K7b~fr#APSf zhoJ_e-#ki)Mldqnq?Z~MMHY9n0vq3?3H!i$CTtD_(+YQCD<FX?33F!fqZZU;McGhs z88&21GN#Kk+u89rIu%8t69}QI66uLMrEpvfD+wB&3M|pT$yM)*KUU9PdjGk*AK7lc z40knWNS|a$vONC*yo&I(pwFrkNmlI{@ml%S=X$KJ9naDgw~Mr)Y88AnGuq+5pk1^V z{!d=I)3I^{>TpaQqh!|Ksd1=J0QaMGhc9N(J2&#^tw^lk6zG-7o&iQb(<Z&k-)cZ& zvad`*Nu8|{dkq4gr4YmX2eg53e5XPTXa11AX+;k1`1mhq*sBYOhUvEx8E)b*e91yE zINrim3RtUcRYFX)Ee~A~kHA%qx9~+HRJeD+EGA-Tu@{C4gHR%1F;|1)Fj>-S#Bt2K zKqro~KRBgkL^lKQo#Hstpcf+Trmg$^ZK;8Nj<XFYZYo??pRpDl$0se&!CKJYxZ7dd zSJ}sZz~Hc*_gyLKZF}Yq@E_3QZMuFgWv~5AlR-=ZTc#=F<1tF$R)^`;3%c{X8XkNb zH?bg$UK|MjYs7I<lfP9f7?$Ctd-VdSGVyBL#rZ?z)6b~N959?f#qVP5E1QzFXO8t( z&K}oYq)nY!cLxU03fi;ByE(mtd0|kHB<$8jU5~rieYh^iiTBZm4AhI&*!RXXWYA~k zDg8?Cq=ngl2}i~9G1FJmTWh=JTU5E#P@dqtbWlDS#&`kYRu}_MJP#y}oe+-&BkeVt zaXBU$ZRf>-XYBbJp|AXQ7}q$0x8OHmT-$bG5Tx^b7$5Z~=BUTiU*Do0Q-ePW-MjIu z{2;zG=fG3)`h?2osj$YLthpcLO=@x`8BpLY8fMKS>)4ri@S(%t-EDR^C&)Lj6MHVz zP`!?G3$xaR9^LN_G7FDTX5sVakXcx%G7Bd%8!rH}F#L<>LYM{T=Ojd|;p%mC>L%-Y zn!5X}W%w2V?t{W8vj8bDZXpWX?!QDO8e-+Q*9I}8?7`z<T$EwQTAIaEYkSJ#FHeUY z)$>=;QyF8x-*0pz`hhDDt^|WY7yxTOvwQ@|bXj5I*`Me|0+{rH2f!!E`P}b6iF#Rw z`-!SsG21`k%7<`=1fTF0ieZ?RQON>cbcmMUiNYF-Il^2NQ_Y*fRRv1MIH|@LCi15w zWZyz%kZMu2iGRZW2dPfF71ZnS&2)cST<jnE#)H(Q|1DkQ0h{@~CVX9~t27|nFtuh= zWHLE2LTVR8Tu!M$N!XH2+11{~*r@_>yTTj~@_R~OZ^kPpbTboWYu;Q&`$x(4Ztg#3 zqsTzJ`k?h;p_kjXQ;4x!uN4PVq5opM1Hjv*tb=pQ27+Z$5bwzME@P+tsVLbm4yE$) zri~HBbvk=DhujpwKL^jCH3t;Mw$oJeBw+}rI;Fa3Is~8BEJ=0PzFm|eW$LA!kgDl- z4Q^@ImPmCom!0kiH}i<LonkLn;WCWuvbFn$*{u~C;Yx`**x4!dSf$G``4GJQAO4hj zxu6?-=?j!paE`SV!vpvp)S1oplqoX=xJWL&lJNO76z4b9;{D0M^ZQU{V|QB(d!m`? zH|SQc!27_ml-gphUPnk}0SsQQ`r%{N(PKaVmxECN$2C{UbD_YZ%RfFs5hwU3++B?t zKCXsEaU!g(g=nZSF^TFO2}Hkn8bR2bXXst7KTM;NpAffhKm;sr`^deY3^Me?o}@xq zy!UmZ$32KIMHTR@w8boiF}QLrRct<7!Xtd?Cmi$|l`#6ej^w;Zn2^t8KsQkl?EVRV zU5e;l(+S=F-JpwX)442)@I@$Wv`(QI7d#Qfc>WXJV9dr)es3v3p3cI^*9M~n?f}$B z*<yA)4X9t^Dg^E&rsZkOC-kjPSlu<AaheS%T_Wktf$L-gPpS3yJzixx{WxFS&^f3F zJ)5{p?HG?|J{=UMnkosOvy(CZqA}4#98-UDq`dVRyb4e4Nzl>8@aKb00gHI{SpRp2 z{HQp`L^HPWVHmh;6~R1Ja(|BOT#{KycxejZg7G1W=}{}Bi)*I`I;1sl;HmCv08%lV zUCPjsDMZ!Rf7!bZ_Dp;iMLL-=<_tb;9xV@9$28hIq#bRj5%0|?S~uXzUVKP))rZ~n z6i&Z(Q~eWoEM2Hfkp`S|p$ISG%G6S)NcwZ^X(^ZOn8}aVgwCWJG^SeAdf>kg>chs0 z{Ujz#9V{KsD;;d0I7B(?y&9Ax9Tw0j>Aariu0`3;Gc350P?O10hVD-7i@+Xm(LzC> ziA~_;t{dX64|^Ggrl~1_=jP|65nJSEr4g>P0a!q0HeS@D+<2or(XErEU5%|_PMz#T z(VRe%3*Yy`@?e5c@M1`$%|aiOI%%qX3MYnLyiQP;Q5#+<qOW$<PidA*k)G(8Ee!91 ztMDjbG4x6Lz;cT}ObaI9n4(*77oXNsV`aZ4yMegtEKT-Eqdz|y6`SYL6aq&YzYN34 z)>U{A<$?Gf#@yW~!`IN{G#E6%zql@9wK+`A3r^`2hGuP-_B1|Gzmt#ti;_!_g1j9M z)U&mb6t?@m;2b*)r!|X%Dy-e22e!D$nS2#Yg5P9P#)-ZsVr19+p3t&^dl*hpeeUBd z+&=q^oK6oCGrjRtRaRL3ed>vFs#|&kx7IVHEAVLzSTCNfTTH0Lko1*PI`68x!(iKE zs_9KHEzC$%5^`NA7i6kI1#bSui9k_Q^b`CX_#*iA+`F24i}&uzppz*u^@@=1kS^3J zrr-Plqd-jt&xBpJX43-?(}diS!E@oVp3a32T07)WP~2fW7k8LO-&WbBDD_pEz#|#b zKDV@;3*8(Hk-1snLJ0%pJSuRcY-sxx?zYd|6O@#Q-9_-!8iggOE+oj}@9si+Q*19D zCf{6%Q+0*`a_F2qol389p|lRZm13$vzB0>pR<KF6R6Q^1+`#`*v5}o94YM8Ao+vj# zZ?WA!nZ9erUTV*j&a@$G<V;&k#OpeuhD4*1L|krS%494RKHxG7Xq~D2D}IFEZQdnJ z>NWv}HszL#EN`YOyYW$!X+BFAV+s!9S>`$o3UMq;`-th9So<iy#gvtb=g&`8;m(W4 z)gf*CYbtwzH?Sue+ZKKgQ@0x*plA@rXP7n`GnH+QddJ^Tx4PcpZ?u4uOWDR<bhyQd z``yM2)Y#~>?H2YrQ+7L~M%={hx~8W5mwNZI4fn)r4pCBa9YenAO2iD7b`#{HH9an+ z7e36F(p}grBu;wXk9#>=UCSu7E_j1!B(I7m;*j9`V)8&mP2;vsBAIT}#w@1EPS)yR zS;3_zfz*_payxyHx(Q`41q0BT-gZnlm~yPUh2VB|sdE_*sopi7;6b_(QFW_$wJbi| zV{unLq$sp(fq{4uaEM<>U9eZqgAp`ffC%y<m(;NY(snVX8~z(c9Gi7)d(V3-m8ZlD z`*tTIqWTP+fWnU4Pd98_TtAc)v-5t=gGb{+K?qk8Y#Ed}fBrI$D>I0yTdMQ@L;r;N zOv%~6i7OC%E6hVNra`W>fj5GKaF?8-r^Dk+2r>YJKz&ZZhRZ;bUb&r#i?BC%M$7l2 z-L`9fBDhqKPn#f`SX0U$>F9zW9JPD}T2NJ3z0<1cSZ9V_k?i)pqExyRK&j|A@f<_8 zK8}-j1Ih!^yK`5`??1>7T<Q`plehk6wW73bq|2tOX%X~XTU_lK7JZ2P#Lq;36`}|3 z#R9(_yoE?by^3+8vUVFxkQ%!An5;!ns$t~{*O?;5%jpjWuZvp2C?%q@pr%ae5Juhl zIlbg{xgM2--(m;*K+wTNKjs5g<cvo{-eC#R_Lj=@XK*&yOIdVSUdf9EScFm);FYuK zwKV@0wp*2mGhsFp**PfR|1uT{ym32rIoBpy<!{w6MLf-UPvZ*9Y~-JlefGdW*< zJz!VcCxqYMQuo7dkWSGjH5xCX9@72tM#}sMgY7F`Nycdmm5ri)uBMt~RJBF6;O0lb zBKKL%tCBBzAXqgEhN0QA5f-F&R@<wnr{vH(He)H(w=Qr)4fhsx>UJV(M3-)fXSI_4 zcXnrRH0s$rr!j405ri1i##PDK)f-z4QH|Y5o4KS{_{%IiyqCSr$E1j*Z*jHC#>h;m z4JLp2oR2o7m}I^Ea;>Osud-24948O>ZI1)XsNaML0d+)YV~rOzuQa-r{Y1x_&4{qe zztBL$-foxykz9__xhI@%GduLsEzzp(Rx2`rZs~wyv&PK!J%&-ysmO5JS6BHPF7>Rf z6@~6XHMZhfQof|9`pL@J^3je(%EsZPo$A%l(Q^sPFYi}EcOK{<$ja|TylMHBggq0H zsX?}a&fYHRAf*oZ)88;QG#fdKdqWd)qX_DLdd}K04f`k35>2KQFy>u(FD>E11hx$U zBUhB1yqeX2Hld0L8K$+jDyrJHJe(i$*~3FLn*7~wap@iSbYB;~5I1+I$e|QA^&XWe zgz@@ql)Z3D@7B#AQo??qImchAJoyJ%(s^fHhTaX-Q@7ZVQD3Oo-lKx#)=cCg_hDhU zvK2NTOr(N!Mu&7L0~$jUNKz8cPk@e)uppSK|6CRD%<rMFa9u+FYRtHP9if7VOKzpI z<hvXx`}_wKYoZXDsoP=OE1r@LNKGk?PF=IJj)j$KH_#~CQT)8wMWb|t|4t3x;H;wo z1M!fa({^BS6HxXG^l8PWML#%DgW#)x6T+A9QEb~G@nfg-Cn_3h3!pSotWzpQxm_U= zGBee_jNG%W8P{vu+iusPWycb_c)OWe_AN2e>9WmEpR1W+rfhQT1X?Zrkdlt}FE(p^ z?^*BY<Eqc-BkaM~Kz2G-n#LJ?VdGqy`3Cm#N8odMm$nVB5vM(cMOl(UW3EzT`XQ#N z=3bzNj>vm?<WIBs&JVJF9TLe4Cg3u%-D&&YRC5wKMrM%RUQ(nA$TR8i8B<X@TxHNZ zgygA`M&Qh^AI>>*0VOsexu+nxUEy3x{QIqJMuMW7R2I953T=K*1AFl%1gnxP6cay0 zSzIBg<l*3W_O!|mw8iVO^zLp8^y2sqDb!t9M|0F-{6LG5*Gc|#R8Q-SIoEZPKNXg8 z+0)+a9FmD_220W*ek#liVwYjyD}?=_@}}XmAi^MNhF;2oesch(*--zP<5j`aAiq6w z6*Ab<IvfVAqQa;$9czAaO93Zz#i&dv+$m+pJE7+~r5708o<O<{$4e6qX^;GyZ?Tfw zZB3>cf)9q<b_gDKy;|u~3qHpk6it2OTeX~~ns+a-RSyK-K#O#wQ_z)6L7|I1w{uWl zA^{)sG>rrQ8UlKZ%eyISV^(^)+{Mu%3$Hrl+EgJ|GbWNI;W}i$JWAriuETJ#F|v#< zHmqG18$HUnayjqBGAub0ZsoGBon>5IT*y_G>|RZqaBqij_tqbOsf=qET-527BJ&PT zw$j|6n{2o7$##PL>H|HW|J~p7WJ{$LalYNE&bM^YVwbYbweN}vR2^8yl>0|~EagVY zZg4U81L~C9b-sO^y|-wV6CY5uKeR1G?xfrKw}*O31SZEkV`gWejxk?TVFHKr5ni=R zmN(sxH%inJ)2mv%*!ydNu)d;Ab48Zza}%mkB3mX9rtA1GdL~SbkH}@>mN?3c<0XWe zSCI0oB^sA>{iXYGwz}vrt=Z+WU4IU2BH;OrL)w{XJB^*_bYKQPd9F0L(?*D=m4={t z!uSXHDgw1Bi-X^!JD0P7uu!u`v%H@^Yac<?3i@}#+?+u$+-L5(k;npj={bAd^-JzU z9cQQ6(TBtKwUFjc8@>=6g;crtEW1v2xBPmoTE}#gHmH{;HS|hvhV7z&;^oJw9!uG9 zKb2h=NHf?eG`Z`BLDGY;gh?#K7qv7*6c6z{gn$}3c`sJmH-MDzkV}fimCz+e$_{s- zj6BCg=t)#=V4wWAGn4}Qxugh3^`bB`fvIhESZ@y_rkY17hERC=vI{;Jef>k2a>^xC z9ewsVG&5eDUWM94-D&e6#&TM*XI-dIK%VjdZtYzZirr~tr-?8S$ni9!rNP(S8=*Vl z=DX5FJw@47cvMvkh8po&On$n9B*j?n#arpLu=hZ9U?~>`Dgl*<4piEFs8g-3=rqZy z8xgo80~O07V-DCY)}B3HKUr(rWm<(N4(`H+j%?hv29v)WcNr-`K-V#`985L1a&{FS zbk`*}1GP3AAYG{DH4AYA2U^`!vyxM&<_*4ZaNz^#+iMi2@olG2hQ23WSClMZ*rkK6 z`fRQ2I>x9WzDr+_*HTG^qo`s&<&aC4o9uP2xYng?gOX&LG7c*V{cgb0>=a}Ddlk9V zuO80esCuH7RdW<(cmynfD@-MiU&O(7pS**)w7qySct=*%m&3Hu2sg>&UuRQ!y-Onx z*c80`Hr!P|Q$xp<X1V@o4-3Z6sxka7bw%At2~OwyvLQb<Y|@Luvx@1}e%r^QQ+{-L z==eYx1U^3eX&I_&5-vX|?{qGTM{g*}mgX~vgQ;FbnXdL|#KWC7aCVtCMitu*2xCke z@l<1=9tcy}ZnusR9y4v!nKtci{KOE|Y&#G0UVXX}c+0e@(RNOt$})FSv#Ayai0*K5 zL9G{4;Y_@fjB5S@5#zQAF)pPM-%S<2AGb}^yV$muGBj^AA<EEa>Hp7<#*U`S)T~_A z<0P@Rn#<G-M)BCgxZTs@lC;=Z&DB;SY=_|T@?NTd4a)zS@#s9K^8lUacnkGgxC$E` z(lKOJ#^R)jx)77(>z45|b=@-cn5b=V1U*oPK6DBeFt)HYHF%(Yf<F7+?uLK$F-Z;} zx5i6h{x1ekl~#RQovtBxu)fkc%CH_d*i8_YO<nW*%Db!S(f6~}!CB{z;4Pi99fy7e zruAA=?Q%@qc2s!RxpL7ct79{LR#mGwS`>$A>p?s%OF-$_C}}&@)bq0c#3i@%RiKF5 zpLi$WupM)lCLIG(XsqVU%r3FNd|h>LTf{+)*!SBeAOfo>7eO~UHS&fd_(VdC!%n5l zrb;!mOzyhdQ|+oHQ#$O}jOQqL?(bsfwJY7Jk&bcArkdXp)O5^rT{~7}5jB#-zejQC z-p{O`p>fogoOP~nrbar)DZ*?u0HlxxDG0aNjtf~UjKO%i_g%QnT5=Afqyg?4aYRU* zaTsSH#7XLi!y=rAs2FFQ+Azp3q&l%*M~~t>>b6mAtN$QQxP`gNskWo0RonEaPyh$x z2R7;H8xvzDDvItaNWLA@!D3gNY8HYYprbX_;A#fiEY?xIm>9)~YImwZ9|)^1N;UlC zDufB=qb%w3Ox;c@iRHG*CjU4M*T&;msZSo?&s1Z?gXwWQg&6w$YNoQIEx@;U>@KAl zX8y|lnf1<OO|{i1MrQhVXxkWD*V^_rKqz2)uz;v0Wdn^IJ&Fk_Kytje@1@e0Q;bSN z+DK};FAY`&f(S*-zEM#^3+NKAtbU6oWE8HpuSikzSjnytu5gZu3{1|neI%OHU}9L4 z&KMZO$%(5(f>x(Giq$}n(-#vIMKIx;eqkSg5z>YtyKP0ucGGfPxCI7>;$dg?sSQM8 zUD4{10*;igkq}I^xbti~WvY>Jol6f+GgFSA(N&9vOx^Le*C>a7G+_4ss9%~0$ohJN zw?lUnM!ZSZw}^SHh6pEMV4P&yTBAW5R7t$7S**@84*x!-?LkyY)nMBu8eE0jT)Ja{ zJ3H5t4YKn8s9ga)U{Tykomx@g3YC=R|4}Di<~j~jN;wvY=aqH#{S07M3g4ASzXwYM zU|ZeNTa?3hq<r*_?3DHb--7J?n0KiL8Gcw&I|8*t0m^-pgwo+uOWgg7@HsO;`ZIdH z8b&zVc2|8^<#<Jz!jZO{ez!~ab={&=R~uHC?dTTl%0g_hBW(uhfq19Yj~|u=_3Xbd zNVuj=`s8B&IiTGP4XSF|DVU4tqY_$5p7e==`pK7qq^m7XGgH#l({%xo?vLG(?&cur z;uZm>#c8+i2uiWBO2XpnXs4}36(vZ&rW({s3FNfO)|G~DqJ=9?W9bT0i|bNWvP-gR z#z@HE^k!$LG&PwOxvAp<vyjf?J0&HC71#BK)dp)n*RE|ivA_VTlPlf<&dA6R`e~e^ z1T#+vM62#6(7i5&iUQicG%f!#lKqw4l6^F*X;!tA@@ccG1Olys*NOMbhiJ=Rxa2fB zKX*tw0;NjAj1=6L3WLFa<h?<O2`4q8fKl6^i?|~@PYiQPUk3h+a?9Y?h7WWCD}IgK z?_N4xeZNqR8_KER4e7{*s%UIp2s6)Rt$UDrci_bN71up8K;F0zrLOA|<@$x8l57d| zX1eVs)2dH#I+@UaF;2WkDBXPNmd<jq_W_Hsi+(mZYwl-M?j5?Z+d@UzM##4>q{?Eh zU)UjM)=B-KJhh5x%)@hBX}g0R9+@6#fTe$mJcz|UTNP9f*d=xhiybHjPBh_TMWIsj zlg>CTsNlzm=M9I!rxF$X91A4Kf36BP!1gLknyIewe@xY*UPJvMzXz&%!uF{J|3JYH zf4|FJXHRt1xePNp9h@UmI7V^2UhTjo{QJA?>l4AHzCu%1^(5~3AEP-|ZOEwECm8Cg zHaj+&0};TXdz~xKBIBAX{~?yD(unU$10RWsV%qYB$(L}piP$5EXk4}^ITuyx3c3vA z54hQlJBQc-8XQBK@tCdJc2LMo*)NQ<?H5MLuP>nbj-nKK<$}vp&d@xdUe?a1+eANw z<Dhmfkc85$f&p?QkmJ{mzah^X&^e_ap+C0b==2udlWj8#*WrId@V_Md&*VRE7bU0d zN9mwxO=H09keUNg4ryN?T-qPdN(ZH;Es!MYuW$|7CfqauS5ty@0>0cWTswi_v&4fY z;C>t0pc4sKO(5YodfK)L{o6(=C?s(*5QoyEBw&0SxwnAMA<0lh2FKgj3@8+mT{&oF z*wtmgK($<1lZ=~R>#H608OxyWQlXJ-D4$*E<1lUcx*z;^%Ix2*r|yUsBo$q0L_dQX z)*?ipy?-DIEM|dv4xpZL=7*>@6fd=0A!p84t9tN!q%))eIUcK)w5_9Jtu<6{fKx)< zY0@e#AHE26*1D7PVJ5{ihwY-W5V(F*5@ru$8%=ri{j*wJ5x+^BTG}<F(bg!YQ!c<> z(=Mc4o+_Yub}&tvrVHt_L}Nk|6>YA<D0ltv)P<yre(6lfxs%}4n@dW<-B;1+?*X7j zc@q35S=;vMxuEW)p>*QNV(G|LKbOvxG#%-fJV9jQfq6>8%&Y0!9WTjk0@fPNeu3ZP zq9NQ-eZU@w^q<p-dN3MrDV8Ti$wTq+1e)1>!OYlN8FF+QzoQvq&dwEr0ho%Y?(wl! zJ61L&yH+@p-KJW63@4-JjHzxLaym6X2vt&4hO`6Os~02bQJfPiD@iWGLr7GPPK0d0 z<@CESq_?5aVpNFOs(r<xWV?L$I|UXuVq!H|`iXJK|2iSc)(H0OVk6{$-B8YmWDXl> zAt)B8jpj}4@3r5GW@y;lA&q$1<D1xkHmY4}8qzp{*a3qn6Hp3OxDIRphJsB?gcPs= zNCump&^JT$L>#ta4IPC7gWuFZFT*5&e0n)oJkOjB>M+GRy{QIq0U~lbpsSc_U%_1u zY1dGsJ={dIn`-cNX*5;~ix4!JY9G*0X7T=|bc^KV{8;}*{d}wcVi+uK@yvDWDw+eU zBI%SP1(q`w8n)R~i<en<K`kqnVCKZzvb6r8c9!m@NAN;}T3zMnK-GUP3f8-m4TJLR zZ*j_1n3g8owYDJj%!M)2dFro!BVwGh-hRosqJ|>UhL4fpGmg#)mlR+*`XOxrcOmEd zf=B1lPi-f#poo?@greY(4#^Kia1EsA@r49liET(kDwbXrB4D$fntu<}hUxwb_%ixM zz3G9kDB7%a&onFSW$%xfBaOSNnUzqq((M+k7R281mX2lsY$HU5V(XpGl%4Xl4ZO_r zAgoSy+CE?U0bd;yM%h=s!e$@Z1?<(IFTK1Q*bQX{tE;egXW_(5$-NWkq`D~1y0lR? zH?&3=oN-pXT;LY3pc6#@9=ev>V6cP|3y=m%f;np1O*M}YcIplN{>~v#7-w?!<pUSh z^%5Msp!gOYTWKf>w+vy|48$9hgu_?RLFqd$?!Wa%ZBkS)_FPyN)td*XOsXzQG+csa zeHNBTZIke2RV?NnTFmomG515RdL!;;KADU=F0N%ea3<-Z6H(exmrbXCcb&^ZwYlf{ zUB?uE{)bfUQtfVs>30pNS$LRi@%E_o`1%UQ6)`!sn&fI4sKMZr?C0otFUrUa!y?=1 zOtA+qIpM&<G~doghNm5ZxcorUL`cJnUamsaHih>rcVX#)|1GR!k85(-Lpt~d^eC7L zOi}q^V1}us_KXlMR{}<Lsq~Tr#0OsUt~)#KT4zZuKowlg^i}fYiXOL+ZZGFsNHcKP z=rFyqhRv5ph3_*Zd^18mXka7V5jT>6n?3mY9=$0de;LLo!;UvXitpjmgM2$R@w>(9 zoliUpO1$iF;7k^~^eMHuq;E5A2cRV$Derth(6Isd$~=Z|TVGTjW*sHGmuWj99B@h6 zOk0!C<g}&=jazQVkn@2x+cJ{U?S7YZPA-lOu7zz)rrIZ|;gYGAuFC6YrJ<PD^pkwU zwuxO<K(`TVap&}?t3FSM8;PgNx!7HksRk8GK(m#NC4|4<A#TI*tEuyrE?_V3n~NJq zJGm0^uNry?_5z+9)i2QoVgNTG3}u*fxcv%zF;Gf<&PaJJy-<1pOM4ZJIp$~_hymTR zget|M4|5)nPg7-c$EZY%T=q0AfxA9G47Y%Xmj?@3bAYZLR574UjXj_hi)cZzS3Zpe z9vdN_E>o1OlrNl;HM3qn-d#U5dp2WEyjhYy*@bTq9*|2Kd)OrY+ubO{j=R;jL{W(d ze0ljy0j_IL8enOR8$8~{Zv+O(^<`LXtiQ20N1d?t>dQ)p3H*SCv7Khxq`oXy)Q2dm zx}K%{%zZt6!QiVg3U2mI)=1yVjoa8BAyR!dxM}fKTlwW}Y=9RgxTKF<DaTy4<EGy< z61>8)ZV*xzUc9ZJ1-LZR1J9qR@*ld>I7;3&H@MTdX)ZFCJw8Qr7rooH1y>7@>3q6n z(dv}8XWEXtq{A7etX<&z>a%qE5Tad=F-(^94}2gmhLru*FfmHbnX7VTcoP{WKZt|x zaVrU@2V$E8DK_Ipf|~)yz>LLrPz`T~Ay8AJI#1`KGWP@WZhWBxImXu^;@M-a{)+4D zany&1+8u|=U)`-{BrA6-OgaB|{b3T;VE|K2tU}etWzxh;gNdJ|FA=t#z0~y_f?rmb zzJty-?I52~&9eXQkd<&?x>Gs`iK1{OAokY*C?1R93`)ZM{_LeTeobA1c!7PvYwDz& zbbC#`(^Y`bHxk^1Fpv-2Jr8?Vv%}vyI1^@|tho(&Q>5s<lU6!4)|*TlZ`T;K4UT0e z=t{=4wZ-wykIR0ftX>{KT=k*G8RYqfAp|zhf)E%y*Q9E<#!x*)((i>?k64$1ome%2 z)GqGJsk=6i2sVvjX~3-dN29;STAfk*ff%tF^9q<8XW#GNFqFWeB@B_kk{S42K_)(W zLuro_!qgH)+1!V&)1<K1U@=ywQQx3(<K#dO5prgPE~8uNGFob@pR9M*&w=&kS?9`A zu$t}dKd%vDm&7@2`<6sdIhr>#S+GvE%STG+9?GjFp~Jkoqk!w@opWH~2X>e$q_A4W za}H~j29|S8#KK*^_-hFvs%mO{df|}_Nb~k&uQX6!Mt74E%5Z@qj6}t<g?qYkJo*OU zi3|pyn7zs#SjT*b7X-I!@Lb}a0l2NQiAo?c8S~=CR$aY2QD0oQD)}|aeeRaOC_&0) zyJnOXydU}K<8_HHu5Zp=_<^h5rO&L-)#;baa!b2Vr&j&IC3BIKV1R6JaJDTA_?awS z{C3C6Nrv@i(YQjBDQR7G+CYSTMViZRRG`RI^~p8^)e+Jdl7n;HDPgq3_F*t5r^$W7 zY5Q_XUx&1VN5_aXzN`^XI=0fo)7&}ORaYgWA{%IeIxF6|%f>+fxfH6V8z((_Ng8sq zYFNuy>6Hm8w}Z?MyX)udixMqL!iBy_Ypb}jy;eC7s0?b>h}zQhkYB*(zo-@Q8Oxd3 zin7mkN=#uA1$z`F;cOrEIv(mXrvuf8=v4R?wFM&SnU76I0Tc+OBpgY^M=Y7}DdS9c zBoeA?!6eTt4nBy2yF<%%w1zT<xEE*7nQ{3Y3MuT0DZzUhRbc)7byz!RP**T8b0rz| z#o8=jQ|h#)O=0(6hda)YadF)w!^*IQ*I~1sTQSLq>N@J^#=se@s8pOnt!NsHkN-&* zm^8sr6yNu6H`FhR(6}TW%*LWD?c&0)v=QW*VtiaP0==%p8^ZEZPjCuZ<53T*kQr*z zF_i-)^qDPS3mosUnS8MSTpv^I%1*mSY)ZEkLW2kxzC@n-2xHr<j{5O>Z02lW!+^&e z1Ma$W+~FHj&23bXLk4^w1>&&~y?7xq>WlPhDZX?`30rPM=IV%;B0v8iCXKI#y-3}f z#J-u5$$vnR$IZc$=wD&M+HeOcL;B_~6P(u3!myQE;PuCC7Y56({SIR%%!Q~K^<`n2 z%)*_n`e^e?jbmJs_)&&*I<s(pV5Hr8k48wXUZ@=>UTeKoCk}Pg-=udHHoJ6tWG_qM z8k&L-9+p{n0GzE!!X5|89DU?S+3D1^;-RPAl_nD5YE~m@G#Xu_mbj$``E(fNQ>Ig) z%(OA$-<`TI9sGuf{9zI2dQl4<tR$vF3FTiG<JfivN+>rM2Al08Fhb$^F=M2bE}qBI z3!fWs13ML~!wEb=D!wF;ijTAwu?NocGo`_9iRw+Gr_Wa0R&gOms@Y80toW`E<=$F= zXqn`BYhVU$05(B)jEQg1S2SnRlle@kFMUpZuPfy}m+pxC#-<)vwrHN1h2FEkhc%&k z|K6mtU~<ZKEcRazV|<J@uPI$2O*&xMCc5w?0hGngNP)IO{>`OJcrp(tq3~lIv_E;3 z){;y2lN)P)szdtFO$qEh44QH@Q`c9%Vp9)XX;nVrltpBT-iFv|V5K~VNr{`CY0%?L zwGYt+_3ijr0`?DFZoMZT*w{moL-Q#|e_LP9(I1p2zR^R_AMfIw2K&m@RH+4x5ZhCP z-55dlQvhEALGC^_(>4*+a{tPu?85)082>EnA_s&pc_1e#tGn*{c|q5RA|@&4hQVnJ zjHxi=!PvH<^P>0H>^^v^^ghn@!{xgR*zL?o1?rrCnF4cpW<K3;&px~DJkW}`S4lY5 zn`yV~qa+ONMc3;XU%rR|N#JUjrmk485eA;wt`!pHhywNSME)>8xEc5^<r`r6*Nxmq zP(l0{MZUwyq~&gq*J6Wq`;N~WccF|$HwqF0OK~}Bb);3HsK*idMwXUvWeSCzL_KDh zHb%LmcP5>2Y6j|sq4)-FRLyRoSL3G!)5gZA7Tb4XA6NZ-N&vMxqY~kt0^zoAT_)#G z5VU5u*kE;c)pO2YXbcrR*~jEP4BhCU?{b&iZQDup57Xy*)SKej>8ieb)Ck|3z6?nP zSkCSRjwplP-2O-$FAH~d7Ln-?p<8(;d(Eutt#T?kNFPPFT@?O?b)g)9f<bj8L3KFn z))X<USlS<$YTBqPZu|r|hV8{s&BYGeRI@J@L9Yc7#SY!n_`o%2>*Ko;LE?h`=-4k1 zZ`#yImG+y3$VsM+s}cv&`x<?LxWTy}%VH#EaTv3RD28eWzv8GCNG6A6k;AgcVOiv` zEOJ;DIW&uHAz7@USrpse5w9(_?H3|lD0G*s@Y0)Vp5bq~1r@HZ28aF){#LEhY`<J* zefPJo@IJv<loXS&u2(Yk`VHb4m$Ez4wp-9!<HR4Vac+~d5g58o3Q$AziTO{O-F5NF zZls4SR4tvGoajzz$udoP&*PQ`3`N~2S+@5o`xHBteM;K1>YqUElnxj|!BuQ`OAr@% zc)-cL9p(I)xYk!N_~pyn(&$~T)H}A@XYhrrpB||Y!N{Zn*Ay~kd?6u_N0Hu<46?QQ zGCy{`@UCtm6=qrRhOCtEBd+$P_&xGdX=<pBf_F)%Pj|V;<fS8rcP-UK);V{&lKf=$ z<!I3fw7DA(8spX3T`=hq@wb;pl%vuw$38SB)Y6#U%dBCz7rLfVg1?XyumSvwy@Wn| zK5F)5jR27|#(c2MiZ78nOl!8YhsQ%>L-W~XowZX;beFQS<?6<6ob&nmxl=yu>h^|$ z%j<=DJX+9Wz0e!X3pz){jMz1=I}18xWv9h;65&_=#V+KN3TJ@R9^7VRo0l)%+0Evq zPMTqt_Q<a_(6sD#Y$yNukp_Id41OPS_#KCacn14%IGRHjhxr^<akz@ZH5|Uk;p-eW zad?cwFE~8Mp&^06J{*qVZ~$pQmcJ5*Gdc8exSGS~Io!<QyBvPO;TaCKeHe`8upfuX z9Hw$OiNom}&gRg|;Svs4aQGO9f97xthfN$F;qVfNiG6u~98TddpTm1OT+QLr9B$^Y znZu7cJjY>pBCkIVhjBQbLpO)BIrMQ@!{H+wuIF$IhfN$F;_x#Lf8@}Z#Oss8VH}R* z(9NO1VKs-VIeeDGfAp*BN9Ya5)j15Vzl%Xb34>jK&95-`+xvI#ul|Y)O3OS&7NNp2 z$0JxgRi%QZu%gIgDfU&&vv_?Kg`UdF5ysGPg+5P#;0g7!46P*akN(mt#Ihnwc?G8B zDYU50B)y;<9g9oLi!9j-g_4SL8bA~ZW|w&&n30DYa)p=rjsRa~?-akn>nW$9hgTN* zO1;7e@4^K<Utb0wpUto$WFDy`g`|S`hzI^gkRnnBf6zXpoQTwX4QsD*v8?Qxj`|44 ze^6m&q6;VCTC+YQBO?rd*Qb(f8o^@C&WkXRU!|tb%7($&V!?Tx81hT<;Rg-nt%9Ec zLXZezFaR*XUxb0DZ?<Y^du-rPqt)rd!Xpfk#;E9+Sd%%fSMT_QK7A9D`t=_$aL{1O z6;}>P9(vW)!>+kD<+|Y`My8G$J!b6nH~h+)HqJJF!i^K{j!EgxjGHFAGN(*+XHB~~ z`<CfBxie<Y%DeTpU*CSmop<FI%q}eQ6wfIsy?buiyz&a~J-$jooWG!I;l1}QTD)W_ zJ$}ZYPb?Qo=Xoq1pRdAaAtZ)3NUr<loE+v#opLg#O%AaV=gnD;%xN7i({D%}Gd9NP zD7O@Ny=A3^1wtt_bxA>`WnKZ0RROpQf@hvrKvF8JC;*Zw@mSI=YW`)Vvwa1=g_hFt z!U~_yQz(=z9AV5Z^AuEifH2F2f<l4D2uc0wN=v2a^;Y=6$5SxRQVa!{SK;$O8ep79 z!;DbNgZPb!F%GvlI?xay?W~+kcL?PRC8d>?g33zIyxC<7Ek&ZQw0w@G9Fm&vVWCRP zONG*cveJ8L^2S^Y544Rac_5}`wm1jumW36fFBI1imQ29{LFZLe3Q*R$9!MRF<MULC zWkBA=mcoLvGRzEW3UL}<STWB_yWX&og=M~LEX87ZA+1x2XF&&2<&}a@EEJ&d@Q->r z%gV9}N?F;l+@rDFv}=}Eh;vFTmEM9v53R1U3dpuog@xAFs4n#tEW3v_-t=5n-$Dr> zT~S`>8S%^OBQ&2>%m-6L96K^8;`ooYqQ6*9M~u#Blz0lfEF}#0tDh<7g3^jEZPyX+ zh92Wp3PnE??|O{q6`=;^m-+;;psb^jur+Bw3^%sN^zW)D$Dwy5R2GiFbWjYYKPs(r zx#<{)?Og%(BG3HNLXTRDEIh9#Pn8$?4^R%)PH3N1!~LpDxOqT=r9uge??p%vb3@}` z_@3*BM=B~13Ocf&zZgaeT?Yf7=N{2hiJ2k=P3N5-3MY7c^GeHcf+<BBz-}Oxi<MZZ z3kv>)Ljja0HLb_;c*>zAE6V42$^~8?3~%i*e1UI{h=D7ErN{8JzZJtECt!#6R+N?t zLG&;g9R3(}!;-VK&{t7eQ7l+ymeSIur=$ey#mxpq3}=MUBSwrM<6-`t<AWlW7eD~9 zd~SKgg7O<7Umhg`o9+suF`ES&XW@9^`Y9@;eFlPEA7X!`i@hG~h7kL2y4Zi)#lE_W z{lPBwhq~Aw?qUzGuD-u|Sv5?Qy8El|UtS#_76vnLZEY<eo|;;nUA+Qk(_vRzvu9Pq z{0ftBb~f(0S%y`wsD@Ysrs0y35`!V4%IjU=^<Fmr{=fdST=q9C_;<PA<$o^VjDGH~ zrklUcA(n;wX@22fX#C|Nf7)O8r^dDXyQ}|y!0+-lE&0Dq0h*4#U;67r0h*3K?JxZ6 zpn!k&?;n*P|Ki~<)E4UZi;K+5-P!(2%iB@zt}dER%faep%l$RA_dl?rZl$!U{x`o} z{oq3nule00k3RPJ@1J<`si)Vjd*<2ao`2!Rm)8H`k1xOSr$4{C;s3n$m)GCexM}m7 zTmJgi+gtzE(70{;j-5@rns@KnyKn!2gDvm8``)3$M~)u*`}-e!_|eD5TR-{q#Aly> z@ul4MRp8{;-<)dy_Pg(YIDO{qx${5%bm8J9<)2;v^}N9OMGK&RclrO_`Tw^sKzsK8 zA5s4<*SLA}##O4@6r>1#*IBaQXF<b4_)+()tdT`UBbg;Tix5W^3-9z4!Wz-zQ{zvo znBU2MGpxwan&a^bs)s|IBUTE8OcBdydQ*T0N9geSN^y@OtH4)S!sFlMne7uf??=NH zlv69@i+N%Cm^P+~>0w$Be<7xY>0o?}LvjiP(N|PJ)49o4%1yAoFA;r}K^q~nJVoW6 z5Qkim*|I9isbh}FVS#|@V0?^&;V=yP(|D6T>R!w&SO!)s$Pp;>jqWolJ-(Y~-wkVy z%nq*H!Se%ucR{7#D8yB5c7<2;2Hlw(OO9kg$^~;glPaoM%o#Zu)5nY+;dHxMc)$bD z0jvNyz!6YIjA{Krl|aov1wlPQbwRB`<v|@nRYHwo#lkQB=4m(2$W10AVEv7Dbw6sv zY?=(X&nu$vcAnotSk26vUQr?RIPrG+X$D1;K|&N6RAeNBawEy0u?8||bidZbmOc$h zgTqM7*wrLPvx<a6`8N*+ngga>6NB!9!F>RA$E~sU1VRq<AtX6ML+xmOwlA>H)DDpj zxd_>j+1Y(SI2i!$@!)PKn$p?Npe2Uf>7CL|vV@aZ%~TT69@eV!YEu!PR4pNK1H#CF z*@+E(yb1a7sf4tqFooW$k_frAA0hTnd0CT;Bx$UPBu!6f@7)^LVrq!-M(0OmYr?f8 z+^0>|#A`|XYvxpqNl#2;!-;8hlviWa6C;?7qr<&%1B_%qk%<f#8%qZG65IQ<#<%op zFniVfzQ3A~3&RM>Q}e@gM{Bbqdqt35MTw->*uJEfCZ0rj8IC9`t-Y3z*lSt*SHbNR zm>&dq@23oEEYZYL6h|z%z%xL;7T<t&);jTCjX9i{g$QB>{LG`H8#Iwx5;;07Rg-8S ziAC_`Mvz4COB@Yh;|(Mp+~UD49^B$bo4rZbM3KH@i%4J1ZN%Ij+Zx?sY%q8u^24)P zTQ>uOk(L-@*^xvnLL%VN7jWo9ESg><sl9J&LQ6+ozdjBYP~({ScD%|GsUwk^w}>{C z*Sio&k|6&i$Uh14Pa2)jph+|Wp6~(PB?8?6p0qwSMlIHNY8;lYC=$wNAm-`O4QgI% zClS&&9oC4vp5rk69np|S6y#wHwy#>pzjhMx41BNh@K=I)D}2Y*c1kdi1OdLH2$BG} zC5(=1h`ZdaMa}=Yn+Q1p-#Iltty?41Z6wq!n5RP-Oh7+HQ9wsVV)6kUMQcg4CXOT} zBQ3lRwD1?8g$<Mzu&%wZu8gC!7C~uE&8ycmLgvC3e}d(eG#Kh)Ebwo>j@H8X)?htA z9S8uS-jV<psEZ)p%cc`z%jrlfj?rhT>K`==`Z9dORsRs$SL^a)@Na|fCLZPzn1|*O zQmn@5ttY*q482F2f^nALO2~#=JL2pF^MzYG;;_0h6H~5<m|lar>T4i<0sp?a03ofu zqkDU48y$**HZekbfO&dcD=lwmSw|<d_HKy_(n)MSAqU}Gs^+8D5IxXNB!_Ca$+Mxq z!ME-NgI)a}2e+qYGc&@tzDB^$47iy{UtjO`xK>k3OhZ(#&Fsa5ya!(+&zGh*yCc2a zIfN9#_t6OkH3Or`K%m`$Ktlt8h6X}e298c@?b`x<B$SS(L*39a$3U5Z-gBX?!9B?b z;S3sL0G!!)WuR?F%N(I45t=86rdK%7oSF1`E!G>8ADzw8jf8X!EL}C;^l&d7x29{e z<LEdTN&QvakIpCL6ZjOB9!CP+WAD)o)D-Kw8$&Gpp}zVXN&li)(tm6W=|8=1J8LCV zFwN+tgiL^M#Alp_;=)PX*k}?r9c$H?uZA034fO?IUmlL(98HW50nT(RF~eA5g0Uo) zBtFE(lBD4=8H0s*$iFwVS1-~#J@z$YyP-9_Mc<(1IOYXuFb>KKbog$RH)&MN^+N<R z84Tlne@L(Im|niv_UKk)i=ja+n>82@=oZ3I+Kttc*wMz+e^lm;k3v6sw4=<LK1R|9 zaPI@@^zrp-HMhhzM0=z1S^K@gX(SG4#0)fIf;x{S10P~E5=Z+>43saL^qt;0pA%~d zF{}%zGv4QudIL>v<8!*&H+u2%z!<I0e{4*F{sm)UQc-a14vr~PUx4umz6`bPX!ux0 zqks?4W~Z@u-iw4h4BwqRd_0(UzC_3pZl`$7W_S%l`_)kyN$K%0a>lerwMMo?G=zEe z`MOlK?Yt`PvpHN2IMA^h#tEQrK2`+Bgm?Z#$eVvA<k3(X%8et&cf<J{3F~C2-*~8B z;04$?o*NDI5k<%Gq-5juea6IX>xxZ~j*t$4h7za8w|BInk@vS4NC(n-2>UVA>9d{r z5M$~;?kgvo2pP01gl?`dk}Jk0kt@FI*PhtgrzO6jmp3lotnxJ3aq&75|E$?-%I_F| z4jzQ@7rqUlG%+3cpYF$@_KtC=gDx~-S`s!^Lo@>-$pGL3LrRhz1?5N@0`p<lR?B8Q zTUBt*ggVZRfx3<+@ei53sc{`!0>yY9-A;P^{YPGc!T-ohF!=A5m&nmf_LO^k1%fA? zort9izOsz@o^n`+?E*gmr2^6`iabHd0H1zVL8)+4g)gVHd`_8%twhNqB%R7N@L;g0 zd|j905keAm6_gj1!TS9)rkYhzB$jz@DlPL&E12hj&>xVDa>3(E_mv8zg#~3f9(w*q z$TwQIr(nM4GWQ=lQeg=LKQ~gJQ|5uS{FPe1dUg~Q`6$leno!|}doXT##k_eC(Op^& z*^kE<u*CKWq8As{4)U~ax==Qwd;zSMGpfiBSQeH~dWDE}b0dpU#2g9vJEn={$zAC6 zkOt!PlzD{9(6;Gw)$_SveZEYw5q&<WbJfwUpHW^yQ-<6NJzk6qi3_;>F+>lz^yuB9 z&8&2KW{Y#?czoGVcx=eESeBXWXq6QS`VqRhD=OxS-kbPgD>MM^lRSt%=>=Xv^dU_M zo+^QSsp0zy^jHi=8?DPz;JwM`fs#K<&5p9Nib8S+ElW05A<0FvBOT_uc&w|NGqTY9 zKHxXApscir(p1454><}gk0Jrtc)kZEcoX+#LhN?UO=Xpk0K^hK#DTUP)ix1r6peG( zLLnHw8d9sd^mH{7N_``SXQ+}V^s}IKC=HT!t-GS2h#wO=P<MJ}@Nm3K8#>C1a=fMG zj11fw%sivxv@=IQNe3YRM%s5S^B`G0#F#}^=x3D{dD2S?e7O}_c#=G6q2M9gyH5wG z{g1TXq0}L}KrlX2SJoGyck6BuJ-&t69v=--UdYH7YV~exlibq6xtyL~xtt22!g45; z)2*4@Qs}3Zl)}M8{y_7Y?qQW#%X$>+>(I)NhS;H#0w(ED^I~NQ#-Ah>7khj_`K?-a zdKMIc771!SNf#`4ZiQMI<kQelP;NWxd1%AF2JzB6yWmQX(km6pVBMLVMEbzoRk9*4 zv-*P;Cd5h7%PK1QNJ3UK%Ha4r$P*!@xmgsvqJU-meWy^fh!Oi`$cS(+9}zKA2gxBY z;CKsso?vNbc6I@*KSCTs+InVzuM~wA9As+7^l2IHF{4Kmm6Z`vqMHu%ObM5~&*Bu_ zT+HlOX*+ffv3!K=RYxX=02$2|1y7}e{L6l=8B7kVtG&}HiTNL=gFLq8ABO52Ui)7N z|DWG~e*gJh{u}-5@!^ld`fC3jmUoK}Da!5FFnQNt-}-^s+rMX!D;QR)jXfs$PyH~D zKBS|6>o`Q28dPS57qjq=1im<i7wA#EAMZpMIE>`b$o-;1{QB^?2u(a)Gk1%FuNVK& z{R-}WJ-0i!J)PULd7SCoJ%__tJpEgF-eue!4?!%1t@{VS=i|7B^YGOi=Vcr&=l*`~ zU&GVECp%Ew_GxZ^hU4=*&+jGfzKP>^fcqci{)rK+F4Q^;t@p0&@N>U^b@=~k{QvIs z|Eux;^ZW1knS1;(e@l<Qe=FMmvR}`_7tFtB;edZH-v7$q|LZi+<@f)0k{G7m+tAbL z=Xsdm^OrANeg*e_@i>FeyujeHwXGKr+Lu&QxE{hcKKK4}mL8H{c8Nhdhj0AC@D2_) zLimHve)eoX^7*s!v%l^+{Uy&((=EV|-17dN?_0=S@8A9Y=*z>uckJWV^Ms6A!eah# ziSbdWOBn6xUBdt0nrH08JFnaRr}=Bh&(}rv=<egUUtslHt>OMU23t}Y%;x#3aaFrY zmkMte^{4W|c|Y>|V%$EA+atOC+<9hK+2VX|SC_uSxIIn{e~#IEaeE85_vZF>+@8qo zCET9G?RIYO$L$7g@2{qJme~hz`+9C4#O*7%eK5CMxZT3-@)>4V`(^uSX1`LcH*T*| z@!@t=?kSbq?^V<1_6yve$n9!n8@N63iGMA`^#iU0))Ce=UAH1sdijp`%j_^l2W}2s z96C9)b2y$uD~G8Z4&%_mp_xO%;SYKSWez{%u$99PIXuSUAr4zO+{a-vhdVfI;P5RD zH*>gw!*v|4;c!)#^lLa=#G$}p35WR{W^-ug(8}Rh4u^4Q=8$k0sqfsM)&4l5OMBRP zzb>2fuYpVXPaQARJXKuO^`-i&_A<ZrZ`nAIos&!cnP0Z^pNrqh@wSZVetha`zr@$) zD#Rc5c^iDl0bqZ{$B*!}DSUnSd-(A9G8MjQ@Xgb7q>J&!5w@1aTcW5q^>z609jou) zGeg*s@MXbQ_P=C-^pE7pwOxKX{!`;y!})l?;V=#@9R9D{vxEWlOZck7HKZNjtuUdj z0dqdUmwPk!4FC_pR}`fot-bN=nUGh&-3;(+_<k^GI>}3h%2Oh|3nsxIAUwiX;rkHG z2sgpE56lP;!}k`L&jFkVlj3-YTLthom=H^1HF%Gk`1>;)Y5<<#?w_HY&j4nQ2YB}Y z7N!i~!`!?E;9(vn7beV2gP9p+0uB#mVU7V*;2Uq!&`I<Km?(<?hxGt&7y|tm+`Ryk zl3CmV0DlkPA_(&&!0U&?7z}2^Rbak~g|Py>hnod}E4lf3fJfn51>uhYjJukU$G{v9 za632e066U$;IF~F0^q4@Slo7iyHlVJ!F?aVk5hQN09-a4=1pje8h|rkkQ@u<Jb?A^ zIl;Ud;L#B*onrv6842?wxL*hGkMQM#`4xZ<!k{65c@4m2696Afa{_z&4(n$Jz_uG< z4gmL)0PmRyZ5OE_Zvp&pBEtva1#U(-$<Fe10^DF{c_AF*fH+_t3-C>DehZ*;5~C}G z%ixQK^lJc)1%^8w%n1Jk-#Qq?HUK=E&eA^z@T3#)gfQm-F3*5A!ngn<Zesab02(F} zvKrhGx+k+bNB9$b)zN@6!0DN+T)6-b!q)=k3jobiSUn)TZ7R?PxZe)&o2e}Qc7X3? z0gnLghXAgg2GgifL!sqnMl%Q>y#>Y>aDVI;s@H%xF$}=XIjr6gj-J8FD9j{e?@U(4 zeE=P^P^S*`Q-HOzSojqH$K^r)1^4j)8}eAW5Pp`&`wPG%m`Iu-%m9E--NxM40sI3j zmo9+&D*)5(fI5dX#{(?53-AVW5x|%3VtK6x_|;u3?n!{(=0n?n`wsx43RswEfX)Jj z1HwhzjPNyXw$Fz4g|7_zHNcnPTZQQZ+%cP_(+u#DB38FM0A4=_#vgFc23QN<hhSa} zaN8V)&klfLB`mH1poN<eK3>A|eG=f_Qr5ov06sAn$_`<k1o%)H^dq2wH2`lahc*JU z3*Z{~?C1_~as}{~V9p0v179APcK{sYWwbFC;6g8J>qP*!bMv};fc`6?ED#>yj!G7O zAHd}TYwH?-vqWaj1Na?$UI_mKz{T?!eO3cJ1K%1jp945^3D6Cg^8nT@g*pNADu8RN zp&er&Ux2qQgEj(l5x}S#C<~aQ0cO?#{xSH17$Kj+R}JRR08U#4bP48cfPaT?GnnzM z(%6T9e!y%7nD-Ftn+U(=?(F~<J`Cjr{1*YdWeqdu0^G^XCBTeae1x?HGBm$>4Eh(u zwE~nLW9_&KVD;}|jsi2nmfy3wLfGdCW=;mU6TU<U(+qIR)6m{vb^~1WGz){!x|ZdI zFnb-iLl}e)tYdkt0QlrHP|sjS81o$PkbtKJ;KAn@?X>`0^gOJ+APhqC0-rAcz6jrA z;NAl8<V#Qw*e?K1Tn}Rngs}tM`A5JL%mZE~WcVvA{ZxR`D=eK=0C&BDT6;C9zl7-i z#OPKJ@P$7ydRPzegFnNV1z|o!xB=#9FeCi+{{dPAa}mIquK_+_&I34l6RaPRCIP;^ ziM3+`z{8uF`53?zZvoB_2I1Ma7`>eX_|4mF?n~YZJmgk}XBEJ+I{|+%p96UJE+`}5 zRtE6ygHYFK26$@=&<B`r2l#CZYxf@jitn+xwF;p5FyIXC2wyzR%Ls7(5$Gpit^&B} z2+MafK>yzXXY3;Y^FIcf05ih&k6HQ%KRV8EmI1!}39ILJfH!^$^aSmK_cHLV#47AB zpRzj-hX5ahk8m@>SGgJCVQxm*{d3%m5M|oYjBq$NBfN>55#GhkD0jY;n-M<D%_#rf z$jt~*J{xgEsBm|LC`*g(2uE-;!VGRki1Mu%9^nFRMj6*fxf$UG9v<NZ__EFaOPK%v z{Qk?o{|``00|XQR000O8gqlT85c&Km&x`;7000315&!@Ib7gdOaCC2PY;!MXb!jeT zcxCLpe|%KMxj1|_d$Ku6HaQDyAV7csLD8V1OEl{yurb*XmEgveT_PmGiZpI%OT#&U zR|3JaYjZMerLErTZM~I?elNYZ_tv)Z!&Y#Y(1ZxeFMohg8*9{wiyBKz7P92L&ogH? z3E2DIzJGoHdEt|D&dfYB^UTciJo7v=&&*aoxPvot9LK|-rg7YUPXFiR{`Y?r{<3HM zA)9+8{mq&C4NKmf`9R~N>+{z&egE4{4}CZP;fKEWz3)r;-+Cm!N&a5`qu<M~xX+XS z-S4k{<mRlbjDkcNJ)ZEH7jFA+lKlH&|2t$C`~D3Xg7>uMV)7!q53ahA1lZd_e#hQ7 zk(2Dbi0p*-{f|D}i245~T-`2?TVgPBhToE!WL!6AG-MjmIqnSzEY;&CTn7&eOVoP- zzf(9aHIXOz=9~t-)AZyP28ggD?~xb#x8M@T&HV@Z^nd%;+JDX1bnB@6PycR~9@!+p z`}3{@LfBURYM6YETXl2O>W8F<IIb~YFO!=Ee{Wq42lYB{*1@>Lg;<_JFSG9(aN&Qv zMgRZ5|C|46NJW7VavRzNXP`^I<XPq|Jme!ZRB@BhZ*bF1862k^7HpdBoLW&}>ELFC z))|7IZ}CM<p`T-ZvZNrljn6DuDH|6@^GjyQQ-azSi_gE(OSiGSX5*ku>oBdXjHcK$ z@&H0lXf>5rI{v)59YC`gs5c1;*jO4mOtU&F4P1TQirV&V7tBDdJ6pz=akj&1pg@3- zm%LJt3vVBJjlJ8_$nii}nh;uDz?GHUBJ&+(+R8RVAS{0s3KW=uNZq0B1r}h_n$QCU z*84*h1y;9@{wxbCwYF?75I8aTA~Xg*%`3&gbMOfnFk?;VX_isX6IxPWt?|-&$Oz$l z$UNF}g@;-;^O-9{6?~?gQPonsQp!PmphC0bP*Zvb$6=)WrJwVSmIbBff%LtfUV;wr z8yb12lJX#tNFVzK^yfjk+e=?bM`Y(lrzN325P(_ni}d-t^cj|HCD2UhkOtCGZ#za) z0MBiQvH#kSCI2ZG1Q=r<*<6rEI>%z~=iRgo$|P$G=CZ-gQ|majSUi~KCWGqAf;{>! ztiQ~`uryvgc%NZ$4Q*vHd@wA3(Izf#T~d%2=#suI9z1zJ{cbWzN>er$SU71(8x)CT zQXV}GWHNc6-5`&*h3!aHkiv;ihmpcg4h7Fi77r3dnV=KJMcX+Tm^@DUc^lNwnq3+F z34Q>amBCF0IEa{=fCU<}c9=NL#Ss@*sV;Z|aJoZ0IO%?R)||u%8nD=~*iAdlBMoR- z1VnJVrfEQe)&`(GAp3TBlSAxlr2jS-@SHq;CzoHwK|$$$&aLHe-A-;l3gLF>-{rQj zzrqb|F=Kn+&kBFJFy?vgPKZRNp=;7u(_k#;PjGS&omT<TT8;$@g8Ekiaqvj1x%c}y z_TPX{w;w>v00Q{tHSYe<$<f&`A1Ps{n+_XwMhz>6m$yR~@W7a6zjnWxg_vqN0+tM= zhWG+^jh4gfrKB~sKq=AvgfGB+(7pt5SQ&AI?&cEoL4W`X550<Qbes*XOWAT$=tVY# z1Gc$@Zw+lS=<=Y=;tZSudg?5591Te(!{!gLG{3=1Z!#gr(#9iD<1+eqCgknBhJy~W z@;@N4Eq9_^A=cmCAL4ImJPbM9^zKY1Z3+ngTj)B-7B!CIS9qw>aWS+x&9J$np`QGy zZbfpywq3|g87n`m5F&wse0Vi-$YD@Vji19|(sHcOE6AK<aRP?6qSSC4+F*tHT8eL$ z%*f2hzmCYpFFTkluvR7dqpiw-8Dk`8?q8wDv*y85wUC_o_^#r;s#^f?To_FHZ?7Qp z!k{U`n!JD^(wGZibg3~hs5hiAG6_{0>w&Wob>QlG>B!aCs&=2=gr^Jg;dQ^4F8DPF z$Ixs1JQNV+M3)~1EW?t-&*|t~Z)p>NCo)<tWk{(lm$KxjKc$1gVlj=@zhZAM&qy-6 zjb!oIlpFz`JI&aR?FD%N*_LI&fL=RvZ2`Pmw-?MslpZJ$?uP<rq3ortL%>z@p@9W8 zUg+q#^!m#X5d*AL5V%22&h$2R!x;CX^63FmGcO~*E|>=`4Dp31iJT~$J~uL1r%E7- zDlci8YI+^X1&~xac*kG1%wY5Yq@PdtKe*{^2C^8q8<U4Nf5Pgg=CL_h(wAGN;Izat zeGwa*>B{C$l-CLt03KXjrwMy+h2#Pf6o^z{hI!zX7a7la8;>C?K5Iyf+Ik(UhW(gv z%)qTr8yPs1Q8@7;liu&Hp-;v&%}vADPup3;p>G;cgfAM+qto+F3$QcEGQ$(*=Ng)K zMbn_NLl(|&ZtUv^JUV7TZ3C*@V+)fy!SR9kOxV#O=hJUNd?z;%aPs0m`q^|gWhh6q z-Zvo<M6qmUu+rOVo#3Irg!a^`a(tlN?36cpXw5VTD=|%)s>Ft+iR47&aw<8Zd^jWW zp~+}|=7k%}xM=FD&jO<jlof21Z$Qw=2x=uqB9~H??irD8laUYUfcqJsv!F%FqerG+ zjhQ=vS#^(QmwV*d9=aZ86A}x#EN-tRn?3YwHc*_a$K#`4vw0@3(-j{E*-g_?B)NL1 z2^!n3$pT%1t!UrRS<1Nfonc2A=k;6bQS$9awLNNbbTp@tj$N37M0PMAz-xECR*2GF zp6&;REy6VV(p3qm{wd4r+ij;_#d4#mJ26@{rznwp<q*H^5=xuRpZSOD0m1?hK5{4$ zOC@{|+fFVkpU#MUY9f3Zc98%bjuTLddMjkVYulxDkYV#%4YqK7J3TcUl#<f<FxZ@w zN`F2R=7=J!i>A!PW)W=}x!@(Tz}n~NYnrufcoo#WaSC~>kac>*QbWhj0UBCrMjNFz znxS;$d$pWgkaYERdI7{GC^2jEL?vu-(~k?V1I^p2ba()9nU!$9ThB6@gSFfdX_`^W zD$L!s%B*eGw8989lofPnHp{N(%^Q=qT2L-oq15IHi98I+pZ*WvHOeD#kZG>C8wMT+ zbYp=oHO;{RIoIxrOA}~o9*1*r2HgrDq<&p#OB~3<I2I#(6JzN_x~51|38IwQ%CL z%P2UTvX#=-8(H7>J~Ibrr%TFZzUkJ%v&x4?$y|7{HBIR>D7^-G07$r7Fh=lYf!7<# zUyYI86v=e)KcV0Z9qu!Pg9;kj;mIfX6*=4&>=FY%LGt#HvmiUHgB@sc!^CKjGoctU z7=&Q-`Zkl&VMx{~6@p58iw-G&OwIzF{E+gIQJOFc1`u~BQG@(Bs?96v8`=ju5nP&> zEJO@E3t>H0{!A}K(i0)uz>0buUv-kw$zz?r{DU?;yoH#ICzL+Tc8E*_G59OaVAv*| z51f+b1qP()gNJ|!ImwJ~PLmI-lcKrX{)$Tn@Rbc;9Q)#Jr&y_=kU+U+TUbrg>yQVa z5n^zou4yr>*+6S@t|nVG*#hJ2*KnlWbC9)jlY~&?v7Ph!)Vi3xPLP^Owb^l0PP5lp z<R3&+;U)R)bykeXl~-Xzu2gHU%fpC#`96%um#XY_1@c0B-CTJg@Qf|&ES@fzswy4r z8wXkz-YFM3j!ILMW{XjL;%jJxKLwERYc+J)bxa;ts<IHBgt-rOx?(ti^rC$XnNnIO zV|kid7l#s;i3d$?DnO=MAWCCpbYh#S<Q6HbWTli|a<eReNQIedi=nc3y8O0dNSXt9 zOH)Z_p-Zs4ayK-)S+&p?^gQbTi`pzi(}~OKXos3|i7O5t_c&ZalM5OsO=kJ>H@K4d z^5~0tK4`5N_)kEwP>$Q>xf^DK?2IEs0ewP;=nX+C7P7Ta7VL8V#x=l~P&#(&23D6< z59R8iJUx`JhYIx2TntfuGL|IB6a5qGJ@`+ZPg`?!qogBxqrEOBf9#)C3#=K5=6Od@ zy;Q&u(F=oeY~hCb6<tY5kvn*HYS(^b)!9dCfIvvK6=NVks)0@t0l*m&ErVyKhLvt( zQciTTiLs!r-I0ajSWdav-n$!RM?!#k$yXhfW)$WR(?@OtnynN_)mk;1R5hwgd6MnO zS~s<flg5**?NdPJSFMxND0d6MnMft?NZm0R5+@SKG?Fe*>3S@Ohu8t<x)j-}RIN*a zN(|8qB0$Mb9uqt2>kjcc8p;Kv_E2>nU4!i4>QnZE2FDq;ObEI9+<pPu@yi8Fn}}LS z%MlbB)q=Q>uTr{&mgYDorIG5G^3b{~i7r!0X#vPHc|0_bWUYb*0B{)q*R_M~0Hp<? zp4!?3ODPxffv4<sW_cQ|m;|a9{?jL7dTe4+JBU_8VK6%9y{e0<u5O%#J&3le+uiBv zfdaR7x-Q&>neJj{jYX^OA$^<Dh^xCbH_G5VbjJdmKcVr-(Pe_&L+UKSb8?z3-1{$3 zfKM6Xo8-{r@u0Thd%)pPahpX6^GbvV@pJ#3HF3GR&3y&FOYW?>BHz*G9)|Dh?yMP> zXSTUD__o{$q>!n&;=H{%-gGFsNZjkx#JzWG(MtFlhOgmh34C3FuPf2p;42Pa@#tK= zwy4-<fl{n@j*~6UGR+mY*TtJI08s+g;$BYNn_d`+{*B@9d!2$*^=UZ;Fj+y@YB~Av zv8@whw`r?B<G77zX@1a<=xqA@?Hn6|&lcb;-U>8Hcisg0HVRDb1PpNku(1NPYP~eb zpVPPi^>Hm{t{zUss!r4;Wu`!n;E1yN=K;hqzd&c9qSg){i}J=O34PH_VuAuvpf1pD zWud7rsQ`GHG>nSC3l@?c>;jmR4947aAqk_DzEX%Y<>W?uQ&+Jr-ZEIt7*$KR-T|#y z1*&jk73#w~8L2^;cQx*=h42+<|9&T=bn*oi2=FifD5d+c*jj07BYx1&@6gLNgT0%A z<}SwC!a%;cjh3$=6Sab57U)838d8w$T)BN(F(^o4;7>U7Oj`ioZ7$2dq0*!@o584m z9y_?`*I4}gd6137)aElmP1>Xt?Z(KdEV56P&#TQns@$!7!Na#>u*pXU3qh)xq|YI6 zk9Ir#su0ys`e7l80qwm+q32j^qOi9L8N1q>d*oERt6R#(GMmo;->@1;^O@)`8`nYe z_pio2XaKFXws8}NB@Ew(;iNJ<0}Y903n$N2Sreh%Yo`FNIP7r{Z_sv3mIO%fU_v|1 zwxV@`1BMF*2-rT%41~IoSOdoXS29*#S)kABVGKe9{ZS%FG%vk)BPv{8TI&D>hW6Zv z&yC~o*~PwJVb5O_<Fn`vd`?F~_-r;b$8{t2M!_zm_WC3tRX|e=aw^?!(;4FItqCrm z*I&`4lYe>Rd>rhd@wzD!54oNN7FYlT?jLSYo8$YdALO_-_EcPJmWy|mz-!xn4B#@q zeEqAL226(e2a+c%`z3g1Z?M?9>@QRJ6rYKx)jd%o+DPZhJ@oh@MszSI<<aFxwe<O$ zP@{wh3th}2e899Yz0+70CNvBFsr0%yGG5MnKx)?uIP^6OIc`@8G>&dBO+X2hLnvx= zBqGx3mtf@8dg#AnJgEL@Zu)18q1&Jv19gWblen+?NYv=hsI75(8?jAP_#0TIu5Pr2 zK(m+*V?$l=fPRP;5!VGGkaV^BJQ#!ficrY5lSe3VorfGsa}S4E447pmJQ9=zk~um7 z^dE#wMD1q-a2&?9oqh=o>D>geBhtZ3JtA82-@%?j{@hG|1xSIm?&y<wlpXXr7Is2- z6_l){^3V~3m1bN-m6v*ap^{(~a^xcJkGN$Z=X+?@1T-+ypr0p%Dy{w$n1NN(a<wuS zX31z4S)^_e)P-t&u3FE7`I0gYZPW(mif9U$MoFpEEO65GfT0<x!g8g_UOFKMB=8!u z_5~ocCYMvL<CHZ5R||Ot%FIs5q&x<h3becVO_^j|Yl>zN_lBcp@nE>dO?z*`27+BC z8`DkgnrT#eP5_mo%_V5nX1WIj*Fp_S0{OD_(<Cwji_K0CfReM)ZOT@Gljp&VVlYJu z+l*SZK#tR9$X5;-<q7m1=uV~hMp-1sUtUC4V}a0=t?$&YNEEj1!lsdRt3Ro(ILwr0 zT~7N*Gpfm<(2Kw=>Yi8ddEh)ggZtUDk3EmECuPqQ>=|ayBk-hy1DXc*QxUBelcu*V z?8blebhf@Ke&A&Q<fIG|{55J)tJYn?m4YJ~95+yDcFOf$>I7b>{R7(ZV^#%lL4fo{ zhEv(9z#eAor;s<;lE9D0E(zdzz@^kNO9Cn65UvM^!EZxv*t#5N#Xuc=wM|e%XAtvH zH+#MY&(>$YglFKC7?=V0lq&}ifK#783@>qeCd9QJnwMX)eB(Ir;34r~%W{}Pm2S~C z0A|U6Ei4`kL^eT`KP?jDYt`V>kj)VhfB0YNAdm`znKpn9Vb4ML?qHqFx^55a(mkv* z_pnahgPqyC0kT0o3eA`9QK(V6U7><Br>aWIfsh#V;nI8v;f3CNN51*qMI+yaUK_6I zvF{eND+)%EQhIaYyXEqY@;oq~^l>Iz<BnnV0AeGCE(s$g4nB`jy`SPDJ{$h;gfqm0 zZ-gp@6FNEc9)l!x54Nl~BIw0lcWtqh75i_jSk?!<|I7-c*A&P~d7PDUx3sL~a-&qy za(S(k+j4oM7<^brwughS-UkrOu~wc~o`?ia)kmw>K7zlc_ok8W{N9<ksBbK}U7ptR zxM6`jsXUprWhCn`XqzQA25=h#cnJY;MIiz3X9QR+2HwH<qhjDqe19Jl1$@h5-~hfi ziGe-%UM>dyD-F8`sUZ|Z=5mXB54rV0ra~#3Bie#Ud9~6k5<<oc?Lo?;FM<SbGnVVs z2Et<CMUd`SK|BEvz13+tp~O~;Pf?JIV&E}c>Wg{Ar~bxa5C>nOWs(JmXF2={RaIi} zCos#k9LnzuA}ONTsZ+n+QBFG>&d~Gy@MKF`>hnE}&tG8USOqbiY^-qoviBtj4l)5T zANp4e;_ASdaZ<Ul$#TYM5@EEUT+-y!SFw+QYIHygl2np@)B{+z82Bv@cJZ*Bx$|id z4r&l1343-j@xyHAtvt3Bdi{OC3EKKtVMGjE4`pMU{}mIzS%oxT+_yOHZp3zmg4kqt zD2QUgP49Iu(*vfa8J$ehVI|QCZHwcr46u{IVWgf>$EvpoDk5nkJOC52gH-X3x1<Gn z-Pm^VbxsW-v}Ap*@X*QFm`3y&kz$w>_!vHS?igvWn;t?Hx%Vwx%a5%SpBiEV{t+$` z#~u;4zsBOfE&gZ$s#>u}r5`A<?@4o&*!RWY3y?Ozs&CQJ7I0DLp~Pt5vgI;z#|X~! z&SF$9#K0|=HBHZ!FPYbnAQIjh)f5%<Pt`QqF}?qXPqLa*uOb6&OBOL0K^_wWzrwx6 zG~(lxPNDZ5oW{qsT>iHFh)zzddu#3Ndy7dI2iutN*aazD77<35+dAqDs1eS}1a4+z z3*r_fIE<4;?<jQ-QYtwU&Cm<R?6v_M6G08OV$$Nc8r(k0lp2%Cz(*RZLhl5KeSv{s z4v$+aTAl}bSQ#$bYA476Y?pF4Z`-HHVN$-%G;(gDM2}Xq8o|fw;I*|a2N2b7%XvV= zV}Mp6(C0IfK#rT_afva3MwaW0=jk<~p2eDi!={FCQjQiVbiEkZ8)xJlP;tz0ZrE!; z_C$#5xogJU!X(0@0NKU>_?nL3+sK)%!FL!v<2-~r485oe!k}4@q3^|#JNbb~zLcx? z%s>QG9`W_X@hFeX^BgELi{lt+d=50JQ=>pr9q(?Pw3&BwtRFXcMmfa|zCYTy1T*Xa zig=&I<P_UEg^e}WY#u`nQxqnF2bmnYnlwmfX1i>f$&e1o7xn2xV?reu-fF^R=_bM& z{@nd;kB|0%4WUHlE0^r*^Nc`Z<ozusBkRr9?4{8IA=kyij>-gLDEC-qbq{0Ihj8DS zywzf#FL^b_yM#SE4D+4Qg?F!kc$3rVcuVdtWJGu}7M;rk){bigRy6JImSRpyMcA)( zSiK_U0P+&__)26GhQ)5Dblb16x1@A^sBVhp?lvR?h0)C2DbhGSkgpFP_8MWccH#5g z?1`~D8JOis8dL5<jC(!)e7f#yW|e771tAAU6GI^^ly3MsnOOjXTL0qZ@jj1#z79uk z)=N+hpvdC%{+8AR!&|;Z_KcY}_L;O0ez^UnkgFeL?6VN4bXU@kixN^+o@-~3Qogq5 z*-<>I`{`Hx*g2S+tCjae^Ax7NX+U;t1l$Qs-T<)LgyOb2iK~RT<|iPY=uhB^@`95l zXnXL33aBK!#NuiRn{eBVt!!3C7Z4J9n)MA5b=!&F523w(N0ZeBBB_oy)Z5-%LEn#R zT37pyiG@yX(hW{-G5oy*e_z309RBXQ(aEiYH2(vQ%h4)*1Z1ZTt*?;l7YVC0VMO_z z{(Ml3A2Xp5;ph|txbwFQwOh4l2RuWqIG;r4cQ|=Y5ws3xYKFQ==x`Qr9nLu!9nR|@ zSlr=UfcuCf3-fJ@U=By5>DU^3^IKvd1F6k*0?S5&jTDEL^C8}$x_S;Wz~Rj)WVqAS z&G>Nz;zOgU37gGJs=GsGrfjPQB^43M5A9$W-8cp#WtG6StSV?pqNJ=U=8`y#GrsFM z)O1P%W3&|WZ+<>%BJ4|fq?-$BTfR$NJwyOKLGmh>hNYS|BXGdIy9GJ3M$2*POIRgD z?j{|$PxQ%*$R{S_0)1NyGIFX32D6fHd;!doP^H;T12^i(ivjds(<%k1x?FMf@b>2J z%|ErBBNwrRB36J2&5KMlFH9{<`Icx?M<u^4cur3B4=j&nkoGFJLLB}Y#;gRrAz}*9 zZ+TFY7WqbSTc9qSgB`2HQe-T}8BJGWMwy3CVHB$`Zb)?L9e`0Z1K~PN!_2xHGK$;L zfYI21YdOVGF4)K8uC}(pl%fx(B$sM%HQF}d=#Zz;1BS#VXkr=GWf)n8H4>*~%$D6Q zH<;5S#^PM#SYuIn=?u&?oX5W;6g&@K=xuPZhjD2fnS3te*!gTyG^@dRBT`KbF+=hh zrY}7I_LUKPhglnIwm%bNuh0eddj1G|1rM{=OJVl<FJ#SMJjEEAxcE>t-^pq+fMiVA zqajql$lY;WtLkJ(P2#z5CqouV7ep|8X*tVr#fKwjw44XfHG?4z!{^q$SIjWDf<J{; z-v-0ch$Uz_OS;)=X%!A|bsV`n{wZ>|zFt~{oknlWP3+CoY2A=L8?)E-{w}%T0i6rx zC;#Rd=uT-unR4l-rmsR(pDUNfZOry(Er&km-#kAaJ3qAonLfMLab#+Ec0>sab?x+p z$!zJ!wBKnh<JuvvoraQ86?&98v8q7-ifb{|LX9fWCvcgG^wHPQ>YNYbeC*h<My}Y& zt=5VXel`|$ZGj~Oe}&y1uaAxPt**H3Pj2-Qs>w0piYKT`b;UxizSXEn0fklftyZ(} zv$mn3eg*lsu4dF5?AWoyMnJB<zOY`f6=AtPV(M^dAlCYs#{9Sixhjh+<&DQ}=3@G* zPXO<wW>P8W;pZ^y5(b?78ZkH#MO3vVw2Z2rI9XxFU4!Zi%FwXX5W1TS@hixZC#|81 zCoQV04>;Zx3wB9X@*WM`%5hMsAsF85+`5>!V&n|eD!<jz48pqrxqB=M*CkN!G8FEl z6B!EqdJEeDacpt43wn2({o(cB?Urv)O1HDU-uy;<Q)On-8B8S01i#^aEeGS3!vd)` z)9Y_#+u-))W@&t*-Xo{U5qhH@O{!yRmHAqfe){p%C@CMaJsnadK<f_7=eR%M;MhH8 zF>pV8B#J#s-+`pwJT1B0=Ccjps^}c7DpniR<m>IJ4*=P2nBmno8$wUw9)m-VG=gX# zeYjxt2I*`VS<#0=aQT<*gt=0&B-}Cohs$cermRFsD|DO?sd;vnS^5V{i+rOrOQOIz zwo%leM9V)~;sL!xzqxS}&d8_H+?IvlfFvuW0T@N2T<+)TWInM;;H7uiaIMkRgD!hs zH(idwk#+V=w$9$e$#(!w(G19$YQ)uaFLYs%bOVa<Rl3BPNb|6&J}qY@${BiW2<@s` z`ZI`a_gfmDMQmJgT$)$wdi)0Z&sdOJ7xx<*)aGtSDf*H$`^aGAlN9DOV(hTzN)?0~ zaGDiKbkjFV6HYcp&DEo5*3EMn7~xI2XG8^5%VM+zCVB-o3v}O;Jk#Rnzh3JEV_;Yr z=p88|`#>ICLnM`Ea-`)$qwQSFr4-ruD*<&@J8-j)EG&${EI!ZY_R@zgLFsP#X$9NR zaCFKd<O_r!6P4~OYNa`vrYtq*D@U~k$f&I0VeYOc?JLG?DFp}QbT38eRU5s<OE;s0 z!yPP~%x2(vtrM!XdTA_%=JE;`zzv?Mof=Lo@cONd`>{I*z^p}et4D1<4~?n7#(?sL z`vTn#=A0vj6sUxCM2LUcUM$roI@AlznEYqlQ?Q-7OI;RE^ySN>$~+KJq+9IE1bLjB z-h-H7r%#7Yk50BX3$k?}l7i!LOCm`&rn}BVtrTs#%4om_^wymih?l{>WtFri2VguS zD8T@OAQ_44Jl%L%ABq3s*w&nZ&cJeUdj;6x_2sxQUh?%4EAER-5Ak1D!IxUh^bKvk z(wR$}XC@R5bEPs|u=x~d6Akt4N&$mJ{o*U4dB`-R4(~yXgOLQqW`eSXH%M7N?X-`c z0Af(C1LEoswhcGtfbMplK{l{m!E}U_jc)DqX!<AhD@L>pZNZ-qIO&=LjMt50^WY^M zo5e6VwsZDr$SQI!eFdgF|8$y?o7~oMe}ugQ6cJj$5VlX3c+wgDo<EnS<K72}Ifi7B zMt}}FIWt>}j@I}yXf3BRkA1p4k9CHRO8I(6$di0@nC+X8kzBxW(M)w=G|fjp8XB{W zmSl&&#c&WZ=-fo#Cp52+-ZW()Cr@zGSvr-1UNMeV{1tb2ZXfZMf>r}vaddTzP1`oj zaeTwg{_f?rQ-fbQT;{1^r#yoW4JPsN;XkSjqLyW~g?ryYi~cv&X7ZIP3ywkAXd9?x zazYvI-uP%zaNVnPh{`8@s*L;5j?{G!x$zDVNlOqhpg<IxRk!QXEZM>aY++rG<1f-U zNcMTC=^Rt-9Dk7?^7@6O5L=B((HV$bVlQoh7|G_PKbgUFAu-s*_Ju5HS-7=i6M9{^ z77w&;1`JT6t8ItuSqx4x=`f_7J_~JZXL<w=7?Nh3LL<FtYs4?ZQ6b@Yx?_#F6=Jq7 zw%{WlAM^3y#D^OntMIWd^g6E5+%2CVP!de#x|;+R>k^(LG27+B%gU!BzF^KM0Y!tH zRQ|eEUDoe-LmFTBMva@UM+F<EahE`r^#@N$E~Cp*cnA~?TbMM*NOk|k|G=&On+N}* zbV9*>7!4TrVRRpiD_LeS9w|I=zn`n2TUc2*6bW>I2J(>xRt-P`Of74~xsgs+53{#s z<7OO3xKfyK!%{}+G<+Ft;r4{`uRPMjjqJen&~HHzNk@!aTi64NyXxu(JUzcyPL34e zxg7WNzj(0lq%@=Ed0SZgH%zUg>aq)Jbsuv#hp1(cC$?hH6^9@%Wz&@!TU<+pDp8KE z=xV3WLDVkva|29t*9$fa*v|PJ7o}8toq1zEb%CMmpIFO0K!834dW>1$R?@+oLt(&y z+S{ecZQPyh(gc4>gT2`-K8ZW)t)|Kj)18&1+Damhqmr|DvQz@L3iQ@8GYE#b<MR5) z+AOUTE1ku;GIiI`3n2E}fQd_Pkt`)ECG%oOvw6Ljoe*K!T)9xu_^2MguuW*qW?B1m z_oM6EggcK)Gg~g*EaftYybjaNl?iCeC^UvQjDvA&&83ad7XPf?>Cg|Y)5m%kG5;F@ z{ck=2h7tFoX4l`g%o=#WFioD$_SVM(VGtEPZ_txww#$OO8f3%j{Cgfaex7Z+gMP#M zT{yDGuY(QQ}9b0cnV$l4z-Vg}z;hTX20XTf}s^=o|Q?8fJ`7x7v20zONB0natt zbB?fA)@$rF?OFCpeVV=I>|n2(w!`ZePo;)up}EcNdWF6DUHjo30*mr6hJ)QOQFNwq z@Qo(hPE6eO%FHsZGj%sS)6q^#{q;;tO_-c2GvIax*ys5XyKPr&Ci*DT-vIm9qALfQ zaE)&>=N2^Jlu`uXpi2ytAWUQWwH91g`%N!G`=wb5<)ujq&63PjjG^}Pc&KInc=qH4 ze2(LpIqmh4zD9!qS7<_&c|JECdIuy}SloAnMAR)j?kR6EM?SP<MnYRG|M{Q)`6^Cz z%*Q^j@U7P|W1H2`YH{8t4~Cwc2El_IixVJjsXW+FpB$LH)T_2<eW4(|jK=8(Udw3& z++W9hxNtGVCbZT-Dl)#)(b?4B7W@K0JAxRI9|%h~ho1lPGSc4>aj(&FWaGrbh|?W< zIt$bN`S;V}cbE_=Z!?w$!txpD%MIpGFb-LuHaFCafNtiv@fc`PwsRhchggu;zL8`f zWb)7l%aOb)5&-eB0Bl!<0TnTz0_?TzF05uCVvw?1mYAkl+P0@+vC(m;ALU?FK1M-7 zt=mo5T~VPUz&`M#LDRvgSMSBnU=Nh@OSZFn1N$b=;4>7+#$@A((1ZEP(BzHgmL=Ix z%gL5Q`B721Jb7a_M&v`pXZfv`sIi0N${fd=4&mAz8uv5Kpm7gE*@;5=Xdg_5&t{-a zv6Fe_EnX*0Q?{<<q)B9BBj}@oKc9Z@eN;I*=tq614rI}bgQ((xC<hQ#?r{_`*S_1q zn3w`a$U0r|7j>OTO7qemUPP@Mfz-u~gh4|#09`w}5J>TuX!J)!?tu#S4~*y=AaFb| zJScIb_rP?RcB}xXZ+KXq-kFM@*l$|SCMc-5E-tweq9t0Q3}2DQj|GtcBzjI6j-#tz zA93=diP6KDHw_GEw$#}%D(v#V=}zEdz6UU^4yet7V_43H*?b?`FX7(j@l*$%BCzj& zb~5@`{TOQot0X+X6c2nheY#DfS8$VJodI0{bwG;0-g?>hYTV}9*9i=~ne`mlx_BPM zMS%brUtp9C&zT^vh062L8ao9Qp1KRyq8{hf^=A7rDn1#5Dq5PqfFh6M5`_F^TXvvJ z44~JsxVI9RrK|V<a90&G?i8wJJy6Vdy5@s%5c=(IeQcsPwpF69^jvZ8LiF{3F6(Y< zc^VRh3db}k&9K-J+wd7^0hN_4pa!0VanoGgpb0C@-8>Y~)Jr-6wa#+1lsNir&@TNZ zwcH#kw}jMRKsgVtA-9&TQRkOAo%hHW$wm4e?)UBkQfOIXoW?sHkqrY-_7>bQSb!TJ z<<nms#s&(4^KSVPDd*{UG$qT;sz-<#)%8L`Wa*OXag<ci-S#3JV==gVn5`g=tY1%g zhcSV*aTPK_$LEk*-L285(vT6rYN9BVNkb!yH<fV#4iw9BUJUqf81N(%ed0^xi8H}- zVxSTtUv0%Xe`6yVy7-bZoAcnrgc~olpmcVlvWVISk<V)z8b>%}9I0$9)p^8CAMQhC zwZ73qN|7tH_XaB0rHH}LaFZ()Iny8p|BOD?SybvzvR^sB>pZlNlncAM+1tFUrvSAU z&~%kpYO`exSyFCUqnceOAlezFETt3)pgF5;Np4<iYwILT=+zUD8=664<)VaXZQYTJ zX`g6}V@J@Qz&LpX@&CY%P^V#>M|&^H&A81Loe#)<{x@Xh=p3{N^S2G@xja<DT-0y@ z)n;6_jq<o04pc_BKwP_0`f?%j%JpBNUgqGJiV+4jF^sj#pL`9YKrd^TzF%534GM20 zPri&!=Iv6wJy(8^Jh@*FO@a_uD??uZdV4V!{dpO4uzm8Cs{q~~1t?+w+FmS=9vY3` z_XV@go($_5D<GqjJb4&GHzA3-=|2MidGZ*1Gu6DX(@hl?bs`axSz(x;`oCbhP3Yj; zNFiyZt$EOhN%m(ED;ezRsi59ychGWHXK0JN(<Pu|!nUok9Y7V*IFbe^WC98>7Sj>P z-Vg^JY%xC?orck%xog#e-07t;Aotpa5x*(u$RZ>;A8@lzdzbtWn~VCI8w2~t23{E( z2#*Fr4I^khuA`MsjEOYm@i^`zmGjAPJHrDCzy_yckq|qI4x$m%!~iZ(AZkc;|JTr} zUqLz>>e_>vbO)a6^OE_FL20f}Ev6BqN|^DcdZ~*!w{f*N<vlw^pYm#v_ep0x7&185 zwxF14=mo}@$Ij&Gb8Y21(9^cST$@L8FnZnE#Dsh0ls@4$_2PtUrcd-GI6hRlmXxBG zJ$;m|TK8PVZxH}(W^zgHNh~U9MFD^&MJ*^(-i0>I+}Sc!cR!ot))TdNwG)sakQO|m z5xxGP^pTVECf%v!OfOw{N?(V{ZCw4)SkG#Kc~*mL1fv0seUAQcbfMt?Th;OZq3ZUN z$*On!zg4Z}1R$Or5=hjm<zT&}4|;T}R%Dq2UG|8+VK4&FiU1w;?IUPS1hjGy(!o5$ zPbgWK0(yEPJsaxZj(T_&E1>rez(_E-FW}%l@u{X=gFcV}kLbfNfvD=NT)Csy$>G}1 z7Av%%K<`X44O^t0R-eS)XRXv=E`>05iMnN7$CGGEm3KUOFS<;0RyLvt1;P5gFA_At zrj)Uo)Iyvl%(VIoeffj9%xdLYT%g&Blmp+|hP7;^b7Z|I2L(|ow4fc(16-l_A`}ux zd-Fa|uDj_=xLOf*3W?DlW7ZR_hnF_uwk=pCzood=TZ@cwr&ov6imceBxQ$iIMmyKf zdFh{!eQLFwr?ESi@|tRjrh92U(0i?I0BYI+@pvYm`BQI2g{zP8hJ}83obg6|yI*KL zf;}&Ml32<X1E>L!$^vv{0ObY?BbD>?kWmjU&_iES7Anz0pXwo}9y+UsD)i7%JyfNK z4(Oqkr8txr@oS8L?&`jfoRhaSg0z_88>0tn`lRQhTj`iS_vxeb?-%qq=Gd@hE##f; zqZcout21MC$+}HrLdC2s;$$d9i;XE{I)}bO*JHWV^|7WQ2e9GW5M`qV-)8EMCP(m_ z1p4q>Y&8)DZawZo6(Kb?hCgC5xA7Hx?=sIpPHo)H0v0{+0t;AKKq*BC$cqfM3mHh7 zsFWfgCuJ$6R`!7hHVbwlPqHF*A|G|8V#cTMbAn-xP%N*`%DWOgCkAj9)fw20QbY{= z5sCGg6S!fF+3AEK{6qkTDK)Y%E03`~cBanP3}5=uWj5im%IL3q+2YS5jjc6E+N^-m zAx5gZl47AMN!_PE9-;09S5tS!P?EZ*B6WW{bS-t`;!+y@$q?EJNsAcw5Ya8Un$qXq zfRgKkP`QEWU>il^qWbA2aUZ`tDywxuq*)NqC;)-S_S@a`-zOxNxW~7-1b<4aE7n?f zsl#;{&#c<ITI*sRu1j1Ql;k&P>#W*39?yi<gj_Lq2;<yz%k5~j=HnrjVpl&JKz(Qc z*}_q)xX%@z?J~DC_p|kyJ~XOE&LN@qxR<W)#u>;=D$TXKpO7cf1%E|l4wsJEHpdaI z_ZDc%Zl{z*C$pqkI7fX1*4%D`G*PYRcU#2350UJb3QG5|nypr1VM_Ox%8?ZK1_-q- z{wwAVKaZ|$PdLv@X1c09={TQ-t44xFKa2q6Jl%;~B9&&eI()i!C>}Ul7^*U;*<@*M zVeD?lkh+xLGR=pl-e`$__5{qkXti=AA8N&|md8l7867gFqC>_+5>dKmkdu+iy6g2b zSDnV@^Chc4#p9`=Z6J1M9|FQcl9>awwp9zQLUbZXRA0y?u<G8tF<G6xIWDCq`Y9?T z$FyNZeX@^hz}^&auY>u`IP$KvqA*Cu^+83O)bs^BL}ep1({H5jJJ}YPK@2R=Bf6Y= zj{x^=ACIO(U@97%LuiDEfij$E)`0-~qZPCc&+GX>!9Kd9IC*_RmVT!E?GM;`Cc81^ zpnVRW1LrzYORp<KYuc(ykn0+kLphB@DJX`Pj+7uKUE_D?WdKKHbDR@!EZI=(rSGG| z{1*;mhu`?>g1Kc};{#Ag;gK3Q_1?kO@}P)uwgDZDYQ2bPify3L4R9VGU3dF6sNSH% z5LaAV@Tcw2Q2=!BwLpBLJ(hd}*EknS^3mdj`bojt{QU_JmottJqyl9~lV<oi#wiP~ zV0qf@bPgb0>(*}fXgSZ~<b+G2(AD*e^uCvJAW)My7BeH!@AAY(>~eYo2y1;~X9k=1 zMi!NQi33q@44{m{<4|aR#_1mhbV=hF6rVsvn0!$9mryyc#Q3I-K3cSho$W8@YaOxm zRr{G6Q*3<-=`?maI-5iwwK!e>Vd5;=#L!|3#5!4QT_RSxH8PX}jeC~9^EJfmLL}G` z(64cKR_Wlq^fi{iP;v>ixQ3fp1@`)RP*FR(5koJ1M)!|nB`|21rc?d7%j?^f>o`1- zkC!aqH2n~CKizRe-vhw9V#B&_bnT{7GXS>J?;lAn^&{*)06<@)!85g0XeW60clSHF zgZS`~n4@F8NYWA~^*VXSaMM>z#(MWtgrffol+UJx_Br#|D0lQTZ_rxk1Z{2;1%PA8 zGx&)UR0fI1({-e*#2DFD%uY{zX*-oTKUI}0K7EKBs{4k&2yTZ|l^BnR`^u~yuek3A zCfg}rs6xmM4s4i8n$4uj?6}mFPL>PCvyP#rjJuTZT*tdjl=b>m#p&hwhZ`+}z<JEy zWhd?yx$&N&5hs_J?N9Czj~11AQQ?<<I_gHYoQ{^yGQjI5b_z^SaqAmFkm4ZDf(V^4 zctYtmBzIuO_{Hc>Bl=M)gY6XCzhO-u<FaK7e=`RtZSw(d>NyW1o{v=S+yu2vWJGZy zns&9*7ac4Co>>d9?Tw`?Alvo0lDG?HMtf3Ddg-dKb@fnRi6P#VJEgobX3ml~Ja)U3 zP0oDhoLPyOjqf{-HhuA(u-SOXab&$<x63?<Bz7k<pzC3}NgS=k6=-EBRW_q*AK=vc z8H)fx`T?7;R;kr7m?YGtt4I~EToS|}8l)tv5h^C7Yw>x~c**fzbHR7I%w)?-Wwl*^ z1eQDvlkYPA1rTza-uzcm7bl?ktuFl$bfKKyS-Bb+K3ZS8BN^U?;iaWNPKE;*URe6m zWSCuraC2!W8GZu8(@UR9hM&Z6cIi(roCe`G)TlPB_6yqST6N3nXc{)MMmtShv0Alq z70gI08j|x6y3G|scke2}hZ7$abIZouYC*EFv%PjVFNx%<?+loYvY>>`j*g}a&~#(9 zQ16JWPsQXEWE-sr%b@Rn#jK0`MmG{e<@+Q43TI%}Q-(6PE|GFbyFaD2Fe1%@KLP$$ z7e?d?y8a?AzOv(}GP{Z8A)KBN#hv(wuF^KHB&TT|GZ~Z)ftaEXl6HlPQi(!MQehPs z+iho)%TCF8%5qkpWd8dgqPG(t(TNAK%{%cC%{Yjy-ieRI)}@<H{ED41thI%e=5C;j zGZ1Tcb<1fm5ghuHrrBLRXd!fTqfHY=AHyL*%7Dg6smc&9PbK#O6}_!4UIp>8liasj ztv=DYc=dKhX@Y#SPEBg{d6LBlDhGqcH|*8tn<ta%^GH~}m1@N}L35pto}*j(*nx#H z79Ex{L)*C8qb=*MjZTK1CCz8hYe&L8wFmx!L%`CmMr<5$C9yIQ*9mp;YFn7nGf8ob z6tUzg64<r;>flNi^jjL&;ov@cCMojG?Bw$cFnNO1kKU5l`h_mEb(KzH@*_eb$o<=z zyD<#Li=bPA*K7l?xC)t7qqS>A7@(WK)E5mzwn$K$*xapaXL379x7@a3=H+&yvdLnU z3y9NNnxFd9$x=?~OnhaR&cat(Dd&6+kKUFu)gA94Xgt{9Ozh3EwMd*l>}<Uf!NArc zMK2`g!GqrdGpWr~lD|>FO)D_&3QA_l>9#Jgx1h0?#Jyply^nNk4V9JA(*T-Q*=7oa z<*%9fn_LJ@rM;hNnwJ#eX<4WcuW~`^e*wn1q*O92_R;`)E#n1ZEc<7EezA|vJd4~? zTdS7l;_YjibW|_F6TQnzJ?Q0jro3fgX{~gt-{7Ga&#(n+oFkWdJ#N~3^EVW_*WYH0 z0#l^%A};*Ds<HCui^xE8@RL)n2gB~gk=5E-5GKI(SU=supmG@$=)FC<2q)DRk1gy~ z)5zb*GIJ-cP6HzeQaZ{4m%ytNfO%RL&XO&*u-z5^{Veh6a3!kjC0bhWlq9s7T2t;) zmzmq9i+kJMmGt!w^$wk&rQvZ?5bf3GHk0Nuw;C#;0;n!<PP$ELj&t&_T88qa)Rv)i z`Ik@<-*K15A+18o#6T~gfnz7}CF!!MGJ0`o^dpvli@59<Z93iqga}$RgY8_ott*;R zS=O>}rF03gy>1|408J2gyv?CXLrd{2m~Q%_S+=n495e%O?{mdZ_6ED8@prSzQ&!#u z4eFA=!nVK|O3N6I0-$hjNxHN+cup!64~E?UJe$7Xtv52O%>>QU8>gj>wltbW_a#7# zkN`=`%$2=f^mRBTrFEom*khQ%(woiLN~m9fuu49s8AkTM%<Kjk`?LggKSDu|W%fWL z@R`@sI&Cd;lR;}>Clb9{G#3UJZ#jXs73a!ERgRNoanz(eo=|f?%|Mr77y2)jLamF| z-$SbV!PHuR7l}naO$qU$Bhqxcn-;vw^k2tC>4rph<FL<*1$13W7ErYduk=!j@Om#W zS<%&T)K6jOIzSBZ2bOsSSCDPz&>cg*S$h|KrzCS{DnjT^DEh*d65Awa_*0he!h~q5 zUIG|ZL7acl-Ad2O^aH#SmUOPM&ycd6&NcR2`I7$n8!37jit>0og`J+0F{j(-@u;qT z?OoLsgI>ACP49V!X}x$O%}fuN|1r?Z`vD5qHc&#wY3;iR0a`&_+^6OI8m*G{=t?D) zBJt3GC$ya1Y+=)JQ4F95Qt@;t1N}FK@G(%>;dDb?^rN>K;{&>8ua@&7<Y10TP@mUF z|3kNW6A9=Tn(Q`YFqj;GHXHGDlv~T$kBc$r422hNp$K*ELa(cl`%o-Q;Zz=pF~;%u zUSIl&^N)YTn~@!zQdY2CN*_G23mqMztGqalTFx=7Q;yr@n3i({g=n9?P=fEn?2T8s zXgOhobM@O?eYQTwpqzH_J}5bw8N4W`k&Z~WC9_Xup4Wr#szq2qeZz`Tr3L+<MY{83 za!CS3KRYq7S#Yp(98Gytfz-sw0R*9$Clh{W(J9Hp)<i%20fxVLu)@GA-Ol>DcD=<% z47M(N>L%zJecl??&zBVNgAsPCR6(0TiQqo!QawWcl3j+J@b60A2WeneNF^?iQX+}# zqbMnhL(ba*JyOB1*acD(euavgloEY2RHk7qg^~79+3?8Mm65M_;%j6F9an5@=RhU4 zI4;Uo$Iu3genU-)nhVs-EKC+QDuRa2Hrmz=Q|ZGe(8FouZlVjv6aGz6FCGM}?xP>= zWA57a<yJBH3n*g^aamtQGk1+6vf*}MUJ+`_^m)8=_wSjNNG&IDKyGBq&G1P$edAr< zv}a@pxo&d|ZJb9xK8`L(Bej1|uN~mUz+;*&16HlO()(R>Q8MY+n>raoGnhGJU?$`K zakaU|<Ma9rp=xW5N3An!>v$~(nH4fx?R91`Sg)Tga2%BmsD|jPNvZHpVh|54Aiv=; z6~~bHWCOghStozTn$>$>(iQz0*QCwtQV{DXvn1{=`j5TLcS^X*Q)&(#BK^A#Qp{X_ zHE|EoF)v=Xni-bo!XR7V+l<bX<P6?R2Jb%7KDZj<kB|<08&5_T!}m&v!E4<B=49{5 zb0<GLc_y<<?jO8J`T)ub5ETWM!B31Qo3b4Mw^3*k9RRx_eQ6;iOnsohYC8vC0(_YV z-yb}qyw8z0$Z2vG>#09v;gmTocvOJhhwAk~U5J?#uOwY|zq_WU@#RNH&SfNT7KP$g zt8*9!R20ky^9!Ko*(Q^9W@UI7?9T@Z7ATj8LFoN$!_A=u8$v68Zy}j#m05Y5=j3C| zi-D92H04%~W4EkgzzTur%d4MaY^EH}Z9s=y<i|1|w*i?8pk!nBNLC59BXs;84SKjS zS6c`4VA0lD=|bIov5vt&Gt`v*$hqyy*e#YfXg|o)evqsEU@px`0D?xi%<J=z&v0J1 zox%k>?c@sPz5f~cibVVd+Atpl5TtfNx~6@?HeG#qi%g@>@8oLe&uTc1+4;-J+5+MJ z8qgE1^p(VgGlvAcsB#DD($n5VUAhO?_#H*e&vllcr>oyi>^*qtLz!2*xhB_CZg>+n z5_#HidUSsd3Q>l;#UJA8fyYNmS2GVY6!qwmJQMe}rql07lPgyT_9Ff5MBxv!qMRKZ zka&;<=+)<r=HZdAOi(EkzQ7YfKQ&b9ez~J(0^UP^3HfHfx!#`2ylHcgu<z<mXzPGb z@8gK|XGifw5B-R}8c6$!sMSlSA{ae>bkyUyo*5Z0W5@8v*!nq?o{j6QQxT2cV@M$~ z-g;>EP$O;|_3p#NVY=I}82qV0Kb6?Sx}go1PI)@%w7zTRp|>-)c~>|3_x>xY0D6z# zjhb<8T2eDkMIY)SFa0!K?|GQ@t|#U3DlmXkNC#f~)kE(DIq#vL;C`N~8*-ad7;)l_ zM^!MhnQQ}<s%#$dV#Za$QTJoL%=~N1{A4zVUMAi2b^W|sa>Q?D%4s(z-#TUpuu#wF z(Tum*S-$9a=p5)YXmr&{Mi$LIV3!16NA+9xcAn>@FaC{<ju<?JH{!V80K2xiTV6YQ zpkt^DJIoYqz`Qt<&_W$ZYSafR`U8f^HxU2}-kTtV1zzgVE0SiwXl!`XOA9ef|I#%& z-t^%&aAoiqMD^m)2*^K?9_$)>y5xIZ>~sm~jGjs?+o1;QIJ#l3zuR_dIXazN*5^?b zz!F!tVbOG4S90br6Ms`}0Ri?EUYVH5ZVSVci{uPmz(+$@baM&}DXZgy^_IemK-|W^ zc<7N|>rT&|qkarvz5}`JTnmrybXko@qT|Riq0nvKb{T&GpebDmTS3>2j@YCyJD?|Z znFZ%+9~mxu3@9QV`BEguAMN7t`iAX>3M3(zGqUeitK(o^h{4m4;0fj3N+zhw`iVEL zE{l<6{V=@^95TpK<T8Jca(U4PqkqwZ<X+x!uOQ!r+h;Ax<^1)N$s4Dmp(QE&;OUtw z_g4(3%d-K2nUkY=p?kVVQhu=?{aPT=go(90sWTIgKvwXiI&Q4)S0Cijq=M)Dg6a_f zE!-&?Q)^vJ`N*Kw^^3u$(Dy}-K}=+b_b&pPytm%*!G;v_fw4NK=Ys5xcOm9o$NN$} z-Y@q9-thxLb{u3l59P0)M2?>RV({IW65zYU$jdVksavB{LicvF_*ZmnF^S>(1D=&4 zkh^)jqL7tH?iSRg0(5fJhz4eJKbTmK_Y<2%)qNrJNm2{Y0`5Nn^ip^V@N_H{<W+6Z zDXrDwaHJJJuoLIBG>e>^P2OPLdO8Y~rcY+ytamH+SET1gZ(u+c=+-e%wLFCXz`~z} z0u1kT(8}VfNv)V42enEQ#Nb7oFE=yoTVG%zS)1|TZqaMFO^e5YA|HyzD)S#vcktAJ zg~HNVmPFa<Zh-}f)1oITFSZ`$lI23|a8<efS!HQ?telh6l~w#Oi%~WSn*0dzEliK^ zvM87(uRh|HAahIuGAB7m?}bM~OU7NO2~}BZ-1PH8rd;AFd<N=BMc56z@?F8oxMP>Z z&N2(TFkUT16xsUY&Q0(I<{M`6f$`QSFHpjk?}V*xtqAk^#!3@MC%aT@lah+LEPAe8 zjQIwvMh4$_xC}4CyGpiJ;;D>IKi|mZv&C@>UQc+2rQrFk@!AH9Z)|I$KUbCtnz~Tk z!fUBm1*x=v%1k<vd%86>jEM!%xPM>)qcdtWhRcKD=1Zjg(J<rUz<lIlpnq5FLDea! zPF@KM_sIQzo(wUgEApvme9YX4Bbq=4eK&Bi2M-T~e#Wf>A+Rj&xV*8Pyis^O(rXSa zwv;JVF->W`fajk=JL2$CE%5#lq^C39he0>r*+St11F2Zg-SSbetwBdlMbDGaeP*?a zSIdOZJ@6r@WxTTbUn`iq%4`3M^wL&Y-gaa-5(wi7fu-fLF?|!yNDNr=v%ym{-2!PJ zdrrWtOEWY*EI!=fc(1SqB-*6NXCisy8j03V?u)}Tb+_ZI&}Ms_%uuT>U;v9hS_Y{D z?I7mxP`B|csNhdI*jd?l<Pr}uFs58uw87+GREx{;4ZNd4kjr)Xb}4`T6y&p5Xo-Od zxE(0quG0nF3?<S%Ht`obu90!~2~e7fA3WJAsE>i7ZYg}rP#wnw8SzIiAtN@&@yL$G z-xpePYh2NoxN9JF{h_=ewax+p67$zt)LKEkmq&?muK-U+tswi_mZX6cnSfFxjaRh% z^?5DL6HtmAA1g&d6+0@(@n}9vvxM%uMtB4m(h!~Ga|>JBiiaw0i>rdV#1IGhwhULE z)Vtzp#ci?P64ZCXy~XHn9KyYMkmWZ($x99Dz46dWTO39zGR!Z9*#jb!Vb-Mj0aqLb zfC)!Aj>*Xc=p4s=BNNInPAG4I$dgRT{>~nqP?oX@#q@VO8zvO!?~P2@ZWN$Yl((|Q zD92SDpOFfy`$Oih$Ya=*==KbG?}ew3nAxCPO-bQw;t`>|gm8ZAb=E~+V$a!Gx4wnl z%4G7=?lFmvjdbhMG2QC2s7AFSH_na_juN<aCldhG0*EAIDoPk7GD-Qc4<=}!PS4#y zgI-^Art+3{`U|BxrbV-W?36b&+ra71aGK6ya_=nY1s<L_W-p7)9?pDE&QRK|YMtOX z(?lI-<gH{H7W_ZJoCTP(@`@;!L;^P^XCLIeHIXy@s<g9^c2>@zFW_;4Gb+=VaXl*? z)d+egJ6d?JMKzFei&CsfAFI<ClI0d+0g<Cz2EB)DXFWtV@2HqvjrbgwZ(xp3ddF2& z5PK5OY|RxXKgR7UCBjEPMQQU*&R?>l!luoBOCFyn7z*|0H-OyiS{&>Gxd|W-T;fSa zA?Q6{CCCBTeG5{AV^9n*JMbRfagQLc1YTm)*nAy1j*JoyZ7v3yQ|m6wUfEiq!r!nc z+eq~VnD}RAM&|+d=wRE~l&C|`oIET-4mlGyOsX%;yq8ZX3NffhApgXxkMU3;`6m<% zVj#rSh9qU)Bd7pSg8*uckie^6r_9XZ2v8*wXY=fq=1fk`WTXdN^JThY43WmuH@8-x z(f}Y?qXe4%IO<%X*IE+<%9NthU!>mwf-Kl2WvUtKl5xoNAPeO_<4NReh`J5fx}Ri+ z9y6#5gI)3z$26R0p}RrXV)}rbrp&=8{T}$xUHmAKGaqZ1dzGUa*eQ9m=AfprGn$FJ zHqIVkdUIxb^sa$Qvm)K$rAH3oHpLlwcrLnx-1izDRE}PsxC5s-6-okPuFQjJHv`o5 z2-*%?^3*M6HhHkaf+x_RvmHd2{2tsx#(TnHpq~lDgglMDbs)KSrymye>L}oLf*G$_ zl+0Kdn7p?`3GH5*`GRiGdD*V_SlgH#IC+O%)mi((h*`Y9X9_f|_{OnEm59siwGF7j z1s~(>9>wfAAD(vE!nmi`1lD1Pd_Ao=zzo+L4~#4<vTpj_Ye^h?51N><-7JvKNGvs! zxX8t%|Gt5-vu$}n%DEFm>Ylk!eCzYq!?R^51$QV6@_d+t22bLq!gcf<ln5Bjr?0<u zbybV?s(Q<z9_F1i4lf1PSCAf_tlu>apYMF8TXliwff<QupdyWL5d%B$U<1LWcjsDL zm%Yjw3g!U@;?of~F=-3Z)KLD%cvh`DaVTXKzylnMm4v`KG2q4nQ90*PFMOW$7AwFO zR)ZzjUoMOI<Xx$FSxLpmcuN<yF95dXxADMOCSk3%g<CFV;O0mWizU!0%BEsY%4u^i zXkFIdTKzTNuH#R^Tb82tiU%WZ`rZZIa=ep-u+GAx#%c@5YR3`r$(K;oN(lv>ALAWo zv}CUS>nE|qjeF%9LnJ!YZ}8|qVA_v?3Gw<Cu|G9b-CyH3ghB{Y<JR_Ivl6-WRYctZ zVI^enb0OARw-<3FL2MM^p!;;kA?&yt@D4qenS_v#j1l{u64qTvT;lc|yld_Nwx1IN zc$##iOu%7Gp&hRNtg8w>fp_E`KuCkQ{Wt`)AeOJOa@jg>i9zB^QskN9KAWv;jWP^f z9VstY7&0m99&DdJ%n88zH5Nzb%mFiaje~WP7;MCPSfMEiJf$1_S<BrjOQ*4dvA_<7 zM=`@=KD*(=VrTV<Ph0|ny7zkYea~*2pu@C2ATA);YK2(bn{7n;LJ|N{2Ksy*iB;!9 zHV{B@LEMQ+P**ijSH2N{qC}@862fTZC9H}oWV8_qR>9LzZCP(8&y+BX@Yy!LtmSfs zY|-)S;If?h(6(9<AKMPFk)FVDO^3)Cy_CW;I4bjSR6Kf&&LyLxaTmiEAq=c(j&^bT zoh%M3Eo3cm08c!DC)IoLSdq>c!17}7Brd~Xld4n3HmQO&spRi9sggXyQuVPE_l++r zTcbd;CMv91DgLY#Yt&q)Q(@JoBwlM&i_^J{(abQmZ_hv8zHb@6*}ex2NzxwEzD3wR z{LMwypv?&K&4wVKR$bDxdTdLH-WF(tVGn*7-(pS4*4tq0Ffe}6pU?thhu(tSAoiMG zN7uo|W%!eGp}r{aYbb=}7Dm`zlx`AndmHiSU4n7XI6e>qKT9wfYc6Ro>~MzyMVR^T zF|cGd?m<Au2V0Lu&HCDtPWceCa%}5$hGu<`fmgaMf;vK&6@Pv~+k+t5{E=dF^v+aX z!lF1m@73ii2QZG4*D41XjC7MfwcgG+RJPLJ?M-fX(Le0PnJBs_!Mz7@@iuyEf{2*B zcS@qpOD)AynC)CZn^^ul%>PgDspPX=dNW~&6fz=eSi$ays;6h3XD8?^jeR&>2llcp zWZZR|N*C&R>Fg17lEy1c<eeiMa5HHRB3Vp__9WpF_do2>opHL@uONl;*cKe=)9*eb znc~4ExAMw|2I+M-wHN4Dn-Jqb#eCi%O&r~OxjCla)#d7mPNdI{R6$?ZgO#FgaqS{G z59qL8KvD|Wog<b;OAOk!d(TMQCeZu#jBV3@V4Kc4+DF<nh2A^@z!n(k-dFU-oX{In za&==wXiPS1OoyAUovmNqLDB{)OwgEH5tr^+%<VL%CvhYuK@BdvjJ>YMUe_Z{rf<H& zj&Z62efgCU^!`o*XYWZg@ZV;STyLYFuf^XX$)ioLj4X>XW#aPhlgpxhT$FTNl&8?8 z*TB51!$ec<ve1NNw2-;9_tB1@BU1gLO3hv?NO@Ium#{HI+-n)A$e6~<efV=r(C)&o zmXeOKn}8#_=g4JD%e1lA@q^ukJ_(?<;g8qgcBTb?jsqtA-cLcUB=2XKPG9={RlAor z|2}y;Lm1@{<mFqZN4waT=#V_Ubvl)<&T!>-x+aA`&c^mTFVKtslGyJQ<Q(8PpN4Mm zyE612hQXiBQktzATHzhC*e13L&c$~gm1f){UyM!}2@3Z}samyF{sK`jw&pq=r^O&{ z0T$1|+tIBCxhS-WxqJ^dO%J&)xQQz+?&aL{#KDB?uAo)N?Q(qmU-1WU;=92(Z|C%? z<p=Snr(%W;cZN2bhSg>(lrd8;!^+CoKBf$-UA96QE;Bh^SZ&4g>U`^rDBrr$q!ri2 z@Gw9>Zl3zx%h_+<KnHn#ch!#U`QIjXWJiHXM|3qgQuvl~DP?nYXj1}(>0?ny|0W91 z4C`)#l-D|g_CcBCi2ugrssYQLgx(=|oI87LEm!^GjSHPs$17CWR{ZBba~vLb%mp$Z z{lOONm?PX?+ynp0J}rP2P_f5@zWI%-KXd9oZ0ON)`Vyzh)KUbA=8W+S=}g5aJZA?Z zw`CUI-r=&`U7RZkPRCJsK<NU~uogzD94>3K!Ku2eI|IytBt;DT8VR#q47`XWf*vKf zGsS+EDPI<d34i6rl~0N;Fpn~OT><)qSi#^yPU8Q>ybU!uUw1zd15ZK3mU4YRV-U)3 zx+7GvNGQdhDBd`M{s>r`9Coxzd7a#`W1u;Vb5nB<9w%y-(mOfqBPA@Tu6~ps{r0+k zF|ZI1OK5VxzIBbic9E~2wD}0-Mo}MgXwd<f3*Wos2pHgwqx#YEL6;e;mTs`u<%t1y z^tL)reCprPS3%AL&KaAtcL$~)-Qr4Y#~}LlP(^wI{fYEAh&$2`T<q^OA^J*(5S`+t z_k4713rHWH2mrt`=F>7-M{*2jc|7=QR=md(HR*^Tpa&br=6%%_^Xf;mAus)n?p9RW zTg!%~U#;synaD=Rs=9=$h6<%pem>jpyMX7K(FUA}W9-To1Lv6NM=t~DOdL15FrRJr zL7zhl-X=wqbtv?<JJ~JFI|zyy=-mgox0EWe?v2IJ$Yig)Ium*&?iiB(+?mFDrIYmv zp18TDS7P{^!2tLQG}hyz^M9h>e=Em)Y;^mtu93G5MCU-~gj~>yT(=K9N4`KqGw_V6 zD)#}_gC9&Cm<`!!2oDTKrzE>_)XPE3q0IgPT9VSSFQ5G_E+e`605h}Qm5WZWK^D~! zdZZiuz)^#sKYM26lF89aWq$k&`Y6qXPfadh*j!Z`or_m;9nSxIUJ^Amql~_@6<AN_ z_Dj&rJJIpTHc;thyzbR<Vo5eHLcr*PYaGB@bqBE4B>&=d3dp~mT!Me`XWSY8<^oZq zF`~#F<==c9Tnpo0^C<u3CixeCUu;XsHmy(7wr*T7mUmCh_$KeVyT38UXM*RXM??G~ zx1aOSr90RN`#g!?fitk0@Bj@Gn1_u|Oec2_?YgW}c~rIyAagL}fxPpsY6<?zSXtty zE171v*a4$B9f{fkL~X{#&_}1~KPs3DEO=f;LKs64FlssdY>yXG)4cS_->}orp+_!^ z4F9t~{X4_|lb_=77qH>~#@J6}{t$V8Z|uE^^Pk&ruHL}YiNC>%UId!W-eziIZwnp% zZ+u(n0DI@sFYtXk{gegs>0j8pfWF7xbLnyRo<}>`dp>=gy%*4Z?43t{!`{X8-`Tr_ z{_?*OL#MXENuOp>6?8j$SJ41_FQJ>++f60*et@oJ@8xtgd#|J`*?SdzfW24KCG6cu zE7*H2En)9<bOC!ybRK(eq6O@|ndT)>*ozDHG#g|0;sPu+vQNCF;{R#yTL7ZEu0_v$ zfDs30jHsxnV?<+uF(jw~Mw&qw#Kh4-1mr5}2!k;4%W#gLRCI74WjL8e&8H?!lbBy^ zlcwoy;wNbm5DWh5Cz^yrn_$9C4jr0cC4dRxytVc|Gt8h^?`!VuefM>6xzE|(wLfR? zwf0_nEur@}_=s}m!e7ZFPRhb(<nd8_{E$4Nr32vvc|_qZp@BR;i;w%rBijEKUM7!w z31$5oEPLjv0ELF^96nedL^LzNJW%-?a(`B-4_YMotS3GjRQfsQiPF`1^cj@NRz6j& z4_YRrxtr#q)dww?e5O&KaDC89$!8SxiO>hFk$hy-CsH4jFZq1^3h~kDg9;^|KNFt~ zQTjQ>5;n(Q@xunF4I&VW0<L_eTL0a~2}0tp2-)b0q4a*!UayqgJf4uJ%GwCe$NcHI z@vL(G5)Nfgzp5Ki8#+G~h(W~??lMrH+S&-AdoL1KXzlNk=Z%0{KiCSA_%;0SNM|8a zCl5spgok9Bmz7bTODM{7R0Mx#gRCx?1U1Pt&nu%UzTz8TzFg(Mp9`~M0O@>_R2qJ& z-bxkj4XD(mUwSL`zL#=7#%F5vXUXFkLiQrf8wy13e5ltXsF!D)?^U(LkLH!vMnIK$ zLa%Co{Ir>o<Xqmq2?hBk319tkpdGe*uU^qcKR$rpkzWSjm+r$a#@p!QpwZ6|$?(*K z#({<&C%F9zXt>7psuPkaa8=JCBC<J;mnX=$S<tA{6D%@rT4)<Pu|d!#B+0pP;5jnE zqTsa72Bq_mGPI3*j~8R>8+S~oKhx^0mo@erA`)j2b#mw{$mUDvAV_qf=MWN-><a}v z1YrIr!M6$X|0Cr8wzEO*srBN6Ix&#_LdAWRD!zd~qiE9i!xz)5*^U%t)fHlyb+Xqo z>zM2;=a(Ai7aD#4s@0ro)#}{#nd5yXO-DDh%blMooL5x#+b+K-Mm^TH)4=TDo8QDx zXS>p_cD5=MN5rU_-W>);jB<BjIJle8Rl$F=0hR+y#pVsEOO@3wkkzHiA>Y~sa%Ypm z*-Uaj;maMyr7tdtC37~(oy~HL_0j+iG!6`0#IRY0p|$>boCoI!Ks~?#fY$)_0z3<_ zdna0f|7n{m<>5AP1#ks$JHYJ#w-ek>aJ#_m0=F03UU2)s?Q<)UzhM-eie9NOUc^fG z0jPEvn8;lyhYam_v~dSw=>JS>FZtki>E9yI9NxHY_Rc;$+Lk&YYM>LszQ6opAC&8O z1k3ID2wFPk5mH}opIo7R5{-RQy^Hh-M&9u#JRbmP1*l6^Og&S(K;is~wBFaG_5R&2 zYs5{8GtgIGK}^yMwSF;o_{D=r1AX?D!ud6#tl5sY2m<q-4bD7(6o5ql%K%ma<O6Jc zg!D}$v~?u75#UCE8xC$bxLR<v;Htq@gR25p1+EfYWnkaXHrfII?*`Zl@P|kI`X*HY zSo`$_c@OLdf4_jf^ZWj9Y`*11GSRBN6YV8;s^~Y<rl;ef5yS(!3;4wBETBq-@R87+ zr+}Pm=0*xZ&wICO_-6h?&%HqCxJ`ZO<VL_~<|3ikAmS)Wo1(&5v(WP#(%`3vDFDef zHr+^ar^F~7y6;g1cxE38&)C8XV{r4z11X#*MYPn&wMx5Kk-}5Y(H**~=X^Lc@gKCG zzIuz!{v6q&TmD?&7G3Key6bb~`df6|bm2~#!Pr3=JVP^Z9uxUPo)u=HTpPHN7a1T& z{VPKHX<fz(uFO`?c;V<C-*(=aJ#;(o0@2{*-SHw?R*e_<%vNF6bJC{QZ?wKmFKTO# zNZSYppT{NNq;e(UPC}S-p<30P6oEmWk?^8)Cxt^0c;SrAC#jqkCF7F$?M7u~3-W{X zj+--a2RTS>(bW8uL4l$!yeamSB<-lFzHLCoM%QJcVguRia2Z}FTyy~Hq>O4q|K~9q z@dKcAsOM?o`KaW1GxdC(c<z=w!w%rh*k_5T7#m*r6wTf&e6t_@p923q_#aR%OX4SD zG<Jbm$T)!4&hd@!6jBcmtyaB2Zq2L_*%^e380R+irrXqRQ%AZ@W)?pLui$QDmy8=$ zWzwR)RZsk$M`^w>W<ha)p2ST<)jWOh5V>bJ4IE__zSvI#fj#IW;o=;urf^d7*ZT1f z5W(-pIVA${`o_sElbl!NTh-1h3NCyPn#J_YAdV}Hyi5>YeJ1cgbnY|WvsWrEY{swR z{b$JS<Xk*i{?vQ2%svx%vfTHy?_@c{t7<sTrWC$;$txioPHyU;gfKgtujq4rH4Ihf zDR|Cz#*E_aC@-tc@QINrFCw$dHwlkDL-g&SlmXWU`8K{t?!?LkvDSAQJ=jb|chC-? zOJ!NC$`&e|eH$fYe|?x}Fj3jY2(Q3n4vhj_D?J(eudq?UDcwe;OEMDXvs6JWMDd0` zo0*yeqNX#@kjAg8yl=#K#(*si8$(T5jAj^v>y0*IX#-7bT*G*UO(B%ji6Wh!;hW1O z;`6(oAeMxMteY7o*Lx{_u)P0W<SIg1U+fX#<{BdJujS1%mh$GPrDz)$4H#S{?vIxk zQlhk(W?O&Zvri1ZyI^*wL@DXrdWbax?=Il21(8i~Zi$*HvcY;bYUYO9-Lp6F>fgH- zMXB-H!j|7F8E!1Sw~+FCm9UVJ9#9vxXFsAXU6z+FF2vU7^W?p1vl4OOw0ydnU#gBz zS8+k4YK<A`Z#@dV?HMjT@L1M;Dp#`7wO*Z>ZeE^~o3rAOk`Yh)<}2JQQ{is*v}$q` zi#LPtu9n;tqwnEn3MEek%6NS9bMhHDDtj5f9oY63+(oYphXt@QT)yQf{2#TgkvDZ@ z)J;M=KU-zagVZqhSls>9>}#~C%mP}%gE-VU_fB&0WnZIazjD5_6(`@Iy2%SX&5rMG z=YpN42)QT7@m(~h08ic+4in`=_euMw)$_?il;+`h8L<;`o8!9}c38799Bs0BX4i$x z+r);=TTZ-C{k&%iJfL|nPpGq3%Z-BQ+z1j&Id3_qT!2OV4$;B+P>g-AhYQ#2JFeNU zUfkWFWL27Xjyv09JQI2v6i^;}XWel}yTx&39QbckINNp3hNF5@c*QtCS`}~Xv){rg z^~W|$fmbClMm&`_Ml9K@;&enmvI3YGTr4~*_}o6tZ*#*HAGvb-u<HCfc=KwnlAEws z#w9vi<?OJkO4Qrn*f<Po86D5{ZI~{ccv2L*jS(`cP=|%4>JvR0@R8e?<uI8knuy2> z8upXB;?SQ}^yKyhbRci+^F(;##0=`&f!qH;2KgrC_#iZt&V>|ing9b%W)@!lUb@_L zBJlSE@GD!whUQlueR>FfW$!NtZT!O1lwX;F?g8*?15iDEgZv8S{`dJ6g2Ryfij)Tr z&L)6zfI@&Z0LuZ)0BKMEQ2YuO#*0|#R{#zGoOt@bgI|ex*2k~3J~Jf0GW!|QCm4B0 z3OpAA?0Dwy@GBVm#`qPI?|+J4k@9W>96A8H0Qvxw;H?G-2e{?gABtb0ZDfG|(*TwO z6hHd|@hiT~vFt42ZKY%Z#k_}b1pPprbvtm^PsR;*_RG1*ZbOQU9RsArE|gD_@x6je zNe!;Cky%2ek{&UuE|MeWP|9)8ql7HsBb3g$is8s<0x}&H3aGOM%j0<e49Fxxu~E$r zNM)5h?k5y*>*JK=81cCO0s2p`<~W$g3B&NkV}T4q>0>u66cD8h<RwNRg>YQbHssL= z{A1TUB=3Jr;ulD>3^X*Ks^05lC+$_S<8f>G_q#>0szBXC)I#LAg3%Ors&dt!d(nhw z1Hv_a&TF`zxWt*rPD*0>xgg;)SgQ8m3pqf7bq5xw@+`Nh6UEF-s&wd&aM~a1oQarN z&V4*^OmWIZGR(@d1))3`N`<M+S>kBzMWQ5=$hCx#+^>l2b6M`p&ZTCIm@bZ1lU!MM z0V=_uvK;CyxEJ3Xgjtds@t+U6IIO?Sj*idOvf8*ws689++6KiQEpVw~>ybhytZS!m z?#JHiz}#dSDWpKNZv;g1SFeql@Q&dPZ_U17v+((0={UF&m2%g<LM9N|)@ku3?G|0^ zd-1s{&0~j_LU*KR*@lrTyB&lZhS)$3nY4P6#IB25C1WS>4tyckf34&$FF7M<&%y3} z{1NZXV}E3D3?>j&MWiHL?o^PqO%_<1rUoN<-t-A3cp1}k{gPn<zx6NOjhC;FOsMZU zJ@p8GcpB3wiuxn=P`)AOQJ!%rqZ)5V?y`pQwEHZoWY^Sh$)TS>MLHSbWN3TEMKmzR zo%3KE&yf_1p)zuAl2c$<E!sThMrGK#JgN-aHy%ZXty>%&flNk-D>4{XbI%yziCsQ^ zdCxAdV2{th6y0FeAJ59(vO*t5aLC{r@Qc6Xo<{{#LnOn4P2C3gpyr@#c#K!a*~IAM ztac%*S~vt2PIWM}uV=I{Y5<D~@aT%58XE@o)^VnY5X7ByrfA#gH&b|T@82vn(lu`A zD;f|vE=qW3Cy~N^VQ1j={+T;{{G6PZjMMDEd8!!#yb`&5Pk@O<N!d^A`S?{TZZ7a# zy}PM$27DhsVBS!3P|~)BLOEip$~&pV5OIMvb|T4~O8H9js5>Q2ZKj5DaN7CFPUHs9 z10GPyfuD(f_I9qWsyju7X(h`-5rwZ|HJF`}$h3%NpN0!{KcjbX$<-kg)dRoy-IRBA zRkk=qgT{?lLipKlW43sHhIbxtpGZl3f{0?dPK^_V<GNF!ZC5(Csu(UFFzm$4W6vi; zQxLz%fwmx<09bI4EBAs&0j+`5t}ufLsayaS$h}IPK`V}#vJ*0BO`J^z&vw4Dh38tK zfH!baX(S20Xo6_Y5n?n&w4py3TC+7s(FxqPv$9R(HZN$87O5>!;f`IRSLr%yajV}B zu-(aztU5$0b*N(OAp4!pdIKc#{JG)FAXjA@9Sf(N7biDd^mbTNib^TV7Mi}N&8ocC z;?eLh-m@Mq^gJdG7%)%|ECtj$Y@t$%!VxOe)hUkdqmo_3$X6%^3v18>8a*bxe}msK z>1=<IbeR1jT*ek)jWS%u(>#;qGG2hek`3K&I^n8pbyc3z8`YZX)nv~J?FhI{LOQC* zo=7J(c9pYIka5dVsVGioxZQIf@iOw<g=XV99QnZ1;!M{fOn;kbWJ%TcY+X^+PtLA0 z+$nRVv+FwqV#Dw-5EOCJ+4b$&z-V58q<AE)63_Ce!~=NRb`)$i3!6~%AENuqq@YY& zWm|k@8{6Vm&P8#AHlg%>vTKlqN|F7u17x@HxhM3WvJ<hO$PA2u5?OThgWxr;+*aVR zCgN*+<vA`K=?Gsef)6_{%O(^09+rj-pc4&I%mb11&3K`_Rruo$^4+w0hQo*y*&yC@ z+9gBuHl8Q44y|r$z3*uIZ5I11U_DTwu$xBFFyZL%hMe|~ub@z><QwAkJ$yx^-K@e7 zl<P$n3au<@8`?uW!S0_UVOgLl3kF!Mh5xd2@ZYK!$w<@^G!m7KMxs`OS6P7p{wp=Z ze;d}oe_P8TU>zEcDnr9j8_{sowsJQ)CH9(+dY*?e{VYgDx+=Q>4Wfxg%{M;5A3-yp z$D)rxP0$H6EybT1{vmfS4~z0i=f!O<lc2xEj*7m7m*sB}eHNiiLd{WjBcF?R)f8u= z&$u!>6fM!f|90|R2VdC<5iY-grlvCVr?@#iA2}PeE>oMgCE6g&q*8zfq|R)EZy?&( zW?q_3EPc@uJmY=M#-9O3;PQ(+;Hw~+qNY8pVi(yZB1?HFy&0jo6ewb-rD~6IwVLYp zi5wH5Z@TQFh(bZLgoS*d5agLUuW}L}Wq~^h+uEPNc>&KX+2e$_kLR=-W(c8!lJB}Y zIp5@2BhgY5f!xR@VyOypGXbNec<r3%p<bGO4APBeVFBL0fO>Xn_JvTNIYiTdc7bTp zvMQkBl=@EgPtl!_`$7NRRYIW>_C7wIQ*o1p!n(j+)J_+{kW|WZOFXA$FH}`(@onST zRk`i$P)ybURkV*%MXOL<klAcgz`sJs#Zb72?1x8QM3q87oHh~yIE$ZyoCh*6NC6OS z{CmnNWjx^H)tQ`#n#C{;Y7rySDS6qb<2`<k4m{Wlp-Dlugzlv=YPwki(bbiJh*=I0 zZP%V#%tF=yGXHEC#|Jy+#U*khv5Cz>sluo7%-N(wLx0>^%GL0&>c+`DUBKP6;BvbY zn#2|&e7S?DEO&8zWJ6j132rAhK@(2H@G+}haa8;4tF@#BVSa1hj;m}eZ&d4>aQ6jh zPa-V@Z^xhwg>X^YRc>OJn}t_V$4>788>~E&is=Tb0`ea#{IS-n89{in76sIC{=5w) zt8BAyxRn~SYx3&8RsBR#kW0&qb8%Ox2nlxK(iI}id)RO3ioj`AjT)+Z%7}&yV%tgo zNyRewQoTET;kbgJ{<!HcBGE12_FfoY<<(y8Y?Tr19#tpEexEX;9XC!T&C*okG~d|% z6hT999-w*Nc}<PiZ%CwtPvdo8ZSMC?#(pLT$jjG%;-&CW`E_5D@q3^0Yo$B0*QQvS zjt6X6VmU!rs3JNaqwoZ#4CjwtnP#7{mmQ|rXS&kRsv6!9p!^!Y6~Fzh447bsA7xF* z7*?wHC;k54_UVv^pB~y)7sB2WTF*{(Hp!gLvV<?~!3m#ll*_+JXojaocxp;$1-`sp z#+`{hn$XG)L(M*-UEcE%->|~R+v6l8%{yC4v01f9qI07HS*iB72!V-n(i;y3PAZ8H z4lyUyk|b*OPg!J2(x2QgUf47!F+&r3?%|DHDDE5%sH96@H_(MRr+DT<yP_X}s!)a$ zO}QHRI^h>eqE=kr$Y}>nX&PsJ|B%Ao-r3`OFHhxFgblM(HlK)}H)@j$fe~z_t2z#C zn`q9;63^mcX%o8)wVK~vOPBLL@JNO*uGef6#k(;UjGVb{V93qFMajf_<;Zxhk0pB7 zE@C<;!P%_DLbyHB42g7EH%6$(2%b)IRIn&YJNyXlwsXVaUD<Q-ke12lxhSb&%8v?H z(5H)vvnwFT%V&8)7CPb>HrP;el>25O4D9HJG~cQ-)1SP<bH!MZ|Cql7R5X0r@ri5j zu4bG~b^wJK;d?U!-7`9ha`WouAPgqVd!W!VdK01LO6}I^(8zqFP(~*hSc4<<A8wrl zAOBKe1@g<Mb6lAbo|~L7vsZowgA0XJoZpIDy7(~6#(71qslI~W|0zxNC32bEpg+QW z0L(;uB?=RcKs6htNGJ*xn-4WLPhz>5TC_O6yq$y0^rtlsm&j4Oqjsy(rtq{=+B4E? z=ZdXEG;akWRBmrYQ&w){SL}y%W?A)n?CHAU2`alX;n;@X84S>foZxvozA|EK9L7fL zPlooJ<kSEbruv$u5`b!`8wLqg3CA=K0%0c7#1}m$slX-@kJ=32_5q6z@JjSK{im90 z5ys%VNZHn$-)f+;%9l}AdA2)cf=b`Kag;C}br&DTBhCR?%@_93lT3e_wv}2oLX|w4 z>b;OHD(xYI{Q^?5k@N_77lYT2@GFP_s?vu|&3X36Tj%?gKUXS$jPMdFJ?^U!*?$WV z37&El3UnV2BHoEI+$4K%x$Ic<I!6$qlDttw?w}=Gc;++_jBXVkM>TE6mYnuC$XuO6 zm>^xVgxj`l+qQe!wr$(CZB5&@ZB5&@?b~<x{oAT#=5wM><r^8Qxb_1n--h#lcgoeB zNqoBo>5$m~SHX740+be<5~?t*j@b$s9z$qQ=(=%<n>pac^Pj53$2kea!u=s^NCGn{ z-i9HF&TTd2gF3R74<bmtp~vn-5nKhNIDjJCV{s~lf?~!HMua}C4UAzqXKfv|;$9^l zvZ87TU9dDn{>r{dryn_sJSRitB9$+)9{yw6*HkR^ReBT;@wX?Foj0q^EX?vzdX!NK zXuM2{B`i4=2bY=0??d_OA!cx(leuh<!;oGXSZBa8+bLe4@kF1Wta;ibP8}p#kJy&# zMrK6_RU0FTa(V>W8-=^+e~FP@L3%sN2vkK;7UHQdD-a6;_O{PqGS(&HuJ6djJt@xT z+s`TtVh|Lr?J5PeC=YN;mm6ovn=YzfQ(}-+IuKqp`2F?Tk2!14s{xj^Kyzqa`hIKR zDK_2OVlXf|XOW9&N(gT!Q#j)JZ$0*Wi*q(ve|z<$H9l0SUPjFpUD>VhcCMu_6lUjm z1D$Gm->9JgCO?_kIznSW9khA-y5bT5Y1<#h$l7Pq5_5iQy%W4LA3jn<h($RanD>e2 z&f;)c|3q|Hj)cVGFM?MH&ioE_^yaaRMQy{v>!z;Ev~7jwWh@oSQocrAUK^3Qr!5Ld zND=`qtfjN)+_RfQj{n)ky!n2coO)D+ir3T5k+lXEe}v9u?pG{_n!NDfkpST)NTDW# z<^ZZ7ggl>0L~RcAW+VKN+&)*t@~9V;HJeGx-zqmPR8k`BHR)Nyz!NhVDxvD+7w>aj zf)#cvyi90|a6GjbWOn^2w&G;AwJcR7ALJUE3?JJkz!eGQH3P-=k%T{n*f#s^d|5P6 zr?X6l7*j&+L6)n5$GVWt7gmXWE%s+V7SZ(v%EwMKXnz(mJ>QN`$wKOj*aqev=7WoP z%}Vej!%}`D2Y6RFWONGaIv1p{O`+9rnj~+v^W|<i#t22>n#$`dyAdP}Z+&)7pz-a+ zdjD=IbWnsziz9K0p*Pj;wn<MT`95XB-((RIP-`*3h_$_sqU@PUHju9Pp%JPb<BgLS z@5cz)hR(H++GnHLwOh6Th^*4&UJPuFfh13%%a5zd#*#}m-blMm=pd(Dx(ny9?a_P? zPk$F>`rNQ;E5q`m*(o{=F7hC=e#{P;Rje@x2bktT4M6L|S%9Grit95Pb!#7o_X*YZ z6uG6n#Ny43Ucc=}iq%Fgep2Kko%<tA>}vU!9jAF5S+32y6i^_0W%H`|B+H})+wcx* zHN1_4&NgcdYQ4_6DbQ2x^t}w>sX0^CaL`AT5j`neCq2YBoD*3}9ubuynv|Q(Cpc78 z(8o9L!qsYa1GzZO-bk4npA0BJx(u9L(k|ItrctzSjKzZ0Lhqu&=$`Pz)oRK(<nF+q z^}XeC`J9F?${xVc7VI#M^Sx=L3orQMtg@Hl-%b;DwB22nc1c$A&$Qe!y?Sm(Md{0# z{-sA1vw*PUoV!b?Gv1v~toCc4T-}?nUUVC9rr{&F^5ft2Q&fcpp-%Pni2B1HhLf^I z)b#^!T?lQ*yDJ=O?M(g=Zy^Vt2zS#^yFOkkrBp~4VZUdP34KC6V^sN`TK8<KW?TAQ zRiX*n?#w>M%37FMBjvV&S$OzV>SY!4mFafAXgz_$#uS6ykAKeDtp@h+ZT3|oO}ma8 zBnQ<@z6f9&$&ixDdI@;LBf%e&lXa%amc{QZW}ngY4%P_-p?nxRYDYLkCA*ar%$()J zb0dDJK-w%z$hk5_V9MT_4+I@UZ88LtY|c^TLW|9qv_c{4N=~_`-ePMIfAEJwD|%Gp z!cwJcgdnqNdPJ5aCreQbBxL01xiQK^W~&f!k-?Bj>@$JAu&6-~Ea8adzDYhGi{aQg zniI|_^uwe)zrG~Qba#e&8|*-MXsv($Gz0zY>ka?l-Vo_=lodXO`gS{8^&!dS6rG6K zr9&w&Wh+`(DaMnyKs&#ClmOBv8}>j(C-zmIZmdAj69sO|&D$1z>M&AFt!CNe@?WcY zHpMt3jZu#Ew!6$z<t-C^w8{!qVp6`tI4)0kUJ1V<<8ls((@=<Gfh5MlUx+9Bx$9h{ z`Lbrl<Z3tUVS%o0@S$5{ko7Esn*#LI#Z`OpVvGqqYsKI@LKm`nR|WfcvrN9$C}=Xk z*>z(!M0Li~BD6v=U8$}V1b)nyj@#5vARaU9>9DzV?7CP-Ir$tI`xES<7@bu>d2t!o zWrPg`H_YowY+WB`C3{D1%?<!DfyNt(IlAr%o1%RCkMIwck5FtJa4qtJrU-fVKaDr( z$GGS{K<H>>)@!Fa*gWtgfc!<uP3|x~fXFE@&TclIbEyU{MeZ_J4Ty`03M=I=HlB{o zQ70w2spQrT#ldLj{8E-+(kjljE0_(9a77K1BN9~LTw^*_vgTcDy2U9<Z2NER<-o_^ zblnOuFY-+I1RE2$Guys0u=K=VOV@wt_}QK*XsY5^Df}VMoN2L;4=e%|7=gq@10LQ7 zg-Cd7moC*%IcodHUJ+W8bJPaZWdf|+9UJ-qa(2GCFu8MPLVbONhe_Nrvk$S3tH81J zte{EFo;jk!b;*lV>0nVfbsMlP^Q#DeNf){0O;I?gy@c2NT0>~*?J4c+9{2V8!>Df= zV&E<QK<46|x5I+VLBwbai^=h~+$G&4u$6pMWlA>KK@{Ap$$`{5G!iFo^>YM^jqz3h z<r3Bxj&IGl8g|9&n?Y-eJ}+|2xN&KW?*STmAufz{lV)aS`yTRet*bpFKiHW6oh+ff z9M%!YeMoX(aCAQIiFwFtSCCWkKfa?BBB2zB|Ja|`>EL?SWP<Bns3)A@7*fIv3ks%Y zupq~g355J4k#h9PdBR-unWmBc&b~IyM-b7@Hw~^<`(z=uHt|{VjX!j%HmdHeOOzIw zKk>~9Vywe+!ET0QA-I{ash+;FW6K>G$4obOO{Z=x9;dM6EtnQdMm4r{5^b$tqA?!` zkD;MgQMODQ<G2F+=dSJ)jJ>wlharSPN3p#+L4`{;AAq)sG9Tm4r6HGWP!GMZs$p^I zyk`x{DUL@7^+5$>d$Xe?Xm@j9nnK;U!d%lSI9x$s2Ilx(u@;_61na)}ZxVaZMze|8 ziM`JT02#1Jw!iNxqV|$B*|*dzktN4VOscV0oVFU%J*ES>r<|S8$n?A*sLdkZj-ceS z^=u78{m1M)Yi&HD4H9^Y?yrO~0l7>JAXeMjsvuJ*FkbR211_EfCo(dklWNi!NKm7g zpM+9T0i^LGwryxTLTR6=D-3=KkR#Tqt`dlJ5FtXK!!y=uR)w_A?cXXUK^K$g#ee0W zsF8Sekp?L`UM}1ADdaf!q~~?I>y;+LWwomA-$aaH%hZkspjlfRb7b6b=@8+9ra(Mu zl0&#Y*+*sHE(sU**m8qY;MvafvF-2?oR$gHfSyQKBujF<Ko8a|(YTo0)f4McMVLv# zR1#h>!HsY2!do7vFEfQFH{uqjJKJ$udskJ7gr>^k*z)Y=#A)}xF^^iNoj2rJcs9x? zfBZ7MWYm55m(hytd1nWO0H`x0S=>YSko<*}Lh4VT8u<mQsXi@uN`KhG;mLoaJFzr_ zob)lBaZ(CeRx1a_IeT~}3Y`9B_PD9{%2l#PD9;<Z0n>c+1|<N}l9=7Jj^~sPSyLQ) zq!{zb&#^ll1jA2=)>FZyaMhDR*!)QR?hXjKL0h@xYvgEUYn5Alib-R|zbU)Ko&}_* z;Q^#x(%xIsPsD_o5zEgyhAOAJ`MBwfAtFEkhUkjY+ZP-G0IpVyT6xkeWpff7l-7(h zOh;rTmbF=CucM6M=vvi6#subIAI!?`89&QPBy@F7hGDNCU!{MD9<J2^JIIa>GT0@5 zq0oOnWwgBe_@~?(;K?6T*q=geZuy*OQu{)H$pIVjx@TGOk^~P~8W{5qCL_Zdu?RT1 zACwhgUFSUrK>)xu#Nidh!U|e;caLl2SCw8;o(uOI7nWJP%YqGBkB@tg+7d@TF(6?y zltVy0bt`P`1a{X3%G0%s%eurrtg0G6J=s2htMfNP5<ol^hO-k7EWG5HJ>E*C`1VQb zhDjT4x$6t)U=TU3|IYO-$ZC8qNbv!grH3rVZ?{dkr-Vy`<R7mq{}TvHepzNtxFZ5% zDUr1BUHy>nYaBK>BL5cxe+c@YV(vt5B`-c@TEvS9QPb5!1QU;2|5WDWTXLUxkx0qE zg1O}R9tbWLe}I~bvZk+-MHDSi?r%%n1UyCUyiG=19vH^rU?eJb?a2qI6kIAgrN3gM zHVl=8hXpKEHs)%odolK3t+h_;HC42)Up7%*fs`*nq@7_gF^YwY52(+Q2l9x5ETA)# z*<Se!Ei~&X?N!U)k<75DNDw6BaKOvz^3vk%Ue}NMXc*Nvo)~R~ufO5;r;p^`RRX8T z=#C&H0c&Wx81|ti_){f-IJf9(Q03l~AFb^R8LEall@~+&%<AKOng%mtG&x|L>qkfz zVX5mX)9~=I=-pS2v&QD{L4EkS<v7%%nUZqdj5-h6RoS?5JNsmVU9ib{l(hU2qPRsx zEeD$+dpYEm9ml-gBUW-%J-P5eov8ZeHF4ZQK3AUjaBhZycjX{l&81r8kdV+@5UOAI z+-*06Ozq1eCdkm4g6!F@54c1A@ObTdg4RS|R@}=}g1MfBYYweGl)WEw%aVVNz6+pr z4ypNmh+-<FIRVBoW3Rn<Y@%?3YCqr6Y)n`a;z%HD;0h!`6j(Ycg6d&6?>S{qm9>%@ zLr3UIfw9p$p{@-Kke4@efL@D!H3!@BRYH<wT7E`Cuh9V~rO;N{;WU*$Y!C&aZrxj0 zV4!p)g?6w{6j<iUI|A%93BrkHaEWeI(G=LX84tLbg4uHKeTCo@+Vloh6(t*9ATK{k zp=g<XXdumz^L&GdazZG`QX~v0l!GU{cxH)BGC_mG!3tH>$_us2NsLN+qNa3n4uE0v z3Saw|vvr8iLn@1m8vmQzA{`M}x(sq!6L%7X78AN=C`ZFGlT2%<XsAS0RK<IiMsjAm zw4;Tef-Q9|XSgrg@wy1K8zvQbrVCpg6irr5mOml{UiKcNbauV;i0B1(oJ`pu<=GBi zegR=3?_^Sdh0YQtlgn4cHy5H6Qi|Ji_7OEs3YQ3H>u?%q&0HrlPq(4MfP()9%-t4p zqyV0tnl4Ff{I@TJUzKJQ(nYjmJ9tlIjeGBcJiMt6g%#cBG_sB5Aa%-C{N124&h9xU z0F3)OKuzy;BH?<Cto~lIYhz~B!JfNM3M5YYH<5>+C+4oe-*d!h7Fk!dExH;9eFzqv zkKz%D=#a}S?ZoEGZR2_eXjrvs79;<v^=sZQN2rta^uwvE3`}EG0P<h7<vQ{lpb~sL zQ>Q&rm&)qtr0%LJhrU8TDomT~QOB5vEIV&^U=0ex;;nxnA5oXWhxm5)0!^X%lPL{` z)Erb1^jA7j9Aw<q*mHsN25JvS0?wg+eWHwPvjzlJvhgH2jL%u~8u@snVZDed_Cd$s zS!|kiWOZ!0RAl0cnbot6s^xZh?K_fWHFLMh4xz_jW<MyrD_@($l(abdX`19I&{5*4 zdYSWW!L_KH*iwwMx9SlGStagSJL#NT=Rx`=F$c|rO>SKP!YGP3?Dew~Ves&{%@AGs z$iE^ySKtFP&V=x`fqx%qfqmsGx&l3{zvJ9oc|IC^QY@9B&xl7Klm*~e>sLDe$-r@Y z7A%rwTU=n}G1YvPlx!?@Mog*(FkLd)S5d&V5GOQ{nYuw}Z|2KN2D%6ZMz>5FTO90v zL#MA`?k~n`imE2<F`dj)1MMO4(5+eIoe2`0x~4^2<+poxrC-Y<vt;bvXgIBoe-oi~ zv%wl|sJ%Vm3#i5_zB>&AXq*biEqg3{eBv8*HFlZs7B6c@l|EfU9#MWkatX~NOxg2| zqsccd{=B4O6jQglS@Gz)rJA1uE^hw%vR?>kODk|87d67k%UrXOImnId5*sxzXP<02 z!7_%9A}^)KD4%(8glBw3ixY2ND6Auw-r=d2;)O_O<bb?+Y#3no@rv{t4U^hq(Dl1F zVk}+cGmvr;xFC58$ap|-dx+cuZ%|zgVe>}@8$!IQC^+jjHOhhDh=kn<abrY?JOW1{ zksYKif#Rtt3N1vQ!F7|<b!@}PF%~G=5gtDPmgM#N2G`;Bb1?~VW?p3F+}oGzI#^!E z5!2-<;7VrQ*!qEvYc9R-h6B-cN}NQphfFMwWcKJ+59tmNd(br}Np{~XZNsQvZmHsy zX*Qq2!$;!hOGxk&fu*FtY1rtlgYByT>;hVZen5h5l=B4)IHsTXh^HoBcCx#H$HaLu zgD3jy-UdgvjYtVlM(ke}kBql8JD%!OCE{^5MT2wE4%?{YMo(OKC1t{H2k1zc=cCwj z2fe1))FliQ#iXqiD!L)X#KNQD$<nVg#N+l8Lt?{3?>x?I;Ph!{hBx*HcAy~6E;Ex4 zBF$STA|4Z{18aE(!fu@sjN3p?OIys4eDrMubf(Ib?s8(OBQ6hV2o2HOS+<XLNs<y0 zHyc&xl(e?OgAX=Am50qO??gsv)9PEf*~XFEv~aReA~sPl6ioMKxg{6S@~MMf8Kf_m zS}3q^93n0yw^xyDtPk3qB6ZbFy3Lp@qSXijGSY{#sH0&MSu7gK%4|PLu4f}B7AdgN z%u+mq!(@{Q-`z=oDQ}Br9AuF2^e!%PO6#i&AkE>M(Gg`&8P=xUx2D+l4Avo?QtPg! z1*Losu>Npt(nbR(+bj3&-cGRstBo;lD?@{qI({hn^Z;|!Auq6iUMM=fBAmh#@Q19c z7+#U^k@3CYEV)Dz?ao1z7RLQud{)4boJHy&+&P_K8`GR0RLgysI*NIcSG%*NPzO88 z<>V;aobPd5DGJXGw*54&q2zmEXpODqiLuGdA^o(rpLnR0oETuu!^VI}!^c4RMuQy< z;DiJt6M1v~$*1VFKoNzPj=TkhddHAe;HGSLO=O{Qh<o|=zRZYt7*j9@SLDYPvgIrA z)rWYh)<yj&MIHFE;QKZGGQ}bBX$U`mz|}%(lcH7MRU>8aianufzt1L;vdZqejJSK` z?9>Q?&9{R^V9iE%YhE9BGr20ZD$tq{2isWL|J`+s*Vj1M_~JO|-6dE9M-JZrQ4-Cw zHwZ9hkIN$5tS7UVS?hhLB2B1&%Kb1%xE>OobfDlTTRoHjHORKE9T**6b0KE^fU|gh zaxLBDRT!6*tiaB&PsOcXd!d~;W*x;|+BA1d3^&yu+;{rmfqGPEllGB>G;1GO0@S38 z@mb-le_W)(%9DC(=ci0E_T>gK4UjuJc?6`Y%)rqrD?pHOfn<~rsv~PDONg5H6K{%l zYz!W+1l~AEtE{nvr@Ci^O*BO{f3^@wO3hx%)tJj6$}0=TsvmbTDo_-hTh2X#MOQ(% z=nmW)y&X#JZ2}-dIh|~FW&QM99N7gD^=LDr<B6*u?fXH*wgb+)%cYq1<q1l2BbWKt zU=SZ<MPwU!$$ze3{)|7!;|`|=4S`Aao3jIq4<yE?q~n%^9(D<cW3C)1ge6EAlOHc8 zFF{Q47ZGK_76NqYgoM2qpeNIS!bj%-(2>dhGCssssJl@mHxw{u8}Q*s#W7f^)`5MJ zx;G-*wELm#wN)(#wjnnzTW|6_`ut|ES_2JzU>~qI+wNM+2Zgl~?wj|Cb`S@E19A>* z4weBZe2Bu|<Cmy}0-OMB0loxqhud}WC-a8~SpOwuntbBn`T**n`rzttcYjeQpe~SG zxIS=zY5-h-FM#tKOfn$--{m#_fCSL`wEnoelKv}zvH;$IbKndm_!B^F(E5mde*n1q zgaJAMb%9pF=RoFw=6>JWCyg<%15bfTfU3jk1Fr(e!`@Q#)dFsVaDdGL-J<*R`BM-S z8v(!oNR1!c@759z^m(Tm>)+onGki@3VCWj%hHSlH13yGLgjOz~s7FRtzj3ulx6VwQ zS7k-2>*#9qsHo}FQ_rVtOx{<aqBaVB9UQGyqb;A~mt?8-_wkdpM^n$Nq@)_~E%Q8r z@=H;AqM)Q4Urc4K4Kyesjn$_%537a;a)Fh|Qj!xk5(E?8^f;RwEh{2jJV)|)DR6RE zdOwI!jM{>TOrrpYQW{XD^OQu_GpoL44IeTO-;Odcrz?gM&$cFZ%upOfMx7Dkfq)nx zTVjebAk(Z+#fTXpd>;=nm?CMQo9W^e8eYdnjI)Iakh-+>FjugKSnZB7WKFR5%Yibc zBZw6PiG%vRPF&_Bg5+e2OeBn>PUP<*EY;2Jo!22^U5#alg~Z`8vl(u_LM9-S%Ph;Z zdszN!I%}P3duln&Xr1jKKA!0`G@H%va?|z>^wr&uyJjSrmXl>Hp_9;ZzwwEZj!H{k zOf#jKoSM+heXyfeJ+9I09%*2s-_fkAsT*tQY5Ut$_37&cI%%`oX7K>bzpdErg1xrP znrfJqIT`s!qY`%%$SC-(5#w8LXo$&8Fsit3ktonEl9j>M(m}Lh%TknmaKcn0lJmZ+ z?}oFyt&IkLalKu!rEI98asA4~6?ZUL@PtmQiG(=leV00^-u@1#SB=ahg3@AdA26@j z$;i+wEQBoOoaX3gSkwcp1tL_spjb%FFu=e9&@Z()HMx-kC2Ep}fdsm`!#Jn)a=)<I zHOi;42IAbhRqJ7Of4Wg<dRSE|1QpDc(rVmD5~_F8u6$0#{^-cW6{24Ak29#hw`9f^ zlt-TtWCU}Rq10UzEOfU{8jC*|xJMQf8r}Ve<LW>mR8Dc>fM!FBdm~+5BYH~BVv3L| zb`^`Nf(4?MF(sX+zcGFX%)uagAcY2Du`O*Y+_p>BBu6KIO`|ik2CfJ#Wu<;W%|&%Q zx9X^E^={;z6Xo2IMr2eygE{5U*>hJzqT~J9OdE0Ss&8eDKlL=R&7a#Q7y=c|{`Gbq zG%ENX3H?6~_2Y^n7qL%0&=)d%Hw#R*It4X_n~7$m)1bh8ia2xn-&Zat`Oo)DTYtFi z&Y0G>tqBQqR5Q(TTn?`GhH1ej`?3*w1Ay*}Z#(xHvZ+ZMWeK1{RHZnF(GIqJa=2`1 zsIdRp0iPYiWz+;t_sVu~rq^T#t=myFG-emO=Lgl1ONvCZdyRdnrKRjQ`GB*a%xoJQ zJ{|d)dFywNdq?`{fZe<;!-{(NIux@t*iwbvfQiAhME|r#I$YzSl!AonAZkHa3Gu}S zJ_Q}XZ_z0hdP7?UoEkJug8MzXUVLRY13?cYG$_B16%a9Sr=X<l3n>SG#SG?9A5ql- zvTOSG$>E(NAoCmJRu#`#nG};QE20@1ZMG2}XkK1$M62&jrg_VOGDOtB_NN|XUkF1t z_MOGV>W4C-9<5DMO+cyZs3Mk|I661g@}kX4!XJbPU1~I%GCt`0=$eI9q-YWVsde-; zSsR_j<!e($Aa+{(F)zyylbVx!1hA)i8Z17ExUEXg#eeZ~9c=vL`CY#AFz7qW{h90b z&U<t3<vVo4xw_{*r*PyCs&SWp(0>(sn@^ygU}b3uP>_xhwx$4Gc@eF(KeYy@ZfBst zmUVX?V;fqu3|Nk#o(c^Otx^#$b996~ISIUc;P)lpy1Cnn+0$D&So19f{O8QmZ)xQf zI$GiAg}k$$|L1Yz>-&)X^+cxf!;Jms$A4$ZNAq=u7swdckNq7Q1F#{0{|)vVHrn6s z@#ba;|7T!t_Gg;^GPIIriTn0T?1EeVrk{^#fPt%`g}c%U?^Ck6GS+YGYcb62a`S1d zD315LaZ8Tp?V;57?vZ)++T;2SUDx|8&CBoUB2DjYy0X{j%I)X-V`XQx^{20&edm2} z<EBe%$G+_D7C$R94u{wEb0|;tcMx*i-FUM7vpbj?$H(WlH=F0Z?s?ZZyYYPxMIZ9q z>(2H4zO<5)_U+n!k#(KBO}*p0^5WC`3ePMe%*?|+gz(jP@iR;J)0<6*%k}9e@=;n$ znw(6sTLU<FIA~Wg1HzBXXB~=f#I%)==QnC9B$XiplVnW9!+7fujBARPW^>C+4`>UC z&s=p>wZa^sHL6kv<3z6}ecy&|ZsMFYaV6SDZqTs$aQp6C;ZmKGWZvRMTYQK((f`S) zH--E#;LQLp(Te%d_n3~h$bgBK+IXTRfmi-abl+4J->4?xySDtPSozoxT_ji1ptzsV zFIf{Z+>{P?V8jz0v<JiRwty$aR%d8}&8#kjQRHVDveaW-4eRb70*u0Z?JlrNBn6t4 z9Hw2|UX@Kv?)#WyI+#u%KFM|Q*&rh+Z5rxeajDa&h(=4qAvpglu|Tf?n&G$>_+?E0 zaIgT@0W*O$L9xKsAu^#fVX)zR$EDEd$F<Rhr+{+Nce+0$8<!KU`+7<8+NcYvru$Tq zX=tg9&d$@H;j60L1>8F({S(VzkVhG6Q5mNi<+Qo!{$Lk)$vSr5pcBCW?umni{1{m3 zyI1SIwl2a*^8@j$1bNANj@*WQ?xW5yG7LMxtPC3^^D%rr=HEsI4amVj>E)T<E<Ig~ z48|Whf1kd)OS8h@+Wui;5S3h!%j?{IcNg1n`+DTp^ZvT!&jLSR-h0_(qS$7Z0w2)T z<#P5?cLJJxm^FKa0%rCYp4)3jFvUdC<)`=ot^^wV`e3zb4$$a+e}CdN$L8Yg7>%sW z`#wCrDE;|+{=Ro(3lD?8nODp2`t?|{wE}Oq;pFqF)`fz>_xh3DkQRDC|B@C;IN5%C z{&aWB>-^>U{h1!1;W4a+!VJb<ua#l-{q53nAD2^2lR{gUs(FRBoGI-#m8juW?-10C zvK&nYVRVN=gxNaTO^#SRVJ(H2rD-}#L8YT+T}(~#fRQ9UBmLLBPWoFl!NBB;Nv1LR z7#;ZQ7WUYZYVwzqC>I@G9!^D~9{Nsa+_&{^=nkiyXhbnnAO9v8bRI|7pvA6Id-LOt zho0uZKIS$Nt4B4D%sN`A$W6|(Bj*4g|AbeXV6<`6kc1@BR#t`@o*hJ~d)&~d!9o8Z zDM79;<s?sYSjFNmbhs}kZ=yL4WL0lz-<;@zPL`=p>4uu`OquNJbnij?WTnh&+$c!t z&b64BS`bQf>TyuQL(q!HU?K-cNlNjbjPJ)ELs$K)zT$YXtZ`*pM(4Vf#uOn&sHM-4 zd1&#g5}b$nxx}-N0!F0$L(wXx-xPY`y#CnP%by{|9<El9n4qxV-vS}-U(5_PiVYbC z1NA1U7&5P$P^-qjGIu|o4hR+gmf)DNqcOqbog}Mt-EX!NAw|@Kh|*bi^;PG$RNI}J zfV&hTaPTRe0c#^Og0M)dr))Z&)&gO`(hbSs#oi14B%x^GE9Rj<dG+tZSUulCKa4qO zSP2HB=gIg|54Dd5i%67Bsd|cTqLmC?^Kx=Ry3L5kkJ-uuPKO&GqnbY6H(w8SP(4}0 z*)F?DAeJbnah*M@`Zu#T^>|(oqT6P$MOQVsRTnFTUXM35-+^gNo%C?0f#|h|YK$X< z{8(~Wv4x}2nOMGjsuluFs=A3=)q^qKvozC}^zkDk*Jtwvmyf5<qlczBy^><6>%<8Z zRFymWivBPvQ6|+<Q|2^c97<1%hWddGf%tVau!UjH4tnR-D$sd6fDfTGC)&ahLYQCS zSPF++z2k=B#ze6Q=G0}^JpFLL0m{NvAFr@Tbbvp?W1*H!ilZglND>#=(1f}F_2|v# zA*)ye4qC>L2_s!(g4VUNwnZa=&))@l|8(U?1I-H&Pnm@A1v8C~jSi@Xpcf;(L~&RV zW5t+(`DT&jO$zGt!}$#$?N^mEwzywN>gDG&W1Ce;bi8~%S8notD&u7D+nM|lz^;}Y z?sVsu6yXE*?(q>?{l30me$f03+%Mb?wq@R+Z&x^6Bl&^fu>g*EaSMK4-u5{}F<EcY zl_ltM3-(;(k|9JC1X!v94L=D1DC8;<Hw_Z8sX}01ps|UIMb(IpDpNkifHp~ff%t^a z6Nwwi1+Ruj+tdY`luu?7cC871ajH)B`_ULwTmb2&p_Xo)0ao?Mn|S-0#LX+kHYKRq z)cbyDH;TxIrpF%fffLa3F1<hBAEckMfA;YI>>(01(RSG!+c^29y~(}9qkiYb@GHOm zZ0EU-;lr-LzI~Jyeg%Dn@;T@43EM^fINf~{`u+6A0iM15yvkGHz&fXEmwN)DRk3cc z+vO3x^*&O%ymU!yRhZeQfwv`9!|h*(yu!}<eRkP~dsn`fTg7j(+cNkj9$p8%mgZV{ z+44N#&qB^tV{rXcdyOHVTmJcRUmE2yeHv|v`-L*U*HYy)YZ<0;v@9m}dlz^+jVV8S zEw8s3`Od(7(iqhaBA*Modxhcx&OX=slJ%GvniC|auJ4rVDLYnI3LgiXo7EWNn;${i z+D!SO>1y_<?C*$sZi@q|hHL$!9z|)}iu!aQ=@wWNc4L8CZ=ivh@iqr{WdU9Y?GseT zz}=AAD0gMSTA%n~f>T$a>0%pK)?tRA($F?#!g<=<U6<b41Nv)AQMGZb(ffv{=a6@6 z)_sipAJG>S(&?ASCw28dR`YM%^w=2UfPOEK5cz2NSbczXkoh?I2){mCOafSaJOP|O zYkv&?3;<?;LI7ug1OP;UJpfGrR)3`Y7rQxffPo$JPgQ#@09jxhuvg$dD*$=`9_U+? zJ~)3`fFppxWMH3IA1>$(l=sg9tsg$?Bwvd}mrRYI5%`uQy3+)QDTLns&y=F<lAA7( zm(pp>$<RNZ!u(FZGl_4Oe^T5Lu~xNtKg_-dUkmA@^=06F8R(;+n#TgeRVM&+z|p~x z!vHj3eNmL#ERZn8QS3}2bg_cCa_&i=b^z|}_izBn0(U<^K({yJ<zwJqC=0V$J#CYH zhrm@J>dPi=mY<*a@>0McC;$Ke5CFlMqO!(szFBdA0079q00960)XBuz#opP@&f1CI z+Q7xu$ehmJLq)Mac7p(+`vJA+QD4iE_6dv9PyW~J#)e4bo}EAJuaC3z^$r*Btf9v< zmGyEw-M43tz`u0-o4*}<+q1aEEy0y3(5E14*;_L)tsf&S4{d+~X#suMEu)X5-CZi8 z5aQ3w6Ajb|hHrrcu8O|1JB{3sNM!EL{`Zl_7!7>cT-Y`2BDa%ix-D!a5@zET`lM}f zaWyr%Q?Sgmw>IX|c#=U#*@WOHVCHjph4V@hg7E;z!RgB$rBAOV<EOWU>$Wk<q1{{Y z?)mlW04VZ`P9NghlI}=NL`~ZF_BUJ*Ev5P6QB-l_!juLx?JrG41#ONdqHMLVpc5Bp zF*6&sjL*1g!LWMr{Xd9k*v#2zSH+qM4$4ln>~7P`=}vN!GF9E_xHNjzSabz@{5eUn z*Af(kOTA8<f=PMy)W`zNs3_=iJ83v25!RRHskgR?pJrBl9(BC-o0$`LKC>;lA1dJw zPWqr7{oS_@F@0;dah%VfcgYEZyo`erG4LL@p5B#`UFX1AlO;F#+~8O6{}wPz;iAwN z2moLU8~_00e+p<}$mDFttY_l>Tf`h?nYb(lgzgWu=u-oOEXUPt)d`D@6i;)NX0J-B z!#;sc4D2=2q^sJS^jm|m(VEC)g4?VU_6NM!!f@WE<ulFCVW6JKAbB@gKadT!7`E$N z##ewYipyKDKQ;s_=a@0b6@fx0aMg{`^`+Hy@)w0E5TVdfXl;S?&GaAEFiRGoJ9?X` zwr-SB=60%BI>LliRypx(Pd@}5kpeKS@iB5yiGZ{&F4_r(2L|Q+i6^maSAhKQW=LOu zo3#Z)=%|MQW2U_gmT$dBsg0}X>rU545dXcTO4-tSW4Y?Y4@aFG<^t+~rs}GN_PnhY z(x}OASc0~0DyQ1EcKX0Sp$je&I|Gqgk0=*4|Gf*g>L*ezr%ys@v#4C5h|R|o=MSEb zaAzVlUu~kgP>sV*79wiq8Z!PGD<0Obb-P7IbcVEz%Bd8yHXlMk+;VQEZSNIS-i|{x z56s~GwVcu(bL*kX%cOcxcBRnas)<7CDqvkFw4ia<3yiC*_a|96EF9AdCyRy9;H|j0 zpmMAu@V*nOAoP2^i=N@rDsL{4kB46;o2-?fHgJS8DP>Q^$`QDanP}<fZR+PF!wTm@ zUtr-MC&E1&Ynq(g=`h#z;5^Gp5-@Sn;`jEnz4+M$4>sf9B!ear=ykXu11oYJJC?*3 zpA@1Re{6p8FiC761OhlN4U?vi++V!3oyQG;1w)-|;PZEfe@kmvHyF#@?aHIxg&<Sf zCLY=_URQ>(_$^v8P6^ym<CJE+;x7fTNA1!@pQ%L^1U2*LwmS{hdoa`YY9zqh;ZAft z-rJ*Lg??{OWlse%%1q39_50k1%*?MadoIHSHT#aZd#2R+{kLaPj3g$dfBQB5_r&?1 zL&wI>*2=`=w_lspZR|GK5WcVV`in70=rbEw#@9h7!-%8;;3lz*w;~NFAT$eY=#tA4 zl96v#ZemeL7aSU{2Z2aZhdU3p22XU;gMxzAnk{c$Q=O+&t>$aOH4`;4Hna$3IJp5L zGR(P(X&JSU@yH{J<FyA`>lP$U)BdpUb#A$OD{DR5n4~0{w*0Fg{H{ic+Ov4gkE!q) z4@xwb8Kvfa;0oR7abo-Pt>11NRD%egR9ZA=Ek>D?sOTv8{dzdizHZ;$Os8rfQ92x| zp_?eRq^TM(Xaz^Vl!ueY86=QuT<IBz<#t_u)HPB&GD@sG`L}KZuu5Y(Ex3jwxIjf$ zl9@jb@wH#{vkP>`*=myy+O&-@#Tbkqkj<TKNC2X4(D1^z#%?E#x%5rpj9WNe)kg~% zEC74asZjHtI2aiJ#j3``zY+w#573eRFG+QSNT&~^|6cUo^1%#(;i42Z7iTxK71;6| z@F13~=BrYoTQ#8c`9R3cB?!c)m;o}-YZ2{`auWnAmSagoUFf6<AmYDoT8O)4Pp3XU z|NOuI1cfamefP4fs;{Qr=I8&cy7W>|FX6as#Nx`FcpvsLh>z}c@z5f75w`S=H#i9> z=tmsFUXIT_c+1k!jRk<;_2Hv^!_@C0qB%LHzq3Y>C=P8Uz_SRTJyuK6>YfbTn-T;m zpV!>@C%v`l5J`cTrP`0_Z#T5;%k~Q7rrD-+{L4h9gY_GjaOe1d;e5KkBDe?axmr!E z()bsh|H%2K(d=u27j}Jcn{XAiHkx4CAESzv6jhDk2~yI77X^QBP(^#%e5_cXxxxp$ zEl~tvCsWHwhS1n&T__+auBncu8Kl5o(*#@dw}sa&gpJK4s+Lmv-ANX%467;oIKHA# zM#%>SV1@CF$IP1-m<jlMJ=06yAy;N|`WUf}j-Eb$glCn<#gs1!<{+z-CQi`wA!0g4 zBVa8EvV=8AlZe&$A(e*1PO=a3d?xMP-#Y`ODg&T*Tfk&)ES0)CWv1VB0L<A^KY%$j zg&p79UGSQ4Nh3?67p*zIA|P<UpF)<wvzCRPUS(0gxGkLe=XN0p2&jPW<Lqv7rFK@{ z(drMy{TLwCdNI+?AZIShVHE-SgNDC@xLx2mD8d1t?*`T<d6aL+C=Xzo5o@3!2()P# zMezc)UO;wv1X$dMG3F&1AS`{i-Kri;ci4TWYPZp#$iQep!l#L#F6!Z{@w)2S9pV9B zPS7f!j5hUHs~lDCm0I-t;}mXrMhBk(mUvQ#BOEVKA~wTiu(13+YGsS~8s2NZB+YO| z*V=YhXE#o4@8{n6RhFLLyMSG-?e@?8_29?GPXBvbl3S!FSs^Jc8gF76+h#+iMk;)4 zue}c}{85+$3=~+?I_he}hb6c&K%NgI_aAR6R|)OE#&L-Ym=sAm$h!Hu4P6&?S*oE! z-B2NRdU!EWXJAJ4G<gf##CINK{%{(X!TgP)^u{uR<ieZrT6iE%x%S@fZ=;Q9e57<T zlKau0ok55$ypp@p7DjBS!@hL-Wgpnw>6X8!U``m=3r|rA+eyV{cj&f6XD8|~(5@*S zP5UDD;k;&5T?i;K$cFQ@vyG6N5TR+c*w{Tya|SAjl=MFIN)nipv&42AcGG9BEe0B4 zyvXDm+!<8sjxxp+K`Ih&!SPdFo*L}{-oszwU6Dj9IAo0@G6oFcbk}VvbD*|A4hx$Z z8N8_nR09m<h?kxu4QFwWIh{~-%ZarGRS_xvVo*wSFgVa~3u5CjcCIspD#13%W#nwT z90Tk1qM;<v#422D(b&@d*KyQ`^t)${?AYSPQ~jap9T|A&Md^M0f{jW8J}yWGdN<Rd z7RW)|^aj{{x&798;@qf3+o!YnN71rMMp@QO$(0&YVciO7^(P-E19jqX#DcW`Y<pv2 z3PkxFbm)xA+}WOdHhG0ewss54aAk&3_iy9|`=l#{3ln9<q`i=fz+h=%VKcIIc8Ww@ z5Gx98j?z^`DRV0H8F;F&xwkRB%|3Fn6U?Pii~s?NQuaLLsTA=t)2?010{y{&IM<AN z0#08LMZq2H8a%VwU}gq-?Vx$-@z#J(s9)(qILdCe0=~VF*RdAM={TR*a9-?IMm#u& zeWCVg&J&x3)aw6A3jNjJ`Vq1bP#fbMZB}R;qg^u(>cAX`Id<l!nsHw)v7~PowyZw~ z?kJ}fiDh?*7~MHURsK{t=;Y2@=bnm=$GS$1uabm4S-eOD$;H`1GbDIgeOT_bHD(R@ zxI7rSE9)#IIl-Zlu%a{h=I>12qYC*c=EmZD!tvn!C@Bp@Xh>A>@O=_pU&@mH6=vJ1 zhd<=Qp~cVpW?!VMc9YTSj%oL4bjp(0#5^jzen?3gW6o|rD;X$+Oj2gc<0t=An|*q& zXYng@H#=D5h^xYQ(7+>CNWJER9FG147I3-vK-pv+e~Q?tw-qVTlwEqX4Hv#Q*|(lG zc3hkIHhTR4{;R$M*O6z81ONb`c>n-N|NUaLadI{K)!r*!E2jgt#GNndw%mKgKP=I_ z2kvAwF1EZ4-5Hr`GmhEaSTgnIkPRNG5+Q#-%PK!^R<_&`2mmAhajeNKl~ZA6h_GYD zi1p6-x3splZqub|c#f9n_Gr>AR^6If9Q%ZmYh;!-4s=F8sIa_*?)YBFEDST{HqyYi zv}}`}`49;LsCRR3dR~88Ys`NmT;kb!+}8KtLJf&5&&CbQWV+J_s_EYBJ@xlRp)Ce| z`GUT$aAcIcw6k-0oZy0Z6`l?DfA>Wd9Us>QZh1QW?t$ub>5x%Q&BZNy#@4tsMV&3( z7R{V-x*5LSe&JfD&{7^HCJ-OC#43fjtpF1EseI@Uu5>;hs)r?NLZz2*T+sHN#9vxD z;-S*NM!Uah)7J<vKMJzQMz18wJpr6-V3}++)#$i&RIN(=N2d=DkO(qq?ue~3I__c* z?uZtI0|9cg=ECC9bqL?8z3cIbKqD~c1j!b4a%+e-?L_9k>*F|yXA)$k8eD0NiJFAX z79u$FPaOzDuOF?u$Ibch&2ZU=FT|#^H!dk!2U!AdT74{$`vyWCqc4pkD1d<=x<~|X zQM))v3-CmA{2wxHH_uZf_A%|kndMBEWU{-Ov@>upF$oKm?S2=I|A3Sp*#pHasOdJT zudk=uyWSps(c%Ll!ZV{x`kU$N<lEcXD72-4&F%N%?W@l(nD)B35m)MpauX+Bw5Z_z zeYO~4Eq^q|l8eHt&bdd_oArrMI5DoC8>X$EFBnIV>+z_2PDnq4+<RNtNs%kA)`x1i z7)S|s2=bJg?i^VLrlrcGfpYRo4J%6cq1}QU4C7S#qde5>OD2GChcn)+ZEtT|&0JQb zgS#dN(PCI7@LCQi3#o>Vfu7;~4d<0!ZMePU*)L0F7}nC#QerzGhA|^(+1om#o47aU zyNM88Vi&zOqx;%!2@3BUYPdozZ=Jv#H`4Ww7jxpgh`gp&q|M~J(Se&?i2j*}?_w4> z)akbrH?}|<%mnXt9=0v)<d}w7`GS?A@^N4P=OtM&?bB!WoGo(@Edv!8q~dc>%xtHX zfTt}w++u#-Wc#>mvy)Awz1CLS=w$e(!Ms0`i}kTIeMH!fO|D4j$z#S>tN*n0c?LAz zP`Q2r36@j5iaGMt4PtW^#-bf3)Gk)MZJF5*#Aj0+6Z__{V)hQQlRM&OWZgT?%{8by zLvFXsD-I<QxAx=%SQ5Kc)zaV=^o4mcH>hck3q&wIs2m6sED%c0J~2gP&U&Y=N|}H6 zL0T;dhy=(p7!@VIp*QN7dKs7sY`dio0=C6t#W14VD6UCXiU}r@Lud5CBZMw}dW?J3 z&lfex0pvg-(GtP*WU%(^tN(iv9e<G$JFZfC&09L=prU|gi8)i~sU%pQXaE+|kvIP5 z+YO7n8_8T=$AeVRUmIwc6T@OziS~oc1ryS8jh0-NhqcOWw&ec(&k3gIT`TG&p3HFg z_RQh&SXeW})DPK2jnnH%)`r*TvWk)Ft=(c|+6=opw1#onq;}N=BDFIx@G@5FYz2YM zN2!vr3ruykD|`5sgBy|t*NqH?4IEG2J}Z{H@KuzI!rY(X$UJBSrgSfFz@7(?;4D@u zOBo5caWAH!hYYs_-a><Jx}%5$frMHE%eQR=+(CDs;BE0ZG}P#2Otem$YL%g`Y=L?{ z#3pU6CzWFAt<;_*1FX3slTFDikF=4xK0);%hML2UCh${S3trvAb?qQ!y_i$`Lk=nC zf2WrLGX7nM>xZRlS?RH@%&`vs*~1az)X+Izv=5_PFQDXdlOuLX8tVt2Aj{9d+d#Z$ z+hj0Lg*b#0c!TCHF<-$r@DeugJql*tc+D1KqZ&$8ULS;OMUV<Xw(jZlYsTHrB&Dhr za<JohQckIYJ&lr;0y|J!OsjT*HrThVbN-f&Kjxw>^>|M2FrojRS?hhcp8m<Qf7z}J z!9uFuk!TM|LPWhm6hFl&;s4WWJeC;n@J1~GNq*t#)Gt9Q&p(JXM&qY=LPWh&;fae9 zhv1I#0_#6^ZP28_2M%$_Vq&Pl<G|$=`9R$3>h<vI-`2e?v_pUr`x}ey1QoZ-qR2*0 zpFuw0V;Pq%liD$9P15f<&IBR6rxt90-@(4~k&U%;Ef4I>Nk_h7nKXClvtm}SH`+(u z-9JI_w1E9Wz39u6<Ef-7@GtLRq7Ooz@D`0`w#X`!-geddOs96AQcg)fe?*5KsIxaf z1w#hnlrL1B%*cbQ*GN|z1QpboiZ=khNb28?_f>Hn!#r+!F?BqGx&9q8L;%Sd#5hbm zV4hoV8Gw~m6oR3sAA{VD#_|R6_7!(cA9)K{M+0X6d29jU3VXvwqAkgvp->_{i3y|n zA%U6J%!;1`53uO%AM|EbGVjekHH-;Bq8flFA?3%OH`ClevKg;0$8mZ``%dKBjMCME zuP>jv_--%)zn$^corpKsLhrX*{JTeUv-68e0n^a9*eMCoF0u9mn8GQQS@G8G8!vv( z*_Wx~Y!|b#e9>KI0TjD9_~(?_fDE#c5^FC1y{OAXBywa#2~|?va@NGlcQp0guONep zY;RP%4a^5?d{19wyqH?<?aA)6+L#fO&^2CjCw-3SNyx5p5H~g&baoO{94vAZJn~lK zokETP4QT=4-x0yLgnmDxbOGt3Pa1uBV=uO0zyl!90OeTsk|S2Zq>i}J0W~KiyJ$Vn z=XK{PTOh($XD8&%!Ej|_v9&E!3MRX1TL}FmO_8x0>EBIFagB%Qn<djt){R=duJ?Yv zSo}Du8FLq$j~0j3FJ*K}-V^sr_o_e|{){;0ltE>On6#wPb9ux!w;p@NV%1?@Ai?!M zVeG+H?!T3Ry73kgzq4LplNdBzj_T3O#mu0F!w#5g^|=vZTg;^k5or#@J>&L3z%f|F zsk5g~lT=xK0SmPA+wVT$EQ%*=@~9~b3~~p=(C+MMGa_kfa(sNSR~S#mN28HG*6g}m zctU`}l7BIWS33d0q?3{2OHzWsLXPEmzSDQgxIU^o!EkVbfI+LczH1eRQ4a`(@npd! ztxf1*m>oz_hkKqZV68ds`jQZ2+x{;AHnB7IAMu4G-zviN<chzpx{t$xLEPDW$n?ZY z4X(UEujXP+HREw2xmQFI98a}6e{0+9n<S7TmzPlv0t=wxzI>+8lj4zJ1D1U3A_8-Y zc7fIS1#BAuO>Z^0l4OB#Ag7SsQT&HD&^O>K5MZEZW==<lXpp>j)e`6qFETNrwv%jU zti02FIkbhtkljG!FnuV)fKXQ$?sj;n4yYQ<C#%W)q)ihp_~6VpzjkWyMcM12p-;X* zGX+hZqng0NqScf+wsPUdOe-PqL}tq38B$B(U{6KKq%Te5gS2ePo+Cxxto^=g0?RnF zqe;n<h{yn#;mE@~NRY6SvNCKp6gli1;Lgnup&LRr0{Xg%j3IJSi1k0I2>@*>(m}zR zf2E$4kg2+9BcqO4=GaI-{m9`J&Osu3=xhhzxl4WKF6*zu+7(kUfeC|736bNsz8EQs z35D>mYV^k~zRuX-<C7$Zr3RVMXyVT9_A~OUG8oC17k4gFm|>@*-!sUZHBn<Wu9!o$ zpMFvqqx;SG93PzFyUyj$8qTsiQP8q7+q9m|(QV2<I2pp8bXbny-^l((<B45SGCtQw zm~oK{`~%F|;OxnACPD}*n%t|bEr4?e5&=vED`eYWKRTs6#bTXjg%pGl#*1+~&PvTN zmoYtFfmX_1C>fYx$lGoqhBtb7X0q!$lI6PgFwEygB}%%@`De8?Rv}m1A1<f?ewMu& zjM^CX{0N3GN8iP)eDGr7`tk1{(0!vHkSu$9Vt=bcLReX=W(|5qy$87cHs^p#f(WkX zr>dz5Cmt<{${^x-4wbhxU*<NXn^jp4g)B>?lR{<j>E&ew;6w+rb4^U<ivE^SbrQSW zqSo}AICw3TXQ(eskL6#Rm@HNQAh9PoRa26)WZcW52jzF(Nsh8Z7>dOj9I9@FNxNiD zl^-x$gd2<eYU?~QY3Ajz#3jYNNszYd^pTgj^hX?6xJ88y>c<<VS`L3M8dTLeZfPpR z@00RlWSxSC#RKGYg+1JH@(M_r+hFvS2(-N2e(vWoEE)z4^9pEQtUKGGg#xm}kBr|q z4O#-<8uzrqhizDy8=}#|uJ67LT#AWlN51-%^$(W)kpArrxyNF?n*eY~S;QJ(4htK> zhrZ4+)vAblSTO?rBo@kj<6%qKOD|Megp1uFE>x$VJoWsc3vWD6wWG{InKoE)Ldz-- zZRSFz*^)A`3eV{EE5uj|)R-jOy%_ClqON)3D#x=^xyn7*Hhn#{k&;+6o*>k`VfE1I zQOYXosU<YrKf9NOmN*KRIbOmTTizJ`jogrQb9*>P-ale$&eTol>a>}QLOOrbfx_>_ zdvfAPK@(Ya-yxS8GdW$p(@*9&qZ%Kv(!IqvDyyH;;4oOQWc1bb7QxlOGPu2&OPmSF zP9dZmE9<pG>$B%KkuD-qZ^Paa4?@89q0!X$oOHROgfh?zDyrZ;sEry6>J5hdDykKE zN#(*TFz$7K9v-?K10sjt*fJWxrM{RZ?P<P8n-q-SRJ+@ML_{fUpmjWNRSyD!?!iv( zU<i0<vgzQfSP-)}e8v_$`=^#+SGPctajrtg+1!!>)O=S8>8>2MR}kg|00vJS!7NP? z{b^DWvm#WpV>_OmvHntLO}DJhN3PXk7srB)TSVWZCV~Xexb=bQswaw@g1S&GxQpuQ zqT+ZUCas{6u2hXCSQ{3<DUy=XBFmSKTMCNFq&Hz)Wo+>rgxNtyK_PJVU&ECvZBvA& zG9W7bE+}jIZuzr*F0Qh3o(Gi%GMg7K;}{q(=|=@8Nh_IB&O4vQ9Nmo*L2*w~L%GZL ze`K9gn_$bfZPT`$m9}l$wr$(CZQHhOo0YcBQ|rF%@6I0)GscM4dxOMRSus}Qoa;tr zjZ$^;B^|%}saX*MqT+iYdL??pK)F-a=WZOnM@6Q}Zl#IAtD#K}M1DXm7APjn#U$5o zWG`i1bRhznl!l&Z7X)##E6ODl37F?VAA&s{B&TbV14$^9bDc=KM9l^3&Juq_m;~qU zX2}b2qC~ywaPRc7DBWnK(H_;o1h=abvb4?G>_ly3(lj`nX%0wPBH;qUIc^~9(?ex| zv%*tM6sPdJcs*}Ux(HtcNK}!da0#TMt;lMQ=L{l5L{1f}unz+3Q)NCQ>~mFp*MP$6 z8<h&IWiCLPicXjBjFV)<Rvr6v2Kp%>Og2W8TCIsOu@qx(_G?1rb5Lxh{vZQJ#83)Z z#E2sC*-EU0ZtR5uN7B+mPF=Wwnp;+|Sw2R90YvS9v_rA-DiS$&S+>SjEg}lGUn%(I zpvO5?Q#9e6z-oilG`S22XmDk&KcR(X_Uj^)F{$Zf$WknG&Q?CZ5nRS7Qw}-FHuagr zvYEv&T`+LX?l{bxQBb;=e<W<gm$5S$aVeW-DD7NXKaYprlOCJTO1r`ua78uHIkFn5 zcLZMdL%lNm@<h10_j4tZkx<;oM?~M0{KKLhe53+R>?KQF$01Os^~Ynu-#CtF!%En& zCRkbAz8EOVD=9zw{8d5MntRI$AT`MnbSWnhAzC~fq5T}Mu=Wg-(F!K)k0hl8(fi}u z<ZT;<k`<c>{uC#liRaWD@@EMvYLw1Me9N;Ejp|BuP4!7i>#8}2+%*=KbY-g_7*5CG z3ImItj)E4$w12xZ4LQr0l%O{<4rnaB`r;sFlx@|CrgNGp+TqOJGq$>d+l+GP&_qGm z<ES}CHo;%i(i=-@E5~sVWM>eU+=>nQ@fCwNUgEvAPtV=nW8JNO`z<6_yH4A;bMk>~ zwUF_ahO0+{FS>De9_#(rzGclQk4eg{AtR%{cxZ<>qgwEsr53~$|BnhGtgwd!10}IP zwWj7DUJdxE8%gzkutH-cqHk_TMnqLlxV~MiO>fmgJ7&)$P);NgRKn(~8F5K&WzKL| zOBsAZW;-;HN_Uq{2+4xSQhT4{kxk$ZsVX7G?Dj)-t-@d|ZNZXgZ<IdoJ@=x?)1My( z36+zJ`L8pNyp4%Z;jBy6#r{tJTG}?}+gx;ZZiE~L1NDd1RiUOb7Z+D~-Nh6oc*$h1 zr6W`XJ;V#&B?2r(_MDE{>|2eF2FP7{q#wCUeegycQ5bk^Tx8&<zZ|gBsyjO)E=pT! zIzP}p8Z%i{q6p#Y=I}oBCLLUq$u7I9IIzbA+myY0Nu!vZ*9H%JLE8?#D(N<t^X4;v zbkGU^7O%U@04S(zAO*0P%(0}eb}W=7h_8CE2<nZW(8f5hc1AQFhgLK+nO!CaEk1Dr z;QT$dK5R0prLSKgVvPKe#<iQnhN?|f+k5lTRlG4ArIU!()ndla)pK?jK+OjCx52qL zb7lg1gDn)VP#NB^*ooXBgef79-((7GsBBHHf&CV=)Y)BCLG{VsX*IsY^h`t7)5$fd zSj#8fXpM^lSl>nDX?FdE9om%O<qXTo%yvJmDh@}#ih~fiH0)u8t1182?hlsbCiBji zAL|=NlHUmV88F_^pEhdphhVj_q{Xzp-Z;kc%-9~=(0XaoHKN+VfJeu9$H0Sv7tl+u zcRhT7PH&&ZF6%n$KKlG>cTz#Oh;iNs?aH&d^W}FuhCaJA<H{p)`=C??t^hU+{)O$} zZs4aca_AUw-48PEyfKiL8;$Cvinv3=56d(_Qm@nkk+eD<J^rXCjV^n#TJlT{a##(y zl9ruPD#Oyood?Z1jScmYor1<f8Q}UKpF1WbjfL4M8}cz>=@0^{#k6pD44sV34QHW; z-F;-Pm=7&OT&b0k<XMQ|rsRRMB`IHUK8u1&c#t?qs4=m^OPx_peuOEcw+6+kzuQAB ze66|mjZlLQ(<1Gb6^9Gk%X>0&?PCKicnZkbgmUoiwvS%D6<&T_rL2IMx_^8#)r0S? zkV*)D>BsvoL-aX?=z8>64fwKkHu&L27j(OJRlnRCb3sgig!6}<@XhyiB}&b7w<Yk- z1v|J)HrNpKl7G{&CJG3h1}}hyi8Ts;QY+}rhyz=|g^F<bPaH-Fi>xq2V#E*-WXi}L z?)@zEMmLw5uWv!jQ#ExIOBHaqCzo>OG(HD;yA<YbK;q#DB@X0(26%V>R7Spoc)nQ5 zP<~=q3wN~lz%vLfBI~t<);tRG+BP%Oxy7p1{F8X|H*YGWmIS1^JBMxN>s$NNVKFME z#JbP|Qz&~rv~>zAg34yf<@~gw4FU28sB9%pM<pZHBnu=uDxZ{z&sk4gojtY>qn^wL zfE{&L0U81VqFKB20xD;d%HZwXfTD#1+eY^NCg2)w%~_&8HK84Uw())A9qB$Y`qyd> zdBjPa`&4$QApQvm_syGUO2iZL3jf@p7A@R?W#yazf_DKIGWafQxw5_qy|#4QxvgI3 zQP!USoEHBfSue%0Rpc^*9_`Hmmit1bcv*G4ThL+S+Kg<+g0617+V!(g_Hfk7!JHPR zUgg4v4TES$hl9+1?em`oU;9q8T_{b}^2;%JPoUOC+A-H-2B>puaYtsp?o7Tlv&nf9 z69M<$$f%Z(RXGhzTb?sZiby>z@OAai0<I1ZYNaeVAX>5Hx4mM@<?io_Oq&uMzZ3YS z5keW=n7!QW4-BP=KFIaogKR!4QczHeX^+3jK955Gw!g3l9jJ;O#5%|4un(hOpXWjY zNDmNW$0g6`)O2rP{=Xv;mw_VCv&r{!)J2yNNa}8m#aaIM*@djuF$RX2G+D6p=cezN zn8rp%{t$1A%0-f<6<ON(#y=`v-l0@sS@4}cDp*`y^UQH$+nFfgU%op7Hh{VBW9YYh z*|1|!GQed0l4kiPd6}qCHK=(e4BmUT4CZPM%O!oe7TQt5dh*{NK(7WkECeg;)?Paf z3zt@)^D&P=(`zTtMsF_AM!`LKO&V?ve>wx&F@bGZ3~)vE?QVt}Taz{o&ajxqNEBkE z3c5=A9lB<OYhw$Jk1?4YF?u#hEoDHp;rvSVf)>q3<2t`bdun>E_Eg<4&|MG{hpj={ zu;h<1=wXX`F}1PBve+vio%VW!W3{C~e6T{SaxAXwgsE!KVwkPqib~6D7qw5kJTv@I z$qw`OC;0U6|5V77-B`K7p5wzV4gAR7v|%a0YT1NGuIGrxR5}Ud5!+z6J1pv1QljQ+ z%J#Grx6+KXTE_QsIH+*Vi)hC@lQP5oa<GM+yfI&x3qJ$p+iEVR3SSx@YReiGnbxeX zZdU6u{j$-Yyk(53t@6M?%QVkvg03QUwu_LFtMlD)l+u3Xc()*+3IVP4V>E1~dSkgb z(Ypj7#Jf7|-)=q-r~c$|MO&A<{^Cq+%aov~a6i|b`aV{-Ir!ZHD=it8UcC~LtMBRY z)sb9tdH5omL^s~ygp90>#v%K*tmB}?nWJI32mR?eJ#Va&r%v{C8X<0KZFH`Emxt0l zdT{U13W{E7yh6IuVmQr&vU$q2T8Y9UbgDEkH{s@8cJeulvsN)qpy;*{R=KTW-CNh| z(yy7^&_nuj0Zc^*kzd$Ckf$<VopUI*+k%n|sHsuv*d2ZUFMFMd(hH39hC7d$uz9(c zH~Vnehns@05s<~?j?Oiox_^D^=5UYk<%$2jFuYkZx!W@NJzrxLD{7(wKmwk9ZB0gk zBg3-u*W5s(w6-)ty~pZZ4H|po!{uC4UndMgUajQ@LH;@WQER&0fyl0LZH?_<YAoxS zb`fHY+MvIexoL3C=th$nSRo9;bR5-HIsWmDafsCUyCL9!!SvCBYK4rGX(#Drjk`uJ ztrNLel)Zvr)1J6nx|O1Qq+HwfoGk}wS&-&2)P0HqDhUu3eEf!%M<+64GDZR5EK>m9 zPhlW;$p<U76?!x$WCpEEs$e$>BKf=zOUI(6>hkT+WVzcB1!!ywlH;<8^kuCl&hh-> zF(*cv>vH!)jNFGOYQQ|8T2l4dps<QdXHwkQI9-50EmQpXTTJMzpg6xw%EJ!0u)dA+ zRoraQMBY}ZbCsi%4;wM#93E$SgXFpDP_CLbE#&k3xV>v6g9!7}Lx{NXrtacOiaFfH zKa*yP9RrdKV8v<`D8<PH_MM7EmGMxs)CC9OCFl!DmNMx&J4La$byh!Pl?RQ=__0`> z$G^r$z>=8wpl=z7fi8YF(j)!8lTMbCJ@@mMiLO`;_NN0XmP2f7jq#;i#}><yORKbR zFpUOLnS$q-2D-N{ql|$@<BRR+tJLnsy9NiMr-_aA5Hi8a06G~hf%lP#6;Tr4_O+QQ zj&9`ellyj8CGB}rC$2|2G4!G&wnOCB?6NpmV?T_AIhhus>|e$e3rAeCSZyPlOzkuU zbExW*5)C7m{m5=YiP#RuUvaUv>E2hRwcpm<n9t(vor~j^;||N&dj>uiH<H7MTs$Of zDY=6DgN9Ak{KC3k%$3nkA5lI8kKB{Tv0-f9#~;d(N15a?<mawqQmOFxOx`;AKuCT; zt1TP?6xxEX^Mj$!ymjw)s<Y59Qk!!tg5)s$++Zt;qFOCA&C94w5q964)KHeUsk^Vj zB3#EDRj<MC$GQe~STFh;U_072-r>F~2ZKj67=UmU68n~&;DL%W(+O>+g?5sr1@7vN z@dn1$?HLQ>>;^Fg#4Q+=-L8((whzu)8<eMxIA30iqp>(6H}2paT~Gyg!_WYk)h15n ziRg<02e<RceXgJ4l5u8N3WJH^Y7>y$5j84bf)Q`qk%j=I26s>uQ~foTEpF%aldgzj zOlqbu5sP`JHLj%{fM9cORhxUr=!$dBsAuD|Hj%qUu@6M@*>_3aiF`(x^<c^_&7=x@ zo~rhYr^9D;>OAzf$C*v(!UqL?e_<R8Linx3<S*S%M4F!1R!Q%7+~s-&NHcfN!lBH- zO6zF~G<eBjO<L_w3D;rXyLDiIBke*gxz_YPBt8nxJgvVx8otrjHh=HE$#aAi+<5t| zxb^uv+`JkX<Ad3@0T@nRV&)gcw3(8?MW`pdB<I?=@@_r8#zdzwS6l5JPhFVUcRF2z zszo#OHUl3wDy|;<^Yo1fJqc{?Bu^;Js!$nLcrIV~2|3pA`t8ZLf>s;}Yuc|4=owcA zOukk%l)GTXVJo2@QQ}pXHeF1@H>2v1<<W09nPeSnhW0sz%b7q(c{!WYv`TmQ$pdx( zi<g>_gTtq|_?3s2X^#@pR%OL4kq(>_%7H?@#vk+v@Ej7=GBEM<OzaS%XU+WHF(@yw z9E&df5@cmSdoAk$16tW?qG;O2-QleG#emNp!auh<n3v(OzvD3cYMC4JSdPLJC#+OY zVJn6NQkuj0%%)E7@G)FIU@`AB24KpV8lYqQED=T^xv7X^h<{+O*}TXLi!sWhPz^nD ztJ@_8kPq&}!FiSE-A!jjUH5aA6ew^|b3>58&C)~%P=8%2xpVd!DlW@EtnpAm>&pfe zR|I*+V1qEWF??_A9f5~n;+GNd2_<@<plEPYw<%CY?ON|PhVfPB(jMF6&C~+=o{<q# zdZ%{nKTN<sz9+|RS7=rQ{84}tbtzVrI(D*NKff+$h_ky&NvT9U{9{*=y?s|+Uu135 z80|AQ3^llIgYczJZPcbnzT2Z>je@ZIWGJXQriW~Q;_-=1CFII>k12s~JKCy^uBMby zi0co~|CF5*uLZtJ>UnoaZshOjRQ(jjItZ~uE5HD)&&7Li<WS9NxQa<p7wK`NUe6Uk z?o9Z%9ZCRv=@?Qw>qngUt&u;*{e3){$@+U2{PX;|AOCxX>t)wn;I;?>!Jl-99NwkB z^LPm;t-dvmkZf8!Z;Fi{y5KBH=db-%8HM$oE+uPLd71Vcv2cKfhJJ>b+j@qWOOJv@ z4nLImnF<6a!7ry@b(?lC<8|LjU|$nY{8{bh0Ub25$K~`A4xH8p8u-LPdz+lRxB2=e z-T4duzkq=e^x<kW2mpW|%>Rd^+8WrHIN2K*nK=E2_^Ha+9kTw1q$22o5MrnCYoUO) z+RqCu6ovss8QN|5>r+pf3MGI@klgp(!cZtA=Ipq_Kaa4!pFGaMh`sKH2y1UU4?GvI zFu+P=i92`D-?U@;T@(vC&JN2Ah^Bz$!MA&ca7`8Y9`|^us&uCL0-F;lDW+bTp?=vX zZaOX#-O2M}fsO|yFeLI>OD|%e?%J_}@UniC6#-!97re9n{v(|-9k(iD&j<;suT-8M z{>eZmov(aEqdEDp;5*nWi5WSe`gtda`ZYu@V%5{+^;1XX{OyBk#Bx}nX0F8@rbTW{ zIPcG3L7p<ttf?jd^pYE>3>>*Wl!dC}y{|%#!caP%bT?9E4Vwt_!>qPAI&qUquM@V1 zuVcFdR?yNnh$vP#s3J|ew+yDOo1}$9TmDiH>aT6Mixqn$oQm^<&!?eCkf})Xi{=K{ z*g%RS#cM-imD6WBT-7|SHlgRp4hyV1&pJOQVu>0P?`&qo_JN3du5zB&wlJ*w)y4j1 zO*fR1wp^elBA9XZshcy6_)(bG(jmZH01GY`%3ETk&gu#4!JzFy7ly~QBzW5WA!|Np zGjbbavd@{tqj1|_gkhf`|A32vrT@|hDbGR00PP@p3d4O*p!w^Y@X(jj`V<OwiUi!V zw=Hk(f~NXrxOXNNpCv7^g+wqJgV0=o5&KweVAt{Lk)ewxD=+r98|{h?##U|EhGBiT zB}gG*$T_%qYJfN#Y;k<>2B;T~q>Do`iW|L14cwE)kwBH_82^t?pT$;XKi3=OgI>K( z%8p!zolAdZK`sxyE2_Jk_S<H-lgk|+(*e;x{))EQ2ynjo_b1?Z`b9fj72iL#WLFfz zSvlMkyuSqM!YOQE{`|XqK+b4MZhVn)ixGmWK9s3SHsl;t!N5!9w-Ef%a|Ki;Z^qy4 zt`oF#e3%D>BB(JUBn-EsfIr@X0h`B4HFmsp1(H)JlbgfB_~;m<NGXv}ZuB(5++BgD z82H4xtLMz(DtXS?xfEPLhhMYLs2h0{w>aWeCU^kMn+@K|X9}FaY6p?nTJ<}Y96K!k z4&!^US_-ETe2o%GsUMI<A2kvF)Y&oBd(N+Nk-S+<nKtMh!}L41pVI(EH@QO!dzX5Y zdbGoH&}skCr_{pp5X$nzt~D9C3;3U#N*X4A!Pq}5d1Kr)t*C3fI_zn1^SY%&kv7el znUBq+duA|tJAM$t<S3On&)P}g_PEe-;K>zwP7rgC9zi*4PwjxyJy(V%@BJ_ETVhlu z<@RTwFAlx0?%x&5^XV#ZBCX;>PqEV;pr!bfqk{-~DM|T0em@eQGt^}ft}u<i&N`M- zW`1jP9SkS7xISA6O{)Ebtq%hO>dpNs!!X53($Kq1nRC#iJ3BfHU>xPxr-N>r;y>f? zQHuPK=5CpFm>ai`eV?MN^_c+fUqBgQ8fQir%UOs9JtGZoC!Tq)_~kMx{Fjqde}P(; z6-BGnD!hk#9_MkFWWTAdj7Q(G$ZPsWgMZUJkdng$!iL~1RL6{RN3Sm1U{FFn{5HRU z|Mvs~jp})Br3C;;%mo0z{$E7u-{ECtU}mCcVQc*VxcU_zE4MAt#51>VD3}&Je^yA1 z#-t1tX)@n&<U9vMJwC>a6c!X=W{GHie?a~T=fv-8tvFvGSjma$9Vfau32DTgm4Dy! z#l@gLy?c|-BcpgEvv`x_bf$jJG;LA{#NtEe_!RL><cL1~`jqNrqh+9{R#jcek1FK1 zdxu4%_OHq;tw_;Nr?}<)vC#7xV?~;WYr)SnmI8}OhE@8Sgi8PX^KLh#+JLvx^qE6G zp4vp`?qOJqIjfZ?R+Jn-nS9K}m6BW(2Hr^3gQU5C7A3f|=s=^z>XJroL?I?<Q)9YW zl#Aj@Ar@$raZg!UDZvB8<<v+sl1oR0DVS+9djIK08`<2?$H&m;`D5DcZd~B0#*Xp^ z=zImW=)h9i9-qgj+j}{Al}e&n-iUJ!^OVBf&2w1Woa`Gx04GIlV<oj}@HRKqqJ^bE zm6$-z^hmR~s-SNVl1j{>{B3FWY?JogVcS6&EH!(Or|-kiMAe!dF&3HMdlZh-I%!_1 zb&lNS3|5~L@-T3kZrk{j$fX2zWo5N<(CNi1@|Om!Q-fsYh9ZkaWpVjqF=CF2wq4v0 zGnE=Y>53~srbXiEQi-@?dUM%W5V&oe48es);|)-sE>uF5s^1Xb%S-7}ig}_&?((xU zmUN&gH12D>BHb?U`;;5mUSAkK72+WR|6w`QF9BMVgfpiv<4>LO*Za>KU)g;RU-l06 zj~M&*=gaj(l&aUd(Ujyg->Mtg-JS(I`zI&ow-~!S4nMv-``{{Fn3vtp&&lyq*Qs9n zj)hOvodVLI_z8ecxR-`Qqqi4`UT#itJU?pQ)mL88dGe2s_K8ewX)p-LwgZ1WI3dXJ zg6yBe%O)@UK3-YVaor?O4P804b96sx)yuj?Yk~_fQV1rg(Z{Ade4KBnp#dW-s6Vi; zyxl%5KHyisI}uSf5XK$oOe(X!yjb6y+;GQVhKBw<N%(tt-oH1;m$!QYa{}AMD&225 z^L^-fac5EpezU80HuoL~YnR+sg#@(74*<0D6f?x$LyK1?36XO2qT-(=)n$*3nS-fg zdFEbnbaxX^oWKQ2Yy@`c^i=%n)l~X4H)2}Qc)0`Ox4L|vmlL1opJ{tJ{U@P_@O}Pz zSu31k$*^3wU)Bw)%GcxPPiy-#ts1E#=_GRlbC=i7DPK+1zPML5{JYYC*M)%UAWXSM z*5-sO=0Jh$sr9mP_}MYkV7cja{E0ov)4;h#CNE#i6=(`QXia|^ra~>J^vu5t_{0^Y zgoi==x#XGdEl5{o?t~KUKy37@+!9v`TY8ATQTT#xr%1(t^y3f#0z?0t0i(zi<yQki zPXT~)!`&zc?aT5P#f4%ea<Q5H6Jn5YFs*ahdGI1y<}Y|sO|T9R6y8n=M&J1j0f^&N zPj$}HIwJZPA^-*o9E<rsJZLJ{<GmS4`w2(G1i<Q>)XGa$3+M|_1zLUQ85lc(Ax9C` z)HRu6hOo=CGao&&1X%E}Te2w&NhQn1jfK6=WtSnP#CL{$B#b{}uviz5Vw!aC4whoz z`)*)Gl$DKQ{hqsj-C3hk>iwuHZ=c5|seBv{X-U5u+_J+Qs4kt9I$nsq{<c)$Ki37u zByJn)oFrJoUKnMfJ}O33Li{9!*C2WUOe6-qn!@<qk&d`7SLf1zY5)})?i(xf6ZIn> zVWmU!*$B6QN)<|?QK7Mdc+O=ebBW$Bm0Al2#~07T!VmsEf4j3Tf6EesCZ#uG4FmWM z35Q+?Ha2C{cCUn)zGH`Y3BvdLVtD&Bb?sOqytp3aV>}G|G>B)=iNn>O<-P|8HNaQ> zwqMslS<$8ymvZ@&Ge8Pb^+zVtSddUyD!b2&P|g8TVU!*dXiFJ-GRiNoK?i&WDcvZA zCRHCFI-VapU!E|8ND`0kL3cI3lzh-0r`SKnPIndwCoRF$AIc?at1Xz-Re4#tD3jH? zKn7^*#h?baVpK>geSyeLXhYporMimtZfICk{=Sfs?efgt+!R0>wl+#!gaH|OY}<9e zxz)vLa7ScSSV=G4(VFkK3OX)+F`t@Qyk(Q0@j0o81Pz+m-P)o&Q^Ga%;Pfx1Eg6mj z>^8}`bSI!advOkC?DOn^sA;}WKhqvq@f7Rb8KIW-q>RmKZ21x^zO0QLnJCexD++Gz zwcx8~#$GV()-5vY4$<?r!6Xn2f+d>SbMg+*@`pl{$g=dT>+H<2Doaa5Zc!C%B@(9p zy7wUYI$uXjNeST=$85GnR@z845;^snimIvxFmwnI#%fEfme8e4p?3GauD$vGb*Z-$ zdJt!pYYKX1MYSj=Yla&EO7fp73k7>NkG1_&$3gnkfjJ~(B&D%SRr9V!!?=jg-c8P} zb{Kkp`F+l1fnYByVO|J~#u@6=o@VmU*73s8EQjfC+Ju6hvCZ=v2m6DH>y2xQ7N@a| z&fDZ8F$0<8<63bZLd6keLS*%I3XB$yZ!KbDB=R#!QAy>VLCvJ$m{M~X0lQ=uX|&+N z;BV=IzA^27rQU#d*9BDu+-oCO@M@p+h`V{-6c~w_R~X1&LMR227>Gn1BX#<t6!VFF zPV!TJx-=t10$0BNTcojZ&r_&lr)_s>{X25(2B>LC+bJ0U-e0g)8!%fI0d_t&LLG;w z@u5d2?FN_{%ygjfVh}W(Zmzcy3ITi*YwbWN@G`kC0U4Q_RzHhSn1hORl6_vGpcMHA z>2!j8!zWcmBF6P|{#t3=cp7qpaCb!TAYvLzd&qGyzG(Qv&maYQg#Bc*ywNH-qj@YU zg_%ZT{JWF1oV}DkUc&YAN{Eo@Qkl0FjDmBd;nV8l6s!73*)d@06-e;QemWowf#uGl z`WWE(SpFOIo=i!RCVA3<o;`pn3kv%!nl|;qO`z4);sHe@JOa@MY7QY_4PYt}2;&)R zB>KY;uqX>+|0p~&M<}WI#l(geV8x+&*(<Xk0~oHpb+8ez@$4CA__t3W6ZXVERhW>5 zEiwsaX@q-}SCST$q$mmq`nHAQvslGaz~*bP(XeuB^%Rj{tB5X4)eBGzbZk*1F$4t@ z=cgohjx7{GxGZCOGIvTy_6m#Yz|jM6;R}|~sV5vJ#Z(h%%1tDW+-~8PjR_NGgLXsi zbN4^ZAMv)+?903emWo8K5Fqi4mBGx*RrWpK>Aul?rN4l^bDE*N2>3w0p3dH^%`<%K zJ;bEy1!eU>L|DM7;R!f#fH~Cg`dV$$B|J4SkiID>(1^IPK*|Qp>j*aSvG9&fJ|<D> z>0V!Rj7bP`acgEnvvF4GN>eCIfg9c~!%gp-7Zt?LW3K!$4fx&t;f!Igfkkg}0-Cdy zio{ujz^d6$IMM*1ck4tQ{rzht>zr7RsEH|A;Dlx7>N4#GelbWb)rtxu16uCE*g&oZ zwb%!&pvO=|!;-PhVsLr=r{_y$bGbZaegoxraroeJfn@_t`yO^=XY^hVIO$-iVL|#k zzUwG&O=vMN@qgi$h-J>j`XPHMWkW28tU65bGi13@k1%~yk%Mf30%rvF!^8i`47k%} zf?Q3VJEM?Wwpx?3coQ4I<&;g^Js^&;K6c_`vV?LClSsps9^eC(No;|h0<}Bu$jAIW zu78{!v70k3qKfWaMZ}B6qzd@?)=H^Xs5xxFlmys~8fT5j5R|v$=T-y(D#55<CACx6 zZ~_Jrsl~rXHc+H04Hl(3*FQrzXLF_=gIItMr~YY0Q*maiK<giLyVcb_WV1>r=2$yn z1z9?0*>0lYhr}L#csWve6+TvQ{)ihhbK_f08Sf&aGJ6eua(`Rr)Y~8<A{igx6c`o0 z4y-iJ^?@3u%vdp?uVS_6gr%)~Kzi%m1^V@YO5HHbFv0*o17G((tVXE8#9g~TH%gQP z{4tqXNM|9JYVxMb$IMTZ1Cy%PzuWLXV*4%@G!63qAQH+kN_s@3gQMLIYpb*D`7_@A zAYKFEFU(*VFomsAbWkRNCJyMFRYNX?3tJ;HY1L7sHo-agEhhkWQF`!K5<O<{@BICv zAPe@x1|(X(siFVHnr*&#QCyfQm>+*TTkcY9R3h3RO}Z?V+(?a#$Z=Rwirzs)K;~F< zSUi@gvAsgvcd#_TYQC?(9l{xe&S+5j2MLE=2*Jbz=1Ks0zXnLr@H*8h>@lWl(9D45 zHlphVL}J_n&3+!6Ue1-6+`s}*NGBVL)3hSTkx69wE&-ky4oUi>HtNm*c0;-ZLebX~ z9*oGsVwR!Q6rUZ9fiJ-b6c7*IaIU0h&r(s@mgZmG{-)+W`pC?`3g=B+1ZQ`QFE5SP z@Qw$T+p(DN>r6;9yZx|76ARGG?Baev{i&ba15DSrMBukoG4w-0D|)Ii*)+carqtpJ z%!I=Dg5|3!mjFQ^fTF(l)bZ3^(Dm&QdM%`ggm~=^sh&=NqqOPe{G#fFq}f>RZ1==Y z-q8FcX2P^ZXG9U9jC7r4iy$=7y}pkS3`BG94n5LvegVI@xIDvtcwZSm93KZ#U#C$+ zMS7~|=tC0g7j(QeBQPg-Z_Jo;_h;%kYVfcrWlPoLndi!j8t@U|G22^&%&ieF$o)Eg zx2y?r4ne2~oQpJJwn{8eqUXnI6<87R`i-<x%XfTWA`Jd~Qvzcdz<8Rl`AiV&Gca<% zgy;OW7DRAbSt<MDOu$BM>5qXwPK4YY7Gok^1b$IvI{`G$`A6&2W&2QM8};muc+mUe zcowcp^bZ`-NIN}N6OGJS0WBQeDdr1SSVDa3fQW4E8j9lsGQTBn!yX6=2yx9gaBn<Z zekyeIZU6p>H_hzLG2wxz0(?Z{*U4eylNgMwqsVL5)Ac0KkDjUidY&}2;t4C>ibfRO zn}~a!O)b+l*<^qsyI?}47OT(q0|TC2vj>fuILnyQ@;LsYI;k#7a)o!c?3Ns6O~#%L z6pPy9`Is0X8{S+sm)?PnsMLZ+7>x+@#?7R-Z6JXwRV_{|gY`fspFR5a^boRf8{TPs znhN(p^H76GIK&17iq>IZ19N?yai@WX6+Uq$cgB-Px4hsk^15p^&Y60}MNzI9vl)rQ zpr~|CmN@J(93sLD3Zwgd6`)8MzRqgP^SkeuGm2D*FmZ~BRP&LWF7?==o&pp%RxU(C z>U=SwuAyNcU_e5IYp&P&w8vORHs)EH^6z3WuvrPP+-oD3f{92<V6pP12Sh{fmzCKO zounHx(IT#BS5uV0zb1lUK~;-#^XU2Oq_)J-0;HtW<u4dvEvgeQg68`B78{wE5`fVe zsCceJv*Q(&RdTH_PL~v4w=kq~u2C#Fg3J}#300-c#3D#O#QE?gUZc0QfRZFf*El~h z++){6u{_c|oiFvmnRkJ{OAm`dF7TSO#flCM8p1*7&a`p7YYz5hc=eULO%}uDz-C)V zV|~{xjjz2?&@<`Vl$%Es^gseQALQW)8O_v#q~!DTqDHhCEZ8vmfy?VwbUU_`&Ipf= z0U~9s%h_oQ`!)I822reSKyk<#YAA|usu*4XH3;&D05st%nx%#NVkD~;uThN>_w|2e zVWS+&Mlp`K$j;!m!XfgJsDAV@#Ri72+>>Smg0>yZ{3Q@}5K_V%I+aKoKV6l>;WWw( z1@r%MSg`2&JK;*&SwvHmrsrY6rMT@l#vW?u2I8_EJ$8n6b8~w6^T19Muo=g*aHT1n zY#`J^SY*V<*Mgh|Wufw)6o#VeW4lCmRF5j{7N<j=_YJ<-7(|<`P*Q*R2d@C7nQiqO z2GAgBlchhbDLZ&&Y1L~i7uu78h4=aV{=k-Cc)Gs&+7D8UO@S0$kg!Xbzq9@^x%33C z2J&R2g6qOH;hNqoBt0COw^%~ev86K;DNA+$y_}2_n&f&KN+B-&6Zo{oG6~F^h>0<1 z1xDZZG$y5akN1_&{pb#EEO|HaUfUi3JD~v3o`uj{)iYq(*m$EI74^u0<_@!>+&)ME zhv|55giu5Zf6K@HqA-b>zOTX1Qro%O8R7EMjS&D*GoXG;e&y5Sql}+;(@iEBf8&z% zyHdbN(!9FReFv%8y@H_dK_x+4A(MYSO9Mqjex?CS{>Q%N(gVomg83|}Lbl$(i5J)o zb{O2yFysm-Mgf|@-THDv)|aIYEJ2JW-7x%57*V2UYO3<)P9C2;`_;k1C9co5P&aO+ z@?+3)XzDSmTqg0YJz(Khqc=>dG_bK?Yw+`l{6S_TPJ@iOoXoQj)w=rA0v!JLo%NYZ zB5uuKtr6AShtUApk6haY4&D>7rYbY}I@}qdcgPt0e}V#D>~?E(4dm0UpdyoJN0qOf z9f9>y4PE%dxRL&qMDani!d_+j;pP$}uW5%(n)&V4Hv9K^^BhAYVzC7eOpbMWn|s=N zCR###9Fcz$Y8Qq!$~GJaiCd6uZR?JYuve_Cb5-YK{KuQChSrk8kgDe{#sZ{|E#iG= zFQ*8Qs#C8}aYDvweO!EE><jU=HC;L`mQ?TeY)shMlJW!#5VDKb<0F*+Fy*NEy3KiT ziS6~ap!uU-Ee6-`H840!INX-h#oq!(KK>Gi<$-{MQpyz=Vvi2;#yP@oN_D%)9aSWx z2r{WOs#3+l2V$J>DkQD0wWjXkB>S+TS}K&PB3r3sEuGs3>8_pW3Kr*P#^_FLm^d7Y zmi#J8jSNksMiYL2sSi<0aVWl~1<EETa<0JHTIKff6ZTfPf1-o@2Cwa8;uLvZ!&)#T z)&(`>iJ1nk!$sg}Tr^R&tO{nR8oKV;0=jQ+;h-GCrWP@drp86CyU?9H;<-s-h<S9e z?9I-)9AH^pcJ9Z|+D~b`G-mhLx^b+1YuUttJKZVhdF6KDmV!FiN$rSFGacpop|w9( zSs@97b9)8YOOXb@07S(5HzM@yiz!9>r+Q&!;%arb6}*a%8f=(|5KpasfXm&sPM?f$ z$nqN=5m3R278P+4#1BUARLpNVtN+w(l1t!iL${o5PG;?goT<7N^#Ie|0hUB9*+}3I zL?Q}ycf;6o{T`DolRgjf0C6mI=+`;bxN?6+RZ<=G3(ZamVWAy(QVbHea1y(MHUz`# z<ow^xnwiwdz1PTyfp)JY&_$?yx_3iIUqt<XVj|2!2AiNRicY-YrH6gGDLl*Y_9}$B zPfAlq`-;A5%Rc6Phsxu7&BOt*ZjYi<_UHTCoR&+L+IO|x9cz<TL^46D4*RwFdz5bL z7U}d=gT~w}yAdOmv?zXXLE%LQ{>d$m!*o~+giYz=AtzbrsX}Gh&^s`c{vgw6H`80Y zR>jy}B8gtMz1$-#fL0%+3dBSJxbvOL(lF8UO9Dv6Ct(DDh>;E;YovID1$mnYOHGZJ zLU3EtdmJ*vaCn+xde)YNzR{2Bqf9v^bk%5Mbp{;cn4L`*<sgbn)0Xp0Z!->iwAYdd zEMGa}bt_d3K8hXwnUe{oCFBTl=p^kJ9)EjAg5bb;st=xOpxLp){VqUIFgi10^Ql<w zTGsI&;ORm>^Q|HN3wiElm%pOoiZS0*pdD#5cIOd5+#ybXn@_w`*#SNtVmQO`@fl;j z<tFtr<Nga<(<_r}SdAz#s{z`NFNmH1AXS{Kn>r1@0ENb#dXo*1MFHusp0fzlf<DXA zTr&CR^V(Gj19YL@#{70^HBn<TINgb;4#_<=wbD9CdAVI-<;%4?aw_o{l$65N1947b zz<kC@VPhi?3+KeE(9;%t85hn?+*nDxgK+({StP1y_C>9xCRE2kf2aE_X4c<cT1p{{ z$QN#zeaW=0=%24lKR4gUmxr)_NPTfmjw5O|8I)-R*h#`F1C6P%mWBDzMXoVsvY<fQ zj1AO4?Nc4^?iFE}XASS`k5V{225>SV#<QsiG?+6GONCugGg~E=+$mYJ%=CLFGSVnK zdt5pWJgqM}bHeW^_Gd7M{??>lU{1fe--@Ema<5Zo1=3aD4J%le*i0-Vm3zep-9<Zc zJv)H*CWQ?=7i;jvtj;5u1y=Uq+^MBi5zgP4I5#Bw+o>6~ag9bC<dzx0RGf#(Wm?pn zB{z?1Vc%^WIoq>*!ioD}6Koi?x9Z^(WSz)~rcqV*L|QA=NvdH0LD?_oe8M#?{CrjC z+`!Z^Jb1Lsm%N$Df+SZ00&NJl7H?N>YJq@PQY3B;0^qG|y#e7mJ9<4XwAwvcFqr$n zahK2=fcmKNWdoY|h?}7N_Bz*E&1i}-k<G+ANkz9L=mjvsn|$c^bJ1(85nXb~H>`R0 z=xnYNdY#MZz0rTKdJTo+<L3<46bMN_1#fYR<NmXNx&e1}LzX0qFyl#fG)bLR4Q`m) zj)XcU!Q|Re2<>^c@cp#YB0$(k4Mw(3C($0xM3|4OFQ*VrC&dDWiDc0e0)>@~$|PtB zy}?K3csYsw3ydjh@5v1HlNX*e{Kv&T<4@M^%=uzEknhtCd7R~7h-QK54t;o<3~o4S zH4k_~D`p%;@CFSvNHdh-u_UT@7&tHWQzLcsXcB-Wz+7ZkI9~BEJg2&+M4ycT$^7KQ zG54gO`5S%#qQCDQDi&aL2#cWeh|tK<d6Osy#7X=O_R*oCqgj;%Mn^fz_$VyK$m%-J zm&<7j@rBfA411b~0_TiOpv>Roi>O^4-MAs&SM$KnO1%VQa|&?kYo~K_6OUrbV@MnT zF&n4B6A&4CK}0jdpjGv!7@DMSCXqU+sJm*wW60VU!~jQicbr@A93z#0VNTsA7UZoK zlGFI3QaM`yba6!?S^GP!oKm3JosIzts(?QY8a(Os+Wd@3U&-e>T*&^N1}dW6z#Imu zjmk8)`xE8v9BfL4LdaqEir6x{){J9^;8o>0-HDa!t{AT~@##>v{p%@_S3~<X$;i{- z$=l}5)JAZ|+bB&Wy1r6}vk=M<5nfu(;73T(JEb#54k;Vv7e574FE|SO3I^5qNWK0P zRdx5ZOlJk>X@%Od$u4NgO&egErP!K0QN};Y_qIRab$eQMV1F!xLoEI^&nsz822R2H zSbmXUvlpK=(<i1yM{wux;@~7-7*>ANgUbx5hlt=Xv=gPTtHqUYVR8`YF)!fHIL+&X z8%la{6z0wBe~U||MQ*mi5K-mulTxXN^lLNbJw1GpznzxaI?n{$oCiLfTSHDAe!?(W zmtKmxUnaNYh@{XO9%#;5XdPAmC5K2^m$x8st#mJQ8cVV2sDp70#xf)wPd?ZVNa#+d z{dMdw){i|p_SDp^Y;CsNu(b60tsl@$nv;5ICRw<US)D)TVMaX3!a*Y)1LbVH<7#uR z`F5%wBuV02>lwR+a%f4y%}|G621eHQe4=M(b+IM4$D4NQ<_Hm0W=d3piji+aiGM0y zhe<7iM*QRux@N6sN!DlO)Lmk2<ZCOgiUd3hm!4T{5n-;u(RMUuxrJ|%jc!g}XAMVi zsiDoZuSMbAxh)ceTywt1{$_)<R$ztIOfuIX+6)I+xYE|rQKu8AWN$>cYY<c&viKV? zR@DBYxcwL$)hGt+dg|^Q+db+u?>V?|8%*pZYNc?_SYBoxCLK@!ZtD(G^cROx&6Xt{ z*xXdPIENRdgR_T&4O=+QvH=DxrX8>WIc5x%s(vwsF~dK(1%kDufW<^U-<g-MZO1i# zRlbP03is_f%SG7yl6kH5gnQj>czx0NO1OvG>5CB<pV8&<lj4WfB1f*$oi((Ve&L{! zhTI%oe|J2EPXd+iEuKY!>nYk+EbjU#g>l}jdq9;W2RaZ|E6~_JF5*g`2qyF<Cz|0S zS)WY8-~c6mrOYZ6-*ax=T;8RBK)C0xeRM3NXV$*i9ULGc2et1IK)fkihG%GzTMy^+ zecm1-Ve~o0%h=(Kkew8BR+Ax7C$lw(L!=*;D#qGpHmy-}+I~V3d7+_HcOFj!Oz%I9 z{Z})1Lj?>b&0F?YsxOtOjJR92CI`b^OB|i%OANkn+;Ip#*R&0Gr|6c49e;Ds^Tz@W z(2Heda?L3AuG1YsjExTFFeAZ-l=-v23(UU@J6IpLMM&WXcuxTJznpGND2MZ23)ru$ z;48907%`@|-bH>G_i^x!vyN(7D-($dA@+MUm3*OdzKG(QV-LPxN3{oiKLJ>fL0ezX zW=(j<$7+(-1k^Q!Bvx;!g>WugM`-IhHMrurqES+=&01r(Pnls`Q=Qk9$%Be-QO?)b z(actoncQw3_b-%Pro`63A*MPSwy4ws04k&=Bc0@-(}4wTy%<*cVxUGYix%c$d`lg9 z6Y0pL&^WdG_W+cm`e>$!^W>vGmFRrum_)n%(S)yIAvj9*eHMqK)KiBN8}(dy5p^|e zb5ng@5#*+9E<<R%PBb?4<Eu-4-66b|o28#rk77y@EtS|nEtktNSQaP0r5d^C<&Xx; zy=I8iyDqSzII7F?{;WM+UarfcCPx^qP05fE?aUG!F;LK1WDBdKD&)Y=BlFt$I(+Yt zH%tZ;sk<1>0C-pbT|0J>Vhad8^L$5p5m>O<jeC0Dl+?-!76n6L(tRaHt(K6Y&!)&% z12=ZH9(AH8SBh<+uNNRczqGe0%m&XxM@yi;Qd~!WUAO=J>Q<2|xSzgQ$T{iyXo;6x zYD=b1`9TK(7;~-AWP52-CoKoPxtESfOqnRDFPIOVYrh^Z+RmZq#c)=fWZG_pXeT#? z@7UlI37+jr(h}FoMm_v!4&J|L)bL^1>)du^`H7hwpz>!?xu`_@L6VBoQ?p94mX9r? z?Z2EjZDtBW?&nm)_5<}drp`hWt3xk~Vlgs~84tr8NG_De+-8HKZsxL7!4gZv7=J1` zMrkX49%1pK)C&M`5eVnM?!qb~74JQ9^;F@uR#IPNf#kBDS%s9Ur6kSMm4E?ES2!8L zITU`^nFdp22y%7yX5gm^@JDy~xk~Gua?Tj_!uA~3QBSfwMUQZ-r3$ivJow+oaZ3OE zn5<G~TVx7`HOW(hqKgg}h=m@8F8nj9TFIx(_7P1`h-JE*YQvNv#s;g_;m&#S)9h@1 z*V;i>!uuE4>1Vt4K##7KHg<lkap#)0R0@V{kmz$76UsB_ly37Od%pxX`h{6Nrt_WC z=GqakOVm9#{N+u(7S+9$gbdu#FdISG<!7CJe~~7feb?mhH=rwLqYSB&D)a0PC>o{s z(K?9a+_{F+c+7c$VlBIYh@-xI8g2F5f5Tvr%0omVB;)o4$f}b~fccPy+*D#+%GPQ+ zA+>iEW;pa<ImZ%Ncdx$B>hzk9pn@*B4)h(B0WGWuv`kwPon_y{2oZ+$=IwhGHE|_A z5%kbg%ZNACY6Bbda<*$7-Fi@-Uqa<Y6PM5z(3#V@o;;ODEt$=18P*DP+Vb4Kl2Lds zGRqxJRZ3l{Nu>xtoUqGy{8Ddnb3J8)0V<B<B}SSR6}Zv_8+5hzlsZ@WW>0;!VqrHe zOqfD=0q({I;%p<2L7;wFesXHU#OmJ<qEyynE8K*RwZGl@)V><>g8%J@%`dfEB&QTa zB{9Y?=*#vqge6+`E$i+;MV3^eA$QDhJ?J2tsPMH}3#QYyj&wa#1jGq>mkIF<TuyG+ zSaUI@K6I}^0G2N<f3eAYLk3G}qxN_{U0I-GK@`eM+<>|8MOb4b!dzLqxMddIWEQP2 z)G++s*rfAhuY7NhdYFWL{~0DA-@Gj3ktdy37~yv5QaYI}Gz##MG?9o*Y3+bTI&O&X zmUe<!Nh1CY7f^bSQE(Z3-dy)>NH4#Dp^bHrZH*-CO47aB;wv%^LA3hA2UMY|<7S(M zOR~wfC4C(V**SIX2~W;??*aI&h=c5<hJ`z)mN?H)bn?s|KrhrU0G~u~VJBsA`1fTN z?Nbd2^<YaCkm1s0&KwfD_QKrv&1ghqA`@)GD<T^`FUGd+8&c3-b5Xkedo@VDRJqi> zb$5+7GU@w4Y=iTWpw|x~FV~Re(RkkHODc$q7MNr!>zpWfJC_OtHPtxg=b3yjg6)Si zjiq+n?#@&9`NuS)PX2W0ZNWX-+pd(#RD;lsT5(qp=yEF?7gab8&aF`aS|J6-18~|d zi8PER(x4;86X8FQQ;9O32iF=_4hP%X54*ihQWF@{)B($wR&9?q+ykqd%qDxA>69{~ z0iQO{8J_Kc`jb;VlWdO+qH{Z9Y;eburh(QA1<=3i3BcsQ*7(ysT*ILC&~okxbX(B0 zqw~4UzAq-2I=#($cC^zr;wk&v=Sc;B>!3na{}OrfQ1o^?<7DqZj}F{jwjEFsk>f9U zy>-efZn14gzQ*n(*@Xcr?Hyx2cbp^1Se4k)%`b;>GpS5b-78K-9nlVdi4KMdrd52u ze7n^tPj+~}ZvSatt86=vHF{N5y0u9yiQWCa>tO&ewh^6l8ga|l7xm!80LAYw{KS4` zDz_^~BI_`CvHFm`P1>vi=|%L{MJTKR>nwH(p-^;jv?w7^Asnf}=QMFgsHfGuxhOY! z4s5U!^k^7M>y0ca!n*r<@<J6GkRzg`UZacO`V7BhBS7i35NNQ1&IkeynG_fw`IAY~ zn>}Q-uHG(>N5aN@O#Va#cMac}r%i^k$0TKQztV&#^jPYlpSJ6qeV0CeWhVqJMYp7@ zHx$1vU*LWvrr@(o2^V;eL2yR^qWUf5_S;##7y*SU`PN6qd4LPb24Z+|O_FB!uTG;? zK16iWddLMf-Krb+8P2}lLW!QwVFp3XuJVmhG?iwf4Eg?S{uFLUQ!T(OPZ%g-utRnM zpf%_wcKK%_assJglb_S0vv%?Wtf#|zwK9mOCv#=mcS%xP=GvTPbwE!}K>c4`{LY8= zZjO1+%CZpOKfUjAfULNhD_+wPPb#}Q(H3I_g>h9#EN5nhhRWX>@#NhYT#8mR#EVMY z)v=zZnB9k+16!hvh^a1#`Mo>1MtPsaH4@zQX?n~8C(i9LeHgk;2_1T`P_OHjU3<iB zs=Nz+WUsc1`fTK!?ahMBkS;=?s!gp%`6_Z9vn_y3z><cq*cro**fBmE#sz0M`f1vR zG_10PEK&o5H|ZXEz}LoUTAL9lYU@Hwyh0GaFQPe#34owY`+c66m4a2<aRKd?#_&$+ z`hUsvuit*asgYY#fSu>x*$+SUsi;G!qAeOe{T2=IL$d*lAb~$aziDW>Q-EiIBs-cU z9v$&4z*n1uoqZ|=C2d?S_b;TMkD<FcouqFMwXfQr;d^ESb-luRK+p}OOx?nvKz$p7 z-KT|xR~zI3h-Mp<6DwO6FE2BP|JFM+BW1-aqs{T?s0p4G?=Bd(_u@+O$N&7nA%4*> zME1eH@6I0#GNX@Vhv@&F{Q9zeyJO?V?yjrq2B<=8FH&-pg)Arc+mn-vho2L5Wo^mG zcg#{3=}Zos10b|2Ukx-}DzF}B6;othvUBUL1cXdUsSFZyAm6}pj#7fg;_$cj&)V2y zEg}S;PyE?=<wtnV_J4i7G4Mz9$;YDR3bu|f!Stq*rE|X+G-~<^`DjVyz~eqYAD!)3 zQUQIj`{5LbIc6e7XA7glNh5o4<Z@XzB>l%@kNT2^=!i=ss#~!%>;NyV7JtEL6LCE% zH4DX$<6i{Ttd#gQH)gi0Z<v#QJ8ODa=99nfdakD|u6Q)IBZ65<YWpn}#yslOPcdnr zt5In%b2k6}YDWJKciYc&D`m=cJx>APN8=B}S92o6Bz6)BU#igBLRl$-xS#zg;%wOE zaxXvKN2TmLo(&?KWPvKtz$@kR&6`uzqo(_L`8&0tr|X@|BVK1(^~(h5@ltp9oEi+K zx3famTzo<Fgf|Z&m8M`1k&K|5L!sX;x|1UieTT<T5Xjpm2!=D{B~X6f;pMK^mPb={ zcJ~usYu`*(WH13454=B*gD-m-i#e5o<&jX1+pE_M5Efn=t~lYaltUFSM_iqb7#}_B zSKJ9}n(XsV-~0AZU~T%R8C;PiXIaD?8xPN6Jzk~54s<B^ISWb~s#7#aStT?9tLmmZ zl@er<vyYse(PH;TB_esxann?zMG)N5f&bM+C0ZZ@K(D+KMX5>SwD7r?Zw@;RrClL^ zza^-v60|nsYcukPQkWDglnLidpF{h!rC=7I*NoSn|B{wlV&hJ>xF7cNkSie<B}YRK zu*pH}@g?UvD{XGlFqftf^IHf;W5h1W>gOHy+XmV(%bzDDLU-XEGcxp-H~gN5b7gu< zc9M^_iN}ik_EORM@=W<w*che<{x8>w)-tB<IqY1z8A`p*Tiae$5m@WURkhEgvF-n{ z^-fWu#cC5^+qP}nw!2T;wryLdZQHhO<Fswtp1$)iYu)?LL*943WM`!+UsWAdB@z`& zD823^O;Vj0!)|vEDg9pUC%w~2hQ*n>>S`ufFT1Nt=s+p;V`Zm#HiBzF$1gLKn4CMK zpFb?DB+zcO;myewuT4B)A<52z-wttYAO90XW3A*<Ms(J(p&_m|e^KrHH<hx)gE06k zdV7A8AMgZa<*c~UbXHR>zb>TR&DSccT21jUjl}_F<Pp%4b-7@S?YUu-W~+23%<h!_ zKDSN7OH9{mWCl8Q>P#Eeh$pT8UU7pokTCGu{$LWV)<p%C9kvQsNF}iqjj>I7Q9Z%i zjgh|aqNxZ2ORYy6R|$GU%dAmHx=cwJy^d0kZuP)R>eX3QxoQnkDWz;jSi)=Hsz~jM z`nWjNaiKs9_8qpELSejMkp3GQ3|*}%Es5(wX5krczq|L5*cKcp(-d#HVXo4i0_w*i z>c#6A$n%ri_%8~gdySvSh@y_)rCp7xt}<wl&*yU-aky89jj#28n3rOpm=NOhbU$V6 zOO>3t(EmB*t7Q-Ufi%0=-H~K468SvS{e%6<C~+NN?CVq(ZO2GD3I@u{$?*(;^CiE~ zG>~+$4Gh3;NC(U9#3+sn&&}v(xExUp6XxK>-@?pw8$TKENYey$XCPe@coKVqJ><19 za#}Z8x-UKoF+h%%o1YvNkC~1iw04!JS&W1QRDW%VFD&Qgh*aIbSOj){a3-+AIQMsB z-cRxxH@c#;0;|834_M)*{idt;lJ;kV*0~Bxe~IUrrT`ELDrwYgJGQWIYV;@=Tb!BE zb(Vn;@BMEsjlQH%3s&j4(9Uo{l`|T1{N-jV)<=J)>|z4Z6ppc<5}{oP)%Y{#)=mCH zMm%USod(?oJF|4<J*$V6d+g#WtT@4Bj5}%Up(5URG0%Q8&pE38gUjYNz!PG(NJ1-J z&O7ZH_&DR0Fu=H~c+Kg>;Gj#9#bxH(ge&8*6;#X~D|wgx=_5;Ekd5+FWa;bdB^!2o zpa?tEz^9yP-x;ID^W!D9HJD$3Hh1Dpu^V<AN8|dCl*9d+9@V{d@ht0IZrcFmZyF8b zCz&&mw(;(w3D2dN%nbS?29PZFvcGg}IRIpbi<(KOSUW=QU3w(2Lx{7Q&AEFd+_20} zx9{^x;>+R-eJ{7i*WMR{BX^m=9M1<!^$8c?^=ib_-ABi#o2<!?s%b;Xrxw+<nTi>< zLmE)jab9wP-1*5hcPvVJGQ)w4jCjhH^XIbSj_Qz~T1=vcTI2&A$w@-aNyxn}@Gy+r zo7$z}D*a<o_loCU!cSEo4u}(xpxR$8JCD0Z<!&uI3nKLKj)ipx;^QO|u}@Sb%Y>7h zV5i2wRMM(LQ9*eiK3}>CXDglTQ%M;IUl&UWOsJ<Wc1t;xYxn^;KuZ;=#eaW)Fv))| zb{T)9Lk^5;mIqegPFzEsPAK$xNamcnFA<S0?}(N8Voe<9XZyezfPVJcg`Q9SwTON2 zeq>&SoZg}F2-^arsU;;ug!W*BWgf@ndHdU<HOxLtVaYjT15s1d3)C`kw|e=Zz-oWE zZp*e+FXFM@_rAi2X%yjQ6w2J9_q;Bipht@wZ0`4bT^HB-qK7zGWa$qVSRk;3Nr?KR z6kVPveZ}XiQfrC5S*#;S<O_PbcIQSkPD(Y1VP3xf$3s36=z2>94gkQ0>i-CK>`m-h zm{^?+%>E<Tsn+yz+F(Qa(aQxQmk&J*E}`vBaG!BI;IgeqXL)9sVdY&Z6e1xZERjfo z-{_F(`M9D3K=NLd^eknIfB=fx+M#;}wW+U6rdbsl2`p~co(LYj3#Gkxo@PqNjcr-2 zplRH9H#4K0RAGf5aPCgDVd?>{bvt(8+VN=TP?v#wBlL5@=njWF2}_iuXhWzKX>wyp z@8W<Wrzfw~y}U;8kf=0eq7;SWzA`4_Ugf5FYk+8&Hs`_XMT{8ppu~_Ta?L$%y~JxV zNj*u0A!}%K&c0KeF`=1+?Hq8aGZ(p>F^#IIa%9Y8Y@b=^GWOOja!`p(_r&}A=uQ&V zKxLv0^4hAY6PrHl(82Q1n3fvFqL+E1on|*&Qr8n|(Gd4k;gv(qq=6Rcn>JDpA)QY4 z1c&ZH;)vLtLRcr32z2M)mj)T)%|Jgj$CUD5&yrC*JQ#hlX9;FshrA2%ln{WnwdoLa zvOV?1Yxx}tIEwvOEMC2?n8GY_ehqh4=k)+L7Q=hOyRc`M938-90Rk0<rf__p5Jh9W z1pVY!=NXMIgTvf1Tq61hvW0cc$3X#^H5}x17}xKc2@XM3w`1U8jb24@qWM)t_P(R4 zOB&fAqVMDZ=LxGb!>2At@1Kk}={1S^pWwP-L)wG{;zyc2D?zj%>chZl_x{P>tUS3~ zPW|P~wd^tIG$^(X3EWyik_`gdzV&e?@d!L%P<2d<4~WQw6O#b63$EN(TzuUhi-$2! zS0KAVbuQsw?SK_w=yuq9cc^rC9l)SCN=>X9I5DgMaH1|mrgOBub$@cvAI%tEVC#gG zX`#BPm<b8RzIw!=^<jrV`Er>}*4fR1sV}sTW?Svq2kU_8V8HllR-H9OU#}5Y8aq&G zYJuPYDRmVHGGw#}2J-MeCXIF^YuZE>a!uYg&*wGtUnPqq*Z|*=7HLkNq1nyRWcRg( zeW$hF&Gzd=QU@7M)mtgcixt%I!<aG3Bz9e+H%5);&hqYINhQebE!y*At)hUSc_1-) zlXSGGD49@uoWUqv(6Z$;{42s_l(YQ{x2v63pC}AY0PKe~AfVmMpccM1<|T~W!68*` zu>5vp4_mY!fYt63R14Y>)!*<33I7AI$2q=jy{vBrlQ!XiWq%+tA(7p`&i(|Adz`=q zl|=}ocyUyKeuPGRzX9wnqX*ylmAv$EBai|hI)yF?XhZJ~(nko>ff7@d#oT<vnq&S$ zTWJqf_Li#NuI+&NNTEdj%c~i7t8Hey=gc_=dk~8};F}|Sl^TsK#(j=jVaX)i<%o7~ zE^GB@K8lE9ga5M7{mJah^IQcFv3TL<Q7))PXacv9314KOTf&HRZM(3Jh(dTjIJldZ z?=11lO4Y$kxw%C_8__bL`3{&njC19_(LLwk*sQ)4NSS1a4a6hDKlQ%aZ248M#4Xku zoZ8d7`F{2Wu}l4y#{phF@$L@bkn6f+r14G+5layKaP8b#vq9DJ^9=u<G{Z(?#NzE; zt(+~%H%{*O^7(u`?_W~GtY?0zm_oEX9SHciv-5Vk`|x@3f4#h^tqPtjmqD>_`lMab z?J{@OxDtWyOz^Ca5QD?;$AN&Q_Fj45eRQ)!S4;KU0SkmGvI0;*hb7v6JFPN{X**{Z z%@XBS`>3W<_;X6xY&=#c9|vRNR@!WYKiN`jI5m<4MQ^$2V~K^a9bF4G6QReUg$%d= z@rW>wT8XthjR|BaqEM&}jcytTD|V)()0lcB=jG;H-Ao6NPq(7(3T%aZ!k>BCIo|H? z9(~XELr;pPJ6GQnE>P7*fljcdJJBb8@gB0LNIo%mxqGm1bJ<rJ=cfXQ@q~$1Tj%T4 zf!L6-Tu>z(6QS+mV8cfQ?b`gJA!+o>lf}lU7yN!B?Vj$}tCI&ewZ_Utz3nW$y@Zcs z7&S7uP2m!zT4R`a!N0-+brOOg6o*Xx?$e1#RHH1R1z@g6mR4iAj-~nrpo~P61`cfr z5fD`rf}ii!$C;^ly<GXBgeECZKujdr6z9VuZ9r8HQ#=AKC2j*FP%n&_cZF>Fe6Yku z?LYTrkbcIEY-=>oKTs;_Y<L<Nad!eD5cO3bpQ2wkX-y?)8YWs#i-#p6GSEH4e7>I$ zkIQG-byVvT#zYY!NVZMo=qk}F2Z^Rn)8GgMj3|OE8&kc2X|yf9qxw^6S}CQIS+(hv zYI(eluFe8Z+e9`u7}&^F>cuM2Xm}gP6v(%-4l*A=pu*ZKBZ!0VT$IX)F<?-`PT^?A zXF^7Wpz-2mejCDNnCrOy=2kh@=GVq(=hq<0dzwSEu7EI9BR>03n5F=;Y-3G>aa}sB z>ZKV}6k|l|;qSB~J&#C__?&IRMlfd7fErXKrI_}x@96H2*fDEde=F1<EB&^t%}rff z(@QNb*=mCX5j0_e+@x5_rFR>ZBm@t;s6csJFZaa%>9tQRTDBXSOsE!2^vmVrK}cq` zhcAAVd>@I<qos0@xTuWG^j&FpnT4H3Kz%vVbHG?9FPPWuyAAC7iWSloMTNQU<#jPX z>5A-C>`SQxO&eUYlBmNV5j=|~6GG`nL;?)$l0;WR(E30UnR#vsS5tQTBkN3X$1`}* zGm#!B*hkP1UX(d1GK{hlI8Cl)gcrW>8mzEGu}4N`)CL}&ON0p1!gk9pY8hj|!8?vJ z-%8}4<C=3BJ4HfPL-=fiP#`*jM`7T+az`}Jdn>685<y-cRZoeKc*Gq~;(D*QyYqjv zJ=JDtM_@zepu6e^y+-jCVHiXNOb5o}_Qwx)Y$FY5vaG?nuCZm3nZS(_g4p-*VoL@- z4+U)x6$0lP#3__&Wh*wWnpHmPZvNpxv1|~P^LwAH!{GMfCRNKH6S5X{V<>g6fSO^) zF9B}CQbEC;fe(0adi0Gq^)ff&ur-MM1bQkB#|5lk@yI}>4RHevj-bcO<S2_^H$FK` zz9IB2J_NQ)e9W=b+&diLaA)ENMal|+!$3RWL()_OH2@#RH70hu-Isex?RQg-D-58l zK5`Uw%E=RzJ_gzXX|eM!7I%m?7U?P_B;iA2y|f=G`m2xN?`A<6vxbUS!5M0QS)vc+ z-x>5L=@acXKa>IM-)ocK{RnR%#A2H!dG&#K7h=dH4=6VsfJh_W0%tU`(qki%b*uPn z8Tlb+y+%JWT)yc&mGV@01Aw;XX#i~D)AK1IJyqir3^P?S=!wCmVi20@`);hWG_CVG zWr{`Y8r+nTAHTu1aq8zQu`vPh51J6UJhBk`t*rBR{uvI;;ymlXivrdz1d1GDvH4>E zL#wrX+sJ6<GmGrmcwgP6NGPCdz0b2qWWjTozOhb7+sYG=Ti5QYnxhKVb>+}nqbJHO z8KtO<QwB_gX=^DUp{JR=(zuu1_V+eI`^+&r*TFZI*i{k$KNSEtMpwd^&B+b$gvHa7 z%#fY3c%z+i&R2JbrBi`vwAdHBT(Shr0S_B!3T355Ml#OQ*<Y)HZ^)E=J{-p^FQJN; zi+j0loH~4K@zZ35j>T3xsft^ocmWiEBuQQwVNAOqB%=GUz3W(kai=T?8m_6^dRZJK z6$rND<XEHA>@w|MyqlXs6aVo|7RSEtF$aMdZ$c*mWA*mbxJ|>f{4r#MK2}Cxr_@FK zl7Q(rz;pG<y8P;4VE9aF$refKvW5J%P$oULY?7dmom*xd22iSPOM+q!SdVDja7C8P zW)1;an5*q}=J#BWJZyt9#a+9CEkhtL5nvwu+LNCS#+Gc&aYrK!*`BW9bDV!9XjJ^A zQI=(mbw6Q|#aZ;|(Dv2{fBv?b-|yM(^!N&Uxrm(^in`^2*EDB@GUj-ut#rh4Zs)Lo zw61#DIH;SOxGQC-{stX6quQ!l?9-7xvVeNa&m<PxYiU^<F&laX`f=%&l$dl$zPQTQ zf8q#Xw^PC2Jc*4!`%^s1|3Llms%USD!d&_u?7aYe=jz|xxnf6K=^X83mjJ@UqWX|P zUBGC){!udQnX%;8QH~1n7U0llQP_qT&!c+Ol+%L!y$UtGmjGJtJL584W8YFZR<oA0 z9yRh_W@|bw)`9}e3$<%Ms?)`nAr@(Xy?|6rTMVEb>rBwL8YM3IG83@rMA)XxBS}8h zb_m%l;mLLHjJz9U4zRJgW%R3UP#wBvn3C52d+!$(D6D}}f3}8-FQ$!u(`Q~b%N{_Z zGR2#1nrmWEFj#u>1d(!?tjTbiJ-pQT^KwG7{^jD@z2zew772%f7NM}#er^oNQ6qPo z(<u4kIH)^KiF(>h8V+zL-0dwrCvMJ~h2<pZk=vghyripD;X1hG-I8?Y?|O<(qX0-M zSH5)e{a_~#C`>8SIjX6Z_ndHUctt(kVlW}Ql7PnL{A60jk#lahy5UxQ!DQ*Nz`V7* z%r{f}v00j`bga11)ia~oTM3kHkf-Lmyq}o_X)C>8GAuA-+aNS7i~qx=j0xHycak&8 zVR%c0ccjwMe6WU;|1)RPAIOSOxm)7-L6#aIA`vl<G|-hSi_)Hhv*YXobQR<Vz2L0G zz|DMT#=m-zV-<C6X66@Yxw+%g^B9nJ61elcS6ROm_6Wy`a8b3H7sWm^cggE6(+l=f z2Q^X_=pYXoJNSdV-7*$@q9{;-S)2!AJY7U{Z2RrFUY|wYhRqOdT?jkK1ZjdwCDFt= z*aEWGDm=)SsrHK8#!n474yWP7jmd+@+i;cmZ0_p1Yt6NOV7&(~oT86e%^ZvXIW<1W zLmO#hgz>ljyqRw8l6-3Z6rDTC^wARN=A#|g)E%Re^gHKI=(D6?h~y5NdAtClf3IiN zuXRVL-CXVugzx*QL`U<tZKb=AjFX0Cc=Ty$atf^ejEPw#73c^3e=DyWOiR`1e)H%s zek0BPC(g{?gNfb9&c@!r`4@`*jc2qPWIzaU`-&Wt#-U(JTM!^n3Uf6loD(=RPI|SD zl1Q1$j{3TxZl9Q2$k%M@dg&hRE}$4HY}BpivnuomXdU-L$KXQWZM)qSD?5Vww+d9D z&jR*GByr9)*`ts{sv1GZ9u30d{xXX&g4qaz@Iqo%C>)LZG#=YThB?oYQNbc!;>jIc zO}oVl@UGbZk^f8{$B2a|S8jAAlWr&)A_is*rY@2`2+vDlt~O^ZfnQ-QY0#MNPs!A( zv|D)|kMF-7(C@VeyW8owHL=*m&DUaE6rH9};H1hoS58T2#&t*NFkoxl1kc2o?np;! zM8SSX0c!~t49p=w!;2kzmSFuP-d3n%-YJVpH}o2+HcGlQG2FDTo{AYI`Gs0wY4mp~ zWLfnc{>yXchX1Lt!yn*#&)*ue{AT|BpBghW{(m+0QJj<;6oBcvQByx!kWzuO7Y;<0 zu+NvM-u0iel+1D+<|C>Fp58f-%>X#slV(fd#q$!gI>=hK2b7<cvbc(uJ(H30iRlDO zR+QOl2Z}&$yKzSc*4E8JE%m7=ISrU+Z+3xLW{<~UOY05opq5s5ERx&n84BHNp>HFL zWD&sQTBtF(=rI+OSt9q6>)nMT;52Pqd-N4JCxDDo*slk#sE3@uz<7b#25A(fDj5;K zz!~f4L!@#ZgD5dAauZ%c($x%o(KgVI)Ndt38nA>VQ})Pk2_++$q9%*edg5RU-N#-! zD;>aUYUyuSeh9A7^}bFbE{)XZiNteb)K}dTBb%`NZl2fx#LTo_g@VVJp;`PM!no1I z={SipqN5ni-x)`6l-@(W5x?-&G)iwb27ZcVKUm)zHkRTEJgOCvEAo;?IZQ`5SsWv^ zE*l<hy$@<vz35ke6A9*<nEL}xEEPggvz~9h&t+~X^(=bn!qb9S_(kpi{y%{&sxa4h zn7{u+<*%p8|6MQU|8KoqlyvMi2vB@Z)bhGkubC<>l6gcXi)5OYC9Sw**P6;B5$bD^ z$zUMHQa(R)>=QZgj{pH*vYci?Ys{lta#RNp=jqy;y<2yZG^HrI=Oz&MuWV%~Vpew7 z*%SI&Kn~7Q-IdiVZK5Crx$>E-{o~fpL%D9T51Lcx!m7b5pSk3$cLWYGCa}NIwb{v; zH@WJ98J7J|iVtTPL&ra7^c&2Wo2fTlx=te574qAHSt9O=<dJQpbO6!1q?m*x{^jSo z;teoTyBM|EMV053L_?DD7?lHSyjb)Z+pt92r-`>q!o<_TOM4vsl0dpQtpFPHBugc+ zWDUVsbTrk?#eI{kOJFqc-{lH_lFpCttHQ|)67v8!%V_6Y1~>1X?m0@wkt%sG1|vil z!QoD^Fp-o!L7fFK?GRnOjQ1wXpr}R;Xm{}9f0l)WhWsGb4~$4)Y!Gm5dI*diuuxpW z{j!2%)A;55(5&CT9%4%k+4z+p3uV3I3T{sI1C(BNZ3XR4x9o!_Yj&W^!*k|7CP}Ib zB`?ZeS?NvThlTA~d;CKQn>Fiif95n^n}j^n_Zq{9U+#VD+9tR<CmD8diWlbX-T5bK zn53(_6tFp1;THOfdsTT{_pzVg<xE`f^hWp~{g@$w!PZ*ABCG3ex>_l9;n)`V{CBRZ ze1L2U`;s@EE%Kw{TVn}o7gyd6KF=;%+hiKOW5>t-Cw(tkDZ^+M9spp79RL9Jzs)V2 z3~Y@J?fw%NIgM>)w;^`l={uaGgHx`&cN9Pr20&*?a!n}k;D4Z9V-IU6T0<j-QhuG# z;3E6;F+IiCCasvVcx+EjfF?RKGxO0bQ@{PM!Js(<<z4D((}Z|AQ}hqiN9Q)gc&6t1 zPE^Z8MhD$iU;!di8{yV^RSlNIM$+)+_8Q7s#o%9fJCYq4GH8w3bR^kMLS;xEga*Tu zu6<W{5un%vmu}RFftig0>qx2TRV>5}AGMWolnPrDGUbLfUZ1R`3s^e<{eVsK%mnr* z%^Kt-`?a#n0*#S*@}8sl$G71A(MVz4!Fy8;wK|*al<;aXqV2t%73V02VMT-*isZSd zJ#_ATpQ(aLO;S|7s7gs<H!!ebI0X`Khs+4s!EJ!C^rU7O!R>#^X+?SIP`<mVDRR1H zB{onfa5WA@9u_yqRIu0(LqOaA995K8D8oIN(u*kRCs{&h=`3Cf7uzjKW;0&8CQhEN z=A&`DX^H@x;<#^e+CR<y1j$5o40ttED=Kc!TRVcbIo0czx1nM>q8#8SjYR9DK4qom zbv4ZFet>YYLUC|$72LRy_&lRT&<$%U!(I)XgEm4W>H~)3grJRki1hwxC1JJG3r;WC z_80D7@f80olR?W1M}8m(;P>EJLaS#`ZV-x>>QFiUjyMX#GtPix;W5@U%BhbDhd7I6 z`Smk&7#1K?LfC=NHX}WDoTm1rC6QFUtCnc*+8$A~meLD<C1EcK2S}Z*rJ;w2%u;q) zJQx8EErt+}%{tmQQwwKWIX&AhDC_fd{fIN~`(OmJ?T8jX9sNl8rY{|?>fxtFFfO8T zj5iD>>A#Pjsx`~4y|5&8g$ML&ah_-CkLrqBf9)D(CZk%Cy5)i>%5$+-LCxDhZ%<&= zgX}BYN5D3exL6twu?9_xq;KM5d_VIaLeA|O$GeMxb_H4CE$*~fVu~ev){QDDwSq{t zXYQ=`1@CPnC1{=V>jS`n3KWc;kg7rXP&fk_J}KrXM1YAWbyee)%~h3I6{lcUK$d_} z8Sjrs5n^ghV3m$}s{`$r>pvbS8t95ralQ*0uurK51>uzCks`P2Kg`$?%L{C@7!4;4 z8Kbm&l>;P{g)UEABtp=)X3Jm_0Vp~OCpM^M&^4twP&r&=c6w!CF8qVG)TS*^rN}x? zK^wqzYgD#ijzl7hD7>iQ4!`CEEsN&N9ZC_4Y3>Jap#b1t8Tb!04Y0US-=a5-fq@M^ z<{<boE?r^!0Lm8m%^}nP>pM?gYTslXGj;G0FIw(dCZc<euV2@ybPmi(DT#EAv8=kW z88eO!S{LmH%q3o^|DFI6dJfGXsEgWowvOVUL_b%k#G*>1{dQ{XHoy(|bfbW=kNJ2C zp6+B@Qv%m~{#IY+0NL#(4JJW(pW}>($vVDh`9S<A_c1H4wI$ssIP>G9+%<@={Q1%% zZA4&=5%%^<^YO^Z7_=(nOW|H<FIFe)*?eD`WT8uh1j{~;HcVhkn2U^L6psP;sq${C zsLG?pv?qz@IsY{&kRp;7SEGEhRh!|r-#N-*nI<4C(*zJxwiBXkoJL<83fB^OdL-m9 zSqNG=+dfZ3XfTLkDkI}xJZIN&=xZ}=3yxHNNohrgP1dhK*TCmw1*C;+_I!G#2zsI| z|7N)3-=K?yeyi{PTpMrJ6&ZMqq5S7)9=|o;7*Z8amcQ~JlK~7>iz8^~5nJxIRKv5; zyoXa?|FUiypGrr9k%|tO(sDrE2{!gn4Z$afb_tCEq-R|S*U!V7opx07>F|kt*bMwI z0!GsE?@ZI()P?k@(F{GCJayy)X(g?jFzP4vtIFv4r(p#lT4pdaV=NYB*R3U=N~zu& zDaMOP-+0VlB@fhD=q>@tcYHx%tenfKHl|~^ql`wm2f~G(!U#r3{i&48lF9`T`<pVl z3OG0|*nmim5l(_A#40q>bK_7$n{??Ni~IT2fy(^>!oQ|y0gkdds8*aCjXl+~^9K4_ zpIjrIMCe+fz8YAR_zU~d)-DQ0&aDVCSr-a`FEQK_bI%hZ9c}Ee^58KQs0C2==<0wM zpvRXTza3y4TQN#oc>BB$uRgc2McFl7^kj_(;--=pbr4rQWp$NJBWm{9HgN0eYvEDo z4BW^0cGW0$7MB4qih7%l=>3@Y*?=ZKZXkZEp~ctK!v}Vypq+o{PU;xg|K^$m)mF<F zLPr9CL%8@>G{ho9;t)~@qXZTnn=Tz=YpgoU!tD`)&#|X+I_7IzTuQ*nZl`AU2%2lG zmKfkbmAV7g8}9z{8=y}D*+*Dwp!T*PWVonSfW#HFZO*f8bd2pqSQ=<82^9lSKEIwF z+~nCJ<kL52T8%qx-7Ahu`bu@r1K~i|3*JuUhvXX&FJwTM<&%mW6)gOV3>9WO4w8%= zub&GJ>^czmV%B3S9Iui#E<$B*Vu~M>vnG%zmlHmrWz||nVJVy%$e0mQg1ZFDOHXUR z9~L8}w|;0ZP`B_KRBB4~k159=zL|o4#bhzw<2ha!^&ak7Do@40ts;ud>qlycz@O%N z7nZ2{yNjryQ9Ox6i#Z|8?k7Ahd;+q}d9oJy4BaTk9_7qfn5)i%5CxI8ZY`2LN~$;O zRGoVA$iAm9r6pyvC>i@NiLBCM;$OlP!n(oCG52F&s4264py~B%@bKs?9zP`I_y$#2 z&qTD@!LCNB5$#sLFvTTQ87kpbpw){EY)dYa0r5It66BI)ovU~u5(zLJHqP!T7F|y0 z<1>f=+durH?et%oqM>UnV>R-6D6t;~B=Q-`t&m0Mp}_HO`^Oo0H||UdRt(@KBAfYC zoUzJUI8eY}tI0$Zw7RFu+nKc}BcmwieCMAdtPNyK2lI2e%HNA|nT_pCPww8I@B_pt zZnDd{W5ns?(s<s`yaZRRv65j|T-tGX_z9O2N=$OB*cm-tWLufu6`u2FxQ0k&TY;M- zBP}Q`@q;4jYOfmW_h-Q^_zWV|6m3G!#V@4}$BSAXpz@^!0WNw^<#!QxloukzA;--! zRnJV!8JEZ9;8|<F?ok}!n>~ti2r$!erorqhjX#DsYV@VRX@KFJHuD6|#|ug!D*7Dq zr?7wevXoYeO6P7`>?4jz8Qfu?ur-HM9h}&Sjd<dA#}qm|Bz~K}8PUTM#izUxw_`Bg z_=@N=Z~7L#9P%U;j|`nD!YK^(x-V2Rf(8|O<MuHef!jALeeRSd_p!KXc#Ij36Evak z2e9{rVU~qV*o@kN)cpMa0QKNi*_H&^?@Rk(h|wUK!6{a~ftAs+B!9GE9&9xr-e@f3 zs-7JvcI|yEAH^3jlkiwlM_GpKShki()58IoEmv}DgnXVcm$-XMcC)OH`<et}1);d= zL=vt}-JRl#JSm^j1(ee(klQ|&Dn~$gTGCX=ZeUD=z25xWgLw7*g3VrChW{wS+<P!D z*^>dZ>h{<{@{W<d_2O#EoXM`gSUE1l8bf!N6en>Hh<bvRaCtB2$>+X64RAJp6oA2R zPHq-yXLHXJU}HN+FqYO>@idYZ6o@a<6tiohKx^))U_l(CNa}*_I>u}v;@b5F4calA zJRpmmr(Jsg;`(#$XT6-${*H0pa;C6p@Sry@4y5(>_7c~Iiphz_9m$8+1ilI59P3@T z{e$a#t5$v07kg;Xy*2@Ey^j#~yjv`}7=KHP{@ppH>3%6`KVoAMSV3hML02A$+YIs| z0eucyXb?7=y#6oeFkR7n8(V*7aUQd#BTVr8!rdgAmpSAu9%2u_1=1t8qBE0Q>V<1j z{^yuDWE9q#QYGzSDhDotVG@_r_*UjcvY)LRl_!`NK2@VwxS&X6@-Wni_PWsg%F|m( zxk(4@$gk}6+ThYDYOR&VGrX{2OyL}v^Mi;+7I#bKbdO~G0l?Xx0)3-`R{BF%!}GZo z-Ry==x7+6d54&BH6inass8;|@NT>bUd9L|oUByn0)IKGiH3z}McGUUPs3N;_4aIAW zO{&S`Ywpl&qjY-==rVtM^_gFgv1UkaSeMeFPP?s9=Ja+`gDx5cgp3>mMQub~$t^1_ zgVK7H5x-F>BQ9n5Q&NeaG@T_p(p2sJcB==czlKz=mUAfbjXVw|Di)vLW3yaKY#ca< z%;Q$N0Nn=})3b?ah&EqLaGwL9Mc_g0z00p!4@(n@JBn|e8PYyzINfc`b6;aTFS)6f z!&!KwBIP2QdaoopPEQ(F{qNP|>?*q=4HSL|r|$i2P=NTC$u^_CpRz+58Wgud%6&oU zXg7OSof@y6#DGC$uG(d1<e&l@ULRbSz=9uWLnDHxL*5U^^Yh|Hdqdd;QlKRft5IW( z<`DbugFhy28TOfpgp)T8vO5X(J9lX>{_PDoGmsDm^R4=Dw>MHn8}e>^`6_n>9J@kB zW;Zn#@4WMsbldkj4tyJH{WU>riqifrLup4G7QUTFr&V2{fJo(C$JpP5&x(0oTs-(q zR=))p3-E3=0ZfPe`J%0>s==Z$qbQ@*0s)lMa1O}9O`X2)ro~vRFU0n4ES$sGvC;5G zrJ%wcnAyHQFDODP#mLw06`{ux&j9(VD3?KdiZ1pYus<u*;+M&i^j@v012`&J0<l5$ z3RQZ`_?MSR*ASqX6p<Cuo10(wfh1avGL${mraqS7x}c&yn|s)3<v-P$xCPQ`aGKAZ zNN2GiD6w4*^c~zi(JfRz@T?u2HueSnTcxK-{jzz--}{^lM$LD_fgY-RCWt<o%@mwO zdB*o;zR#CyU&cTx2ZM^%q7fAf;QYKPkc=PHAMW4h`!rv7rHg)D_?n=y4{*hp-Tm_r z!(m7<gjaJN<3r^4MIU~A`hFgnkhu7lKVVXp=`*V)43E3a&*oBrd%G~%Q`;r@vpYR+ zXJ*fAynb(YI6ZPZ-P~ReNOZbcx!JmXFT-zP?DV%EmrtFoC#5I+_@tIfXtF%r8P4=` za1$lB{4LJaGZyv}rjs7LNC3-G!!eeZ*I6v?<8ws_D-Qw*v}acyU%AP7{F9<fLp>EA zNxWvgCKsPCI|_Y%@x6^Zs_gD>UTQ-+3V(B}Uz;H!LUbLH^oh`B^W9vi)5$uecUF0J zGbPQ{)2OGckj%8Nboa&`H5LFBVg$TRXJ1yeA;NQ<JoOmwBB+xJ;eaYVjCAfoDBP;% zAObqxW_AP%bslgP=Zo82g-IFd&p_wIR-d>mQ;uy=hWp~F9x->}<+D#sAQNQ5q@*ES zbq3@hjc%j>kH83qe%eje$%wdsFk7aPWDzCKB?tBfgU-OdA<H+p$@L*5K+IN8`#ilz z{U<xBZ?{sehiiAMUn~?2t-2v+>J-~pdGbIiPo=!M8rVXhbz|iW=H8JGW7+S5z+F|@ zvOoW)-)9jCzq0Tb`LF*Dod00}j2tcOoe3z6O<XDIoNer_d8hiJ1{h$#c0Y262o}KD z@bz~MPT_(G_d|EflQP;1w5&GDW9>qwvxL6sf1oA`+Krd;EuuPRo{u=KTuaYakL!-N z6NFMnL^*AOFpdOHkqB{k$*;zs0XKT1+<4Uw0ui#-K4_`z$V$hUH>dEu`!QTf@mbil z&q%9ae5^e#=7Q>3?nMbC;B|5YaNgtgCt%pfx}uuzCm2IQO8R^Q3CZ;Sn?WvPZtAi8 zomAxSK>Poj-2Xc*B~^PDn3#W0kI--qk9YI1u5kA-5cP@*OB8exvdc6JfJ_NdOwdyM z4@gc*tWj<I2T_X9(#%ncQ3nU8)_dpv`|0hVZ=$4kcUb43Yi9x~!*9i+<K@HW8J?oW z9(M>zEW5{4d6-q>p#Q_=RZ|7AssHk>-w^+Y%X6}DHlh7xw~fqy`Iq8fZ{!V*|9B(A zWCR&2qb5A6_JtKt#OXG0f>5A^5;E*lkkP~gNs?33JpY;_ONuHUqCr>Dv5mjE-%Q(+ zM8GO9B{K5u_^tu)R$Tmj+680R%V_g_eYm@h{Rpd#b*n4vMtX{B5KEmseX!=5YMF0M z=cWLE5hKQc<`kv>P<<U)g>&T|(@p;N&J37CYPw@?4Yo}7_JjCX<@yX6ZlciHp~^+x z)_pA;^zDSC>#i7&se`_uHKHOgilRyo(^@LvGgR%{`4JJDk!B;P?eqV>*82B`V>`42 ztGHH%sFmEbP%zk4fwg3)LJBg3pEL@Wgl8mgEzx5y_C929Jhgv&Y&<M))1>wu4WPCw zS7EmDZcS?mf2bZff2(9+p&LOYdIrW&n-N?0JOZaQA(9oB$dO-_Wz*TmvaTSA35V_i zS;{IDicx5>rf^@ue7|X!!wHpcgN}#7#`(oW!LN4fP6F)4a-teo_NCEu1%S4O`H8rr zKB`>_z$iJ+-y1YIn<(nwxuNrn$-fO}<$u;P2OsqHZkUAgqG{ww_b|8{s~j^+t#?9c zqz1q)2#BPUP12R83+PodX#k1+Q&InNOHA@<TU~DzY*g8m%5REKf9ChtS=RqUhoq#d zR@O!`m%x8ERK6TnV5ZSJV$k!LKG8)}k2<lZJ@GlnPFBP`>p_HgZ$mgBZOm5`<+I@2 zU%_Bo7OuF&w{w!sL1;J3-Q3HGV&AAU<Ikc3r?q_7(nY$}$rs8}efd`lwyI*_#H<)s zQyxnPT%24t?uzi5`kejOB7{7KQHuGYFm2^>WO1cHxVH?cdC*f`7TGRAMq*rXPFYg; zz_2E^Gak~U$eP6uq0Yh_sXX`{)(V0Enn0TcSo~=rZ&R=IIW~a0pQp`Zuw-O~>aXRm zU1FFGlBdv)QigAi=?I~*#lTxk|F5&%a+KRKl&_(fcMMg<8pQ?A)5I=?HJT@egbufY z9(D?xi8{6Ot@UpB^A>7${Gr;+m|aNR*mPzr=MUZ)MmdU4tY#1P>qWoYFkZaB`73YV zqoRXXVH5qX<iApR3+cDXwS9+guo{1peNv0_jLh;}p|@TfiAcsx)5braq=WQp6;Qb- zdzxaW2k3H_<kpKL$NzIy%p|kKXg~u1&=LXwVE)fp;bg7n<YI4c=lGxJreCAI|8zcn z*XRY*lM^o_=X0G6mzP{G9dO8+I=ap{u1^(n!ifkW8Aj>@&Lv#0?9c%u5Rj5yxyU6- zlIYi~U-Er`iBw6I!^C?MY_iiXg4>?!P2K)A_odYJ%TyD!ESh@KXHat#Wnovb0H@f& zsDY{&4y`#PUKye<SI&uA3#a)@naG0P#X#I(coaS*3Mb7|dT$U<QDaiP;Ch7%bC`_S z(55O?f!Mx{F}z@^&%j{GjfwF3Z*=a>-%e2%>wY9gol6|Z=`e6}ED#<{a^Rjva`#1? zoBcC{nsF!6@b3Nld+U*vx*@A_FC6BiU@Retv=J)IUgR{Gmnpt6{Uh7aBq1Ta7%v8g zS>ryi(wJ_^{?>xQ98$lxu&}T{Ez?<>FT8&I3Bzp9&h^|iube3c;LwKrE-Ebwg{BZ! zvUo|IK7C(jAPzd=kjbQ-+&Vld$<&Ql^L|O6XUlR>?V#1LByBy$ZjWa1Y{Sz=_*rzj zG-R3g`>$~uR+2#TpMq$^ib?G>3OH-b3;>p61QFDq?)~*S`xesP1krw4CVf$V*7eNl zc?S#q4-FG{fVl0RPVb{jW^a5LA&@=>AZc?&38Q&Y{~+>aqXL3IW1jy`V9e~`Z$6<o zxkU7uLto_T49RrJq|0UdRX+(fv14FYFs1S1B$Re@o!4;IuV<Z3Bf_lUBf@jPLz|<P zAG&2N!O@&5H@?ru`{-nxN}gtnAE76yUs!EHDFU457%pv3)=a$R5~}7n4&`u7K!aK2 zL&(-htm4fmmC}1Spxb~KegdEg8W2)S6ir^IB^+PQBYF6}-dhnt{)E+@JaWHV&sB*a zT#UP44pi=%$`xxyr<x|mF7XUEkNTdKYhhhtX3gmTdwVU%yaS((RF(LofH<lks8z4= zpdMoM04F<0XZCAnmDb?lUfLL_n<mMdc-yQJz$JDpc#RaCYNAU*-R@qBgF6tQFe&C@ z&|wCKl773}P<@Z<%;d@Rwmh<l23Tap&X}lRn7<`i1xlJr_+D++Q==a}{JV@wK5BNd z)BEZwv|5OQNl<{0M@e*|&-X;3C}*mLV5@7<bR$KzePEbUMSy{O?jr#imPXy8ZjeTF zm~bk^drx~G%mH36dP+L$X)To=<t)7_HNb|DI)C99LxVvih}@lIRhP;D(SQk3hzC5J zo)Yp``%E!#w+R}UjAiF33-0eQMjz5YRcl~gp*-jX6b}z((&dOT#5b^KT2yygoUq*m zQgDsRgd#^!aw5v0=@p|jrmMkc|70FdKm|@5JyFK?HuKL$JZLw*UEkZr49GFR!)UO7 zFVb@<)8xkQ@6TTwsfWkUcoifBG}Q$*3Ix$f3WETsSO5fp6#&FRy35k>bikpem;i(! zAW$l>3V~QspkQ--Pz}(t5g<}WeL+?Ti>1r#mn^VLiyhOTfORhhpT7{3Bc?o(wNH2z zs?dWEpV0J@^YR%q7?o!$#dzUR`vR{MtUcQShCL}+f!TQe_MrEy)DEchz=MGF(C=5| z&M;}-MkyyB#u#wAvuf?u;g?sNaf^9X{VHvGd8Zkq^Ge7a82M&7(g?$`iwFRy-#4jb zx5!uf@-&1qE)tO3<YJZ*^#c$kV>s71<E*|FsZ^t+dS9mMfK#FS(DQAJsA(mzF*Z=Z z=rf;|rT<rzMl5&{l=R~1{c!dY4pl3?F-h3@=L!VcWC$2!F9yGXrcuh-0oTY3mIl^e z8wEi^l6;~GG{Sigd8=|9Dv_UnfDS4IfNBhlA$FVGk^1HcL3sI=ovSFfn1bjKr8D2J z|BwIc^elU;+lpH1;su9<92*oMql=2r-{ZDw;to);V8F&|l8%s|3(2`RSWdwKWTbur z<{T*yGzx$;#FDQb29^!B3qp1o8+mc`O@TC(F@ng0k(simM9%|c34v32dA+Rex+kkE z?W?s4oPNOLv`HLbOEw|}{zUehxzJtub$O$tP$_UIK60Zr$;!v<26*j}V?2s%Xr{3J z4j|IR4WKT}Gz$S>C~Is5nuAWN)?xN#b(Vj6{BC(*o)&|qoh>xcG1_Cm9#EKMjfKl& zJ#d#QDj5br`WwV^ZY;qV!LWTMwzmEl1jwM<;hG-18;Bl5*@%60UDTN2Feq$E!gyDp zPV#fqlC+K8>gPCXRMut{d@5ITDH@wA`m#&#q!{X75%X~kW333VoPG3z0v1l_0)uRl zB%SF6auBa=>(3bZR9qPsQ-$059ds;Q8Lm{@ybpLfYK>nNoMiZX-mBFM^W-@1)~+EL zq@v1k)M|~F5^D`wDgyAV>Y#NcUKT*iok(K^CcW-C-+m3AU!3}1?+-30hh5>86&O?} zjXrSAN_=>%UmM7xF|IBA6C^9cbE){j&{~fIY~BTK5xH??HeC$WZ4ljtCc&)7Wt<{7 zqukBn6g(7PKZIY%PpIiuka^W_hM{~Uux$uw;*w=3^;5PEK?YW_?mA&a3X_KlRkiJ~ zM=J5SdtX5pX)oJ>E_C!fJp>(cHYb937o^5#6lA9dRZP-a;Tk<Sg{|ri8V0H-WW^ZS z8_Qe)Q+5d?jwa?#YiRnIX6DQR@h#umalwiUaFYZd>m^+MADq4E`@P^BuOPN=lSPFW z6f9<y8Y5M$f|XwPbvcjDp{-o;nb#ASV@91ugZFXAw5i{;^9IwUu=9GVJ;>ekPeqkS zsuUe=?K%(Q)+-Ww^1D;0X}DAvUHVQTGEm)>dy-!3H8z)qSf_Y)nF4!pq<KSXx&!&0 zMsnWsK!70hN&9moPb)_IyT(SniGacc#E9-Yrr5|z0VL1Yv+OViMcPcbwwWA;r;c@9 z=i`UuHX7>E|6swM1p>HS$$4Wbu4Qnw#^gs1G@9rB>Fln0kp#42ot&J^k{@Q{e%<Y3 zHp!c*cHz_KEI4^?AAo$x*6$YmX}n5nyOF7ux-@}s)5((mRHXnZKXr>^ju~WQPne8O zHfQ@&G^gO8C9%#IZnY88&dc;ls%`d<pTsu2e7oe#HUf8}B|}gTR{W+a$h6u}?xJj2 zAj<U;y53_}s?(4jz&WNC1g;CfRrLr=(E4@cv2*>O^=1gumOOs3H5~1P=t}8+kOH8u zbG3Rp$E(=u?3h;h{G6zL27PPvi*z5?uX{2#O*}q?(2*B(CVt-0_w`Mf1N10V$eN^z z9M^|7&>uy;-N4F=&X2?E_uQMEO`YDR`0*Z=N0vE*rJQ^x@R(dY7Ob-l*@f`SmGI7y z?QW-SFa3(t<nhCfaPQZQ9$$EJkGG30K&N?@)Qp$U6*Ry&QU-~ZS*brxw^0PD0@^>A zLMVgi$eA66`&#y1i$)(~P#aBb7=?s3c>M?dT1z^K^1<DusT!a<?)yXL)vdke<}ZDG z-4EfatwM~Vs`hP0Zrz`lwelo3_?TDughV17hwyJo%r^B!TiS^d_Eo`G@@bmpsS&qY zyQV$K<=x1sL0%2s(=A+gSH?TE@!_tL0J9t&jemMmRvTIV)uo~*-6H4w!^5mgs}eN` zh}p&)_R@9!w3@^sCVLGkx6A5%T;6|irl;VT>q+by@DVa?!h=<=SE7GRR1T@AMem@& zX(bgxU%UQ`S=Wq!aG*owOovdUuZ6ANy4tuE<A$GNkZa{3yCwJH&gi>2h~O)2IqW}= zZ8E$?2?ZLWqRrCPfrFRR)!E(svbc>yo9x5j)U*APHZpj#Ni^1x$0rj8?dT%eRk=s} z0D%i9tNp=L1gn}>^Z<3Wy-f^B3K*@Bf1;{ED=R**yyBL>CbO3fX<C+j^^S^$K=y4( zTHjihBY7FSox2JAt?3l;0MxfUM~^kaa(HHg1A5Kye(pzo$`ALA{@>VLpA0gW__x#L z^0(9Fe{wfmY%PrJj7{`hoGq;XqeaSAl8wz|K<Iv;78@swBP;8!R*m#DPiR4JvFt1* ziK2jsXx1n8GH>{L!VP*`wT4sS1i+i+>GiOqnUJyw)QnU%Nh3{iFMv%)U;MIs?9#48 zf>G3oR}6u?6DlKh9^c>h*hcBG_UmgcU{k<mi8H8h-_Zw)<!_zjrXTc%cvlfB-Q5QE z6@eRou%L*y=&Y|xBfMi|>{dR#zbs4#$>k})kt&`nLhzf*72SBU284B15_~tIXf{x1 z&7Hd+Ys)L~_F#vuar#F5#zH;PQtm2JN91V<$F5GsQ(^+shl(d6UnmoY9`DdxbNoY~ zg~Yv1d_|Th`LHFSWCg-SIz%5_`1+R?#0uI*r^Q^cFw7kI1ldk{_>oE`g4ePQ+9SAe zVYX!STQ5lSo-HmjtzLu3mVk$-T^C~VT7n;-xW9b)Us1#qNad_ilOsSBU%u!O6g2fA zg@^v##4ELC_M0}}>g#$5>o!9rVF?MOM&Uz9Y((~1C`)TYT@jbnNFvuMH3_8zL9L0D z(0CC*wI$f__(r@-mDZ(gm*=)xA*r3cD?ofg%6)0r)5@vSr_W%8CCrtIG4rRM=W|mK z@72SgH`WY)i-_AxWzb)|<8Rw`{;)7Nz}Tjf8pgYSL)`%$N1ihwY$)iPe_3mwSjp0L z-e`?tFow*2d^%}3%TG{JAdAWU1Ry%rsIMS4&}?5=HB<NEhpRr}1^ot*6QTNtet`aa zZ%Ne47@GWIytv=-KW#6rCXP-PcDBE}$|hPG%AWy7<b_kzZRsyKg0^RjKUPthtfV4; zYil@m{~8a*w#+J0RD07DMNyUs2`EFmrafsmcLZ2Wc+H3Av`nayLL!4PwbW5E4Y`r- z(#kY92$#6j@jH0&EB7-eU3~269@u|>S7QqEK^Y_fKn^|t0P=rhP&acE6YKwwL6~25 z8zWC{U#Q?Ffa58AMO$Dn8vmxGlcvlMux#QCwb(+5<k5^Gjc;OFjtqW2w!Pd&V~LA9 zvi&*!-TC<SE;_b<T9AvBr&(r}q-4;iP7WJVU+_*s7i;MxMIPv>Uf%I`qH$SFDBD@J z>#Z`^%SSEvP&UPN)JPw}onM!it2pcwd7i)(*~`O=HquJfp9<L3AX6%DO~^REN}aYa zHc1X3#v#{979)*U$5oV31Fsx7IKc0#bV)X5K6aGVNVdYUOILPKH8j!Si6|C(Il$mQ z+H<J+{dB`GMG$51dw+>%>sCT$S8d-cQl0Go3OOolt`x3GR^gN0+i8ndqogW_4dY3? z@)xUQlBJMZ4BzMci_!SMY`VYc+Ijq1LzyY#Oo7>8&|&zHaNcfikCvjumUBf*B(v>a zQ|Swtd77W!j*Vt|-7yixFcvapwUXL-V|5q)IN3j6LKbBf{Okh-%7v>x#_wEB>;xdx zBZ}X`U*Lbgf5l#e-za5Yp+Td3j#fUXU4VRhdwsiRYisLvfvW@(ytd8V-)1o+4yBPv z4(K1=6707F6iOUWf%2gm2+c|&(GK~LVNKIPc+i^A;_^ldG!%+s2?K@~L{(<x34!A@ z<}ieVkIW9IG^39EDKkzv42jmLVc`=AMeOUYv;#%f?+n@&tOFFHBl$2!<YUxnlt(*L znj*kcr<2MDUF7bc%M)@m4m;eXE-Di7F!UzKHVV}cj;$&qSbEjbbVbq-ye(XZ#qpm3 z2qbAkA+=bIcjmx_V%j8HiV>BMk(jU+xN*`^=B>A30RqJ(&l9^^m0}YF)VF9WU^CvR zH%HCNcSgFZ6v0bTs1^Fttly*@HJ45iSui@8{o~orn`Agyq3Oo4k5{A^ek2)?OMb~} z>``Lnq3;1pCn7T-FzlG`{HGXefi6dobveLM+F^05rGQ@9+!}|01u}OxhsCC}gQAn- z!|bUx#NfRG#bSx=vsKI(hH&TbNvGM9UW<_dGKtL`+t?q@j}gTkesxA3@ep4{SZw;@ z&Cq~k+fYmm^tch}s0H1mFFX>SqnSP@|6z$t1q9dCyj!EM8mv*_vY}>ZHJynzNgscq z0ae*zAg|0eKkD!j4%ArUlGBR{__-;yd{#Ctxzh+?nm1<Pi_EmuTp=M)Z?ePYo@miv zDBs{x<rJKg1*W>V8JI}CJGqW{J`)frDgB1w_7)fVBNE=kLTPA9<#h}eipVSz_#b5* z_}S_bWdk@1m&Q{eKp0t4D?v3m@#&V+eg!2oE*MYvJ|&KX16H3T2Q;ffj{+o{)L13# z<3u?s9g2$H0moboxT#yn_WWd3a-3jC<HThCeRcp+!;vKen0;1G$BV%scGa&aFEkD7 z(1{AT2*-nF;P-AzjP_@0yQmlmnAD*vPvQBo(Ob+XsTZtw(s0qR7}Lv~gS#p^8JrwJ zdBo{B89I#-)GA*kTq6i7I%`;U?t1YYfgw$B*t`v<F#pHB^v_U_F`zH3rwbzds0voG z^%OtMlP{1Ys7ivjnsilrQexHi0;c#ObH-qubYRE_LSDUdT7*~q4g`?rs$-GR-_c2a zEx7p)+tZ_G8Ws>Tn?V;ExW%vmg&>UULntDeheWEsx#M%^5Te>=%9g@bXfAj@`=^r7 zxWNfWOX6vIP^mUcsW4WG_I4F-bC=4mR%x**gUZzc0Sz*W$^O07df+yQ@}ov@$F+hD zRf?dlgU$kivX!_hR8kh5-nV`z)0qQkAvFZz5(fqsscQZbJZ~ile^B5$7Ku^s15=4M zSjn?ub1NE4p}fZbsW4(68?uxLrs!gZJ52Cc^Um@7KWv>tlpw&8Ma#Br+qP}nwr$(C zZFkwO>auOy_<d$I^UvfWcbS{myv%rU-*Tnl$US0a?C@E^AJEbKWV05i75m*hU7g-{ zz6P;#+013s@fyp&f?))IyG^+=593-_C6jq&wo3$nShdg?PH;#=6!<>cI&RUUhHat* zh8(kF1&U|&`~P%}3xw<DzUuw<xnPF`(z@Vc+BcmKc}`u5sTk^eUL|ZQvP;GW_SlwX z`bJMgJ4*mN8$sDZz1DD{8_r)`ujd0@2sgZBWo--MRwKA@_gm7Ye?|QOCq3bQ$VqI0 z-3xebQbHQVxWHN1K^F;{`nMvl&r~#Z^oCsjspj1}+%r%+#13|t#(xCKI9Oi?2S$V$ z6_UQ7E;w+VMV#5A{(+f(F*?5Y+aL0s$v-}LSr_R03lXKd(D)S!>2eUer-AFX5(JnU zH7PM%Sh)JCRW{FQXdT)M6o$F9v|rQPSE%VrCXIt2Qo%4>fRz^l@|tyJm@95(y+OZ{ z2j`)4HvcUiP8c_(qO_vPg&Qk(dJC~6*^A}e1?0Kg*}+Hq@DE8|)>*?^gK9lZu;yV2 zFS3uVfpi4>27ho&hu1IMi_WDW;PHpHsf|Q^<6@Xi;cWUPqB)*Rg{uc2R>8GL@;HCJ ziKgnsPty2I(De|@k-U6Crd%-JK&8vXEBsZ9@ar)OEysbF(F1r)<d#+ykp?wlqdfS! z^ra34+!kv%CG%e|4OuH~G-(TP(13H?07;XRO5li}_~z+@vsuJkYHKc;IR|lni^f_! z6e7}z2c>k;M*1z|N?>T!8H7(vY<3jX!#Ch6#tnDgU!1zNVdx+-Y$NzRo!PhTIhN6* z-OvB$<LkS#uK+i=?_*^K_+Dn9_;O*`?0oO$>8&@2x?bzA9#3nP`B<tyLyrmO*r?T) zD-2(C{}a=yen4&zOWZp5e#wpx9I!d*Zb}AzJagS*^rbg%Gc-P?n&0)^Qu%{ZXUV6W z)h1e|*N9xd-0=#Xy6ky4SU49BC%*c`Sg^KxN(IbCzS<%*A2fhlBf&sL^T(?zpJ2TS zCo}#byK}Ca6;592<j0DOa{j)|LGTFt%OosxVJAIzEtp?k13m~>t}R^FXm`gYvPPgm zr$q=2ybXAvX4E;<N62yQ@RV(0Rq&=mMsxJ%&Xs{<hMs89vE<GE>?Tf=ftZ|iT-(2x z1>{-p)k;k4D&|&H@s;A1Q>k3=2Z*voE~e;P?<bazCnq2N+r7W4p*_#+?r&HpH;x%& zS0bADB{F=mY+YXPz#FiHUhWNm{r!RQvecrQHfM-tz&<!K&3VS#^b|LA-@_yxM3THk z%9lBGo_(hKmz;8p@@T<=fq6z*O1?tJl#^RP5}Ug)XN{ruYN39g%;;5%7;CF2pvqU2 z-~h6tef+qzxB38AdvNYqgA&m8@4iN9;2104PynSQ8MyU4)mk!LM%kawqmDdEsb1OK z0tx$c99B28VX)<pggL*YELvax6@&Udbpz}2Z_Hxy--8DCzl7bt^gw%e=l|7Ua8;7E z|JP>iIaT-2u|TwXPauPZv?LG^7GeNI9#hhC7ip19?*RV!UP!Ye(4cE9e$C6reI!YZ zB8c^kDv`pVe+-zVv>MfjK*Z^UI9Bvl8aAh%6ft<k$oQA7kykvI#n5QuaUtxhjC4Ut z!w*HN3}nQ=9?Hk!^IVxdZ-Eo%xfI-qGG6E4iKzVb+~s6wIw$-@gjbyU(bD%;v1~Qc zBLuWz3<sqcAYbxEM+{<#G_Fa28lqz;pp=WN)<7mj)<7=hT~|E;5BGqriZWG<JU;wA zseqg=^yfPLRIYscx{K5{8+%PC$ubBRXg@Lsn>|l`cHyzci&Ji_MH$5P&jUAO8Ca@3 ztnZs}nBx_W0%Xh|+*7zN&zijqPc$fYB~u3P-I|rDlkHE7W{tR?MCCGXV6Or;9U8NA zKsj?``vyJw@}c<WHSg>=vBOTo7P(ruYQN<p_lpsHHvGqHtD%sR9RF4+zEzEN#%wk< zDXJ+m{{O4P|5XU!U#0$M;r-j4O<i0aT<q;_oay!5O#ju(iC+I->Z7HLzWzT+4*Xwz zT{HNQM%^U<0QV?hfPX^%|2ysA>0tQpondGG@A#Fkt@kEd)7dMZ{4a3zR$WDil1=$_ zn_Z6Xn4{J%7d^XM`}U#7^E{GmbDBhI$(4ult$p7k7y^Kxq}u|o_f2gVwloO?09f#V z0R#POkR@N9e3F41Z*(-%%q&>*r96Kp_%F2E!@6r?Uaq<z#|0?1wRQXlw)Lex_`szH zA0!<3K=fbt#}<i_x66`@GSkcx&4jc8PbCua)d5XJb5*9ephY6dpf47T+_4c&Bv4hn z;dNIA=_n+sBXZRovw1F{s9?mFn9yqH0F{&SWmO##1wWi&)6Dn<3<0o1AC`PFO;q)@ zBTFvHNrIZ$MsC4V0V-For6rC?a=|RXeiDWHpz0Q`xl>gI5>wR@Vi07(!oMbbX?Yb$ z$u3z^+z^2YN<>?pkir8yVi99cD8FPZz3X2lNol8uL73%h{S)0mr=)!Nq?l?UfV|Vu z1u|sFAW4G&7W1z7l`t$J3T6?zQVe3X`njjd-Vy<Ii=K&sLlYUJxxgP4fAy0TNdp>2 zE%`E!)EQ(fIIzn(TAY;09uRiM$lpzch>fAfAE3NudIlsjmy>DhCm%7w9EHxzNrcb= zjvE;}fV`E|1du4F$7tv)blvBHm*a2UgM-!Q;QcrJnz65NLF#wAKQ?!ox6K93KLPyQ zi}uQUhHmx0Jun0!**EFofAPA#@ND|Nyzho~rp!a$xAXP;)_FM~^m-s)^tyL;H+|7S zz3JUw{C(P9AO7r7s`$QNFs$u*H@ZVO!0Rh!1KHZ6U+{`k(7Wwk`M}G!<=<T2;{NbL z<=x`;iZsjt-niX)ea`If%*KCi+6S%j_j-O`7@%|A!w~dsdB1<bvb1~}y&e<BL2ZPM z4czSRxjWo_zx?pAc6<}V9Kt?3oi1PY^{s#2d=Bk>s(;S8?e8z@p6$LYe(Ty@AMaXP z-q_#vL<E^{(zo?(mPXYB%wtng`hJ~%>Ux35+711>!M*DBh<sgjdwITr`62ni>GyCh zwfb*xuf+!aOZ5hi$T_vw6NHY?t$2#s6If3F0|UVr?<-E=6<2@)cRCil-6cNf*8U2( z1-Qaao<jb<C?6)QF*an_fZF~2lq^^Ncut;$Ou4cI??%>e6Bv;2RR&oz;W$zK!7`IU zk?cMJv7%m31+<$fxBpq5Z{s@+|ALV&UK~&924~SD6$OI<T9fO+M*ZO75{HY63ds|) z;HrMFo+)Rpp#F?%cGQG3uT&A0flf-3EctM=@5+N^8G%SgLIb)5zABfPGehnO7+~H% z=^zV~vPZtB>&joe$CdB@F~Kp{)sTUF0+&oeSFm{ZNkvf~nA{88tH7WoOJd}`*nyRM zC|r!1fq4}c3zgAN)F(5>q1(?PAJsvi$Ct!eGkXZdE!-o%1yE3xLF~@8+5wQJ2{4qU zLk#Ze3(K4bi}1QjK7DimfHlwr0k|n2H2c~w7P$JIf}VVDo=XrScL?VUh7E71-2oHh zfaUWsG5a}t$dosoS<4?8G<NS111z0Hp6_aBu*s2Go=lZ7S5U0s`^zhUw<~gI${%VO zN6tQ-`?_myewa;=Nz#Fx3c$VPzw0~i`-SzXdiC%)-~a&&6E1HTgp*;eBltQSASb2U zH%iT5vqs;<j6rVa{YZ5SoJN;iB;~<e@y9^z($<bB4(Kfht$}$-1j+@h8%+_I+mR<T zcdV4kQ@)lc)KfsYCUMmC482C72H)vf?~dS11ov&#_f1ngkZ%k!&}w%2ZVD3y0VLYl zZ~2@b&`s_d#)1nT0`RMAb#Y3L4EN<|9mn0knY>!uz7_o`A4FW&YbiF!F64I}`|CmT zRb#-6DtIL1ZOJGUAyx=3VW-|%fEOit?0y1-&0<G15T+5w=D6H9BS|u6A10VY)CAw; zo`uqsxgMPk0rF|TosReRr?{H37^gz-x{sX7D>>y+QWfa>PE3yk)#gzEmgTRKL~>T( zz*wz)0D^dblUzW*7;%X=N?inIii8<Kx5~VsMg$4Q01;UmvU$EAk*~mh1Q-}9b)x-6 z96QGmCk&Ek3sXKBR4qe(z)&RvD9Ou(S6ZBaNe3KVvb)CT1<yoKHBl+44(TnG-VLY} zb-(|fAR@BAkY&i^&{Ik?1_=@hm}r7xh;wQX3zGb#PFJyovIKL|t{?)a44+_te6khG znWA^!tn+YOjr`5v6A5N<1M_70FdzbGzTbncl43r5RmO_#@1p$2&FP~2Pg)wKGv5e) z?nE~to^di@0yYCxl{->;<cv<arzR+8H}!=kf=~$2KcatuY)Ovbo$-W%0kRqoczeK+ zZj3f^q}k~^YRlMJUFLHLCc-WBN*Mu3B`3<OKX?};fb_S<$6>(8p&(BX(E#dQ>W^k3 zFfdyoGjpAVC4#V-00@}kV9zlwdipuc8^-mREWzjPFE!<Z`bc!QgbKU9X{48d8v;5F zv+LfnyajTA>*pIN+>fVLN-EE%`0IW3LF5ibm;VLdPAKlC!3XKB=OXe^ClNq~E^uAO z5DXfH&*7B2V4fuT(|Y(iB)!0zB(xrqG0!-G=h^<cb)O7XVSc*8cbEXsDgI*=h#WU} zsIl%gdcv9E;#qvcU%3Tnk$#TCWCf-j@S6e!uy1cytAOHJ;6Vf|I>-PMcm*^0#ghc- z?Yjnx^U0hfo(LwQD_@Q5qv6?61LKArMm+qo#Ss00^CyB#P!}0p?ai-)?7gueTq>wP z6foh^f8SN%>IV)rS#fi}UE_F66@b{pA!`DfO%h0#k*)OH<n{3L{e+%;Q-{$-ovPf_ zzM!@qq4Lk6JiMx`_0vDNah#aU@VmTp>m<TjaEuN}u$D}c5QyvYXDpzX`2*qOl9D}K z6!|;z2#*!~#{}3=3nX1NzDMs>N1n?F*<h-jx3*O#*grW3Wp-kdG*Peq4s92WLpQ^z zGm5}gngaEex2=hbi5mZ7dYF_{-4Z5q2pT$RPM{ME2o9hV;4EIXyePBxF}^k9Us=Vr zvu^blm(Nxk!2n&oVO~{A&<P*D2IZ|fuwLa*ADna}+0?8-;q#k0Y7o&IDjp`>d_zOJ zE2!NyVeGNxgb0GOX>4q4@$x~L2!iDYH#~a2vt5GZgBLdX5WCO31mV>?tUX#f;`x3^ zqI=LliCIm(5q6Hw^!t$ff#40oE%wP&_s0A-nvK$Tq<BNeWcbdVt-7ScY3iDjG?5vV zufKnP><$2x-0Pcyf6Vn^%15fXb$A@07XyC*e6uU-TR55JFA)al-9f#Znac5dT(#mZ zW_xBE;wM|JZ$k9Xzpsq%MF)xNcvHrBqmw1*9!-Bz(fG6jTYy<T9h(Wt0=yKTJEY3P zAXSxa5<hbScVVyzQu&19d*dfTZPbbE+wF%$H+yG#k2^N|lgU1z`2ZJ<t5eb}oHW^4 zMUduiv4l5mzU2Akm!VIR`O`!kPSlT_)78aact(Ekt?`YT@un(V)9!l#kE_@8o}#sv zEc1PRnVfRbujpi+ls;kTL&mQ^lO*F83s-e1*);Tk&pV!p;$R+aC=OI8<|gYG{ki=b zPXFT0oFG^CzK(-hx+#kIc)LCg%Egzt77+%vw+?ufdTPe#oLmOp@DCxn(Ede*4M>Xk zVvztzA64L;*KLdfF#l-9#R%|&q(5q>Pu4U}_Ux6BaS7;e!YP<NiVhiv>L4n6aGO7q z-@xSnX`{~lF2e7rOOkHMN1y0~4L`FydWxz_lPym+mz4az{vx4Rou!$id^Tl+O-lJQ zse}oDM|voNhG<(ezJ-a~?8&BN!cfdRJTh7j_l-V*B8SVON%|Xxyid_+h66BVytL#{ ziF9JA&!C+ryJf11=IAy`fB6jLAmu%fKq6q>A~wh)E&k3?X*grfMp(emSsUjFf@;zU zBKdF*(&i+jmY7%CpAEM^4=R&9kVi?DX;yyDz30Hlz8<R8$jAthzvKauotAVGjrsz_ zrX<!ti)!S^RXoI}LaN;A+b^d$Bgg~i=&iH~?Lv5qYs(k(Q2)#417dn5C2l=7u!1&; ze{LB-Y66VYyY}PR@%oTJ4O4dihv~cA=GUX!=<8s!YOg$E_7NzrzYoY5j$Rd!)Ug06 zGJe4$VNfx!1s~nKMq5g8QJ9>KGh*%-VHT=ZW5OFE`qB>FT)vddF7?<43pAM|S|Eh} zEDdx;JV-oHV)izK*dupOlkbn%@f=A|Gm}c7B9dORWM<1jAc%~QXbSk;?q77)LB@z4 zmOBRi_fqo+WP*R_hX+l5(oiTQPC8UBt*Qkcr+ynDaUzVLc$s2?{Sru=*?Mq-$bm$l z7ezX?VDS(L3<{UY0=YvMqVOV(fsL6neH1r@Wl6M>Dp^fLC<#-+@}hXrnL#fy%6b-t zK2XR3Iz%E?sj;&olvy;?KH;o)S_~Mlf#kr@tPk*cLn!6wg`bEnBuQp6Cdl6<WE-9R zUP?@+nd^yGObHtFQkbs1Vt_W56_o)^=mbAJVqw~Z3l+o?GIWZ#M3pgef>ZqjJyy^3 zCX|S6To3PRf-GG$$`(%k*uX0wL#U*}Z!utjm=zQ!$pdh6NmAs(6T%Qh*Iili3cUd0 zta+1mbKzQO0EZ-{!J^M{Z~HO$UR(O8Q>)<huw)M}rnq1$=CfX3?prYUJ&SL;kWdu0 ze*ZW&w$ID49=tE!8_z^D0Wh(=)QWmETZ)vk?YPdPWDt6T#(*5Z5L7>mL(UU-rw0tU z(vf|IIR1ud`Fn==@NYN=N)x5QVwUKGJmg@Z9}$*N_t5^F1a?=jW1A$k!cK&&qn)#D zfH>oR9w7oi6{#?>U7`!6`qcu_p6mBBgxLcH@4Pkn{b8px6B=%uK}PI$;y2{5RTht~ zHUc@!y4Q*kd457Y$YgGrNktgZeGt6r0YLe+((-})qCH0xp2#4$iz>-`iS&vh-~Pzq zDB!;_45Y)#-6&;Kj2dSgg+hDAX8F&BE*g6B@(+-5Mz8Ync<wuHf1F0AW7Q2`<+s6) zgKye(Pu5ss=OrA}K>N28HXsi)^)5IsFdyS;MF8NaznODG&6*Sc#&I@skXWRPk?Ed# zsR$NKee?@)xTw{@yQkEVn2gr+&q@S7os-jyC{t?(4GZeTEx168MU@B;LZnqZ1I>j! z9W2T#xTWyff#$Y8$BOIwyf5eX{eUIV12Oj%*~16TzAWaN|Cu{XMx1sN$2wKgcDe;B zy#qv;my8VJUIk|)`Z6mHcQ==M8V2JI)_-7u77tlRG*aQJir$A~8l?6(G_3`?U5>EI zBNG0eArM|5BfkK>+^=xe$+~FK?^gtMmF&`~WM^dp7EBAp#;UPfa<&Cik1RZh4gO5- z?xJ@GumD#)84yjHw%AoNaCy&RFQ;?^ko;nylN<niQZLhz7OsW{>2JY;6YdI&4EpCP z6{Ntotqtr@&a*94BQA>O`oPK{iBJVoK%0mA)#7GR8HvWPIcUPK38`<dV4R!6lny<~ zvxm^Z<G8cu#`uHiXPh@u2oX0+3FHk_YZVJW7`7w%Bb7Y8dI82{`F)NFC*I*@9!Y$J z=`neB;SKZ{?CeJS`sAV<sCD!7)YS_neni|?;ybaR0TNe4J^Myfj6a<2$wdc@q5%+; zWewn$Hqws~F(^mwutXb(f8z0nkH1p&t(Oj3I507^*`$9hkUoUq4Vt5<4=v0)?TkCc zwydl(qm36_nzR9H=j$T6Y40fOY1`xSSV5S7Z;{!D5mdn^qWh49a_L*MN8#RVI+SUW z94-R!yv+_YMC;iF<W-byT?=A3(M?zoA!m?_XIyTc=;Gm0fqr^i1M&oqud)yb8it!e ztb6RR(9O$sZ~wd2pc;?<>J|zC+qy48*`Tux21zL!t~Ql5SJOA)g*!i85aSV6>+T%` zWC!6-%lkV9?Go8td-%p$yW8a(B<pYF*3To!IDBDV-a2JBo&FLvpXZ)-@dgVW-AmJY zca<aB-=Pu?1@Y_I<T*U|t<aX}_8#KSw|dDq2&Egs1So)}t56@r@Pg|_;zUL&iWu%6 zth^k;DNQCJZdNpnjW~z3H-*_BDAQSO!L78=QNISeTc*)BTqMRU1tP(UJX~8WSsd}1 zbyt2f?nE$O6M?{F$$G}bsyzTiZfIH}jB*KJmI=Hr6tl3c2($zwEJ388D8h*umDN-= zE6GyIZVV!5|4R3Si|+AyCN`Ws;8@S^aWn-VYgt=g>eC!l&nIxEQ~1M4{OLH<x-&O_ z=l#D?S6&J#*ZYv@^)W+mb`R!~f6q0=xG0|8vc{;)jl~mZj(tf+2TwL1dC|~%F}wTD zVI)e1i#mL~<lg12ql*?WmTtH;`cX9tmD;UeI?6f^xtPaXfs3r%whI|tix?=DdWAJ* z$~*?P$TvtjdG8mjvkJGM!HrQ)GCUm3l56sWS?*^}*Wa`a9N%kNKptJVWJfIs89Mcr zY)_@gpJGPN-snBbP=EpCC$L*ms+TBIFgQ9-01JB(Tzr0cuWiBSty_vPV4mm5*&U9q zR!`)40hr|!eQD5Wy?jcjh8<U(iWto}-s6l|mLr-C^7eH(?9kCe>>KT68f2A%a!KZS z2Tg!gUw=r!^VuhCRK-ACErNpxOH5Mv5HWnUtA(i0cOE5W&F2B{B(8e!Fav7rHTG=> zdMs_6MvH=|d|Q1J1-+z>ZfzpqAB`kak#3Qm;4ELx2n?M|r#zVIua|X2D5>EOQO2|z zu{v2NhilNZ-xf3)6&cZ45{{{0uL>`&`p<1kJ&K+<PLgqiX@R#gXC*slq|PjDte8F3 zo?)=dWk}lu;8D!(f57J3;KRrBc*$FCg(ZpbyZHoD1FP0(D3N>Q%l~3o^+ajks`r?G zfK><D&alD(9hF!hI|Ua-Sl)9?o+dLAfx$U~(kW<|g<9zyj(UHw*;U+AHF<8aN#h)p zqT)H`YPBZ^Y9lsd`sfwCUD~hClV`f`c`&|SJfXDli+7s9ri*cF$D3it0;)Y?;&z{x zI@`(I8%bG}=QUCQh@Ur#@7W=?-Pu-H*WqHv4pNxV%#h8@Vzm|~G&@5W;kZ~ZaTK(| zh2J;Q7&S@|<Kr+w!<XHWh}Pb+M6SOF!z!f0)?zdl=GEUA<;N;Zn&aGb=aXnsG<dV~ z7NaDvr4CF@xoap%?OUkW$F0QMTV=}?m!*BhL<NtD+OmLSqiSQ)HP$YYv&WZ|h9uGo z4>qwBN-e>cmH_iy>5wx<7!dHe<GaE7Mt*uCv;bxVNjUxpB8=X<j-?FVfKJpuqGUvD zJ;=)bn8Qf{a0PoP@V9@Obr+D$WS4jc5{6hsa<oCH+Fee&2F+=%PM=~*C+Ys4WZUD_ z+4K0c*tLg3L)7L85gaetK&NL`gCP{6%I$xX588CNWB}+5Hmx!viuH3zR0)ms$Q{!5 z0ZiKZE|c20YD2?-SiW#qin^nyOskX3+<~+-Bv={qg+3aD=b(Af7I_%NrO-YgE_>|% zBK&IZ&g<jXy2o$74@P@e47*~{qoQ?;ixmSH1?~Wzedq#1YaBH&*n9D4^b5@$MiQ2S zqG8!FxA7tDKbzfIZ2O4x1PzUay(6GQ^8i=C4IT3Wia@R*iTU(71y-P`vg7F;Tk9Oy zb%g?x=#O{^?bhlp^~RzpAW}(ayXYwmZ-g0)3_KjTvNL?FI7`FMKSRGNP}m*n+MA_1 z?tbUHG&^Y1h=b|1U)0k*SYE1X-0LD@U^qw2Qw&~6G44NggNKc&gVvH7@aM_vC&j*_ z<@A1=T9kOys@`am7^Dz_?B#;}v`QDGOi0*tY7N9wDeiJ$FZ-rM{dSdDJ(Y)%@5Zs= zc2wLy3$@jIt6K$Y<b7Rr&af=?>mi6gJg-ITd2pIJ>wY0?VWYtWs~(W*!YxFCTjJo` zu{lJFS|n|7t1b@z%d-hnTSc3JM2j*&zbllYNO2u1IfuKUT+OL|>r#OUu<Oz62>|C~ zYb>f(C?&zvrPl&_8{=M?XCJAF6p<->%xC*Vs=A0IZ=1J4Q<$jOjE#%)?iKuitPH!X z4#qcrd44sf_t5jCHTaszZc@|+N5OmMY0r%WIRp5{8Psc8c^tAPe9>k##pPQ%2tAaw zE@oX4J!&ZNmMyig9=qggB?xpa+J~QD)h;H)-naMmP${gZo{QLV|2CIeFI@o5_D&FU z>5q_#5u5jtHghKNMX?>gW-GKs)M?wt)GkImGM*n-^#AS%oJjLT!axhe0Zpf1Br5M< z`A}j<!1?2DO?N|AwC6OUyV-wXx+K(3=aq}6i&H&C_ze@gHW(ejmWYQJ9!IyWYv2de zN=GZw`MD};BID#uZsAmkoW8?`Hv6GFy3jUDZz%W~z8>b}(UVX;;H`W@2v6&ZZ>a>J zHB;a1wIFJdt5@8*iMG)ldXskJKy9(qK71ua(pZ!aoEIwj8#_a{;jIi~e6a0l8OjH@ zvcVR+H-PrKtBhKXs!etWzv692Z<qwk=7Zn-v(vb?OfSk}^x5%wE&vt2<S^H>m8b>W zhz)~%omX~y!n{mGnfEtm%R#4&nn0akp9FkG1?696Fk9v@Kx83|FNX*~-(6&a*GiBy z4VVrINvm^6I26=bfIGHe(o8vpELq{-NYSlbic#nqSHSh!fpx~E-F%Qfjg|PBQk%tM z25IlyaZzK-2C00qm!e1|Y&e<L!inYf>1*q->fEDuk!pU`+5|S-uf9Gi2>{QRxsvgT zAsN8NICoVgkFMZ&^jC4s<~ogc3*;GpS_F+NqE0$qEnAJ+Q%6a+8aArpg5oOIw41G{ zoX%9zQ3|nDTL`v4!$3ay3w1H%01~w=NLF4Ie-3&^m+w45+k(S!NfXGtpf~rb+NQw$ z8UPl8scc+<`E%t?W0k0xlqhV#t!nmb1`FXuXhoidkN3C)>aQnU=U5g;;&lXVGa<T_ zoq;SYgF}Ru@xD7Q&pwt&Hm&I`*9xg)^?;Z0;|^m%h3Wk0dFXAPUPoQ64?B#sI3hON z@JpYUqvG0vYeij7ja=IOpdabB8MGJ5gh=(7V0oq#Tsu;|X)c?xl6G4c7r4`f_s8(W zu#>d_@4rtZ6dWg#f4E~LNwA_5hh7$hH~}6BMi$}b^nLr3+=-2#!5E)PGyHLciAJc+ zSjrmg+JgghLf49nlTOiXG-gkvYGw$74O~F>GelfPprc?6<CRAvygi+(o5-QXxu(pe z3_9b%{@$JbjG+2ivs(HIKj4bvDi4X1fX(|i!J=G3by=c>7uV*#CU?}>d4+ZE0cNMA z&aYnZ1ORb)jLv#r-NHUuM={=u#U$pwuC4FDcD4~>6{b!*Oa#d(?+M3^71N_EA4c#l z1RN+>mSru<VmK6l&m&Dunc50eN+{A9y|=Dsu4#Y}Xg+V_fe?lk2xb>fw7%$`cj6W| zt|nNKoW&)ALXP(w!vv$4nRmaXntI5Rk*Q{YAlm?|z&KRkK89Ff#NF6yVG*>D8lWVc zE6Y?T{^3r@WbDj5jZ;U&%}4kL%|~X!^Hu6Kz%cytLDQ?cv=21+F}v0{pbfpkjt3gg zw!+Q3RJOpngr(2VTU1>RdwFAtdF8>wmb)<>STo<SUABEe!Y4^4$G}*wPjG)ghzK2) z`+Z&h=hKDo>blZi0;0cBVard;UAgYUYbKaYOt=X11)GQw%|;Awuu<3}D_%wO_ol5_ zZct>rWs8CecjUpCR*ae!kxQ+ZG_*^t6f@nHsL%8Tax0v0t4gg)`lJGS8Ew&qzd+9h zOkp9nk91jgOq++E=+~W#aEGZPxJLiZFfS#t+p^^h9N-GH3(6&Q*M*n4WXti6KC@J( z&W(Gx%vsAG$1Ou?&H=;XHiN=>6&g-msk!~;)D-<1k<JSZXj&U#8&d^me{`WPx}TZr zI-6tudBha7hAV@0Uex<EjcNtKNF>=q<T!4dmC@2)bC-brulqdBy;7=O&8J|ds4V1# z45kX<2C?duy++JU2)YD1jiSbui1<1Qa`zL{1P0Bdk4vR4gfwG&HDdTavcCNyOAcZG zis{n@837{jr`ym}LD+HH@Y$5qeB(=ZuuGQFxS~N+6C)9xg|Uignq5LPY#~G+{*2u? zz=cz+wkAj>YUXp~GdP_72iczj>zadlr@T367j>fJR3TT`A+K&M2G!NxZTC!kg;cGS z>yKh$iq^N$F+CiAXLRs}^pc7eF<f-2A4>Rn>MC2qE5*_z8*kDID}>e2@j;g1{x$mQ zkBWIB&93&8om#S4UmL+`RLF6g9zsV4bn9jbWN4i4mhttT-G&?#%pyu5h8Dv9aiK4A zsI*DMpkmes>=`@494?}ezyCZHg4WR{>d{&@-&Gg&qE>0S2efw3d}n2Q#TCD|H81`K zmEVxqF9Z66Bo(QV<r^!YoxFI}cSu&eK$b$T*S*y>w98g1jS0WpXlan%t)gLpY^SK) zC<YBs-mDX1M1Q>lYbZltvZ;XKvZ`Ygxj`hRMqDz%Xt-m|T`DV9N`5Vx7mTXC9l%k< z2GI3=8V{_JZ;0PDmQuT`aW1Hm_0thF9xin(16(Ms<0Z{}DqQZ!Pvvh#hnbr82b_f< zdO?*^gq3t~Ni%A8880vaGyAPVjP(~taA=rnplQnS1e?2pq2iamk<OP{oT=k|y=2zA z{^+_<q>gIIyTe6t`nsOkDCx!cLr&fw9i%TBI4NQw!S)=mzZvQ1$;kP4X2eYCkD?!! zYzh(1ezPH~pwM)`iN~G<(~9~+k6?t?fYvK57F{8ZPQO-5!!lw)C(f!XGhHIcZmUS^ z#!CiRmYiMjZsnQ^LSivOW`)U?Es3j%f%UGrNNUo(Q+Hume3sD8zPp|Bnnh^b1Yd_& zeD*a%B4Qii*1KeC>95>9DPRGxvf^wHcJ9>hj{I$y^#etbb*(A?sIhKKrn7`Vkb~DY zCm~-KqS3U;a(M%3Q9(a>Q@<~(icgD*Uxg49{0hM5f>k|ze$HGZC)M+`N|+{Vjk{y( zP~{Su3A-Ww8ivrRqm8=_UW5;zw;Y!M6O(7P)bXNmf%Q$?UPc4fuD?%}NwU-r1J)b~ zLxyh4;>`rzY;%(}e=ZjL>tzdf!py@P-W6pixC28PuxzVDo1p?LW!v6Uv}&R$Ba?dW zWnFE!=psKtFxJ^$B7;(nVGm2A8Dv~q46vdcxTwWxY%J)7_RZUg5?wE9h`vh2?Se;4 zt}M^N9d#pa>`4I8RBqAgfSsE_Os`xKpRf&x{X(sH$eEcaO>xrINIILgO}x}xur`ha zlI>jHQ^uGj+BgkS0ZzGTTf!E6JOY*w|3}ULAZY}e#Y;`6R>n+wyKb3#dexL0MgiMn z(2`|wE2x1j2^HWackD##BowGe%yz0DO{*n*r-MLk8<o=30N#<cw&5=+V+HxYT;;2R z5?3G^Ymv5SCVLp$qT_{i3ACU=``TU-OQxhFeb);tQY3$yNL}jtEOx|W6Q6r&2FiQ= zkDH788&F6qNyf#^_0EV#kXU-ki+(F#sGtCLR+r>R%LuXM93$M}Fz+tTV?M{MEtp|c zx%ZMNm#++6+e?BDU}_R}yj2Sb6vNIG`Y)4-33U55lTmLmKbUDvQDX=jIQ>Hxidl#v za}|a(m>8?`zxVXs5pNdDfbTco@c=D1vCS`gsz=A1-PY)JSmJCB&b9`3Z<{r+D+lfM z30i$EQ0Kqgs)x~MW{q~;(pLB3C8v5~2v&=U`qc~G9!DMWR^?JQPaIG??uH24vI)N_ zi^u4^9$TV1<Hj|8V({yS$$3Z>u{-xOP>1+Y>8W}^bHm$K_eccFDAsFV<Cxrh!HHFY z7Q2d=fie27xZHk=OL*Bh)As>%sn3vX!!$A9*Thm^LV-ApxY+Al71Iu<jAjkcqvzv> zP)HBY=}dDzhhwKMo7!B=wjf6H2lHejVrcNKzrJ@Dq&4kCvE=9cmsi-*{g)F8*WKt= zyD(hwEB8jAmN<R{YWL)|h+jQ_J1sR=WQ7&IqGkchxgyeycTb(eEL9w0fo#2q(I0)_ zqdEp!N|ogb&O#^QD}(gfCWou9D-^`j><X{a?m3_1OK#J9K1@Iu>|KG#?e$-EgCCQd ziE}1hf_Wc1NG;s2wj><%6LX#UL{fv;;M}??*EXKmeSF$oAfa;v3R;fG&#T<Cpa33K z%sHRBN_ong%e?J@+d3vO{Zgh-U>)BdqkT!^;~y1K^D+JY8s`)vEppo=jxp^5nJue< zs}X}g2VFOwN7?PO_=HKmQ{)QRH;O>%VuEC71|>~2CNP`1Qebx$+QcUl1eQk3y~o08 ze<T%NE1lY!@mS??TqIJT>L_uEp!bwX4ftob=&(1Q8DEmY7-&A!ZG_JlHHkM1ECBm@ zBDfe7xOu?J7@*84)biGs=tSy>mdOG+5kBIPn`)7a>PBR&o<Y8>`6^u2Z8WU+iA6^8 zv@9bsoWjPtoq;SCpMzfi{c_T!>&ht2&w?%%O&yxA0bS~kPI<HzxFlVirPQsVaiBQ; zae0Ar*VoWU4n9RRP@$Dt!^d|gQib;8JqKA)Wz8)iPRzg5mN~uZb-1(|Ke5%bniq<V zP3sYl4}=FEkGS9xKd0JfSRNbYxsS~9h{)dtN|POFuc$<ixde^O2hDB(M{K`-^nZEN z9`%d2d!S!r#50T>5l6|NU`dO5*9&YF=tWii$O!+ak%`8N6Ajc07zgU``1AOqBv-)q z0|I){Jp8Wbu5}OI-v8(P$da!&EyLC92S|+#5McMXXhcWH$$)N17CE^SG|=P2HGCs? z4E`E#&89AtmG9|JOjY#JbR`rBL_9MJ4*n6dx?}1+a^gkAOSPAVIy+rQ45MD}`oWJc zYG<(lj1C?87Cknw0wll+z#Iu^rS*VDi<PL1g)|Nir5Cx@_9CD=B@nIk35B+0INL^J zVziQimseI|i#7O7Zn4=Jbr>BPyqG|vlz1}8ZaDA@!Yi$5I&94;7oqIYE#~+6ng1=n zS}ZWxBNK+RsJ^QHVJ&pqdpl1mCstNU%1-_ggV~K@f>B6H9D|MEb^J!2|MCef<M0QK z0fCjO0$Se}?Z6Ip07WHYE-CKMQDuIH@6^KT#ZG;h@q&QO_w}e)LvQcS?%ElDki3Jv zvGI51rm^zS+#S!;EER}S3$@i~jX<_;n?hwV>BS%{uq%dl1E!4)iv>s?R<2DsXjRWo zi|*q*o&HAp_RB=fAfHD0Kp0(*!(8+YCNU}Tq+24g9vlr@ThVgYgnZ3U*oBrR%!Ki3 z1{Fk3wz*P%EBdG}*;5A{d<(liJTpUWGN)Gu+Vd)QBX&u9ZNhM-W2v`)dT0`|h%F?v z`JNp*?5O!NCm97G+4#VqR{X%+!W+$$w1LayDcrdqk!8n&XQ|MQnv2pSC4G$Y^$P^6 z)6smo^nxPA4DX*xU+_sCq*lV$G!l^{Rw+_Gb_fn;)}3P;q-40zTUN?HbHDtP_S7_c zP<8atPg`!9k=PpHz%}|3PXf#(1bqn*LD;k<%PNN5TVpti_RV#w68fx6xjYq%+-H9< zE-w&UK?PQ6PtQcFBu&=_G=~NeHapJ>n`0`kt6dxQ^mWDQ*T}jadv1&Fu%E~EyYLkF zu3Y%&`RP9gPLIt5(C>+a!?p>|cFIxVi90P=1s#K-YOz|OFIpkJdiC^}9HmYxwBc9K zH%4eUWjSCO9Cbd(%s>sm2)cwU`wL}BX6t0x%cQ|IX~?aW?g?*|*u?msOAuG<QgPF5 znfInQE*8yVS{~Vi7dStBe7Yy}Nt0?s1qqWC=%t9~oHK^-p1Mq(_&u2Tw9rF&=&;jf zsq?GMrY-GHm%p(B)K-0~vK%-BH|>k!Sa2g<5$vkDZ#!GDCtPnfCC3g`*py6t;Pn$h zm*G4?bSZOEKfPh4TAAi!|BCTL4C3$Rt1sI;?hiTgQGw@#c_g5l!{hVjl#q++=<ugh zW%Rt~!Irg8woyZ=4^0+*8vw<lUCot0!Vs@Y8@Z~_gVY$C+TF4PmC9jmBeYvo!F{^U zZEKv59FA4p09Teem4&OFTq11VizFw>;u@}l$1c*q9h{Ls$u}n(pu`r(wzlfE^tPQu zK{ho*KkJqnBkc8RXd6a{qjlA_9aL=kpt;Cr&BXz55+Dei?#(HtFQ_Z;*q)K?gaCJC zeazl)_1Z9(Hbe~XjAUO<NU%qqeE3vPPm$y5${@wu>KzyR7+LY|6@Y#r441D&Jl|Yr z$Y&pBRaHhL>-m}DI$_<*=Mp2-&AJ_%9roH7GPX6@Vf<akh&U4`e(A-0N|n-Ro3eW% zFGgoTcr?$l_2#yAX)Mpyu-`~+7yGegeP_{b0p;g$rt9^v)T$Vq8!@MD&+;B8N}56< zT6ZgQmY5ZZ{~4eb{7u0aHIs&3)C-lfqux_<<w*O$ct0nnKS>#X1huKR08l0|$AB(v z5Xw^$>>bMkIqL#9Q8|NX63fAKL$6kmqLjHbGKnA25zpvCZetNZJmD|8jzE$~&2R=O z?i!ytCFDX^y0HxmRi5CAadnOI&QzZ$OMTT^@0T<>7h-xLxiv%KW#^+zJuJ#h2@A+2 z>6b>D<tb*<1%=aq)~bOC+6zdczv4XqH>>6M*zvrajNJx0YNjw3q7F;-M>g+#bXerC zOl9li&;9<(zt7(T5VhI4*|&tLP3H-?f49OL0a+Y5cF81Dk5$Udh%YuWCsAANtH<~R zRhUF6$yx*B&E=TgyZ8Wc?duDrUv{vp;t4y)OLh*bEgd8B2+S4I@;x;U;8dl53UX2i z=nxLnBZFQ+RzWH?vD679nT55)3#C7Oz*l|ci>12Sy)^^MawD%`>6sCv>#$2wAGx$@ zaNNzO$@zyL_ES><b4zsN3z!G4o5P&9Jc^|y`*RvFs$j2-#3;EUcCQ~Q$=jrZ0@I3b zZ3REe(ot=;G-G>F<4_;LhQ7cjIOLO(KQcRR3Flj&uHq<4rz3M&vi$=SW4P(fFH3=! z1<PByXbOlCT}9e=Cs|&G<i`_FFk)rd2)3>k%Xq&O3%m$ak2yEV*_<=eirjdxtpF30 zuP@+&#RHwqv&a1)d&R&v+ST@2xkzNw(Fqg(a9g<)%|?p-5FE-jvln-D+VEv&&~CBI zHwr{<n|tCX6AEYR?%60P_$W^Fw4_Xt`Z<$98Jd_Ka-Q3y2HG;O>k6R%I0%5koR}GK z?tN?K5khA$jQOO;{qsj;#5o|ylaZQEU&bXX&hDSjb9YIUyNn*N9B4$XBQBuQZFWdh zTaWk~C<)qJBH;+}s^KdoA_N+^t+_|U*NThv@+#4p<)GzmEw)EDmtPGUTYVIiM1_yl zS(>s$R>@XjQyo%Jh?tLY)dKPqUIlC}DN^r;Jv~$jq)HghrF5@G5LYO|PEfhJ<_!*5 zZo3kGs7oJt;zi=<b*>W!^?6<?UUmRCIM=W=DtFj<axv!{HeG@y<WU{jRz?m6t8RNm zn?Y`lvhIUUBH-JAUhb^6tqb!)WulbXbhQYaT0~_iViBT#O6(RB(NFPp{SJ|dla1kr zMxZM<%p$cDz0;NJigtWVTgZMQBGz>)ihE2)XBq^_*s4UQPnSyVl2Ia#;aEKU-IF!~ zCCHRn@FxRY9tyETMxo&_D8*Cq)GY$7Blxy(KE!bEx>I~A?Gz%B03dV51A@oY4Pl9> zWmT8=k~cRD!;2*!pHR?Rkhz!|z<P=m0Gu}wYyJn{m_9q1k8@MH=C^u5twjICtc~oG z*zG*!rQP$1P(&?r49r-Tz<CQ>I32~CumAD7jqv|0md4d=K(rq7Gf^csbVUNCT_d6> zZMRkv{a974<19ATaKmU(^}33nM6=pRT&YpWZHXBwGnu~h%1e<*SND+jEPYUQ;tvc9 zgweu+HR@y%%>oQkWB7|ysJ#J*-_>!{mDmg4BSn(xk~IJsE;yY;lc$m)u5eN09J;>! z-IM-j$lQA_e`vl}srH%|zD@s!cg^$JhJEeb@AKIG54d8(XZv>g!0*rf9ztH9N8{(i z9f8L)nMYUO_XBtkkZ9fw-cJj3DO}$!tlrI!kHj3{5;HHHPjhomA3jbmRNn8K6Zx9A zX9IZc*OS@j^W`>s;@^DqwWY=Fy%FlS&i2nM<~Ih6qe5Y%#P)7!w_^3haT+`#qOcqq z9CI*ObrujP2K8Spe!l{41IrmLcC}x>^Ie*6Zc>+lKbk8v$lE`gY*THyPN}v?R?oQz zex+-adf<mHGEq!x(Inmf98V_R118>f1iBvylx=^n*|6z<(Y#N)*;^O_T?e(W5_{y< zteqgs^Eue)$&D@wZH=s_g!!fIu(e0S@HzYntxtdeFsy*rBhj0qw1UR8$}9m(r9Vtj zzgjjeCIObBNb8Z4pd_+kcqCVVuDwi?6pgqLe>MBlY4I;8PGe_{lbv}HJ$Lg|n!AUg z5jjhzyyo{2GPaG5*e?>ru~n{MQD8JJoA|8A8T`ei0LfZS&ag6Q%%>`PDW5Udtx~&6 zGwa+wOGu1Lc=QKAVwE#Z(Yc0E2P)&G=iKt`e>?m+{#m_yhPDas&e_2uF7|9++Pt(S z2op%;9+(V&G$h50IXN66`-(1jaT~+RPCN)Ocn%j&<WDJS-Y`|RIm6*XQyO;MaNBL^ z^aYDWx#Xmzk6lX#7y?k~0B&2=$jq@ma6wC)4pf|Kgc<`|Jghg_ZSN-_HodZQbIS+l z(UD{3DE?OLq3YU@mcN1T9O6?nP4{)q?#uecpnCmO;3=hzJ<&+ZFDmA6*8E8vYd6I+ zD5HKQx+8{byN;T@$;*eRg|s7VU=fzNQa*c;d?&`^5F)QHU#2VbJWU<8{Cirur5@bD zoSEDKGltg)o(-YFQa7nuQggu8C}6#Ttg*ns3JuPF-l2QWPZDtU&{60$h<+OSOyako zQX3PFj#zIWr`q#N7-5*hV+H?e5${2<G}z!CVbaE+UyBSmA+@75+JDU`P0e_cR`XO7 zqFh<!C6~C!k$Z;JW_j7;?}*rgKGz&g(-&l$QIQh|WAm$+4r~aKrp?JuSR^i|_fI16 zI`aufj$7g<e2@_qJN<F=vOJ=GMHc|EseY=3!nXT|Q&Ma04-=3vwa6y8so>E=XQV1; zlHww(R(0UHmN~Rmd%Kl0Z>5Txvov<Y!N?^qhAzd)ASqYvli1TxD=W+H(&-^<7Vf^c zESWde9&Cnrd%yXE={m~&PUG`lo!)UTLvFHtNDmlXiOe_Yv8-T_TTFR_0^b~|hOHe1 zpDb~QF$sbiPfy8AIOU6SvuKHC5@P9j@}}$*erKc&3T^QO4)==QW=wNama~R_{V)#( zlDsgF3Yn=KbF%mj(pE4<0x?kpIKCP!q$hv^m21lo;~%W&U=M=Li4!8D>b_3k${%`| z^v_xt6E~W1FvTNkUC)@4Yn1YoVg%1Yn%D@w!Msp}kG5JT&|c;K4juPfu{9~l+-a<j zu>%8i3>&O0s{?e}^AgB->;;TI8CNq*T5nJOH@<E>1s0nnhpco#^+ePwEvXPo5GC_f zxY)h;%>*nGC6{!k-UbW>54g85KlIY8zrnA<ow)JNu~<$E0Ces9xiyyF!F}O}H5Xq; zP`04A!y7nHO^=2R-~F)lLhwh;UEJT*WR%_?Vr6wDsJ>U@lW^_rp&C6G6=u9oXICS- zK?}v_`8YkkH>eL=-}if@n7;4rf!dgT``a~7Zxp$NEY;cQly^rDQjFq^dt&|zBd<lK zCvYY{Lc;oQj9JG{gE6pktR`sA_r~^M?OCSA*2x{+VtW)dx9dMqN&qUj>nfZgOcTJ+ zDMcwKWh=;IyNiHEX=DCp!}MSGu<7KQAaC!27wpXoGhYx8io%O~eOu$#4Jx6WTWgSc zu<xph1(n}6%=!{L9xPap9)i&qihxezQnbU?Wa5Nt8{NLkQ_R**7~%o~)y-}laAZ); zx*HRGJzH&K-PY9@H}aCbA)1>KuQ)C*S<Fa0tVR#M1F*OgjJMMf4N%|SYJI+hde*U* zH}fvm^Bgf2T}eA}9*p$>AzBTFgBl7gj+r-89Sq1scwxhfx+GjMj9wr2#*RtzQpIGz zS10ooJ3H%7z0`P`y|o1hIBr&pyE0Hoe$o#4Y)SxLu@?ny<u&7h4t7fPOom`tk%Z6} z6A=;=0{A7ASmNwFhZ~adlLw0g<BKz@Wl7k}tB)Knz}G2<VceDKX7Ly~xu{d7k`MAy z%IGbOx4hvtZq1TlTAm{~jNL6lFx^JGP*9WRVnS=vQ1;lxX7aL<!E(7w>o@C0tK2^h zikR<}4M0PDxqG0%sfIjT#qbW*Civ^$ocSvW<_T0=ciMpfQn7x5iBZxd)wRxD1I&NJ znj1D}XSuBQ`Q0V1r!1Dt^s1wrLIq8`VcQ0>N{jn)^80r#13q^keSG-}HbC*pN6;_+ zB`}!j{pJ>u<E3{tK1825T3C6?1}s}JqV?GuTq$oMIOLKOBWBjXN`BYftGXQnt1e*$ z9#0mv*b|s7le7khEyL}$jll+!EDGjjVM}c=(w-NyS3?nlC<6c&jxq_OojDa2WW@q- zg2PbQaiv|-ICHQLD?Z@xj<qn7iPzAQB*~U9J%$*i-lp#3&rHdTuwhY=eQkG!Z2Rk| z;TI+31{Xv>6nt)Krd2quKC<j;D$SCI>Fux8HdAFsG@B3Ki_>?#8eOP|nVOo3lkW*~ zEs}yteB$Z`Q(P|N-F5Ajmmn13a*_E38y>cLA^B!FDxl`bk-G0hiz{s_{w2EMrlXFV zW5qX?XlWLQnERFm?#9<@<tg!EJ^SDn;AYyVhY(_}!Qko`Ya=;negT!)?KYSKDvRWi zc!wC@6coKaK=I`7s&hesYOyfFr)!LhoDL~x$U`g|sw9g;w9KK^i9kZ2gSjKc(Qh%1 zfqLtoZTf9UidOyJFyfl{iJ=dcVpZu+Pg$^WAZ*(N#q$LVAGyYH3kwO=Rt;i6Gs=w@ zr8h)NOA$xZgV?5*G)QQ8GGACr_fS25>Xl-y!CDw+kzd{w3Q0<pF+8%d+CjjNyOzf_ z)i;o@stjUWs)r-&y>b@7jW^25+m6LN>tuyaGMU1MIl%5ck>WW?ba(`HAy-z~ufxvX z8DS^Sow=)>rs8}=ryM_gTps^zKG;qlHC7UG`P`M|X%qH!9w$FPxb%K94LSCsM21pI zB8n}VM}p>yWwC#Y8h2G$U-vb-(3dckR8b9BlNt4?&EHXBDGvHQWXjw}nE8;G>g>nU z#V>8$C2iYzGa@G%c8`V}JuZ$+9;(7fIVnsJn|EAAjCAr~2NX-Tm2mo1q{?UvEMr2& zBjqZz$(5R<U|9|uEl*Awzds}SH;L8cJQR`8MFc$DIz3~4wNlaMMuXw=;pT*0#(pT0 zTY^3PETepwk7N+!q-8oMk=M!%!A$BGMn~E+GO_NcoJF)lOowFJ5E!%Gf%@^8qab<? z2N`YstuRF%{FR|ZkwMvS?CQm+h)#vO8C0=HB$m69NeHr}V5W*vSez6~b}+!8o1z;I zMQd+b0P;prTcRF_A>e$Rj4H!zo*~HR8YQmB1TA46GIz8W&rwd0%bcCQX~((*Eh_*` zR~Ntfp0hw(k%v@@db8RIevE*l$9<uETdsCAhOog0zSY8gBvYI@gs3V(?7stw276c- z*)X>Iv~L*N$M-gt!04~<beD!|vRU6_2q1(L4z&QRM2HW2qd*E*Ln857>P6s<Tr>9) z2+bT>wFtOYaAIiJHqYWbgvi99)aye7Sq~C$V6}pp5B>vUK%Ku%jVnB~yd1KgRBDYh zPHRDpiV6dw+<<$|HlV_e%;NtxW)I8lxi<Jv8#18J;qh`3uSGU>_?80+UEu?qGEm{P zj4+5660kLd<2!BFI|k{k=~jnbQG{Jukc?wDd8j2t(YtA$paVWcZ~0EmZZSS5>oYRJ zGDafaF;{rbt*T@?BfUQ?CMJ6qn#4w|PYVVl8evPdLe;A8u&VPSzp}Fu92zHReQl8C zau9_>c14MrsAhdAx7XRtjRg{;{7_g4iFv(fHyAVp9LsX(G+Ro0Lo~$M!~02`{jyG_ zY$(|*LPY$P&(SQrVNAo;^K}7-0<4;j=?Z?3Y1C=_j5|}$a&NaF_nYvWA0*cCd^*K7 zorq>FbVuA?eE|aMB4k=+bH|n*v74m&rJS+ykrjtXl$y(DN8Kp5V~>{?D;3?jZ{VN_ z*tXkpU|;E^0rgF_D{epwlZ1{!Nv1W-4!U^`u@8^y8o0()d5k7NQ5LU!QPr>_+sZFR zEMj#J<RUL-U6r>lNf{M8vXcAE^0I25F3G>ki5i;l^h<5C|F7V$vm!rDRmKupwbb#K z`A$4KZ);|$x<0TS=G4XgmI{Z%hEcuX9>?ld=2R|O7!JXO%Y&MZr<Ut<C*nJ4_WAD6 zHgZ=#?}iROY*>P!MA@oucM3M{8C=T{X~nv8&;fu<`!H{$*u+?d_3B>8gIfG)G%O-* z^9`$5$w41pb2+Dkmy5RZR?(p+nYL^(7Es-JZYr{A#)Tz3vbI%RDAd`k)WVd>Mk3Q* z!9QmvZ+;pZKvAO&75yH_?auZQR`QHbF-(iDHrjlsd_~Ps8gm)Raz_zmLA$Ms&}#D3 zkUQ_vn&ThkzYY5zy+#y1ZM#~GO2$B+I6K+@e+$Zw^A8zX4b6d2@2tK()u{_R>Y=J` zUWSGGV#_r^h$MyKmSe^qu|e`y(-^_FmuRRMk=Vm}XljGB&WWCMCVES~6*1L^Znqzc zoGlfGPTM&^jmQOJajNh1+GDc0pQSUjxO)4iF|l_A<fjLgMeA6s(pxK}T12U8T4D&U z@L7T4)aMRc8h-S)*4WjMhERQEX@_O2^TYDXTN{3POMO1xriUMot8NQxy7fZ&D2wE_ z3*>iM93N$2{P!%1)mU&F>vWGE$ygme`cFEM#&sR0X_fQD`l{!N^>(_}hYN><{3lIa z#5{1qmaw9Fpt*Ti0V{o~5c41@R=Za0P?P!CiY>RLWpal?ge7grJk*07#TmhPi76C3 z<6S&lg0JyqS8R+av^yIavQ<l72S=;bp1XndM*NCBQHMWfC#Y0P#(b!^UCPzywXY%J z#&r?EicVZrJ!s%KP<N=xI6t|yuwkSssd)s^7fC}}F~&r&ND&U@BC7>2+|q;_vCh;7 zo**1S8H}4jrF_uHvA~NK4P(G%Jp9=M4l4|G29fqrV-f!t3GHVTB?Rvy$^qN!VRViV z9$WNn)hYdT%0+c(XuewXqP^Y_$4H?Mnl%*)bZxE=ym0uc7$-$C#&oVN+nG@H^Yk=t zBWQ(di>RTo^q*cj_y982B!H%#M&JD<S0Z|Y1a3q43jV6ZuY2w+0AD##n`(j#o)9h< zN&gE2vFNtp;5Ebi7NL8g<$i>5{*YWRI)SQ>iV)~NU%s5{p6Mms0%qwl#?R8FjGwzK zXI<}>OIp{v!?M<O@36F;4eLL44ZAxWeqenJPg6<}hKXepF=-hmzs{5J=veyn|K@sE zV_#v(>jkYV;SY3a$DsVk#9P+4E-n}5h^LRXdKWhM#~S~bYy4iFdyAJ79)~3?0N&yh z$&9mFv)ejZ_Mb?&p$j%9F7o-=c_0xGF3mf2x$Z-2^dhc?^?D8N)jn~6C$@Y!xfXYq z@oTOS_P*7{=-yxX&jI+PVjk2Z6L5@5fXZu6dqWWBF%saLefX=0%PxU2Z17xtv=#+x z$2DfCZSgn2)DjvQlWXN`AokrBM#wcmJIHHGiJ-6GUL|Bd&*;E#f@Uewh-04c9MG9e zF2&%Y0xY9JMt+Ks-PG;B%D@(rSx=4l`hdizxQ}-;`2F5t6uj6wz(_#o0A9c0Tzz<9 z=xxRXYcy(*GU3hkV{Xo5%OPh$HM;_PBy1U6oBQ27;d4o#04{3sbq`Zn)Ni7%BSczT z)V6lXOZC?{lB<i})m)!$t0A1VZ5Q_h*=AG;!yqQ2`BP~DbqLHw{JzxKkD%Fsj_4NN zhhJpYy1H_Y#?>BUu-RZpn57tz{B8YM>=RpC<vqi*1-CT3oF-s3wULCA-wPX!YD>b! zMsF=rg31-rK61tTw7Z!_aZ7@JnOxcE-U2K%cl_lj+dL*teH`4U-Fs;Tb4>Jdm-iUk z>ZoN%ydSCUNT7m5HRN!T>l<G?R(TA(3_8+SM;U6NBUy^>+~YCsDbt*{R}A}Xc;ig+ zvvg!z=e<!IuxQ`e%B@tvWND94fzgzeT*z&mlWb<&+~lWKLdxzbx=3L#>Phl0I4fcd ztXuYIV=`>Yv_BQEpfOX7t+7QSP2#a^P02eD1S%s2{6nacj^m2M!i>=n?u8ydTDFk` zft?WVB!{hl>eXq|vav>!W;&&fE9(bP2H*w+3)kkUAGi|<j|>+tnAMveJfeJm+A3IY z2eTr-OvkQ~V890042~uS!zyWKB_alH_ge%^QHN4x;!gfcnG29(1&<Ugf{&)=N;61+ z)*L8O0}H$GFo){tDV~Hbac0GPcx<E4#^E8QVVxz(7<P8FT_lfJz`taH1zaHMNOUOI zk%%8#0MAjfDFJ<b?g~1dJy!ul0CtHRi9(mQaV&LbNdUDVUgvYk(4w4+ucaP<KFp~r zm*i?^OvGtI9tjcFw(qcHM8OoDKsiz~1#7^guZV(9yoZ6!BzhQEY46nSW1%6>F`CxS z`&oHC%E{NegR2nFZm|2}XwLEub*%1#1#IWN)!>bC@56%ZXh)z2=y<DoL*T|aY39Z` zVcTBA;>=DoHY(!sT;}B@DRoc?mMh%$DTYtYFf6F?Da!RcFGMbSYTB1=i)TU*H0HNa zpa#Eif-Htz{}4-ayQ;HkIGtKp)@u)%o;H~ekax@F--6ApA@jO72CLa++^U6I^W%=8 zw*)UNO!yvKf`vB16laRYfrT$;CzE9nV|Hm1O8kc2`h0c<j4*3@dmhS>lO3y5-U5nK z@=4CE*e$S|MM0j4vodd{X0#cj(Q{bbCkY;&G3SEiizLhQ3WLK@w|FyV|E6E(X_3@X zW1!izu>E`iYz@nDx@U`e-dyOMz4Klnunsa28gWM`;KbNkT4sj`acH;B)3ck6Ve#Me ztiiDN@{Z+2j4OANj?zlb%_T>LfgK%vmyv<wP4{JkKfx5_sHJC&FcT<p3{x%1;y5Q4 z`TyA-Y!;H;7SzePWEW~H$GbUfV%W`njkY_^)e3@_k;9yPX2&2^QGD9UJb`)~9+=gm z*ae~*Cd0s=v`xlszRxs>CQ$1L**EtCZ0IMLJd8w1$fgZRjjy?X7;|SW?65R_#5Kgn z*3Tz5cBBJwoZ~&vbTh7_3n95eyH>=8+HWwjrzQxDxJQjSt$~_tb&=%CdXB6P0x1G@ zB5^8@dP=XtUiH*%XStc^a<*na>P*Je9@MNGckPg3-55V7@c*t6#Th?teCnn34c1Aq zSr)`80}h}PoV9RQn~$5vzQ%6Ks?a)2sqX^5e(i2rD!Q!|Le}0?S9KFfTADHYse-jO zoFZlBxAfP6$-WG((NN=<=7^RO$Fy}=^H`Fr>1uIkxSb&^qZ%qvNZXL&A=WJ1S9ZB0 z%wjXMccZ2qqfIu=;Pt*+^_8u-P&<X5U>p{$ubuy-PZWX#b;uFlMwFP&pcWW;i|0Tt zlx_(7)6yM;YM`OjsH19F=9IwY+a#N5{7yy28ot>6dARrT5JU?=(j=ZOlXebp_h@iJ zS{aU`9Qt4fyRcT3-y8>AQE^;qkWN@V$%N+w*Fa98p5Un-&xeW9jFYgCi<@-~c;|gR z(wZMrQaO;SW`rY(7s6+UZq`*jr}zz&fy6mr?YtK}Q7}<T;Do_tMDCGynC(_WQb%bP zCg=!kOE9&-#p8BI%biix;fsVI7WuFlfTiB=?;dHz2(aRA{u1gh0WoMiPB<paDk1Yq z*xe}JcBh<-e>q*>cr+=;zx;A>`sj-<;mO4>r(gg1o5{s5<>~mFum9Y!D@z`40^w$N zqKsxlIfTF{A$Kh^+k0<dEC&JNHP**Qx<U6o&%}eE`;YGZ5a9Lcflpc6tiydlCw1SZ z+zfH+U}**1*fsuv9}f_}()J(!@RU~{Y1IGHg|Vy@_j_5XTLRS|M#kdf_1y)6yYBRN z-Rn7NruKbk+47gWF!FZ2W|AAbxjfI@ZQLkh7jR?qts;RbW@okClu!)s$}QWyQUQ2u zY)-dwLC}si^@vyWti?>U`=-l?r@HbLvF<Bnr))yKjT5f!G<<pBxtdvU&m;+V_t6yy z;Vdw{Q0Q&X<Ak4Uj9pa6b(1km8|~GgAF}Z+vARM?cbp_=%##(ytUlc0(ox`N0kU0) zi!r$ZpcT5c1WFs}{C_Sj*D^4a%}Nw${DSZzm0pGU$T-#oDxqre;pT?qM~PKfi>{cW zo8%%LZ&3INNq5uOP*$569BK5ir9a@S1XTF!ymv+bZR^lLN~2=wE8?m`f!hX1N}@_S z!o4#iD5|bfU?x+Gh2dveN#i1twP>;Ag;j?Dl5|=Bhld0bE1B;Y`ZcD4I_jd1CW#1? z#10_wjz%E88JCuHSs9q2^9+y*ZQhQm*cd!uyj&o#s^FbM@Li2n)FP2D-Pa4_7)gks zL6ugMq~Y)3lY0T6JF*T%m*Zhw(HcQT3M!DsX^F~4ROC(LaT1(O@*>UWa9Wv9r)>H} zH(=$Q!hl}q#l^tN!tmOgh2bT%w^vf!k)OD|SEs=%Xzy9w-V1E+JJsF+xA*j#wcH2L z9#r`|w%4-maOH1NOat`<bFb{$V#PhAEX)XlqDXP6<C#*($C6iPnsKU`d4`&9Brk<N zU0iKCq=d^&@F=bs*W4w3kJGdB3RZ4)g?e>oGT4qvvk2qBWJ-Sxby8E9p`%PxMz!c^ z9^<`y%Rrqnk2GRcAoe!P;}&miUjz$zWqMOZrXSTJuR5GQ*cU79%G9>4xebtS)(U{{ zv`reAaqo`sqbSVTRE$~<I^7(rLbN$sGtvbDJVBwzpI*4r8T^u`83+GExj!17PLT0s zAyl+1g8taa17*V;7o+oA=(84tk<2KL9p-FZw8xipk92yiH2g8$b*b%0_IA<`84KD> zpw1V5?uFn-Q(X~4mg%l;v8CN3vzu93Q6hBc7X~UMm4@hhU`L;0BGM736~&D@f@UU@ z{E9PC|1&9a9h?)Nnnj&pJkZjRTCld!0X2Ze;PRWGth7TafCGzCI+&ga1)nU~D=1Zr z{=J{XWApcSIUIfVIN0MZn(!BRiRjOsKx()7H0<#OYnsuOnu^SbRFHsNq^*f0btJBV zNn$zFHbP_9148(}<Dix&T{`MwJKf_bIO<|M{0&>+ZwOo7@*kst?y<xA1XvU>DELc& z;4gu}=lG8WqGkQII+9wR%11%9;%;iPkDwPE|G|De>=#&J)8!TLMlXy@1WKVgP7d&N zA6I!Hj=QbQ_`4)asGzcU!jN+a6W5D-$;uqnxMrY$^QCIb;C2gGEOS<B!{Mv7IUQf| zlaPqzN+Y|Dy0SIEHO6dQ&o_g)N0Jy__1lsc?c-z}-Cdf{QC}HF%}hcbF5i5GpBd)i z-okLouTCkIVb~c&-)=tafA*J-%Wjz;Q6a20U}ET?OwTFr{}Rc8BEeGtW>SV9Coy_1 zV1;UqCZ(UP#B{m{6*&Px#4q}X22W2sEl}y!fY>yV_CW&0Is3^%j^ULz6fL>ZE348h z$r0r62ES;~j%V46R?c#LH@a`EVPB(Ge7NB-9*?!B9LqtiYZK$;5FgV=rUwBU!q9T< z>vJ`VPTSe|=4OBqx>F+{Kka%JN34NM%=eNrIzY+&_mbWBrbJ;v*3E4sn6n}wHz@O5 z4qfg<n4ipj_?dIRbe@19gLhNk<Ch4_PsVN`3FC0iMJRj&w`y5J(Cg*rX{#YNx1dKz z#u5HQZ}7`!tyFEFqj*9iO8nk(QsgObSjRPU4Tp+4tj6$0!_%Mzt<mOHT;L^ZIlwPr zXD7}O%qX9ppdw3UXF)3v3<&&r>G93Mh<p@Sml|vf;&DK^!hYiBBHrdE$z?Lx+HhE! zNDOv*Re89LC+MTVTq4JHR1984#m8Dk<l=@Nko<_km=KnYL@EjiX0+BnsNi>|0v`8+ zX3*MUIX|(d{uVRe*E1hA`KMf~Q;;_dyZgs%|J!C8XA>qHreQFo@Bs&ae==R7#+}9A zpn%&f{{A0}|397_c-(!@;-AhZYU*#h_U{{OKSr%dNq0OtZ6y?VWTmq-l|fYCL16qr zUyI$^`I#JMD6{4?QK>mo*2~1fMqj5FP#~-M3{(A;aORn?`S;HI_tP|sK%fOyq#>}O zbCI0Qv6$g)jki<?!%*z#E{IeMAQ8Pccuq^L`|rLC>3*0+<oADrilh1&r)sW^#ofuK z?o#0l(6Rsizmg*7T+}xqKJGPwG=v3ujX_5!;%|bYa~3EnF6&viv648{{iOWuncFX; zBjFmpZf|xC%ig|8!H%cZC8Mt4tS<zjvv}7qYACgNS_2O{85%1L(4^c*-(V1hRz~sB zy<~^3MiQ|ko_;Htl*&fBS6{nH#@9eG9>>z@d}<uqu}%#mAC2Y(nQ)f_G0w;1qmkfD z0^W-i-&K*CjulQ9fZ+Z`)3y>rX7&in&t-|Q)`YXcDLS83>Ia_6sg7|hbuUb~04?D* z?j9-uhP%ztHF`&z8_hE)l|(1kcHbZkbxn4>qjmQd#M49c`o)ox(nM8T(2CiYEjX7i z4yRF5f7lYH!hzQom|x)4>Fis;Ex2Yf#EAR4$p=fi=$%yyXN{NZ$39ZR&oXlI%&AeR zzhwegNg2t@9>aZ*z=Rn{Xj7M+<2vYC+jo}((sn;D;cyH8^hEVt!V$XO*3oD(GJdXG ziGF<M&v)qsw(o7;*7d{e7)S{oHwcm&{~P-1wzO_bMX(oV$r&5(l80}{7Ol(~S*5iy z!Q48$m5a+Td2ybgJ5fSmPSA|;*LgfaZqJUZMro&cbFi>nEFx;I#ybpt4Z8y@WUbe6 z5gi(>`C>dx<BLS4(W0wmZ%_ghPoFGX<^m-YnZF6SzwWd1UB3D)$W88Opx57Z2mcGk zA(ooH-kW&5?H~XwDnE`8_VInAJH6Yr)W$KWg%#oW!?~}3q8dH7=v2$F8wUgU<D3PJ z13^<8U`05UvjZ2hq2$Hg&y&Bk>10Vm{T$c)A7{sZ<JqxB`*JPfN1FFP^a%f<w7}#3 z&7((n_aRgNkG3WMs`z7i|Bci8s#w0nKh{M5vBv*HiGaub56>EhNxJ*g|EX<_qeJB% z6Z~(SU_|%|7lI#Yvj14;|Dj~S<NlLpou_2U0JASSidLWZf3+?0mwC0FUANA!?kAQ~ z&Dxzp(<e=kSv*a)NCVjF)qS29)o9K(b7TygRB!5B9cU0M0a?%vXnQhI_AhMJ<TcaS zLj^ZBO`2ym-eOBqv^`5D{zvzI_l9y1$0M>RB@L|G%#HG*uAxi5?idk<X7x91VV>-6 z<kPgOP}9rtQcEKe$v)?DzgfkX`JN7?nzUY1U>cioT*Zz_%D_f#*ulPaddfxx(_la7 z^gGRRWj-pCQI@-Drd!%+1#Chx;RNm61R*WR9b=wzonB+jB`Q3lvdY<AQ!=Kn#w({~ zi|atjiDy$jukc<W7hS&-MeXKWMB3?`)MDiAp{&T19c2x8G?}CQGFc+dYL6*ypv{j( z#&qCx-W=E@i7%5no$0diJ>!^kJUYyTN-+jtd{-KT3Kmlv5n`MuwX#aNaj8MNNa>b= z%GoV`Sc5t~RfeuJ80RU+q~el+p6yBD_le=%Mh;rq=yaNo=XlY0GUt56Cka_2vngYl z16kDr=$B}aPwG(>BeD&_Olnp_*k)$m_MF#sElL!tJPHt5W&0ew0zO})W0?f8P%|fB zWM`dSp~tpE5S6L(*J9*g8=_t$&$#iQ%(APE-U^?zjOywUtI_IPGYsFw5sY@;ljqe< z$;P`eUTz90Dk^Z}g_x$gqOlfRU8(5A^dhOK2BKUabxf^9DFy8qknD`1`e&?#g=E$0 zuhoK4jt&q8D+zy+N!?5Zo|A<y0T~BjGB_Jxn%SvnUfE@SoO4hQT9(cL;mx;dZ3!0Z z*x_W^EIy;6nNJjSRL47)L#ay1tX(m0V}Xfv0BiM4nz<jjR>e@(2_SVciGK+m-q+o` z|1g-87r%_VJspn<i@5QqJaA=7MhDgPB-vqbAFur==<@T`%rYC|cboLBw+mZG+=QqE zY*nElTdSK-mdsa5Ywi|N&TpzOs+?yBZ>wtTe*{Ig_n;RvHR~QG{me*XrdAg@B=NII z#UE5Zwf%u)z-;&KrkI)NCp(+O6kNPcBs~Ry@fn8gX|6lH+!nGAGy56^sIR+>3vMW! zlya~cLtK`a&Kj%*h+o_Sl#3_>nD%fn!1a6sT$MShc~ld4I*HGkf&PED={cZ4l-Ot; zgpvYJViOT>nZzMkyjn%{Z}@(r$jcHsJwS&oS43BFowsUH+^7aWeU)HLQ>X#${T4Lr zxA4<AlF&IdGth;nxvR0;|AC&AhHqQVy0LXT!e1vo83pSbkAipC{|vtVX3gxcaW3;3 zyT4$^C54}W)2;_=;d->*^AyFCoh~e_cjPku7NCy+=ob#qM)GVOfv~O~V$f_55rQvz zQ4nH8pUrhj_`dn2uZzuw{|pU(z1nC1g)5F`eI0S+YAS9u9;odMX#LS@BU=9w8~^Hq z8vnA<_*WL$9oEOS@;txFIH*BPVOPiV5!*1D0ypy?6&<x7j6j0Sr_N(`$TT>Yiqt0l zWTfFRcbJ<2`f0FWD{=2F*DTAocjx`p_{I?8BI%&Rrl1_B{0tsrSv(6rQK)^KJqaHp zTAoCY0V_{>9YfoL-cE>%0b(ap9%JlFOdCNmE+bM2>Xf24x=~d*LdG7WGNqAa*KEtJ zHVC%ShBM10q_G&O62eFqL>MYDVk-3Dd_Ik{K3X{v(<ViM_(&V*saxY@0cZqJ8u+4+ zce;<7$tQ7{awJ}iHC>?e1M7#lnv#VglQimPs2`((lNpd#7tI=SUvu7c8j)HHq(@0= zgU(Nz;r7#=XM@22Ca7)Shxx%R#v5MDm1A1>|3w@6!u>f|K{``=_G)Lu;SdB>uR_yQ z)*y}@EqF3pSdF8cm1asPk`d|<YR#%{3^)Iw84A3C#^GhFeZScvteDZo8%`pHsbE<) zq4g!&5Q_h5_QT8=h#(}<gg*DF--qZ{yLEKjF5m26<66~Xm{b#?av};C&wRx3h^ena z^QV~UE-}(y5tP)8Kiw2c-2optHy9j@3q&d{r@?o$OToVx<){BB;m{@aHY<Y>Hu5Od zh8;mW*3Yd-n?Y!#0Eq<#=LR&`OjU<3rxK|7g)<2%ehc!EM@}-D<YldL5M4zZ8a=^U z5JeLChB9<JC>vl)W(*W@C*Q6>o;m>(`4Ux%uX2)w%^BzvogS*JPd&%CMrRtWFHXR0 z3VIf-dgA|ZjBh%|4~NOGtqvhxHGqYPmR!!n1d(Lv3{Om<D4B1f*&F?8p385kbuedN zB8RMU*jLr&7^%Y=3?()1ZEbm6rn00JNdgZQ6>O5ZB^Jxhg%+H&&OOPer8>S1(=oqx z?`9WFk%{mvZ7OZm{@}hV<T7KeU^))m3=<S4y^W!AVnx~kex0XCpb00$AqGe=K+Zcu zMJQeq<6EU>4Zh2zCWW&}jB{F=O-Lu0j*1+skV8s2Ke09>K4oK&ld)WYOfce`#MUp` zuH0UGvmy13vEz@NyQ+Fl7d6IKfxV6yc@_|bG&_$HT>)YuB^1OEHtyHT$Hmkoi!!;G zbL3|ldfTzOMFT)ySmsgQevKECMMb6b!s@KAS?A>?TT6o_v*c9cuV)aChd&#{X$woO zjN8A;9dXgd5T#+8XNQPEgSbnFuC+3It9!2-QTl~v^XW|9k-9)G4CN8#)&$9i;4TRt zvP{;%=paSP&Q`{{z!2kb)WP{rVw1eEOjJXw6N0g2Mq##u-NXpn|A*EjonYefI=G6j zt#ERHAsvp<3|*qvE8cX|+9O(1J-o}(!o#ouk7G(C&cJz9;Y|Roe=!Jg@bh~wIPcK# zC@-3Kt0f>CYRKUYX*Nzroas%6B3IWY%Darl<kByX@muaN<wmO&fVu}D1M#h|)jvhN zEvOjdE1g5G<f$-2WT|&3&rv5c=pf%F<7|BEb``dCS^yDWyAph<g0SsrGFFnef2^5f zoQT2&FYKyuKDQy63($rnF>Dm>aSW$o3BmJ9_7F-Nggz$#s*WRHxAKOKT{eLhL(yzU z3OhaJoXRUsUK?$ac8Id2QJbO=F_Ywlc&ecFi5=W|Z;psg_O#(fI+~A~7r9V0RuN7M zu@7Vvfz2tprQp%02W{Cq*hg_FTZooHhe&sMHsIHe9fbODFEMCv4P>A>aJSp_NyhUG zH8pZw-%ugr2eu|(MeVB8TCv|!^K_EO5)8K-Ve%?CxQ$RsBKwMFjjsl48_C8aA1I|b zUme(b(qG?bJ_hV~!y0u&+tNWoVFaV^9tyre=Q)wkXPu8T6BtGGy1s<=PQ-utDo)dq z6L!Lh4*!nRv$Rsj*6zU5SbxwmHC3K-GEQ%`M}ze*2J2sb<3*pdG1ChA5R6*28W#r3 z2)8l5BY1M`&eJj~Zc^}3-w)?DH0`D5BYOH^<B<pW?Wo*C;YakW0a<3EO}ypC7m}ry zB%LG;&$svX{VAR5TYyLICBPS+u!^^%a}SL#?%4Yxfiu21iMOFT_$@Gt{TA3ncvBB) zt#Pm6ixk<q-rCpN9nkB&v1*|OV~fHq%@F&v_b5xw9Ig_f4(zmn>folT(SBUcVvIr| zCMI<ww1GyVi&w|fNqUjcfe)8`^KhkDX;^eBu|MOAZ{HfBn@h7{eDjDK^WRH`W~v<p zvxu*Bpl7yqHj<&LC>AInD3a_J-NAyKo@P*EJ_@z#Us!nAB1wZ{0Yfp=W2ZAYM-2-4 z74|sd9*xaT7;d*HqU)kIm2|rmNU$|k$p8w1m69UuP~2L$wjV3`%$F>U!#v<%ni@gX z7sITSwX*zNADt_?rtjg=MfU+qVl`g~YgK4b)Mu3R(#(@FwH>Ihg2aCAzRkKE)L9#D z!6Y7gk?-OUKmN2P2pSWvP(YZlz(ykc$1@x)kTf(0)pAXN3`C)eVGZ!G5#oVoOPzXr zZqfDZt8Z#%OliSg;tRCLGoOO@G_HUrZv~z3`S#)Vey`(@{wxv2>T@huC$1N%qtk>4 z^%0dspDiBI21@8|YL*N*!=4WhP6f;d1+*|xm8xEUy~p{a;9nZf?cB2+*bH_lK%-WN z_YsVRh^nMnvifYc&m?{{>CIeaJx}wJy8&M}`@28y?7lwSd-byJFx33$JvNm2>Vw%3 zjf1q`Q(rBJ73RvfSS4kc<{1?A-R(%th7~Ma%G~vycZbuOc{xtk5KP#ge!}_14>5vy z=)H~5yV~{%3WuYrVJeP_VgeHpo9A0dyvMKdDF{>A0^Knp)qs`bOzL-=;mZZ;AzvyC zjKc9{f?H;teF^{LF>%I8s@EJ#7NAYXHHU7G*r6nzT*cQV_xDbHq!!&ix(0J}hY8G! z3cEM6)A*W|A@tUNyA5UbFv%}n7}mG=^}t`|WCqeUbjj~R!Vir*OD>b*1BNZ_tvYZi z{t<_6l}U<XTB3DB=f{l3M4CJrbEk31jb2#I3<AX1$GKQ(Gz}E_^3P7_6*|?8zVHu= zHkH8TpQ1yaAhfBEDLXLR8pX!Fw`Doc|9W&xs+sP|BtCaj^zt*E-IsnI-=gkmo_`>S z?xJMC9jw$b2lyOCK9CUlfNJd<qPR;$rb+wncc8!oIG&0hJa8dgB-dn<rrA=+k;CZW z2^>r=)FBi14$h}g8L5dxmKO5@ZuAF+Npb7yE~ux=7gfa251Rg%yuxHK%T^eZ$(9Ms zS7Kl13^WQZv<;xT6fuaFF8Y|*%~;{6Wvj1O>SABd3{!B+xl8=`Fak6WnS8T!@?bIc z=q#~mUfsu2g0aw|91c~QVn5^Rc0MmV-QaV>aEbBhPD9OsYGRh)v0^6W%!$MJd|a)S z>0^m|!Rw@;bVihze2&B3<b!Pi;soC8oF!GM{6XU2{v@yNtGel_aR!!izE%JU>yhcv zDsqk<<&@Hyz3$<KT2b{!X)&5(^!}3Xs)3WCOrMu!N(R@oz%KK2tS#<1#R#fn1k%5P zzs`yrZBRZ6=f>btbwu=hM4{k()a~Yd4?=7GY;COvVs}V<xbC-64pYkadJT6Bk<2hn zp9M2AmgtA?HN*Y-T>t4OOI^9m!fKNe{`H}o6eng7wj1fFj+lf_R7?yog#+<8jjIG; znb%}793Zp4V%wVLFvD9uo#7pmI3w3V<8KtoG47?>g*xeJrzgI{wehaf<?Ougrl(yB zxk_KRv+=8Ja=i!71_m&N6B8JmZ@<OS&=0zrTMj;Wx3%8Ai8#<H{0^_TfH`%=5_fxq zGhGJNRbJ<o808ro0^+5uq?Dj*!+1PSRc1eIQ=y8{Z=xa{Lml!EypiRuFMJKxP?ii; zwh1;tq?$OZg;COC!*VZ}a+bcB<muUYoIyW}bW~!P{b7feeCL04j6RKIx4cnta2IUx z%IKS{ab0KgRw+o&8LiTe<HsNmwGczUO(|xD>hP`8kYyBizLnV0CNn(SeZKwU{^9V4 z-M|0z>dmv^&iC7I4q(wL9G4F|!~fN>jg?v@j3}rHVT&Vzs#);ZbFv5`9a|uRpb|!d zZ3*mY6xdRT9eBs~|FCEy<Nh5*8?V^n+g<+M@`_bP(Hwd<%U6q<)I;BlsdpZ_P<g`^ zP+t9`S(yD7&C+F3h4q7`rSzRe5o;t(op@--DwN&0Au<HVs{dM!u@KX1$}#i_DPyve zH@t6yHpH8wM#FWxmQQJoq(u#5{7@Hse|<SfUy#q+2~++!l6RB{X*_q93jN?dcwTNd zAB(2rcbta1>rb#Yxon_GjBEWnBE4^Ovr_gmy4>I{+mH-V>xlna;vMmbGnLgnBNrc% zQUtEVl<-EA@W+t&!4P%Z0!S?EbR8-}iSmwCL@5;7h59yOKH{JNxS>%#M>LA!l#U{? z;Kk~ur7%(ERHlxVvY2s55`m%}K^TmA?2Lk!uMQi9IrszKd}}{lkL*{wu(~Md?7Vo^ z={eHeXgUtyd9X7budj8qr$0PGKY!zoArtVoa3{~I0y7D4;uh`-Da1X}UGIZcLe6j+ znsLvDXu5{o3tn@=<V2Ak>+I!ZXc(N*LS*8X&McC`l#&;tYIl^-Vb;F2?D4TS+uLuY z^y+qpcmGK5&hPBit4<>Fx3PLvxd7NoDN)60<>c*_i9Yq*ZJFF{eQ2faE!RimK(k=M zv>asGz!^s)rmBxek-v|8_ivEx{(Cf9dNrV<-r^gs%eY7-u3l#364d_2oZhuVE`J@Z zysTAI3`ZFjahSR)nC3velv+70_3eQXMkv^MU-#`MsK~8()-ciUQ_@i=GAt#aQD56m zQS=|#IIZIEUPzl5{;m(J>AkYUUcc#ia-K|eaaODF$#ay?vx@a`#-zyBZ&*H)k6f%S zk1;eFyDZQauFRs%J)R8EsFoYtsa6@2N)MkPU)N%Rg%xXzwb?bfS>z>qw$gN%%?ldE zK-?JkRiaW~8*PB>a+YRD41JCbC%<i2Ds}TnG>o-dl07;TffQQM90F?C)IBo}MZy{C zjt5sUmp}!ob^qGRrzNJ6u>?BXhdc1U@3yxOzx!_6GNpB68r4OArlQQY!=tYC9Md<y z@7Ck!ZU#q3-yFl!uEG^Q>RRn~k8hT?{IlD#@7B)&8-%p@<};j(bz^dSE1O>4Gx56; zb`D#xbJ&KRm5^ihh!~HOvDLERL2ej>yv4k88d_b`(gv+K9WvCP7ZSo3QLs8K__uFk z_Z}*yZ+Cv(vwQ22uV`jq!uM$k)k<Gd(&!cyHGVIbWIrz~`u%)t5->`~VWU5hr{U%` z?{eK*o09IM$S$PUKs{?dG6Wi|KGFJDEqc@?U{IuQkopg(Tmu7*tUFxm@s@7Ekv^R1 zYyfO8&AoBV#;4|lyQY~gK{O}JwcJ7h*J(2<hf|cR61p3~s1g56XO<FblLvhqHAmC) zsb9)s6hR^E&~Vy(jjG0C6nsXs-eRU!4_jH7IlXQ%b4*WJ-EMH^CpMZ|8pIEoTiCB# ztR8u)+{t?otow9P%3hgdOtE?kk2Hdb{7~3FcGH#_)sJcpcf6dctcnK9#Hv1iUe{5Q zvvznh3FyNOjec5ofvf40L?|d-lF&o3Fwmu3gva`-zf5$J`DYTfgxx220g7};k{{`N zxIV=t!Anf{@(|=7eZ%Pm!Pmg~_}aXp3^Asm1aH<XEv9LgOVCDx*l}_4Guxa(K@goI zrFJ4gnu<NdbXg=i0D+%X=L43Jm6ncEY;lBa07By4I!Gk~h`~y!$M8lh+vz&B_pPPy zqe7*E6~DU)IFc&0E?2@Rg|5LynZ$&cEZ0K6(@mr!z$5YQ0UA20p^A<GppqwpTm$R# z2?fa_iQByjo~CE#<OxEuG;%HmRSUyA?{R_zqVlM%gDOkJ(U@(ln5x+Bm7*9kG`U(s zB;Wxa{ROUalU}SyPnMv(|Gq5Z?2N-SNwbzEssshIXh9$Etda^zZfvMBl2BpPQ0*W@ zXP#z4RR4NW$5VFiM8<$;L<(`1(`BG)x2b>~Db1YLiBcL>tG^)EjmOx5PVZ(Ayh)}B zodzXiCqtgAnAqxcCWZv{G|6EGLtnvU<`S`j-Jy-M?x7Q)f$asj*Vqq`NITox+v+~E zGu|!|d`MBqt|gd>7~+i+l#t}0XHZ{v8`Vja^}fJ=k}j{`ZrL3u9;Ohbj!`a}_<CJy z07%``(1@AQUubcZ!Fe*7;p`biq9b1*Dvg8d{(Fx7cw;=lEBPC@g!}M3dFL%xetnWw z=v;<BPLc{{-;Uh9eXz5)C#1N(@pXUW%P;Z345#&s!r52QQT#ifPU1N|Nve@{Rl;^K z#JRMB)-|_mNiwKj!-jJ`J;^5+LIK6}a#W-<baWc0F?<DZF}`awu9rRz5~u;Y;6%=* zF7y_tEbl3PVs2ODBxv3udqQpEiO@=X%WG$CedEy=Uw-xHufOS#a}hmdz5*}%@YHK( zue%}143xpoD4wMidXOQ({xd0Zgh}adaYrjqjc43Qap55Wvf_y<U0f8%Z>k;koCD=~ zURE4NfV35c;f<tfP~D<evWohK6QTlOw;mbxB~ZKt0l)$=p)U!u6Qn2Q4G7DTL&HQw zn=>+3Vtb-#`p&jGGJ^mUJn2Yh?{7cv?>u|q_v5=q%%rwrY9pjFGWVBmWQ=@NUJiMe zmKJO3q)K|P-0DP~RrJ#MOH{{tR}?E7kP5ce>9o7G7BR!ZFR@ZeZ%KRytJxNP_D@T# zaZD)gt+(nU8i*)oHNwpZSAG2&%`lW6*o4>2XsO5Qk>2$?e{=Qg6`EshwCdn15Yo}0 zL;Y?mr_4CiZyQr}2Yj|B`mHpke=jO44eH-3gk^Nw@eHc99dlq!CB}ii#U&jEoY2;q zxouHObrt(<X<b<=LEB6v=!)<OFxak1=Rc)2)$3s+$OijTkXT)c9)1PO@f}ak(~J$e z;7e00fTQrC5nf5H_}y}(>(av)+dmKYULHCPu~f0FDJtbFphh4C{JJVD5~fw)_NG}& zHA9-&p!J~o?hLvM|5=wm=5l-BAy!J~jNEN&oxUT7+gg)IuE^!K);v+^eN?~YX|XLp zeUa!J>CVyT<?#d5sST47wo^FvpC#|!;O@-^7)_`S3!{*ES|eqbY)dcO=*8zH_TxVG z<88az!~TRtGT=V@nqC&ZU4Ish+rn`#YK+{ga`B@04#Qi0LjDb7RaB=be}#b;owp~Q z2iDUE^vtg6ciWa~2qqbzsH(%N)=jwc;ke2!gvt?aKZ;sc;ihOtc{KgWVH|YksufX9 z?Vz~MbH%o3o_DqYQy*3eiibL?Ed4?64DH(BtjOoH(A6<RU+t^-;JC^A8n@mbJO-~G zo%EVprebrsW*upMq@@9K5iHQY8#|b%6fpBpenoW;j5awMB&p_AElN;m*;0ydH}c4Z z^*HP2)p?O$)h^<V4GcLnRO`za9-Eu28&JaqWxJCqTDOEF>^~1k5BOF?TCvSG-h(C~ zG_WUYcDwWtO)|~4>5z)X9*<Y-tncEWrN>sE?J^&I5txhAqoQ9e5_x+#<K|h3VKn0x zw+&In`fg5SDRIVYUkAG;2Nwt2Y?lWp;Q3}i2_3yBU$k75sF56PegP8BU@-6muvic) zLRI&~HVA!(sn1*%LQlQ7P9_dOKKN-f{Je}lm#a-{<et60@!sCJ8=K++A;s+jbzpJx z9tt!;nO7(zW!QHp#iC0Tr7~pQxu|hD#(7gwyx=B9&RD5rO!Fw2DK;VcePRsw{47iV zS?9+{GgMbr!Rzbl95X#6l6+4Z+%qh05p?pd&Y#BiIkZ!j6z`F`#_I2#_u*e&Kc?Ij zm<8dc7fHlNNy!<^#H^H(adKM>k1dGgl53GIB1YWG=9uh;F<*3!9`uj@@^<{-?cnYB zzNrYp5c_qxE_UrYiHj$1$M3(m>GkpV6h?Ip58jUd!Vkvrwfr>oS@)pX)6L+#s%D!H zACg;5ewh@fll%&$wuisYG0ZZEO%FG|`tzf2zIk|_U-id%|2m)dX^#8o_}3@pR-Y7D zeNl*&eVo*O+?NUL*Av)Od8rY<c)u2XaTD&m_-*IeZ_oa+13w?#^unKae*1a<xBb8T zEWh`D{%!AXzy0kmd;Ghho)UR;{AQQZ=5BF*Ttg7;9Budi>sYHced;WU+QG@1O8XoK z4IOd_T(NPZRDD!l-C<F!8&XTw9#EWr!{|rvCOE~Un;aOXpO%B*AYs#FAz&<iBQ(s> zpix6Ko5Yz;po^th&uHbW;}|g5je(sCfwl(1xJQp>aeFhkkU~d$TrClPrKE>xt>h&} z9lN!U*kb=MkA^~}%i3z@6Vzo0d6-53|GH3aaqKZ0j117eNIuRP%&h7?EtLgjDZp6* z_VRz*d(-YVZe(Hj`#tCWhfaGOHmxQt%61k-Qm!o9iJz<39$UGyPzq0rY)Oo`g-u#k zB+YMsYr#@Lqe;q3mU)LWk;!hLP$&R}LZOyC;F}kqyw*l*BH-TP4*~8a8s{+GR}VLU zAC<^JYNje?7&YH?*RVg=ES;-|&kpfnu(BmGhJxb4p*RWNG?4EX>e<R#MCuu3sU&x4 zOjW6!n{#uMqP6-MqFNIndi_-8_Xwy9e-CY1Mbw&)avs0kv3t>x`@^O5MMv$PeM3S+ zuiu@?_aI;S#yIY2-0g*bEJ9{~j<QZjR|Bxy=V)cqgMWgD3i$d_&JgZK@xF%$(a(w_ zgskODx36;}-ePtohoRm^r2XrB43l43gTAL^i#vJ`c-OE$W2y5O0P0!9Go*ls>l%cY zZR8`oC`N#!*|P@nu*)ms5V}egch$y%13^<wjh)3@0?&)C0&Pt-Fqj1?78w9~1YAz= z4jXwCF!ch6cP1mC<B&<iX97#aMU+u~&jt#aA_ozY!n2r0$T(cZs#k@$mly>74CUuH zf8DPYAZ1llitCG!v4Q;?(eZdZ$g`0Qlz(xSlNAPcmh68pe5%b1%;C<<5#MDS^AT0I zq2?DfRPq=o&UBOs1*TVyRPRuC)cfmuPYN9?*PkCYP>D~>XnO|}G2|S;Mz!l81ltyz z5<~{^r!-21eWk{&Co_X5dsnr?8HWGBFC+XyCK41l12fMLoYG~ARGyuF!Ts4;-L+UA zb2!-GFGaI}W0H1vN@|1R=iW&a>-6r1L~&FMdOx4kB!|YWc#yyA1e&_Ks-?~tZP#vY z%FSB{K{T$eBpxv%a&r?vrTAqKLL){j)H>X*#Q_3v#TALb94n6XvV-NwE5@fzId*xw zT`PgB9UWB`P@P>=M51IcQV5xP3+)rkOincuRMrWGX3AJWa}RBm;4XEQpT!w&6-%UI zQIrxJ@y03#Z{a}<&*(!qmGk1@<nnBQ$3$Tbcq6)iBR}3RV;+{vi%f*`vOCJQ{mx;Q zld>pfN-PfYVS%d4@nb%?vf~f4mN<0}2@B2$EUR&G7MK0gsKW)rf`d~;^mU<}?p2aM z%QO;nk_DHaxtvx$3dL5S8VN$d(XT3FBgup~Kc9y%KtzztPRtk<tgC6eprl1YJ}n(< zlqj>U*K_$j%Ou-oiF+lyO?=y1>R#!}O>et$>HF3jnzaOj@u*`a9C&{CasS}?{__`4 zDG-12$;*S?{r!a}+-dD@k$k(^{^@RUw>YYWFRGKsyK=Wf96aJLx^9*O1H&E$kmw=u z!<$z?R>kRxr&g=4lG9aFZGBbp9F7jB|DGh0b{x*SiFQg>91eZfwxgtsTkRSshH<rP zb^6BUYiQ~LR6L@)4v$t&hd28bJzn@(nVtZ>!ZXMJkoi2GquHi4Orl0BT~8aWI)x{% z2eQI=CWeZiETig_hzLj58Xa9VwRH7*32I<3sRY_AL#4iibXe-$YYwCT$}S9V1Qm$2 zIBC}XNX0G=^?P><xBW6zoxP|c2HATmOIK5ruB;?|PX(!iY<beGt|2XHNB_MwdkZ2@ zS#bfm-~tsOazHoF_3x(&WL4inTbqEuQMx#%JVbqT2{}<mo04LVnwhmrLfd8|Bt?~y zA-O7dfRt9>=P*Vp^G4u2UoK7gBn~N`1fpsNuu43txVpb6I>T%NJ-w>t@Ke+zM4J)* zvtXN{d?8e9w4~Sx7du%}Y|6!^RmE<?k8u;aC<gsmdQo&~yC11;Hi0I?A_)=SG^>Z* zq(Na&5yL87aN(ysa8^GQ95~7Ut4%7HR~Pf+q<ULP(Q@!~tF;rO`Ppnm^g{F9LoKxB zR@2C-r5Cq*oCqq;qmQLI4<7J;9|gKnG8$id6}*-8DR&Dzmx-U&MPKMlR-#{(;+>?p z7vtIU(T6zY3JvG;E8z4uYze}~9O&AZpfv^q)Oo9fLJ<mUEv$f~HVyOuC4XIxx-uQV z?W3xhoH5Ag1mQQ}Z?0oF)mQfh#=NS&Lvc~^$z^cbG56ojCwHMwn{kyzAJMF#)Asfn zj5Gy|xtyK#b)q%ZgRI)8NlZB?Q&NQ*CHOvO9y1lafM31yL6HuM-ucfbY0=t<9z0C{ z=d(NMM(aVmK>Jz4YUsGhHSrr)#&1v`{{axSRkW7SOXXA*bfO9c{4yP17BZwb?@#QW zTp<r?1mLy)`kVRCh%qdC($F?avetk6X+Hir!94>cE*cm)b;al`ALZO2!x(D&UT1Rt zUMA|$zGHuGSBNfwCgOVTB@A{=jCtyswl6X?SBB0drIi=PSNSh#%zU{rWPW}N^YTB3 z-LqhU(QhkwNgbS?45)t#89Dnx+Gk|Mi{_<9wV*+u4YUhjMZ4h7tYNS>L6^#IDv%29 z4;4b&8+Frfg91_&SBf+HOA~|SPKRh!kUC;n!LfC9<iF!f5tra}nt?okffqRP0=Ixw zSiZyaC<=e$p(E<CP1Ss=4-_b|U=CZ1D3Oh3O)a%~HdjJyLzyV(QO&^$m1M=@<Tq}D zhB!JroE;uc4-ZH24K%eoD8?!(q6xpka$2fntke;*Y?cchD@NVuLvJacC|Qy2b7YGf zCW)Unflvo2rf^TuG5l{cinrdp+S`%ll=0y##^(pSkG<z3dcOb6dpxDbd#}C6C-nH4 zTlyv--S7@@QEUUTW<aV@Tp{2D9Kf+_E2V^@l0bk9|0V}yc`Ns@h8aj#^3SHSL`jx_ zq?fkWiW_A3U;KKIXK!=cP*upbL^n-En`Y?Rz|CD;M0<hlcWD~ARf7&&p#P?V(}#;A zi#+GVD1D^e({yPyspLak-c}Yzs{GzO68s6p554tuUa8otoF&xR16N8A=>k|Kfa5lO zGl|*Y8$RuH-ea*>%H!O*@5Tq?z42f^9C>I~$HvckZ!=}dC*m`82?(lZY-IXxWHhQ- zc1#XD(|j_9;Vrt;Y|=M592Xvb0rqGdAgo1x8BqZOUC#p?XYo&Snnc01@2_>tV2ty{ zE(`4|hEZ2N`ERMussc*&S?&R59E={K)-cToJgPs((iEU2@ey__%cWZFB-!j2YFknn z$AJ?%%OY|*>W2u?7`m*-F0YToYcWNi8N?ET&N%6!J5_@d<Q_gQ@c~+BnpiAqpX6B{ zr)sH-6JUP9<HT_p4Ye8?9fvmZ>Wf03>-uFIZhm33(KdtX2!sP*SId^|4=PwEPGAaK zH8ZiKDMB*`bw18d`=gPvCe6t5RR)@7=QU|X9Ms{7;mQl_WUW>c=hWTZT~4()=*#Om ze9Td@ORxCl@tg;O3OF}?k4<GZb*1Ea;i7<w<p0ExaA*@tNxJk0fN1Q18q1d__^$5S zNn+3Z{hU>av$~|htAIWbVW&~e_EhExu&*6r)Q%YDQZ^aPo2t6Dj6DV<Lf(WizX<^O zSeb(b7mX|%4MZ1_+p`Qp`=P<}ks?n=y^phKltuL_%jNdt23RiD+Xjv=Zl+6}9_Mf0 zKR<ZN$#KlR7@q0UIIfp8c!9~Fdis&40y^(IyJK02QZf*rlW2Jd5-Awq=!k_@Qj>hB zAkIN^IEmDvp1A1A30>(g_WpC68P%uS96rYU78rgAXF?J4<4#8ubo>M69lGozyW?4Z zYMfL!ra9$Y080IgnOudQh@>o%>O_dwa$D3zD}-8f*TZSXK5)AFT-BX1ADb_JyqU5B zFRW%-pJ0}3Ene(@0H&fK?5qgjlk+6hQQnp#Q8e6@MOKP&V)Fs1i(yz>-Mps~DUU=9 zZQo>IjM+;}zB;9<6s|`iW^28Pad-0}oMvaa(!w4d-vB~q+1vh@^3Rl`RcIxyjdRTO zFcC&EXt8*4qZ7szCdO~M-waa3Gd|9hLt%kYZ_#(SQodh!@K$<RO%L?1HUtRA;#`TF zOMn=*(fqDn&M)wKf2R7V7(a)ctyt6_kMsMvF;xg6uP5VanNbI?;@o<_C4a~9xgB?3 zvi6MR8(wuz`tm>6szW*i)*L*pTyfmnmDiecEcnQ)Y=xb0<u$gF*++08njU`4Ww=yh zrjG;gT15zx(Z80g-S=6!eiqo@c<t)dt6=IWoj6Cla`v}lXcDhViup0uhmmrsa3+E7 zczCQV(}0q&#%GPmbd34V?5qX}7x+Z!QZb~W#U+Pf(6hHWB~ehbDIn5$-SMZhhTsjn zHCEP5bx!jUrjHp<4=}ioKPFTPCllIr(T@dDZ8S`41YLs1W2b<&y>oU)h23Xybq~p| zU`F-G7t8|fKF8V^v}dJW$O3m*iL9LKVW@SG0&Tho{AHR=_<~!d0Vu7MY%oX!R@jac z;D;s*K2^HV@Cwkl4zo$Jlssz21btK%^*JD$E{MS6fYJlvQ<%&@a1Mns+6RW7zxf`H z7$)J>H0J|P!0f35^L2(c-Xc=E=M-VhFQ|!j-?4&GX^B)_P5@g#q`x5HtS(bgXE4%* ze7<kYLR_~Afq-n+zr8LW)qpWPeK&&^(dxk~eq&4)Fcu@`FYfa2lhG?~wf)iCG1^1~ zs*c@oKAFwFNG7>vllKB!t-iV0F;!Wzd8QkVUmEJbYk$Qqy6&$aF>4B{ht^{nR3MGs z%qK*F64SusKm@~yVZHE<iCMG1)o80JjbCX#txgt89@$xmRU5b4C7zz|kL79@u8v*B zNWQnJTGg)j`}hgmEsVLCB1QQwIu&-NOwf7-fuuE=CKNo%vmr{zmAaoWNkqlEf1$H% zWmeU_gSQfcYy#YAl#~7c?x<HQv=WO#Ozt8>wSTho7-M+Ce?5v@q93N+wC5%o$J;9k z^To$1%uh1K3`$Bjma#yL=LZ!W@&zR_8S_<w#79C+2L1E=0!2>j_{(XH<NVPP?iu>e z)w~=JiEs+$!P?%AHcGsM7tglbhSrZt>?H~DBX^!eq2$c;L7N$>!Z!ANBB(6QB?W2p z6kY&cRqEx(^97+>HTUPj+}F*cXbrXl(R*0-M->37Hd3dMXQOeg+jE~+R~E(_PG$St z_p1sFAuz9h?=cj8-9%2k=8fu~X9TOX*=V5`H0)oxCl&eZwI#iAD1q-O3C6pFfzteJ zm(Of$tgw(FyWk0~3%0x~c&>HifP{%a6>j?X0UTuW?e>wokq*%%)F}c3yhg6Dx0KXO zy8yFfF?5!9&tK==`IHXbQQO)6E$$>Y5+!a$H5NCW8de-#B#o9WL=-Xku#fwY*J4RU z@EY@fO*u8XQpW9Fd6jOIfwN6|XyYZ1r#+a#49nIiD4^vrhI&&@Td4jMcHdgbSPFQ_ zp_N&sS6i!r+&|%iy{JM*g+=umqF$;p-IG4A&|)%%utU|zIa{4+{7YVFp`>Z{EeSt# z7T%6tj`Ek&A5dNtNyFS|2dX3vOIra>;(jl#rv^|G<5zfM-e;%q^T?4RD70Ii6@3sS zE~e<=gpq<bOAR?~0Lv(~0?*ub#N^<w%Ic9g)0^3Nk`RBB(>tKVyq8T+;Z%3;-uVT7 zD``(?DF79k7Ot=P@j(PcRAnjcq;4}W1Lv;W=&Q<Uo;A)sqF&vlCfKN6$^FNHrM-%M zha;Csqx7ZPUALzDda*9!BSwC>LkAS48_bFbrW%IQJVj>H;r5U)6afNGfJ$Ep>m0gp zftme4fbU&8@TPe~Yb!-w&jPWe3x@H0ip$RwbOK?D+$d@qxMX6SO2&bvhj0X7S`quy z`=?lyda{=_5P=EMZfza~Y+!_DE{)tZ6x73sHeG{Y{Xr#4f8@VG69-*205+^<GepD= zu(}wn?3WTQq(x9iTOy?jWwsy(5Pnp+ltq9ZXF?%Q^P(zrzyz@F;0BT7P65(yl~ib2 z4x-xZU`)PFZY}{Pd39f{47jL=!FJ^3g1j(Ue9b^@SLPW1;9(?34Ff@Gjnypz?2YI7 zWjMrzSb}TYqEboN@fNJd;<H}Q>`1Gs(H7|Z^+{?4Wq(QOB=sMjJ~p~T+Jd&D?<4V2 zh?SoB$wg^26dvfX?(J8{P+<=%?lUj*i_7EfZMB*uguK=&Vk3InUSQ~tfu*0Xrb7du zFp096Is~Okq^Z!WX@TLx)nQk7_=+Rtp2erIJSd%`copBovdJYOF<zEV2-WgB2cE{L z3b<|J`ME5&W0y!~7nx2j#!_3(m)j}d<l1a1HeZWMkv$lXPSK28Ee@UGWDZ;Hin9Dq zt}I_Eao@2ZfF244)Hanvr(KZCkNwofKSg_Vt*HcZez+FZnrPB(AC;m&Ff7;5J8o?} zh#oXs4_jYElofeVm|G}YJ4&N=jVthXsI^*1+SM;lUrtvSMoq+=z<RC_R7aP$6;!L; z`959vup#Y&`{ZuXX!*}gE-!cU)-!wCF?Czc`NCokptwOBB)l#eZw6d(q(tIKBd|?} zMYt7Z5f<8-Z0u(UQz1-v1cHi-$}xcz^k8=uN-xR<-kSN}8ow%I3Rm38wWt%2bV40k z;Ez=y7~P@OrEP+SV-?Lu&8QU5F2Llcmxg1)gW_yFMOTqBG*wLt1?UX10W82(8<1x$ zmGkh?wF>~BfH<{1$cD$gEPA&YHQr%#QMWkG?@lUW9))hbswI21cYU}xzrviSDl5-> zMWof|J`-=X`ESd5Yrq>I0ZoK$EsdBs8?aVa2<V>ZLejphv5?cQVsjLa#^wq>8(>_v zY}S99lX{P)L@bPToh|C!c>1Rhra^*QEKC1k1<Id3u1Kl-`)52mSb^AHVg8<iF>9a@ zl8y++LNPv})<_(t3M&f3*Y6<=TUuzL_<FHWd?&h~U5ZdeH9cy;WEb_SUo1yoe^NOb zuml0OKlm(a?6|@+|5KKr9fjX~#@cY0aCsMbnLNeNxCJ`5T7RJ9A)WtiJNG!p0GOrT zecGdeoh$!2BD~)b;e8JSeB1YaLXy10lh1D{JpJbw@PWqw$zjM^=M<zl_U=PXmSiz1 z+Ec2;FQe$S0k5<!r3bayV*X@4#XPaIg{xw9nbN1yGPx2zi)70Rglx5sC}Sc}#p(Ve z0;Z5i{-lED^?wA-vY`1i>z;iATZxn`{?O5BbopsbB|cwKqU??b6#56I%gd7_e*N@G z^z!xYi|?LB|9HB;|MG9qcdws5eGxt0|M6+`>c`iw_MgJ{-M#;fC~QFV`1Q-by^v|A zi?eK!cT`Gc1@z5df82fjG}?RqdJn1}ynYVw;mezY-Ph6gPyfFA-OCrz%e@2qSAtq> zYrzfSs=>KTzcwjSnL!}orxN63T#QT|{6ST|qhS2T^5GpBLe$clG>5nZ@hzb$5*|^{ z0Hj|8k-jDTz@bk6SAjG9pwgxhd=h&b4kbB;*%&1}zIsq27-E$bk2YF_+K1VNK6+w) zIr4u(1kp}CBQiFf@+9u1YAR4be!zoX>R5y&x?^Z3+*Ir!d@hLlxed>2DO8t_4I$i! zss?s*Iv*VXGcOW~&El{z8tO<*DyF%blQg1HYkfV9S{r`0AFie*A<;g1v~KIe{O0P9 z*3+-Nx?G4?0@d7DSMbbarn(#J=|it-3H{2Og7@fGyT+9;G7Q(lZ(J3>QEmJ}0BUr8 zT3^QpDgFUiPCC7Y)2e*V2n1@&zBN$M2qoNSmzyrm4Y#9Kv-BZ@BniQlDWEpi$1ji8 zeY*Vk)FsO!+pn)GiSpyq5KX+QC5k*M6XdH9Js5B2h3dacBZZEbjggs-kvktFZ$h>O z4XD0Dr48zcC8UPsQfk9?_hAL42y}>4UfmL@Hp--W7$TL%tV}Eo;g;v-3i~ePyT6-( zmv5sLh~I}Oq2xdtSn+XB$tM1s(?&?7giWHwxmYN>b<*!ahp|s^@CrLk`G!k+Tkz9T zA!Ox(MJ9~5g5{g$1F#JSRt2XtOt=@4pH#4cqcAP#CHW2@_G{E`NW+17{$%l6_41$j zbj;?ZrG8rIdTYNm3AO2J7`6+x3Sx<Fi6)#tUNp6&t+nky#{v~fOTx3Pn++%XIu@Vv z6omO+wC%R)I0rx(=s~2*n4xnD(TVmY30~XERa?J0&-2L-I^?y#oH-n$EaGdIhLfkt z1Y9G#rcqi8&ZxDe1Ut!~(VlnfO)vD2>Q--cF=$8}z5!RSSG^RhXoPXs=kcHwU07#< zA3I7KfMjIN(|kru4Ea}uwg|a}A`p(nf_p_(qRIJrgP1b50wfITVu(<n3ZT-dF@5Sf zPLLkRkbRvuF&*z@1u@*sVV?s6z*#1(RwAgn9-50)N4Pn~KPd1rfw|!a%Ko>Av@fDY z#ydV`y&fHg<|CcgN3)><cf+WQZpUzDzKqWB9^XrGqZC)c^}UA97`NP#a6?gy*o^d% zt5gx@#zA8gi-9*9NVBQQQfoBM4o%H|?~jIQRxbzz$#tXbLnmw^++sdVY{irZQ@u{w zPVP-<pedpJDHLR%|3^VqR*=0C4L=>7(M*4j;3G<3rYqfiviKubVh=d7NoOplOYawe zWT7US%4-s=5(~qL$K;F{d-W_=X_G9zl0tuFkSbaTgDwT=Vkr2Jf2gVOsZ^%n3vM;^ z;mV0uj&*!*$xtQtM5b$1I%rlp*ig-|UyZHjpWCQXl}nAS1~Y57P^+4&m?weao)->P zkk3Mru?<)NBQzti39E_c^^bgZTr#G9RFe<)s9DhrDvoJ4l)ez9E2!n6O~S)n6-z|A z50yMTS0tDP@TZR>;<8!30bCwSWJNla>GiP!i`*XVTcCV<bgR6&R}G*M+U(pw7`N<( z?Lrt#1;Xzk3n_$f?)l|{EI>hjn}5gYqC|9mzrOMpcibl5Tk^U!;Z_pEG~qslcl@m} zzP+pbDpLPSL2<&;+9wK(W0O^{LYfZ^nX^j794(DMQ$aN!Uxw&X62<q&<MZq+&w4fo zn+j*cx7aLJShJR91cJJ4LnrGR=O)Rn$@`+>I+L8PV}pw5_niMl@9uq$e#7A2=F|R3 zUmI+azb@yG0a@Qi$ark1k}4c21JdpKSV!65BD*XUEun5Snhyqijv!0U#g><N5o@6t z^A(KcnH}c?6UV1NV{1|o<}|8pid#TfDp?2PMe3Vv6&t{oV1V1A<eD5}fF=s#xmX7s z;G1l&zGgOWssO)jNCE>G^E{6yFGt%{hXQuIvO!ytT2!N>uN3j^Hw(|;;N`|$dZ!5( z!j?J6Pi8SxWn0QczElKITz8VeB*C@!o%9UB<0IR^>Nb^u?b1>|bRV?z66hn|%UHI% zf_qVQ;LsQ2+3x7J+ydsjPE#$iH)8b2CA@=M`vdR|*|rnMw~B*cV#d_=zyW}=e>8qe z^DE=z=pvJ)*XyOsXNgTu?O(N(40_&wjx)MT=J%?33&ZCkO5;6_Uc5XYb{d9+(|=T( zMHktK+@&Vd@gzH?$j)qQ>8EPEU0%ay6treOLhxFRlt%HIzx{rKvoIXdN3`NzzyaJf zl>FF<0?I4j&W1mlp7mc>ZU8GK{;aA{RWWIPz>6+e40M&Th_NkD5%OM$C<ik2IStsP z!3*{QN2%jZ%6!CkgxqA+F`P;{;dXtktpc-x5)e!J2m%}HXb}J6FO<xLzF6^=j>Sr4 z_t7>nk{3E!gXJrMyt2qnI(?JeE(+(ovz6%BVY=q^RrJguyr@*R?e9ohxd6>h91@c5 zL_^H~0({-^K}ygNlpTpw3YiNwx#K`JI4R%-hGNMF-$-b<#9&9l`@Q=6VDGUVA#~!H zneZOo2)(~fu6&FG9`oF)G@z{nM+5)!)g7KHg)hndbYM%ne>*Y=kS?MXP(ie?Nf`Zk zy2SGvKMSs@4d{|{1%7zEV8>fw$QaTRcN4znwc%OJkA=}$h_YN~ZQIr<oxKxxFH5b? zzLYV~JB`b&%m;2FWtgLg%ccW1+Y=16jj|xde-c;A&Iwq^uUwD+LLXqq!xY~d=LSnt zjdHXMT=gts%2sCmq2W^vz0eynuLZKDo4N}TFU7J5+8y@MeF8*6%^M`?5;}sKD{_^p zLzj#$#`8fBt%3o@6l28=jXU7fQbhu^7}V{<1+wQK>14a`EGyU(X7V%!<ocxQA5NX4 zs|Y8)^aPCH?ZFoLH#;|Cs4``dTBF?UfHtjHd=4{lglKVZ*;CLv_%cEz|3?z4c}^L7 za1H{j5haW9x8r_~P{5hQt(0S<;k-b!em_maZK-?5b*>ER3PO5;kPhKU@)%3tF0COQ zaMA`_v}G)=(Y+{XrS(N93+D7k7SOBZ^JcTTx`=M={+4lRZ80Mm6HLip0l;s-ubpQ8 z{TOys^oM;+g#@f%|H>?~n-w(&OO8pxxHE7<GL`wC6%}XhO8n4l(TndD1pexXXWOc3 zq<qt`y0r6WI;gj+_`uPv_(12yd@vxhmSlYVbKae~C-dX+c%Xbg136H{{dxz)`4KKw ziUp%9mI+t^iMeh^Tg<)~&wfxQg4+_sx{)!p^U^9xQ^Uc+H!Kdn`b4}++cGA`iwho- zVWV<MWI9;Jqsz(mOx89Ij!`N4-HCpDLzY?@=3(jOa4H<pp*MQe==D$gv*_3U1P&sD zd12dms9yat&jzTl73MooIuw}!Sy0xUZ9gI@Lk~!;;lygtg&x+WGyxD7c$M7&z5w!& zLhPT<Ur{gIGOdjV4<EUYd>~M9?I9(F@T<1gTaESg_15D0{SjTJA{_VC*I#}4#iNG% z3_4MHSF)@>USB8_#luH6Po4~QC)5?JuAllaf?W!AC;G|$ezyC3e-pi8OX*rsz@nsq z(W82bsV;zPwa9sK^NYH-2&=a+y?cjNe;~4+_FV9Gv<l0@MOr{%AQ7<dqPGgS|D%<< ztx;WVr~E`aWLY=#kqowOyIbmg%b}6tQGu}xtBNfCBJIRt)yB4G-5kKe53lAzXa^fT z($tiYZlxnK_ytjN>r{ZTAj<gz9Hq;jQ#4s!E_rj_pB#)=+TKYtASoX;eiPc?@gfi- z0l-eF;$0BGnu9byp#4>QAh_GByR|Nm0%qCtG@rRv5YuygKPVDwlQMy~c*4#&Ff?GH zb_a9Vot*;=ElW7T0OgSvaFDBVYnb8{55CI&+BwM3xrN)}UZbf@83a3=E2$&HThNV$ z^5mdP(0bEiN}AW;No&sL-^x29I%R{d0<gH8^pW9Qf<!Uqbnu+;5V4W?cE>~V9;qvN zs(*Sm)9K@)6XH@P+U+<@4udFa;wz4X3PD>*M<b&oPqQdfHX=M$5<xXiCb@>CZ87@> z2Z~c~9Ooxvb!QM9FBNn`LdLQ@(KX-9bkwg(;SNrl<0<Z5C9&z{e1=z5q)2*R6zDVa znhQ6gR`mZs2HaR*U-z>RMJN|sM{jbxyT`OS(UZLBPWv3%X7T4bik{#_`pZe~1*vJ^ zXRTpA;_K3nEbHM4at+2j14MCd!Pn;_I@hD-XBHKg#Vj92-Dy^wg>coMFMJAo{g5K5 z6|mU*T_naN9}JL;6lWh(eC>}<Vf2&QV0?N#s?`HfTMvDxUw#d*f9Q`epAeRO!{`-g zv2k$*EDI!Ha;%t*(SB)ksm8VtP#=C-5;FyNUKo_)&C^%##%cqvr8<|@lWOi^7}P$@ zGp*FXsc<=?gVKB=cqS=A0jvaLn1j2@K@c0O^+mDpWM=82-@~(rQ-N(ca0Pf#@2~}# zfQ{q%A!FgK5O<FLM5o}v*c_U(D`SFwGjB2%?TLAPJeJuh7>5q=>TSLCKu1&6xoyVv zjUS6v)bn+y)cOzEB!M!Fqdfn>G&|2{T7PT9ouD^L-hqLnuqQZzVM!xGk5b!s5*PW~ z+g3qxtWd|`)`OJ}VqHFp!xm^b0JC#4Ko{L}!|?G0FI_U>i3#gAd-LIBfz4SB)<1=n zPz(USS8@P+`9;l%iD0_0DS1GHX2xbUFOfyf2w`}QmV5(4uxVJ6MEdK8gtKBV@I7A2 zUt)~u@vstk$!j$BOJP>@;_HXyPAF7mC%*g|J3-ux)cC9NGKw$pWo1t!e=|K<6?R3B zzWln>Bf@)y1F7<~P&+=Kkqi?+K_XQm2K@+}P8IV=l`t-jr{NsG_JSSw0ROn18djHa ze6d1)FRD*;7{j*sr&lP`M`I6yYYD?7SY!%Az?3kyia`t)T_F~wfyrMy^sQmp3vCh1 zvKjKGPi9pHRGH2K#sNCxeRV8z-xtY!v#LD~lcFQ-*>oj-<(RseGo2!3g=vw~f}N!u zZC;~Wu&<2ejSW{~C-;(8#LfsqP$nf?o2YkN+lI7ZjYN<li`{+haC#Gx=9w;K1NTb( zMX0^R39=9{D%2m9RweW*+_}(TEbE*$?VX^>lM>j(NvK?<+Pnup)$u0itscTEbj!2} z1FK9AwV?3;Io)4j+=Z!*kDOflYC|Y1(!yyZd|g^ptxUtu9SmTqVq5DGLrS7cAE6Y` z7cs5Zwj)oOU6~?5i^q71RW`h2<Qq_RIT?Q{fZmCw8Quq<_=*o{B~I4k<N3^9z&Ner z^6_+1?`d%>&ke`({-B2k7^P?8FcP)|&rv3z;CF}^b5Px0TQm4g`0vOq%KAfJC8>b~ z<zySo$!^FY6)(_Ac@r;;9+57ci~>)XCjhp}pvxAN-b~YrY}#8%5vR(+ehPJ`nYI+j z9A?V;6|I#UWMm`4^+}g>LJ78&f1uGP0djM65J0upX?_gz1DC}~{~hu@YDsCU{)Pgh zmoW*r<N0WOF-ny`5cCVU66<<6M5n_11}4e0kJf_H*nev)VD0|`4uqT0EIY^BHQ=Ts zs4`#{RV7s9&F}=Zl7sR198Cbbc`wKHjfQUuwvM0hhFvB|d6v@Y`Ha+asGpk3x^TW8 z5qjpdEl*1)7d_f~x3-|}b#x5>sd-LEXgE&KNj(Rnk>lE+@TQq_;7TNnx(kF-q#s|B zZ#MS$m=t^62$wlqF2TtUDJcUDH>2n|4FPn5)P6lm2MII%ay)0aFm8i>w?D(s&S=*} zW1vF7zzWEx6y$$Y8oG+EC#LUeRqTyNFbp#_NOO)jgH+tMqin3dm{Me-H9G^eC(|)> zX=rA_n>>&9ujJZS=0rDab%HaWG<dWQ#Jnc*OyPK$XU4Te;b(fZN;nNVRa6~D6rj>g zna&|zx+;_H42rY<iQm$175JG-R)n&kciyY2SQf$4krk&a!c~ONT~4)Nyb4BTQ8L)~ zO9Z<(3G8jJGy}0GY^|`tx8o_UA3BrL%oZ_O0%jg`Duz`l#?XTKNKqc%#}8k{$kTI4 z74)wx{nw?#xB_Ko>#8vZZsnkVD?fAXny*4bIAwj;gw<Tq-@B8ya7}L?ed2iSp*Lke zaJ;kJjC^~lJ202#$Hy@KxYr?{2jK!Et`akco%-TrK8S|-a6IL(mB5QR&`|Ds%XOxx zYo8I*Gk!E04Zo~@jwVrxwZ9lM&16u;()s2Vg9YSZHjHhQv?a1+RTcsPAjU?7fi?vj z8~E6j`c@*$?M4glo(&dGTnmiz;+vn{GCEFRTlK@ogyP;%-VrTHm%_cxfFo{u%vCf> zDMyUCo<Hy!8`o^FYPo1@J3XZtC|#f{xhNdX;Z^~}o*K#9gb*_#m%6W3W)~kZV3^y7 zpm9)Czas(-FSHCYaTmF7+VstBq(l_+1|>`AbQjpc2z_Nu7DARf$;1O~|1n|u=|Cq# zSJZfXsm+X1YpKArLxXxuN`NMZ+U}ilgrCmG^CAlPXMdxGb(q`A3J|@<j|UtLfxWXY z5&GU$E$jUZJb$E!T)WW#jT7`@Z)aeC1LrO>kh#g0W~+Ow<Jjcu>`RoO34I4@5AX`1 zNm0%zEt6!#ET1DK@YZ9L0~H+8Y>xckXilozjg~fC>g)Su-&&>9&2ne8a){5Gbp9gi z1-zk~qGcfoM8)m9YV~T?%I|NR$$D$!0WgZy4f)V#gxlDTV^m?O=~NNXTM@5ftvdUy zj(lZ(`WtkoO2$4IIh4&s0#ODEPV+I%8?Y4dI7;yf`0U8-!xNYH!k(Z}5A9XUyzO;e zj5n^nE|XvbS2~uK@ZSFL#U?lOoNsryLYy%NWv{#LIZXkR0{+5XPhE)VQC0^0mGQYM zgk3aaR*^M=_cFvy2Yx^*00z980yOLQrH#6m4|F*vY_zVsR<bjURqRm<vy&A(F1T+b z-oRlP?KB#Wd)Z){kCgcJbs(6l9tUBKNP?q6rPAk9(X4H7K3X^;R-nMbc6($0vD<8J z3X(LWQ`;JAs&G6Ss9Zrwm^FG>L2Q2{F6>`f509H0>M}mGZZJ1;B`?~0`aNE8VNXY3 z!xcs{c;k<%UaEeL1%<piA9c+;Vc`xFr$2<%+oM582xS(Jb=~kgC!;7!kJHxrIwl{~ zeEx(S;4=JkOgqi`y1UVMNbpcCMCHS9Y5T~0K%gE%b}4%=OJ61P>G$OUyg2OZBRl7x zV0wi2nDUu%_j2=Dnt9Lr4ap?*4D&GHU`;P|dMPwg(uS5OlW9qAnxDXy4$`&^HN#;E zI5bVaq}hfRVE2lEIVj*i+9fy3j_2rErVIv)?lhZlTpXn#XVBg8U_Kma;gD4Dgm)ip zFc@&<s{6P1F&>aH>M^<LK*jkKsvOU!gKQFq(f-Ziece%3QzF$AYTXBDG)sE(k{r0A z2QQmoRkSI*qAfUrq#{JBnM<q7mf*ppa&>fk!q-Z6pU=h(zBY;Q6z?4N)zw-MnC(Nz zskbZxBdo=J!`xlK7!Zpdtc`roBa-6!jbN!x`<Ox=Evx3U3Ey$xt8h!&;rXauZppzY zE2wuGr;yE??>enA0C|qnI;RqTv9lI`sfkNmou;n4!MwL~wrGW31lkEDB(l}yOMd~% zcV3Pv`@&n2_LX1sN@2a}(}p^^=@U}-WYhFS=VHP~ib%>u7jJ-uY)(P!k-{LlS3);* z`P0=Q)78{EzSLR}nsTeELIT??&Y<6Im&Ki?pTaxbopO+$@CGfnB67fKh;m?z&nX|q zdO(Lr8jVp&uMT?=%k%B^vNl>=L}9_SKPt5>fUs(lLDjVdaV4JH+aWs`)5A6bMdzW8 z9Q42SXJ;=@PJpLlgzJ7ud+Na72xT`y^jb%$1RCnn>Ub!CWn6-qTx4!<mD?NCRL7_2 zj&mmRVNpfc|4il5SP9yiLiNwKqZYE(M0DT0btyoUGVkokXkj><mB?co4E1W6+t=-y z0J2ak3y*+RhdoE0U4WlHr0L=^<fIW#Ru+M2q2u9QOQxE8(apBf>jqq@17c$_o=-{d z5oaJRr%^ZU332M8TAIA*b+99thwK6+NfE??Q-oghN?X6K;|K|ifh!r_fu79JV?ZCO zroux=9c6p-sn%jsgcf-7Gb&?QGIunS*=3XgJhq5wu)Bp;W5IC(6a8SFAzdOVn<+&_ zmM}`)-UxKtikT^inbic?s33qT=!qSfNe_5zzIDyFo>WcBGh^3zo8b0H=bQa2=d5}Y zR4abiLC*=;pjC#|mmpfxWW!bsE?*+&apNEu1phY8NJ_wkAU#rwlwx6yiuqJ!FQRO% z7)=D#b2y%(?&AHOJ3Gv0XXD-;)G6J0BOuaV0&f9=3_BV6Y9*pZpaNY`i_39t65r@1 zi*%6As_wxVM2V-Ej6)KygdqjAr3R7mO}SA=sq{nUdC2$=8;EuKUhD}}%V(wgykO`5 z`@gUP-dE-FfOS$D;wO1`%mzR>$i4h{etK$dt@Lm=l`OAjg+5I?PD*s!f=Hx%_0ltd z>D0qVx4o-)X9tfKIWd*zS3H~z6bEnEng02eiiO+Z1>3==Hz|~*<~pz{$oP#ODNS65 zHEcKaxOuY($L<*U@(fQk>>U+Gace8SaUy6l?^k}KykSOU>vXBiUQK9>Qj;{Y3qw}~ zn7@7bKmHI(WiHMLOv2Xb&C!4igwRfxtZ$ec6{^!3pRs`-qFq^nQ%XNl_3G{}anZxc zZ%?BaWyM1nj{sjTya3&U^WM)zR1A9fAN=V7<AOgwpTyOSdS}N>po;#}M1u26C3N7} z>uHp<RS`Pu40`Gx{uj!sf1x;>_O5Q^DSB&58v%w<h=3$BK%sZ?^ZB5V8lSd)=4%;G zJWh8aR{pQay-Bt^J$1$um)SGcm7W-j0KpfKKT)O#tk`ZmkQ#p_k1C)$4}7~A3tClQ zKMI>4@XentFIvAW;FQtJr_&~eDTD1T7UOo;jL}^r{#{@icc=Bk5v3^5z)~^}8l**? zIPK!7o@{V%V(28qL@)UQsxjc1e|1yF*N*XB7|-0^7~U;PsKVR2AJmeT{z8hlEzpb! zkO7{Dk};5xM41@B+R-V`3q^}vtwAFzKv8*OY)@1pzak^J1OJas2jk;x5S`@%kO&HT zh%?hw$D8mb@Nhd$<5cBR%RM6oGwHu4aKf8Dvk>`CWqjf|us0OvR`RO08z2D_<g^Nd z0)k|6Hqv>@O1!8CrtFJ!tNb<}xuMikEYD!I-##n6rG)|7IZyk&9_%`>UmzLTz(98& zMS%+A0tEd0#Fo9mtrYkx8&p$8&niOSJC&jtDBB8p&w#ZoX`<wderqTHZ}?{NqF?08 z8)C5b$_vGKDiv-+%cP69Kz9<!z0gbOkY(xdaoR;EUUh?$u^i5Vcvp((0ib93JGu<h zGqi>|#pMur&F$`PK7PEpx3~G^$>!6iwo&(aiIevRbe*Y{E~K(ui=(!7$D_vaiGH9; zs4!-VKP$Y-QoOdnV1<`+HsXH4GuDMgv{5563FD-=h<9>UaDxENX-k2wF9gm!p*x;q zZ2R5mG`rL+0oE28Nx630i`aky5@G^s(H!9VV}7Kn6?7~olOcV+#NbiRt*HtiKz%TO zfbd-8f=o<^WvKY1y230U44^qmJwbAxs;U_i%ZmoJ(k-#hynwJXq>S!V=o(ofK!niO zVcv?uwgd-JL}m`6vrv!=NO4BN94R8&<We8z{lIRM>9{xVA{j@f->h_6uy~!(u3o#f zjVL>gy1ghrso4wIj2CXN9JNb%ACNsp8XS?gI{FgFw1X<g7^(6ym4Irk^%}hDp=`!# z9O&nU_O4)CB0DCwCWG1=lWxvjv)9&JwUY2V$cD$gEP~A&W!xDmx}ps!ELKv;E(^Cg zk8-W`Wu$W!6ZJ&-S9=ziW_3P8jlAqc>0FFHyfa6aY2l)i$%wX5zM0w`^^!JDrlWhK zdL55O>iP?v1p<k9b)+ZMVlx2(VV3k8X~j@UdQJIyn8R6E>YHO4qn~MZ7E@36G3<j| zAnQ3a3sRC@C7+Pi>|lDy+lnJoB?g@}K~u|3YYB+v^{8edO6g!yHDFUU!(}@s17vlh zWM2;(%fOnrq`k!1y<h3T(oaM86#zziNtibJaumagSDm`K@Ag*N@*>8>5noO7xBc<F za8kG~-w#G5X4NlfT~G5aI!<Ztx|8Wx*|ShoB4(|c75CAYVWJQa08<T-cqRI)6_$os zR73lRY*tfx-*WvXIRfhYFvl&63=YDEI7JSEARhjMbfKD}G!;^ln4zNWH=2Gk9JPP- zwcRZ$GFqFh_=bg5)N#?1jra!8eVlhQb_DAeCe~D@Pu!}5%1bE~HmBCkRC8n93=)^W zug5o5tfdB&m3c2OFwk&Hn&G`Gr`xn|scKKgI>iwdB(V|%@$)I}P<rPg%f_CsVuXRJ zVtSKH()%BbU(;ab(=yA$IHVPKcXV?Xx)Z||fgR3Dw?38L$ZAPNvr;wz{h47A6d(2K zo2e)j&PBe50rFrycV;sV4m4vmJ%U-bd<h0QcWJWaL5^1<<3fHn5ljuIRf((lykZjM z6*xKm!zi``MEM=K#POw_AI9LAAUcW7mhy;iEcK-vjUt(K&ZR!29L^6_x~Rd;h=&wo zu8;6yl6dty<{0?ga-xsSQu2*RXT2731g|1^v2jbrLlisEaWEGzds-Z@fXIm+&KX6{ z70XZ+b#;N27z*$^r_N{F61font4MIYZm%u`E0DY-*ozQ1iT)4_sgoDoY?8l*qsP0~ z+2~X`x*Cn_oqqv_RD=mg@!yKg=%<E|$0)GHG(LofvAn{;%cUkXHbCq8ZrV9623c{o zrX9H5_wnH<PN(>{;`NMP&tkVP%DK(Rk05QoJV{VPL{u;G0W3is?qgnXPhCfb0Ned# z-tV3pwu(BaoQ~_l1wK;SQo-wZn4RZ%jOAn?J++JnV<2fUYbfJS_$m!Ir*zIkrNHQ9 zfVMx-sZ&^wh_V}f1K1}_0fxz55IW%@npx9ydxlNiu)F#(G(^sd<LNNtJ4>z`3WSQJ zf`2j{;sY9H#|){m)Lo?wp*tQ7@~(~wp{nUJ2CgQ4I4o)-LQh$W)@iDuvOw1|VDy-| zU`T<8P%=8!W02xu|JRI<D#W%=^ATAv0lrjUE^@vYb~J>3ojplaRUu0Hq|wx~N@+2r z$2se`uxDge0Hvw%8|EklZ{&)h)EBBBh7*jeMt<@%rQ<F5x`Q#3cD8|mNjCI0Gv~>W z#r$z)WJzT-kM*xrNf(7|+Aqc<Z4*ny*92~B^hhY$=|0S>=mrjq9|NG)MilMtZf`t@ z9&c^$?!xz-*2aRnv39%m7}WyXWX!(7W{SJJ=F!Fjenf?~=n=dXrFL{hU#ozlrG`_A z%temT^U(}AQit&@J>HD6CfOGzBsU+MAC9C_khh9k&lGJ^1eyYO>cjwZ08E6>ruHV@ zQy40a6V?S(p-iZ*f}%uiDM|(v#j7ue$K!zvckLd@i5-Wd%-O0~s98*a8yJCP5C9WB z$EHE32}2o>1JBId(|U9Qc?WMoiY9(Z;^!)kel|UwlN~=scfs{WMw;wFr}^SE>Z_LH zRIYgbyty3BvUh)D@MsYZg4iH`n-8`(>V_m_lfkH#HPtW1oMqGSg+6p=U2AYLj8{L} zqJx_PQE$kzTX#+|G5A%xFAi?FCH$PSqn2abX$r5kHje@Zo{64TiHZpVZPZKAK=6aM zf)?7(YpsB_U?8Fw4RFF!G6CS)AML%{Q16=@U?%COzJHrbEiVK~1*U<cWnV?=az@td zcqkC)eM?jXVT!FWcp}G*oj8r+Yvqg<wH;|p31XK+KJ>yD3LnP(JBpkjw4q1=a-M8& z<1g*?rk{prtfnGikVJ9&ZgGUywz_JSxERJ#UZ&JwhpBn(ucTV=Fw)eT=1s=s!yEUn z(mf<Rj$v=y%{I^S$q5B(CDuU^%kYhrAwnzzKa1Iho?v%?R~IPup?OQnriysvv+y0E z*gj55%)63aOQ@wT#z9O)`5H~L)m6m;F*?r*%&<lAq~O#%l@hger}F&Ql}RcxUk<Ru z&hqxSfd$a~8^Q8DP81!G_)P)4#wXl}hJ_L`TGrp(q$N+q)VL~=Y9GXBsl8HnD3~f6 z`a?2!lW)PWd3`0<rE4Y50H8!>Y#P%D;9W5q8O}!-ql<)7h73|G9u4qcV`ylvz|vAo zE{ax<5y>!`7%&iQADtT%I&W=;ix5`q38T#OY(Q@&4w1%~1D30aYj<{dSafUl=XT2a zSngF+Pdm)fzur4-j{gz6;l;JF$>_+bgbs}q8XjYn;hBq$hQc)2IBBUBZu^i5oIk)r zE9_NOQJY@VrJy=_*~FX5y9;P@j^;7r3JA;nvHpMHF151zl<yOD3y&&4!=c)Oi29Dr z1##Gjwhox;YVU~ZkyYJH`==OL=m6SyHlC`~hT1WoHD1+wjqqgGfKp6(fb6UPtInXp z8tqcLIOA_S8|z-cvQst_%9vlddvP4h?+<?1=XlZ4EIYMf45!%zJ)p)o9t9~)EL`-$ zhzgAKfQkmCp(oXC*ib7v28loixYRu}#!PynLM0Jz2+~N*sEO1OMn%`qJBop(dZ>03 zGhg`2b1#qG-jyDb8+&XbqlQBH9BVC4%GzyfXKaldvPkQ>Jr}zhi6n=Jx4w1CkK+P0 zXBv4OCI+`n+{`s(X*E{aabwLwb7MLlmg4RJJ>HB_o(}2tb)U(mZU4%fz_u@ia~D8^ ztuAcLY_ok#F@z?E212c)BsT{mCE6lNSneX@Lo0&E*#j7kwSA@pt87CSdh<-tGB(zC zo2adfwvKlqkN|tpR(}VHv~|C~6K&mxrz6}z2242_8;l&*DV9qTAIE9jF9mVKgaL4v z><-2SX{JzhitFhhJ1r8Z>zxZwqQRq@#~m07$^x9_gTdi0s=j$pXmdbVu09GnT}KOx z%59=nNdnh%M!YTAt_;TAA4nX8eyH2X3Y(9DVgk=LBO6RRAN6E?^WC|mk%jzVGQx92 zUZk1wN!-!I?GQ_gjXB(!16US>=dsmm=qV})2eiPrVh1b{+U{ZJiuSDOwYe#u0Pv%r z_6D~J0l4CJsJ)54du?oGGM*$guc=ynv-AR5tkw0tZK&iAl4!c_7Zm|F^(~rs<m`>6 zlHU2|qf_fxzZq5Tar04cYz^INg~>)r)s^yochqxlF=5LY*^vU-4~0QASmcaZqXro? zm2U_MS1+U-OT$(6N;6(b+$nNt$$P8aa+AwSPC+@8=`S;G-WY+0(a7<hK$$D)%0W5J z1Oui8%qg>8uW+M@xt!PDi2&pgPZnM%90HroC<6)Sj&qnrg<CtPyY1z5p`5L0{B+N9 z71!Adw5QqkV~$phB1>Oh6cIZ%yUyO#*1_)Mog16AN$)P%rP(=<TX>tX2^B?+qu=X6 zb_{#-?fiZ8E8G(J_PjrGW(B+4$jgDj&qeQ~weetZUi5zcnZKR?{Bvt#W23Z<Fh?iA z3xxc2l-Lm}NUx8iVBT(jg|E0Fc-ivaw)i!)4lg$zlx_~FBjc4gI`MP&+EPVDVHnVF zGv5sFO=6l1^jnov9KRg6OaUOCth7dVI9TJTPXWfe$^^4ur^j)jbJ#k$BZv<u0yy1b z`$2k*Odma1-q7NR=qf<{l4VU1UH&O7hsczNUw-MQyrJ;oeWRA%8~aO^7lmvcZb8@a zS};XoqL0#J_Fl0!5Y5|2-A|`@mEAsS+-v@2?Wb>(`oE%B=RV$u7LPLWzjg~*pl;xM zR^&n(tiS}&hwI<A-~Iilz25jbYn<#ho*k{li^0xE{qET`(bk~N0S7vm)(+R-)#_>M z3vzAKO}^~T%1uIRU*5Kzc5Cw}{fc3;G_Bw|)Vq%SzS<`mmFtM~#4pCP=OaY>sHQ2} zLg2`qNSkcJ1<Ce=wkK}Tau9E^`ZRwG%<Vka#<1F6EN;h6LhJY^?*D7+nV-a?{1o^R z738Lc5+)LuUCUOrn}7oeGttE&J1RLZPqDH!r<hhNNtI$$oz$ovuU6Fa0^`IvYJF_@ z(E4~hosKUGeFuk{WIn}AapWgat$kE;AS%r$ZJMs=Pk6>SDUV`|b<^01;&n=2{l%AG zeH{miW{qEM(d@Vjpij^GKc5eVqw(aIX)&9>y?A%|Yem(+bg=T`s(<O|#ISxE5;`4W zzJn17`()Y%eJzYlm6an@jeeoeZW-n(V7NA!A)d5QkET-+gd@5dU2EaAjDWFq+E$Nq zD@GV7rXl-kr0i;X0t=FMGGkzdCx2o|QKFM(>|Gr;Zcw2BUyg3-A#i8;yK0boSGB`; zwVNn``tLSca74d2>*LPMwj{OBYC>43%Zxi%WBuKoJ2xg}Eh?<Z+m>xk09iC9Qx<Ep z{&9cMpIsUl4vyn4rL<p!<+{Rh{oyh!1-W^WlZxh2ThL_3<F^#Gl2tC``kX~QA}hwq zZTwn;2J%_ADam=MJe5rH69bBC<^A#evPM@52x7PKPgpvgzj&a`a_{JgXU{^D&1j-; z4#ge!#0!%`Nw%~rv*OU*y0E*VHH9141f}nkzriN7*3!yP_kK`^jy6|%3NySaQWm!O z4Pm>i)r~t*Zz97pMr@T=Xr?*G1{Py9?9TSagJe{7E?_5m<-o7*a~%JDRt8P;U*`R( zaPOm3rOHo8x$dgac+M$-lwDrS6qG-o_D?PmGg$hRqGyCrkqXbG8bBuW4olV1qR_uL z3`ajOFk{D)igN~=Abxjyc<VZHWk!RUrlhisL-`yNa$@3*6^M!Mo}{`eky7Q3H31Tp zU6#3IdrDMAl^erWu~f*Mjp7X|6V?4II3|w@ykg+lvgMvCytg|yN&RM#V#<&DS#|z| zQBvMY7z)<9%@B;tT2j5ZzZ<>SEek`Eo-jIR%~9su4=Ho0QRW92wco7pKruXB$IAyB z58)*7Fv9lXU*mZR&+&)>f1pA7<{vh6awq3V(N<%AWak4q?f(^1+<Jzy{&aAHIdE84 zsEVrx6XY__!wbxU#R+u=bu$Am8nHXbWQ`iyhspkFHW#;l#MMw_vR;>xwHM<Hy`}$+ z^yZX*X+Djf^b0)x!ZfQH`mR{qbJjz-OH!1wE2H4OkVcC;5ezWF;On2D-z$`kE2f${ z05n==c9}%T7=|{D?qwoy!y=bgXRaNiww|MXXA}~5rc#NaUdp(#lcRy$2Fa?c`JDIl ztk=`WS8fzBp-IK+_|)F1pRj?u%@D>nKc-={9<|W)ZAQTXpRC4TWuVRqHuVPytK+5Y z);`#k*`uL+8sSOJ2s51jnl)=S=#-j9l))OwVqI1_ASW8p0UUqvMat?@dHH4(YS!ee zLU*~Vg*@2Fx~2N(#z%3wxk5k7;F{C<=pZj<MN-OmzrG%|TG7Tvlx5MgXVH2Vt@ol< z<`#ll!RvOqp$r7CU6{$6DoHGDPYt~K0*r^3(K*nq2P>cN6wk&^_7;oq0v*{x3}^k> zAP-|0h*e_@0T$pqvh3i(VFx|K4q$cma*T>GB_E$+J{&?Z3Km3O+9V2Jj;H5ULsQnl zEgf6b(Y3xzBisO6U&4=#M~~neK79Z`zHs>RGP<{GKl}qPs{i--i|?Mi`~kl{d-<9y zg7MGyFJHfT>bhlr8mhF3RX;E2%&3^}%aiD(!+fJ35bk#x?i+^t_>#5OZvZY-`3Jx) z2V<a2$L0GE?TU;X4yV&dGitt=g9ju98v?jT1FS`nRbZZ;<}=F1#N587Bd!1u-J$nC zrFts7POWaDwk$t1NJI(+Oi!@P2?e7I>JBLaOfq~hpP)&maTGGk%lfvf0HSqci~ZmK z1vE~c<d~fiPmA@S$i!)3m~)#fFl;G-EjA+y0O@^_y&coE+P^ZlHyxJ4n-a&HSRIqb z7o(Lir)-iRhB+ssye;M~mN#Z@D$gRk*40<Ku*sy+yWv2{3(s}3lQSbS80{8a5$nqy z)U(jVeRk^JYw=#5(F@8JCXD)J_*HH`Y<&*U)HLH_LfEI@@Zx{-OWX`hH;nrS9@(%@ z!JA4Sa8piFc!a@<R6G^2Bc${XZn0}|r?Dw+SQ9}#0pkDEg;DQ#@K-4{s+$7eIn9x0 z#nyuKhOv?+Y4H{*Ga36NhJWezVR`kFsgJPqQF>I_NvXr#)^IKU7)(3}+Ujoa$Eo)I zY14)FQCS14E-03&=(o3P_sQPQBDE8Thmp23H2E*~q1@};V^oKrm4wosbgd%B7A5_F zPSj^X2ZrsJTaOtWJ!!rK5&P{%)W_201<OWr$!z!|%?Hx*G9h(@qRu{$^1h%Y>il<N zBkEbwt8XR5_@-|yHn!}<E3B{MW}L<mAWkA6P6>93sf!D(t-Hkz>WEa`GPe3_nJS~+ z2R3~_*tYKMjG9;PT(m;()P}8Ur>3k`7rNF#3zS^9-9l*XBJA>B(qtQYoyGtj)7dZY zlM@Z^^ibJuoT*IUKzcATDWF7NgabWO8Wg<M8L98f?Xr|nb!}_b+rj0C`Lf56GT`0< z33!^HY{zG_*<|zneX~n9FZ$<wZXY<yFy1k5w(e&;5xxb<;56U54`9VX;f_ObV?r1T zuT&Uw{0d^L@J}0!*&O<0+sM*P*+)2|8}CY1Ip~khwc&SW?YyXFo$id!J4hN@i1ajc zI7AGwDA^uph_2NEnK66H+dFbNmEL%3cZcRjGU%V@QH*4dF$C4cC_>|oI%ym@Ukv96 zprqM_Yku!G!!`_vSJU(dgyshNE7DVJr1E5C$E2|nEgAo?md6Tdkrr=64r#so{{HD! z-``hVd=!RR4Fs2`MR;F`uKp5|R`B~*a;8<-EC;BeJ@uIwxQ0!X$%GD8>Aib6Q*g&z zL>S5_3td#HbN#yvETfb55Th`r#f45S&LEA3U5v|(x)AjGc+*6qW_a#keZ%hUfX2xs z`Ftz0s#$g_TFCUZN>5ncs}RAcm7+xICp1%Z01XaAj5iB}wYsomm}rOeWJjU7_2l{g z?O1(32E8sLsjw(=%+^BsK!XMw0vqR_q8Ytm=OGglQ|(75(Mccu_2p9bD+7x5y7rtU zeX9qwDnF3V`=_Jrc#3B8ab0?SYajGn<-6xZGispj-McZ#=u^Ha!9-C`XUv6a7QMQh zoylm(bdEr?-d@DcAR3>0_pV|(Si^?B2PeVtFrT6`A)yJ+7|)v<i=zoSh)p)w(2Ur! z>17fn@u+BRGF$*=0M}D`wXw<IQ%weaguv)8{s5^FG`k>LD4+D-3F~H#!IJAhFsO`d zMmCBogH{73Z0FFmb5wBNE`92D*?_YNJU?M~IURiAgeD>N@g_<L%Q0U-WBh)Ba9u}q z+Na4$&T}_*-X4tAg`9P!vLwjg0kKs;RSjCWxMg}R*~qls3TW=W_($jecK3gLdZV1g zmWM1nn+?(7sHFDW>h<65xR2hzu##L+E*Z@(C;4`KI_>x3omTWPT8~=M`quq25T|rD zIfLTqgJ=W(Yo)EK3Ol4SJHu^pOqGKL1JCS;;>YPE6i(s4phyAF<GOpXLt6<OBvKDx z*EwT1yNoar<4Dtk*9ud_X|#in$Yttn`P}C26@sWzrHc==jAH;AQ3tWRj#SU;+QP_{ zZ3x0yp7q$b+W>S$9Gn_q`$<t>Ug*2jz9V+_Oy{np^*y>=M#E506XCC@NePfTRB?53 zRxB7NtPs-9lGikHD-z>dOJNOiRRY`ElD=hO&MY-KS;a&1$gVL@+(7GYkVphf90XJ! z;$xE<)zfg8GD?bRV!psa`xWT7?c_Xt%SvSULXpJq%~4q!T?*2FqBaLSJf@jB<!caS z&vji`Yfxsliqb^+C3J>mwg=Ix83TrC;N=KW7PZf|ql&r3=4FIWTSGd+@}}~w(6p#w z#CYP0%xpM-ytZ<~UvS=DtatZ6iJ^H3;nbq*MTSDPc~#f9l`m%Eh{NntPTT2-8Z-On zcCA*Dh~J=v3B~Wl&9hLZReFoH^4|@MN@fi4s+JfHXLxDQg^Zee{gab^7o8xERa`f- zyOX(?BS7JFVj1f<*hmSB)pt@;{B~RE=Y!cd@Z<B-**AJyB}l)`zAB0?-3@uFlsCaY z-FCR@e#IUB&o<@q0Ggf1fKZKow@}9oG<P#ch5m{7K?acOu;VZ*?=*hz%0k|Z3`e>V znLGdczs8f@q8Ovie@BO<roB!*Z|*;RcHnS2{o?iW@4i0>@WB2E4mB^7Jy1gC8BfV? zc|6&tB*FtY=Wkm_|D*=zimCgoUaMC|(Qpj+wDC7^L|_xcA*N*UGD*-)^?U-4jaHTp zpX@QufyOzCXE*PWZ^&66O28DkY@&W$mu6GuXifn-^jTL$A}4R~1|FN}9EfRO$K5_f z#cQf$^Tx1H=0%2~$?yoL)H-8>oD&A0Zp?Kgww{WWE`s#}=HpXz=_XMU8NNC1qXEo_ z;uO-grb=It+jeZXizq2_lk5|)gA-)ki9HX4nr~`1Tam{jpICUDCt7<{AwUsz5B8s8 zu9aBINRkIYOqnJn9`&trIBMrBj^)WQ{glDPFz=paqkb_Yr{6JJ5s*b@1Uu^#t&=a& zbU_hq)ewMs*1}ienKsSIsdzNgZqvgt$|G6P@0zsNS^+$Q)3qL0fWng>UEy>#4W(&7 zw?nLxWA5z0utXI5#!JH|a8lF$8wNm7ahn%u5p<<wJmG~nnhy{1=@1&H*}4yNmzK0j zbj<v^p0bCY<#gBy9mAcX0EF@j2>mzp<QvIaaY~q}Z*!Jd<FDgf-^H_mTBcoB95BcX zRTmJK2dO|TQzXFtUyR-BafO=%g=H*5P!{oebRUp?Yas|Ao25bKSc2FXJ?0jW{CXf0 z6j^19(8X2?8v!zl2Xz749ShxpN@;)!nX{a(S|oL$l%pD>5Ef$<Q${eMRHR)u!`5&- z?)hWg;`Xi_Mt`H?0?BRRrYX=DQ^!n@vOZViq_n!SX_sf~%rp)$#XL*AfppuVDKN}w za1`Gj5BoE;0r^I|hsqkx?6QFy^jw;nRjchJi_}CsM~t0QbSBUerDNN+ZQHhO<B!v^ zZFg+j?AW$Dw(Vqk@N#F(T6bR0W9_PkQ}}iZQ?@dfTCS+<uE=HAp0vn|g2Yo6)tz>> zu1tI5ZrB+M$$^lJLT~$vlmug85YJ{c5Vt;Dl1D=c(*<19{Te`0e2qB^Mg^(eX)rTO z!59PR0UV-|)X&QNv02fYxM%5XWun>4H+V1qKDSl0MI9)Gg^yZ2um&lEJNr+mNCtW) z(2&ApL9JfVUHi&zkClb}i=~Qfz9hXfO+)#)K}pE;o$X8E2NjzA+J5_1rA(c8EV>LK zIJn2=Ah<?S{0hO=$AB$v?($c7Y^+4lvU46VlTo(|+!9|lU};ZAdc(GC+b>0;g}r<S z0>iKi((n%#k24**tW~pp38Z9eQuTo;w7M05qn^)iFRx}rd3^9Us-q|Kz<jgTn>J3x z9*$|G!k9YhMfIJRDmqsk7fTBz8AJ4KG9CHYL&QcCwYt%{{VM9?t`u8-3swIVjdjo8 zzdlrWZBCXd?&^T{{5;RrIo)IE>A*=V*j8Qvtu1<);i31%qqa6u!7QTgCR}FnfWjK9 zVlc#e=#6qU$i(MRlx1?}o7?6xhs`T}TYnIr_00=Y#oxm~Iyegu+J)`-qVCuK78@}L zGQ-@$k^aW@^jy*P1>h*6GNc%ZK#=?@bxsoaBR6%a6U~MmYgp?^sppE`AY%<f-B>P6 z%!V-YT2MJZx%41#T3GkTtCi-sRiXoRD{;c-NVZ-_7ad*Kff)G<9DqB}Y$mumHRL*u z&h(m;=ZvWlqJOQywP0m!jH4`9CoX_MNxv5GN{2^|>xOU}I#T`mA*|0JS!nb$QQ&)* zCVPT_W522U`nAd<PAp@Il^<5i6a294!oEyNX0MJ30~JlkuG&`fmZOtRI}6FMqsAP{ z_JI7bKnF3H@lAEX9dMcSWY=};wEAG5P%*N1P;0#yr{{q(iKw**Yy4Ad+nH@`CCz%S zm!+Aj{lO}kw<)Qw@taYK^Nuc5l^6zsIug9!Y9=+X`dYqm`BW3SAJ_;2{9%a9fn2i? zNSk>mHB_y_SQ{HH@Ej!WAO6R9vDnYNMe6Tc$t4c32x8~PoV4_|5H~v$Tm8!XW9h-T zSeYWvZ_`g%E3bs2hDi4{!1PUMLw!`gN_4U#=ceFrc+ue5-rhX>XVd}Dw~MEg<6nIJ z-eh9q^QZS79p4&^RT*Ww>^0P$JG|LgGdY<cBd1QV)OHE@6)>8X4HmWicOAWG%%VaQ zeJwS=H#M@3S~D8LmUx8kY84gVp$m+>TdXYOtx4JKt4qoj?%(N<)nDSam4DI|$vHUT zt4&J!wDCUvtw)%cGs5p&q@-nTO;F+6<E-DhY!;+BBD)7>Q3xDJ2ta52Vqr?8;|6A{ z0LsU*MpQ2`tYB1=twM^2|HpF08u;T6!dTH52;q3X)2@jq{8eKuJzQvqrMs-ITe;Io ze)OifAd$EZ9_c(Wu}s`)g$k*8+ImR^X|&JVDTtVHFhSfncO=)a!EoQ5HkTR^s)_KG z8wFI96rlRj3~jE{iH{_-2FjC#Bq`3Sg!`mHMz}x}|FABe8xQsuZf<<T9^}Hy;z^K3 zcd&<6whou_BD`}i(My}<QZ%#@rrgqDDI(32^kfzTUn=+kg*4PiVrne_6ItC2J)a1u z_%OmAUDaOv0)UVc9GTSm!8QzNnZR*}0^P85E51T;X|NOH{X1E~j-SR|EY?hlZ-g@9 zy_17$w<Q%GrBcef;>TLzEyF5V5TLw_S3zx8hxo`uCs!H=Jii>;1#=)gN+?$be3(1K zl`nw8!h;=SjFchFD*^M%V=gg(ExL79ter_A7LGTryMhwE@}j9tL$plmq8(Dud<!|p zzoIzy>46>?UG9?=agp6YGho}l<%7o;-hYhAG|7tI4QE(-o85Crz9iV=9jkNbnz)7b zG5k*j_lMZNT=PZwhlM-$*o$ZFvVJ{&(aPUAzK~?BpOGgSP2=SPGK${mK5A*qLB9!M zX1l=qPvCJO6-UBl=8ijS;anoI6q|rBoQ;S=g7YMp?acNs#EO*YJD-hd-ewm_xv+OM z+%DGZC#7(Lo+?RA;6qoKBM%QwBTlECos{VGETDT2i-Q^LF@a`~nOnzp`bYAT)eOn% zR)c7PpX_K;n}&_m765%DIe1V$1Wq<TURp#vyYURpiutb2g{{DlehAh-KS`YM+c7Nw znX(A7>G_Cn>j4HwMC1*{;TA;Kfqo-r4W?UbUCcGbp^Bme?F4I&%=oM+;ok1W#+5s~ z-`>9Wi5X12=_#h<gwZb&Wv1}oNhz(Vn>%VeB;j$T<i<k7kHXRtH#%0o88s+}yZ3Xr z5|%%QmT8p(9QT~$?ITfQ%tIAhLB=XwLx!xQpdkd*?t0qVL^qg+hGfJh*@Zh5`vxB! zjFzc>Q1VwWXjvX5!8*+jSFyI)U!EVv7cIL4uL)hhpT8c0%W`^dJPdoK-NdG3+^qzo zMVUCc1+4hNtOMVr6M{%Z9)yjrzPcVOcvR*i6*-?}O$<(FdtFbJ`5jj;Nm28@R~}9k z*<C<FK0U}LDtY=)idvXUo4=Kt3@}RAskfUje(^<3wH<k{s~`W-D5Wl`YOt#ZC4Fdt z0<5Y%Z4jNjPFyfoM+G}&aeP@|G=qxUkFdCDly>RKcHmsjda<gs=(~872$}IJph-Ra zJ?L-u&c!>};bi4%-P5|GhfenlhTeFL59PKNi9-9an>6A|!)wtlu00_$e=zD*@|Gw` zI_>0Ey<3P;??RE3p3t|u(>%|w;;+YYQ8S)+sFGR4UfrynSN2K5m8C?rPL7<I)=mvA zDds>{Q>evKg@%t@vvtpiZCu<UMmZXF*;JSkUNwq9#><-orav+y)~{7Lrp^+<tmGNM zv^-p@(bok(cB|u+TDtR0P#xk}cz)qtX8ql8mvBbzc$Q=s$8FTG$y1?ntjZ>35<TWf zCBi%xvfV_z%Mgf{S1*pXZm~hVmpG=FU0pW9z)L3km{JRR0Gl6`#VUTO-+^jj+^!I% zf07dlh`gfc?KJsYYsxPg8MwN7RCKdDe;uYe{PooL?REL@_`oTtWYl`q{_f7SOq!uR z>viGe&S`~)f1QdSx#niQPEk+HXdE%w<IMcbFU<LOb}oj1`qF4;*nW5fb^MMqyuGCT zZ`hU$_#XIyMZ<dN3|!AK8m3}hU_6K1zHtK1=l1YDgcUL{7syB)11G8YE!BUQaAi55 zPkoO!7MCq0%V-R&Bj3dZC6-Kl%u%S(_n85w2}YI4cAmWD5RwRIIJt|uby*IK*mnAE z^#(SMwzM*EueQ=7w#XYAOTl;H^qynR>QGtsLlW#4u>u?xRxb3y-1NMz*m2$uf%9nE zZ}7l8;NvNeMwz7W;^dSn)b{~i`7$m8WfwA4TwK=!VpZJ7K3JWK-wvxNd<Z{L{^u>E zZI`8*t@@kx%7p@y;jiyJ*+pl29>;sv5Q0UFk2j#6y8)6&`<76vqw&FG7Ab^CKdzc$ zxSpv4SvbODU1oLZRzPa7utdEkDT#`|9Yg-?1oM{_Y$TW9i$GvpF7ST3bm%zBQ6?O$ z8+_`V!!+`TJ}2fuL33NY(B0(rPCQWG+#EqglyeI$V;l+AI?^aBQoS87_AoO5qIPp+ z+{0-Q{65xO4>_+SF3PL(l*B#KQikGhfqWrgO?Nv2pM`h1ry+E%ZZ1SIJ30ylpTWwJ zfgu)Ut6tfQy;ucn3zuY4v{v}<T7Sz6tz46Lp3{t$oExA&98?N?ah>}o^@oR{cGN9& z#M;`unE?#En#_w*WPPPACFk|r#+gBoi-%p!!;l!C@gc6rmKv-Bx!65?xCQ|RJRSAY z5$~VF$z_al1@y|l{Qdz)rOXazNS(~}O^Mz+50)3p>PQ(~l%V7EJ3->YZi^&rkiq!h z3%}zT_2k~)`6yMh;Zg%56&?!P?l3>dzXo&sr3cIIwJX$wm0jpjybw#n(-MP(^vI;# zjZi{n7uwDSAV~_5s4!PJNollE4CYVIPI7CowRt73wG%)|n=ap$oe0J8Qt>Tt+7SO) z;jZG|w!MIVzrpn8?yjPKdpU<pf;HKMS6a~1x%vdD_YUnF5-=l<OQbWZr*OY^T8bWV z=T587b8&{6OTix)Of@dz97%|jZIltIOf&e8Q6O6?DfnF}CcUD~DAjj|CtJDd0k&SL zvSOmO!k1-jd3Ez7?~G%K?ub#DjR6#)s#gz(o0_`Z{96^k)3&QL#1WgG4}85t<ODUt zPmaap(L8@tR&*eO$&k6p?1~~|Ovy>d6ha-7E74PTpWO}#x%!{W5@oQ6uiIpq+qMw0 zkDI`@3GX~|9x|RRTR@V@5~nY$6$;#=^b7+eFHv~&Oa@iEK^&A`UvTg?ca9fjLrKi} zDZ}}w(hwooj<o<-=8jF@Ksk;^K!<LIea`3Kd;E<AogS{SI|5yb8lqeTFW0iXHT-?& z&PD(+ol%@hfO?4O)0ek$(|XMHb}un63t5=G0cY2fcG0{59l{RY_DAddS|X@yis4^4 zk^HcHp0*I^IK$lC4Rm<+0?wmL=T`P=F&xNp3Di^1TZj%J?4ysD@s)Fc>-P5<z%|6I z(dc@|FqGv5dJk-HZBV01r-t=;d;Cx|?40MGDc!WKwbk=c4NfZb_&b%=x>`7NbpW39 zn{|o<(WQ=YZVk6trr1moXxq1{Pflv{1b9KechR-HhCP^eW{ekhOraE3J5g~?OB!i= z62-`L(Ik^|;z4)-D!b8!_WZquA&_Wfo_P3|-c_cM{}j7u_Q?5$u)TV=Cm#C8FODGu z3WBDoTv0^R;p8Sx9uKr%?2g{=@PT%HGYG7s(v2k>r53z#>Nwo<)r%;xNtW&JHkq`N z8Wpvn#x{FHxF()TqJA*HRCZlBU82+Bq8m($@<5+S5<C!lQbB`I^Wy@yg{QA$ITCw7 z@vvg;xdUh{5t4M)!y4rar5xa64oic25@H#;gRYK)Tvi713r4%#@2{$uiYUy$VsMrp zk?Cm9%it22RK2mAcZ?_>^Qo~Ut&6*>icU}701HgSXv+-igA)hiN)dU7GC7JLX!KrM z`K;CV<#eq}={Z?wQc?W0t+$Ln44u9jD@t6}DuIsuO$h1rG*+R!G2^as=XO!7MrizV zQEz`tO+n)Bu^~eH(5TktvyncGJsfQ_+<4E45AHsfH^X(m#y7)DMh$ll7%xqu7auqo zd*4lZz=yq<aDhTiVtVIgsCJAYZT;9U5M55_1(2++4ZmIw9w>Dme)XR4m7J~At74aJ zYFHth>nNDP@Nx`UtRwyyeP)M?iYd4n2#PK?R;DYm!0D@fA$%P5lvRo2HZJ};F@pdY z{wjFEBtNdH=hfW>@(v&9EYL<K4-**%Q<t_^5l2r#Lik){uE%9-7emFyj4PXh+>%vX zkx~3#+^hIM?u35xdOKsB1fIJO5|fMLAJCdIzJhO3Ih3%2f<BJoxrL$p63L|3<_*P) zv$@-8yQ&5bu$!x)pDQ=s_zrySKezv|p&vKZ$)6%*<!0nGZ6nn!c<bLti<S~&s~C?! zhMLFFh3RAXN5jHcLxq33sF2=i9&AB-*|r?t^~*h${G=;>n7N`@F*k1~-CR5jIX_=) zqpQ+ajCJ{)WKuCKvU02K`2bPBWLxBWdk&p%`psnctr*CKU9gceds(rAvPXxV4-&J0 zWEzP)-^PNmwEAXj?CUtUX|8$fIajg_-<fE&gJY`ZoOyqY?Y*{&wrNO@YS%YwRyi7D zid$t$bo4W`?lldylAxpBM-(<9)>SSS0;lT#B>wj1nSmC+QaM@v<L&^(E@zTqm$owD z%~nm3XQf%qGvAngJ$v|mP?Y7RtH8dmI$=UJqvhI4<OA~uW_OOEQ+^r^CKXP}sD%uf zm^9qB8bz4WF;9N84M^CI?c!+rn+dl%pb)oo#D?1Ds%2!pExd<)w0HjOb(FZw;Ww#o zRdVMzTP!_8pF!QPZb~O_l=f@@1!YC%by4ke+7lSJ>qWy=nO_Qg_d)Neb=|ChcE*Vp z8Wu_JzC|h)GW-lc7*}cn+{-_#%|OD>>5!&4u3)J}@NnO`-=~7z=3W6NmR;>j=|{Rr zm`|(U4vgvm4dAN7{#9?RQ&EEcP#{L1u2IW%hFqP22=8m9%Bc7}cx-%QFg;(MIql!? z>VNFqHc=uyhT?%+1Ss%{zb(ec@o5oC<slBRUzo`wI3rvQ>3S&tw(luqq=^*Q_P!hE zIYY3_KO#44N5wYJpQnLFyX_1hU;5jwD^}!(X|ZR-C&2mFXJnq18LcO7N$@%f@Dx`% zNQGj<o@l>5Bj#S0J@7E@DVD5$rFCda?wQtK%=ht!9<czgKY4RzD0NsX5ig;25r(xn zfiY+8AKtj(y5QxD!GO5{GA$tMlw5ueNi@i}@Y*erw-z_Gf+J{9LRG!>`haf9FsOZe zr0Ch}V1E7y;`8AaDrX|TR(EHiSF^_TpfnecBOSBSkiR|AS3EXLW9s+ciE!mc5Ab{5 zZ$vCyr~&!A9r<m!aD=lHiVOvbDX5EgglR!n9So6BhxTCN>3{!#@CQ91gXp9U3J3RR z?XSP-&KAG{P|Klyc|3>R+Cld2QRcB^7iXAuu5BG>S|>Fc$}oh7;+-UMV;?U7?0=o+ zOJM0}eqC;N{?Pkd#6yhuQklHuDWjA4*1|g1WSg?PF_0X-K*T4t8OeG0zmTHaw*hC9 zS!7I|tHNNlqA7rrYOCh^(3~m5wegt0UDV$9rS83>UtQPLA_bYX8MC;Y(%wz$T$SF4 zz1w_t9r5Ry*Hb^n9(5rlo)|seZPed{<P?1u+Rq%LR$fEgne2Oo4y$`V`A+V=lLo+_ z5pbEsL0sI}Gpz?*KUQ1#9M{h#*5YOv$bKM^B@~mhJmos8^W>MmBx$#@Ud0KR$L;eY za73m-L6(r<x2el-<vM;<-4>kY<_imxqJHj&$S`epIyD;sr?SsO7@cXQ90{fEHwx)D zsV^~v)==+gOTT~2h|q9!22#lD9jvSx`olvWj|8V3i0f(i@0DH6arbvpXKyT?3d`oz z%MQvt99&hqu+Zps?v2X-trnc9FJ!}lj=H0cGs<zg%{k}7Z*nslnEtq;N6`@rPDx_# zb!$wcb!{hX(}oLaY9d0o_Urxi5<cDKnCYP?Fub2n-Q^j$o4#X`$fd7u-#?|H!?5HE z7@zuU+CPV-PM5hpK<-k1XY???diz7c*ZK5b;C_T7Qxpqn{dj8ojc8C^SNHRLasHyK z<Q!1~c)zNundHm5#(OrZs~RL&>yu=PYhv|uUt^8;S|=9_5Y2I+m|Ja!TEE`jCx$6Z zzqN)7k2O$~%KdJx8kv-w7%ulk!ru#Sy7QS(<f!oRXUjXP#C!}v9iLAQQK(u=e{XxW zdA^ttth<{FX5{QGkxAVaGYi%~I-=?F2DrC!<2eKgX_5VO8`xIYISveURTQD)#L$Qj zSu`7Qg@5(uJNhZp5Cgr^hQ_IzTyUoFy0W+wHr?niBiKyTmt!nDz=bM9>Jfwcx+Sw6 zI_9%vGi6KGz)QXh=hUCEfA{77QO%RsjsG4SgutnHJ5})(vE;RNp<d=+O=RjrW5jSk zm{IT0!9TK7oe}Xs>oaSOsAyi-OKeojl^Y#AB@rx@YyZsVr_wZP_rM~p4IS4(Z%4lW z0=B$*dYy30981@^ENL=e@}KQT-I)%M3*&(q{XNz-h$O=k=q%>UEkq#=KVo;;vHt50 zb%TWtVy0I3?H4yKJW@{s>axsG6LA|Hw+*_Bh-D{D&UkjkX2>!x4FGmk3V=}KRt2K( z0N2*{Z8tr;Ptce`>xiaKc;+Knnzdo#V9v`Kg3_4tR=nbnXxmNN%#$}WC2uuR90;$I z2-|APC~>*|hjnxstCXY!ujLL1Nk4v`idg!NGPyJbH3bGvk2iO7SIEM-ZAh3*TAl0j z#s5jMPyv$uga<#S5ygXNuv+lkbzi=SXa@3^hXmHXV#X=901XUlS4Ri|zgbYJYdv3D zy#qg<%A`-_mWuN5;#+jh3O?fTAabbJi4AbsB3o1z8b+c9h4;mWot#2YC!)@}_j$fv zBd~7ywVbVw&JY4w%vfo{P=E>Ao=~gNyV&Bo>sitBct9zG`r|lSlD^4zv3IfK6F}1E zVbwRbJcG=}KHh8SfeswZ>GY4}Y!W*r=X$=z^o!9>Tr+SqOmzT3{}>bX%>FIc%@dWz z?wpudAJtkEx~G(`E|#TbdoVPbl7uB6Hxsaob<bT4%VP!{ek;NYZ|A7)PnLhT_4gOy z&*zEYR@Hm04iJqC4c+YP^x{{UHzc!c;4OiYfJ8d0R*4t4Hk6(grwDxU{Ph8U8#+FS zva#YyJzSofwV6tlP=(xTA@ud=wZr?XQ)gRQr;9e5_k-Q8w&*DUmQTSP%leTkmJi9= zHK2r3Pw5LeoDk3evaT&|$OR0&k@oWe@+zR00Tr+xQ{$BgfzE_|!lV(D5M3oH`1Ocd z_`nc>FvW~ZWcQo7l$97?6l=A6l>LZ${VGMymCqC}a<L{hF-=$f8=*&Q`n3Uv*;<2a zFD>R#U{1&}(kVB3w<g95>*5DdNfs0g4G0Jb3MeE~T;aEtyp9w;5KxjE5D@miR~K_v zH-M|7qn!(*p}V<*nWHnKi?t^M;8zX*m&;~rQtw4wAN3;hQ|^RpcC$-z1+ThY$vnS* z&LP{?(JwAEXzgn1Byy=uFUM>D-feK9puD6bPZnh0O9qVSVUxT5BLLTDHn?#DxL&<_ zcH<~oZV~VCuz=<I#<W(ZWY92j*Ix_US8fZ3!=|>uJphyEu)={^7KFz|jP~CM{9eC@ zckkC5$mc*w|IRF+de0G6WXWJnAm8alc_J|&Gm!ojzN1O{F4=9WgYS$Ql^N}BlfN7C zH?JAy%xW#>(0fguzdM9Osyq7h8o`}`vT6boA~e^FvYhv)&`F*_FsWDspYP%0SvUuA zG=-t;n;Y3J2SW$2;>vOIx`^jM-5b;}8%Ke3vV+0e#}@iTX-t9c2eu>yT%EA&K-3`% zlexeWKnFSk+=<#uTO+@WLVL4u(hnz@kS>@XK*|10v5ui-oZUe+<kSB^e-V2|R0G3b z65BY96AK&jL&I>W7NTT4w8wESuYip$(kPOar=g}12A`I%2zI0!Bal?@GsO^=Ac*+| zT%p`ld^qGU>5m|0XOeaCN3rf|-3R(6rs!8k4Q;@SwjRnjE3uEQ*EG|J6No{0A+;0B z?x)byw5_Dc`D8W@FOOz1CcmXjV_bUqJ#Ajvd5wf6gBORJKAXEgoSi?wgGRg^-X9~n zKPAdD{22XY=;y|+KfYYNxi%PSx)5=6wF~6Q6MMM-^7?+WbAO}#0Ln<$<h=B8XYK-S z<kVCvA>qhkNZ1;7^?Qd-N=9sYSf3^|C3<plcZqZrG?-ow(N{eFXU#l&lFZ%p&DZ-! zM=mgwmB@#?>ys<os}yr_5*PP8l#k;J9>wm?+SxBI6}V;G(rOT|!>mkm)ql#e*RRt! zuXbj(G~vw{W=mcmThZKnu6glc{L*A<h5|F$uq?z4+_gRwit3k{p@2Ly>P2>6?>|)Y zGC9Zb<N3V>!Z>rYo1ZF?|8M$IQ;y%W7*uKT4^^;s6fhWo+6Xu!0|jz?G_Mv%Ah5+e z%*7xw-YkWgzzvW@b5ZtoeynO0CGAn|Bkf%0QR99Hc3?JzA!0a0$x=wr)ZPhF#^?j3 z(-<H+d2&(+bJr%W<$o@5QH}Nk!$!MY4hX?qp&JTo^~TL>in6IsvLY+9af@Af;Q`M; zNBKo4H?d#GEnhg7#LXv7yH$K-sxVBtN=}^U+0>p`S5@d4{A#XCPTqj8QRW1o89RBF z2#ved)wavS5PZ?Q&FlR(t<Tz)&#ycBkGBwQ$I;7eD6v)(pm)E%UBqd5*OLS=Bu?4U z6v6=XKL^&zK-Sv3p+>6FcAu$l*!~k#x+(?T=13i98Yc{G*fQ9#3>3YL7C*e|Qx02{ z$e+=Oo>ZQ+nzEXJ-^(-Ep<4}1an};`d^$tLmu4Sm(GI&#OS?SrAlWB6T%*rpQJO;l zluqo&vk?f|R0|OKUiQyLUqCqNxZrn>$q)UB6sM1C8%RyBkz;(IE5#*9WeQkxf8*c! zJU<i1otU+k%h<zuv?wy3$+*7S5hJy9VoBN__kOUV&;3+!5~Cld!o^ix$=#yl*a;eG zo=Xo}3Q<HnO!C*02XwfugkTO`rtRt&jI-X9!Hk%U{T8a31$%Ui2(4b-BIU&KJic7B zOPFRC@TLhi`Ge-Ddl<4ueyQ@L4pj+xZfPCCKbz4j@s765J_L<B#z4t*dOIF{9`$nr zG4s(%D8PA^`>We9k1ECV19veF$U!DyS48M6$hTFIvY>|nyb0l3QCskg6|==oN#>^H zZrPDeI4K=d`hoU^aHmUfRF>i;aTM25ouEY*R!hj>cj&N=frJ$pGaVmwSJ;>aI*W)E zn7c0KGRz}WMwmZLiz9qiB;OgH9^GP~olH2Wps0G4d{cmYVra-Dr`NukL}8r6EM(b( z#@q%Gy!rMBf_-l+<2cfKhAv(Dc{ku4u<s5oENwr`AW8@U%qi?C-w05{{H!XmSR;>J z+n~2fW$8BxKdJzq6zzmQFw@l$)pBh}^n|o=W}JB}{N#UEFZ6??z;>cGOX(^Q;*bUb zlE;QpzBIfpl8ho{A-gV;pLd5WaWpxZgU#01V&oU3UHK~ZA>3_Pzl5;C<A$=H!C+G- zGS<mR=2Yko;`u?hfkG^>;FqJ+noMN?E&XK`F*aV&J(^Iks1W3#n?)Un4jHB$Bxc-R zT&N{sLFp|q<mcrx>_-~mRp<8H{o`QMfRA{+bF<);IEA!W`pe%kG}|lS7Ds*w9A&6> z<TJB|;V_`xZk|JxyKk)!FCIWcl-9;`MFVKH1ZGdTYRaR_!IE1m;F4x!s=HRlvL={t zVFBj4r>sJXivejJfq16yNn;oGZu#iJPrps!mjgz!eERUJ!zJ>j7?ZAo8_HjI?;_Y= z;-n>Gd%m3_mF$<yZ(I{0iMEd&h^8ThTbP3U<!$GJDynQaM3Xh@y>WlHYTP&|0nd{! z^Yrq{Ya9FX#QqLbD-zl)h-IF!w~mI%YJ|#V0J_|mURi+LbF&osz(Q>W7RpF#Y|+Ut z;6%9?&V<Uf!xIZ~2kW~TPVKqpwUdr4HPL1y3dPf>&d#VSTXi%fY*I&h6GE9ETnm-d zBD3@wV{p1K22CxZm0OxaWo#|IBs|1W!Wvk@f!Y{Txggn)PXIVZL%6}~ScRfgEgsx0 z<ySJjD1TyAn6Q!ld<zzFxH82$6ipW}f8f&Li58Q^z|3Es`LOwd%SG2}oPX*xzI$*q zhu`*&gbtIgSTTjn=!6o(Z)A(+X{u^NKHGZZn=X`g9tH22w{~gUs{=uJxWy#`wpq8A z*TP`ex8ECUa5OsHes(u8!WrB^`+wt^tJ%R@i%FS7`V%aXN3n*bp7uLLEdex;j^5}C zd=(H^R=G&@tgw=-?W-EhJS|9R4XW4*Cd`>a3|q%eAB4b=ufe>w3Wbed3tHSN$Y6ik zxQ*p)6$0W?oc9J(Oj~PeY%-RHRIs@N0Vu0o9yeZILRku*S+Y3VnZX;7&i<(VzT3;q z63S#(&N<)UeO#K})kcA<%vZZXZ2d%~)DAmQA>ML0_QDnoLK??+HD7VS>3H;4U4${i zb>sOqha2dj9vkzvhn;(4;H%S0GGN2<sRqBME=W};j_dfO?#PIkz@tg1DPXR%rk(-e zUNeM1q~YsEw30bY;rdmneQYYIPPtwak!34H+<~QI=;D8kcF|aOr9bd0eRWMM$wPC^ zeMseAHZv@klfyV>44A~mDVOne8J<cG$A!g@IUKy=r>F~reQRduh*v+?3fl5>TG!D# z4^qXD4t~UEthS<hVMMIx`Y-6U<mg<+!sq3{$z#0EOIn<bKRKW@P}!we*M)f_lK7Hk z5r(t$0yAPtuZvXs#={kClnj?d5bUHeXGY}Thl_!3%YwnI@?K6!mFOmZ%pD8_o{Jba z?<UL4G5yXZJbc38@?ePG=ES3LQMF*Dx!VVfxYcYkJ<L`r0wPfTINbzaHpVbcAoMd# z@b4*4>iA}$_@Rvw<-eldUWuZ4>ZkWqab@ta^1u~mLE_nFe4h824x4M%#%Y4`f{Ut@ zpB{3{lLTY+N}q-N-@~GA>x@Rrm4IFs<p=s}01TTurW`g277N8S?picH8T9tSPy1Hr zTjZX*qG{JD3#%;KaS3*+wPLw;_&yH759zok3`s?}xp$a;c2hQ>9-lr<>pbf`M+~uN zUY#&=5+*t3&~naqzI{Kgs^dfy05%bj=&MFgNO0oNz<74E`M^$Sd_K}iGzJSLFIWPJ zL{m(n9I=T%udXgme)`2w{Abr#<33nI@R<iPljhR66g%z0r*<G2Pn_JRFlr)XR6Bn% z^yL^c*P$HJcX>}GoR)-fd@>l$(TnlXcagPIZ{^9up-|=!L_DK3$sY@nL_?s;W03~@ zIy*WHZXbo+by>qZMaRr=V;2oA)k7pk7+_%U`K!3>e|4RDt_FHAo^T&9Co0-Q`5*C7 zX8aU{b0nltRxHT+*o7iDc+9dY-z%Jna~6f=FwsfG*Nk0{ql?tzKCOWszXsxtm_5uy zQL0;1H43<PkEkZSLRC;;gO<jp+^S@s`qbROrmk$%j;rr_K_?lcY)SK5-)jb5kY<1% z0=C8oW8*q{wAT3ps|aJk#|7vzdQM^D67aR9ZE(yj91$h|6c-Rg{f+fPhvI@dSkfJB zXk1wTqCU<(&mOt1>`xC|HypMIZp)k?;4Z=2mh@G}%II0>t*f+h{~;mQA5K&mi62fT zLGqXq#&H`A4QSbA(b#YyUL@R);=oq=ny&nJKWeyq<FJ0U^uh<<A2)u6BXwcUdPTY5 z-l!j}gyoEILpttMvm>h_YL&#YE#DZg<*1FAZrvTzw4hx<j&5q<fLl{0pFxqk*E$Br zE<7fdcTspNZlC$_weREStE1o=rNq6wz3<DuV;L`eI2s?sQE23L-C(lQ>mCVl!vGKb zes!mG4a43>^IiKwgQEwM>--!4seHqk7c0Xu1U~aTH&Gy!{>Aw4tg6#ciC{s4lk^DK z{=>nn0p2W&_XEY0N*%}p5UnEt+U-CR?+quANtxMRqc)2Rclb6T?M7Qs;5Im)pTkJA z90M;oaz=q~KBfx)Z#A0OW6S{Ee)HlX{~TzfDP6cE=*y#OEIMxy9g3aH9T(ii7a`Zj zovYLAneh%~>lVo@AaGdm{4ajQrzM^kWMSs*>@YgjHK^0WDLMPee7_r}w_vFH4&k)) zfF2(qXFNi+8Zm*6Jq)bv)|8(BjWi|(_1Uw~R`uM`iOF$lq|;3+43iC45QmMQPpb-X zV1%XdC4LM7()BUXh45)<cV2wX{&e%M@kvBy%}jBRdnZrLvjPb{sy#RIvq`IBY>y8- zPiZgy;ugZJ%hIEBYTf2_X=aDcA6`qnd!gR-7}~G(i5OY!kJ<LTlas~DWS^}IM%?mt zNoT5S>S{-$;=e<8CN+vzI+DJ^CHjt=x?OpHQLcr(WHWlaHfL5{o;0Xs)BkFScgs3P zw<zI8=6Gc}GbxgMSY%e6s=H~LU)S{nU{dngXbS0zpI{TV{}`VV0sk!+<dxb@4E#X> z@tlj!@rK*2IqwA}%#UM_6}`RjOe?-i-iY#Nc-BKFT)3x2+0YJH#qFdULqM_epLv}C zcg(vSrR2OH1my*>p6*b*>`sZ}gYQr<jfZtI+64Nr{y>qi;{6JR?|=xt#VY$A-sUX0 zBOhC->^<Is=Y*WkrV~%=G=R8*?Uv51G29q)6p84($WmIk;)T6kyVqsA-Bc>X@Z&8t zi0bu(2HtA&MgE?A6?E%i_a}~>Mb=mIslXa{_%o#ftTsVBOo)&f2s8oPfqOJgytdo3 zV!31KT7>&+6H~db!{vgm&6C_2)357i<LK`4q@U(8*hedL^J3WD=|xYl6+pntzn+=z z@z#jbeLam~_Izt8jv~1Ocu+;H_HJhJ@K47Ws)%3FU6Nj&FNhDg2yNK4y%j<r54geV z1#8<(rl0Q`5ect;#)m`s>YFD@^neRTfXEXhXuf}fi>Pe&h=&5-!9&TMyJl7<5b^CY zHpa74mz2=1|JltTMN!x}a?9(PS>!>h4G-mat1Sj(Y^1(^Wv&jMHKop89yxs35=dRE z_1h@ACU2HR<lG1ZLFANfO>?>6W=d#YiSK*yG{a;1G!0?8-V*%zLt!X#<-3U!81Zo5 zLzmL*#N1==uherL|Gk{+=|u@~x5U><X~BIVt;fClBEfJ8YMhSW!Wd|?N|KnnDz+T^ zStl9d#AYG6<lv(;oe-Zy?Zt3LxGkW%-i7X?SVCbwd_2}kaENTnZV`ZM?3o1rr%9Qn zM5Atn)f!AWEoiKQ=M>$QyK5;3a;id1L$p9G6J7l;_(ENUrVahh==z<5*Fg&jn^_~r zr8=WacHOKWZKcj{_81|Zjy8%;(`S7ivmIueC(n?3rX5$e+Y&6u8+TJNjPP7MORJQE zq;VFX0Tykkgj19w>hvQT<$PHvA6PMrLDiP2bl!h-!V5L@V}_V?hjJk`5aJ2W)Jl0M zj>okX5UPRET8NCZRt&VrS_(B5o(-c?rwN9~{wKoQfso*~TIN@T9@~!;c(oTpksItU z#&CJ`L72u;W+)ciajhcYZ=iXewDI7Ru!64QHnS&F#V;JN9Z!3WO9@?AUi`Me9O6!h z7cNG09R)|Lzmu!lq%ho~uK7O6BlpvUs)|pvD!-az9>zRe50PZe*|3$s8=LquH}E2> z{(|x<2RblNMY<SU8>4sE%A1t;Q5aBVwiqXh<)z|N<#39sBRYiEEOqu9!}`~3D?8di z%l@PaLrX9siAa*)tNRWq<p}rG9xb8hL()>#*h5#Ds+pg?ydi5Sh6gLiGwd%mKLs$G z1}^`kTC$X8(U@b^#Tk64-G#Jvn!+IUiR6@2WP>RsNQf&Tx14@C0Tp;`!8Eb6G^8|~ zk0jKH!RZGY59!Ry4Qh<0wAMhv1KDtejbDr`3bAi3ptu*&WN^R+NL=JPhKAPp{#<=G zO#cPO-=QE1VtT}$q@o&g@Bv?uAkL3A?Shgj=lEnoT6ge)Hs2Qn`$Wz%pHMi5v*99w zZ*a8|nv`%IoODJFZoihuHwmc2Y2MBe*_WCW_+^kTW!EH`yG)F-eHw4+7Cyw`Wx6vn zhctVh0CJ3-qY^-*V0_TrXWYQGipoOk1A7Z=PDf`0ip^mNaqjxBJ*Y_}&y!SwpQ5(u zK2M?`Z@MYD2=eUeN~lE%apv&8q&i#lqu%JZsVcsRLSK{irnq*mlEFUoAu|8sI3=$8 zH%b^AOVKeF0rXQ5n}<d!?Kn4P0z+(_ISf37`I%_dU@o5h^KB4db`YeqjFxE?;SASa z`fh|t75t&2zaH!JEhY>p&lMo71Pwfg1C%Gv5S*d%ULqe7VV_f2h!{~Jt0vMpils$0 ztzb+sUFv`25W(QgujsXK&frR}caWv~ya?@Wx<!@N?&4+ZJ9G1@Dm^zQ7X}}LLno}? z{=4mXBDqdNVy&sL=Nx<G(z?q=d4%?vT;XP0&5Ho*huwvA2fn}GL{<qHICt4Ae4=7E zHmzPYH>7s7=J7P|hYyGKGY}F^Dc=Z>fsb>36EiezBD_<_L}MMI#ABr~G??p&_~+t6 zcM%Pf#)|%7IRhNu>h0VXz-x1AcIV7ufH7#*u5tHV8Os<RkL+z`V=pcYzfJF^ZmHqc zA!%;S*r&99VtrtcskPR5g!QFnmKJKZCgLm<eV;vX7h5gUu>q)H7aq=j&C2=<&5gXD zd>*L7MFzc*FfdkWs(H?m=?yT4h}CcDsm`6jnUW3=bed%zSRUuc``TcYA_SKE$aCJP zZfF#fw>C|q*DZV*<MOOYY;cX}rfZOZN7I7byMl;w2Py)Z1aPf4+7C*R7}Y1Ej83FU zz*VEzDX}Up0c5X_1E%J5G2>uHk3$;DP?r11RfQ&483v0?@h+U3);LI$!D!_h^g*iB zh7*D+fZF7#?Xj7)t;nchC{eZy&d9~VVX8>nyNVJj?voITFU$Y~CHu~U3|qpTL{(Vq zt?%uYfn2xg($I^)qrevTQ$e){c_Zr6{l*1q&=6CUt+Mo((e5MRLVftWc2o$HTmYj> zDv!78iGMe|`7P6b$!llGXvj|Htf6SL$RydDKb~OTbw~~$L#+jyn8LxMWQaBz1PddH zcIdMVFep=@cNl-M^cv^WfFhXA{A*QsC)$fLFi&j5J>o^JIo?n`Z#I01niJKc7^$PQ zCUX@4v3deUEnxm8JkcHo0rsq_l;zdkUhh{V2TXdfwzakd-y!vzVLQeX&#gh(Y@?W9 z3m2=>NoxQZH2jW158W~aQ0PG>#K$2w9-*!hB*sKynz`ptPwrZQ4?;%9D%rqWKo!jV zA=!y-kg=Oi=GbJ1t^7IVlf;q<xr8%!DBy+<)4-|Y^fMFors~~bx<q0BJ`IiQf7enj zX8{6|@W&L7cL?zY1aA1hN9=`1iS%DgKyt?(7f|m;QrCxZVCw_tn=7(`D;=CrOjj{e zj^8h(Buhofr09N8h6^|ZR-$4bx+X`%kusB1y<S0Rf;$r8?5&dYt~e{y1##-c1$ejO z3H7>7MjqzUODeorajTJJZ6DWS9R@+c+3X&SfE)Ol2P92OWxR4Dvbn63%V7NC#MO48 zO2~PP^GTApk~apC%VT;$F8|go-Rj}QzOq1p`-LSYap-INI%}ncZ*}kaH^6A{PrV<x zG}*EYG*vTPYiZ~Bo{Sbf%|=MNOf41_CEjU-QT0cV<XlxnR^pJjOD>cS+V3eiCe_sF zDF~Xdy8=2R)1|Z5PqFVIUG;{48`r4p4`~8lGr!leCHgI16pE^tFfZP#qkjP@LNtP< z!m+1Qg@ur@XK!foOQ1}#0_z<AEx0Eey?50^5YFa2BU2K;AZ+1{t&`pB!A&KYG(D#n z82CYrQH8pw-euVTmhQ0oVad}oR6Ln6YsmQWiX{A{y~K!o7#W{OX(RmZ<IB<Un*pxl zLWUW}^$W~eeVy^t$iBJ?7uXLSA43Nw+o84m1fwmSU8IsG4bDHQ(vhV&t*KdLu&>|M z%wiAKmGe#X2s~_m1L3%8kloo_Pa_}WPY%pk-b6+sPrZN4WG9&`={v`uxAX5b&!b#$ z0S{&0zD|cN@9Iz!BWfLRUz|Ty+oIn<uq2;2sXQC%d6X)7zX~Tsn=i<iCYW>G(1|$> zm0N1V3n<}dD&$nEWD5OEB2EJ0<4k`Q%-sz#Us8&z2I2WH9cQA*|Kbcn4>-mECScph zbnWlUz&FR^OuF5qOmSheSh1S={_;=NrAH4t8$ac=NuKS|a*!>8IvZ2>t*+`Nm4~k* z7#Xn!Kt?0qALSQwIkhosWWH5IFr|fi;^fjTB_1dR9^k3_(g*!r-4xknz!YBnNF{Kn z3Wj}QtMD?4VBj|?Bp2}PXU!Z3F<n9f0mie&##{ESfY>6PnxHmp3BZ9N{ZNC^Gzh|> zRZd1QZY0v1r?3Yqjv9+6<sS7~@t7dmUh!4eKJ_rMf{i670&$`8n-En6j2(&+?w4Vy z4gGU>1RjxMNb?c9Z2J9z(R*58N>wKe>^A4rEuAtKX8pwLuESg~dn3|P7i>>Ro10%g z@s9%fjskTpr!sd(2Ho~PNF;u6NVyCLnlCP-3m8p>Zz5HnPjpqiz?9#>o7e#;*YZsm zdU*x@atIOY_YfBVy>2>gEWhUjTj@m&*zM@p)v26Myr!i`w>3jt_xNgd<#nao^730h zp%f=Tb`+Y3<1#Mj(tc+c{_(9V0>V@aAaAMUooHHq`EgU5*CSz1*kKsD<-pc7T<y=N z5zjV$a${hh9NQMiFgvt|as7O3gH&I$=w3}X3OMGQ*FJ|~Lna2b3kY6B&2q}c#gtp_ zra+XeEn9^XJt)fDd*~wkiv&T8s^S!iJcu?4HG6p#FW6{!oW1|}is}qmZ+?1RZZC#} z_U25q8ggLYp}fd&&e9cea07K+`Zx0#>B!@qZ83`T85TiW4dsWE6aI8&g0{4la-ck9 zo+hX)?FK5p1fHZbd$LWA#vo}VpclFI9GVkE$Cgb1S=)t3%psuLoZ*H)t)Y9_1Nv9- zK(@<{#R>=-F)?AND^BlHMDe)UC@w;NZNLm;wvAcJyQGX5_pA8nNmROFV4V-nC92|E zB9#r4vBfAN8i4q3lQh{d%M$9WlK)2n7`dB8@QyAU)PR<OaMmH6ETuISX*oC+*u#@l zFu@2d{Eo8>Zb7Y=?e(^)ES#6PTdW^*=kTeZJTjdX)&l1^oQcwy>L&zcuBNSYVg>!5 z081TlbKo<Twvs)`(DD2LWqaV(@EULB;VZ+pf-q;#B?>1VQx4usTcw=g$rAb?oSe8F zZ#a?|Isu8F2r^SY_+UC2`8c?p_6EpQ7<(179U2C@c!>Xd{K`kIH4+I71T+T%1VsJ+ z9=`&NO>K=WtsN{G4GoP=9Nk<E4gZZ}-Bjdl51HV4PBbG@{w~Prrm0|Hv>JwoHqyzR zmC%hOQ=vA*ncH<F`1iIZH@jFPIOSGT^7ov=8A!k|B?wDd61D(~;%@}-i)|J`Vk3in zp#_A4TxVY|+;tbT-$n@_ZJxu`ZcaipU&(HKeLGEB8^>z}&Gr)H`rYKMgtZRwHPN*s zgT%*yLVs{C<F1L0CbLpO@kddhZrI%N1*(XqoGMf2k2he>h4)dwRDyHPE%KTh!*eNW zp!B;Zg=)xHo1#2GcB?1k>QECiS7>dUA?>qS3pz4+Z3yh7Yjc(t#ayy(obRTHIjmMC z<6f>!=f)MG4eV5#+GnLKjW7GZOFe68Qo`I%gL;QhnMpy3Ivves<LGK}VX>5yPn{J- z!0vc-k&a^_+Oq&oEXq76;VYA+S&q(2d+6uw^YMJls^k&9BL|6&+LESo)5y=(qRK?& z{3~4zPiDIR-1>zL*hb3kA<{Za7{sy-VMeE{Ql<0#BP$q(0(^fxU6J%S?D8!E5b_$U ze*SZu9_XGnf%Q*M;D35j{dYaB9jyPiobm~RwnI#C!yf)HPHoLdB4>XK{2i$9^lM$I zhub3;u<U5Z?)!Z|c$67xFfaIJ1qHnkZ;ED_UIUa~{<H)2dt|UYE2+f8v5-JHPYDf@ z5KyizUzOX#`w&?wj$iKm>9OrA@w4{k>CyAn;UZ=@zI%GRb?2$ZEFCr_QFfQ_<5GSW z@u}zz#Nvrk6%syG&PMED2UP{L4JQem*SU2f!2s<17C~;V#6A65pY6xVSfi`}tw`oB zN71p}=0txZ-NGub+7Op8vCY!)VAEgwi77-eoz6dcm#1-#oWBzf^@MKf-G}jhntfMZ z$<#GHXD>+F1r|vEv(3?FYtewL&VWSE88czKq3?23P5k5;U2(tj50;(&2L7MXJ+_uP znEV%AJy0MZ%KsW&Q%8G%vFrb-6<lVdo(oO5XJU6`SpdWEu4vYw5>&~q3ROwO__ZB< zVJgQ$^<v3muLl`71$7NWlEq)|hmMe0$gKRfIH79?5y+X=LsU1Ww>Xm9zyN9lXc0q! z8wtCk&MGE&Ln;c~Zk>VBj-`M<wDm6^S(b93-i0RJ9{}GECx364(`fpzK6PD|2(~aY z?jh~RcccRN!P5w69+PGU_R4r;Ak+8AGO3XO{1GJVTLExR=HKtDbL&OZk=9s6Pjp~A z&I)QdSk?+M6^e$O^^-TpTCmJ3FMFFu9&1-dq}NqHU3F?R3wxkF+d+u&R2%$I=2b!p zCeWXQw|puSBzP?(>8E*rz2(&8bsEph!zm{rS*6x%22(WNO7`UYYpRA!8mL~}$Wkzj zkpn>(?HaP*rfEkS5d;<v%!-CEE9q79^NK{{JCrwB2ojs=*W#EQp&+q}_4+*)nWiXf zToPCsccJm{$IW|eS_PQBTE#WZ5+923TTwQgNi?hY$B*jQoDD{L7wT;4yq(X*1v+d; zJiS;fmOG344~TFxIVV&8jB9iUoS;gtjA4$ei{}NNhYBiI{7MrTT?O=~q(dLrMIDI@ z+SKf=-n6`f{%1bCe-)#+{L6<3a3CPs|C$djuFh_zu5QleF8^|3JDJ}xm<cJ&<0neB zDL_nlxj`k|uUMs+O17{z4HUASg`*{2>g|OcDHANE(DhV_apaHp4CBcv>l)gEFa>&0 z-l7hb5{vK^Q>advRUizQh%OJ4c9&<R*nXLLIz~UQ4rQzbYkT|+2@;R}V(x04uL7Ly zkh@EV=kL0ehrz(k?WPeW%}v^REo{p1wVt|kY}iO@+R%^$66gxODHdCqUB0S{)-mp} zMwT=oyBuY9;+qxZVrNQRV`McAoBIHTa^wlE!Vs7Gx!+4k&w=ZHMk0Hlrn{0+zZq{r zwPrxWX&!*N;G(~k;5qrdT%ynh&@mG!u-L@AJUwA(c#M#-c93~XcS4*!!*-XU{1k}) z=x-#>K||O}fXRDJ{n})lnH9T`2H)7ZP$z#F7qGMQeO7!cjvy{z?)8+UodO@ne{P%9 z`T>uZYzx_ez&ZXIkZSY4DmE4@jb$VI4vv?IH{FmTJ*1?>$7g$t@K_k*ApQXPPwj?a zrJ}x|fq)o^{y%Ej-q_jJ-1&d%R)W3hu*vnjZP;Iln5Gn)Fmnk6TEwvH&L3@*M3Lnh zG>j9LKjvDkfx%9e%9dr(>pQzAPD0K-etAfoHs*4&*Kx-F)=dkxjzLa-+hyIDlp?M` zE6iD3!I6U6Q6#4F2Q$Qed9rZE`IUR#h`FOs53M@0n?jI6l6kx`7UTo)<^h|WAS<)H zKYllQR5n>+tX082ld;q+45DC50W<!}Kex%E;M`g#OGCY`^c%fIib8khnM}Sd){aYF zRprulgnYafoEBGF^@|``-bpv#h`HjIvb0dSb7YVL97GlMY=HU)!=<Xe1xm)vRaZME z>a?cP`ce`zQivaDlbW=zp`}s4`3Q_NLY?ayeOZgz*7659x;(YGTnL!41A}=O$$7eY z%P;0Tf7O|pSLy?!SAW3D67yT?T~~~w$^C4YbZ3Veo1xroaey1wlUxF-h(U7HS0c84 zGFoh&G;C#w{E@GGXdn{%bhJG%fl(mCm5f|m)n+vv$JK-xi}YeO-QLu(89VVUCRWB` zjDHDVg!C;h*LG|9=`rd3ai~#hTX(es>`Wzp&0(3HVzAcY85EEnM5%%`B$SY?QEvKg zq@e>W19NlH^lVmwX|@s~rQT?mPgUWh9uRU5qeA*%S>$Ai{1KDUOlMGru3_7OvA6r| zPoGEGg@pz>Nmnmq)2sYlu_zA;^6gc?02l^~b2QlQLf@Mm7Wy(8LV3k9HrhQjwikqt z2$D*_Up#yHFL~u3`B5An36%F5q`nT6;jm1pf^x1=CbV<Z&A9}9|AG#%V;kJ!kV$>D zP`O2=IcHp3`B=bfcvYl^e=VoJ+O10PSw5g0s#^pRf%kGuJh;yVi_!B1@Q5YQ?K@0Z z^dcNoK%AVZl1Zb!fR;OFV2#seM-mR|DF+<>PRL`Fh#nL~e#i{L(~O#pOdx4nLJRnP z*;!1SIoYykocX6SQ55F!d(pKNxSUW<zlS%;^2spi!p6y|`xVd_QUr&-C5?r)f->>8 zsGDOH6yei`#35An)UyQ~5x*z$Y_*5{D}?R4HL(5>jqrakc8<NGMO~IYw(qfR+qQj= zZQHhO+qP}nwr%#UbkfONsigYD{sS{vYp*%xc*c~K%7EnTctzg9bs*X5nCBUzw5t{^ z!XSXCD;IHEO-C;q5;jPs&l6Jq*e~t<zCw`H5+uTR;j%w+gPNMZr>F}QV+naerVi3e zVf!dyr-(^<BAvXYffRS+hAxm`R?otwqfJfS(}%Zkw4i3r-Y;y}RW6M$x5U|UnYPjY zI1y;;p@Y$jj^<YDTnWWd*%`zRt#kU3dm1<N#Q0NJL8*yaVE{F0<=Z_Dkwj-KeN+`G zKGHM}o1CwOQ>~BoBZmG~lY*8yYMQ$cTY7r4oilq{)A(U~+uiEAvq^P(-OHO3S_0?o z(9!m0?H->);QIGpuMvn*IR_Wa0F=Y|cA6CGSDI|)u0<p3GYW8ms;5t{a@5^yP9M!( zbP5}NztQk%=i*ZE1el&b)pEdu+t#3!H^5rqLq^+)dhz!7fZV4Hiouy?D{k7thI1iu zM953VtToo~=i|uBzW%Ey_}^;0e!_nY|A3jpzLm&N%5m%0D#wMP#a3Oi;r%-dirw<N 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 diff --git a/venv/lib/python3.8/site-packages/setuptools.pth b/venv/lib/python3.8/site-packages/setuptools.pth deleted file mode 100644 index 61cb752..0000000 --- a/venv/lib/python3.8/site-packages/setuptools.pth +++ /dev/null @@ -1 +0,0 @@ -./setuptools-40.8.0-py3.8.egg diff --git a/venv/pyvenv.cfg b/venv/pyvenv.cfg deleted file mode 100644 index a8024a9..0000000 --- a/venv/pyvenv.cfg +++ /dev/null @@ -1,3 +0,0 @@ -home = /usr/local/bin -include-system-site-packages = false -version = 3.8.0