From d0d5665c8714272b4c33cd79b08c3e9e66108b57 Mon Sep 17 00:00:00 2001 From: Karthik Rao Date: Sat, 11 Nov 2017 18:08:09 -0500 Subject: [PATCH] upcoming sports games --- app.py | 8 + data.py | 1 + data.pyc | Bin 16578 -> 16709 bytes services/__init__.py | 1 + services/__init__.pyc | Bin 230 -> 317 bytes services/laundry/__init__.pyc | Bin 115 -> 163 bytes services/laundry/data.pyc | Bin 2478 -> 2526 bytes services/laundry/laundry.pyc | Bin 2172 -> 2460 bytes services/shuttle/__init__.pyc | Bin 115 -> 163 bytes services/shuttle/api.pyc | Bin 665 -> 761 bytes services/shuttle/shuttle.pyc | Bin 4743 -> 5559 bytes services/sports/__init__.py | 0 services/sports/__init__.pyc | Bin 0 -> 162 bytes services/sports/sports.py | 27 + services/sports/sports.pyc | Bin 0 -> 1398 bytes services/weather/__init__.pyc | Bin 115 -> 163 bytes services/weather/weather.pyc | Bin 1977 -> 2204 bytes venv/.Python | 1 + venv/bin/activate | 78 + venv/bin/activate.csh | 36 + venv/bin/activate.fish | 76 + venv/bin/activate_this.py | 34 + venv/bin/chardetect | 11 + venv/bin/easy_install | 11 + venv/bin/easy_install-2.7 | 11 + venv/bin/flask | 11 + venv/bin/nosetests | 11 + venv/bin/nosetests-2.7 | 11 + venv/bin/pip | 11 + venv/bin/pip2 | 11 + venv/bin/pip2.7 | 11 + venv/bin/pyjwt | 11 + venv/bin/python | Bin 0 -> 24960 bytes venv/bin/python-config | 78 + venv/bin/python2 | 1 + venv/bin/python2.7 | 1 + venv/bin/wheel | 11 + venv/include/python2.7 | 1 + venv/lib/python2.7/UserDict.py | 1 + venv/lib/python2.7/UserDict.pyc | Bin 0 -> 12096 bytes venv/lib/python2.7/_abcoll.py | 1 + venv/lib/python2.7/_abcoll.pyc | Bin 0 -> 31194 bytes venv/lib/python2.7/_weakrefset.py | 1 + venv/lib/python2.7/_weakrefset.pyc | Bin 0 -> 12222 bytes venv/lib/python2.7/abc.py | 1 + venv/lib/python2.7/abc.pyc | Bin 0 -> 6726 bytes venv/lib/python2.7/codecs.py | 1 + venv/lib/python2.7/codecs.pyc | Bin 0 -> 41166 bytes venv/lib/python2.7/config | 1 + venv/lib/python2.7/copy_reg.py | 1 + venv/lib/python2.7/copy_reg.pyc | Bin 0 -> 5696 bytes venv/lib/python2.7/distutils/__init__.py | 101 + venv/lib/python2.7/distutils/__init__.pyc | Bin 0 -> 3939 bytes venv/lib/python2.7/distutils/distutils.cfg | 6 + venv/lib/python2.7/encodings | 1 + venv/lib/python2.7/fnmatch.py | 1 + venv/lib/python2.7/fnmatch.pyc | Bin 0 -> 3890 bytes venv/lib/python2.7/genericpath.py | 1 + venv/lib/python2.7/genericpath.pyc | Bin 0 -> 4100 bytes venv/lib/python2.7/lib-dynload | 1 + venv/lib/python2.7/linecache.py | 1 + venv/lib/python2.7/linecache.pyc | Bin 0 -> 3590 bytes venv/lib/python2.7/locale.py | 1 + venv/lib/python2.7/locale.pyc | Bin 0 -> 56560 bytes .../lib/python2.7/no-global-site-packages.txt | 0 venv/lib/python2.7/ntpath.py | 1 + venv/lib/python2.7/orig-prefix.txt | 1 + venv/lib/python2.7/os.py | 1 + venv/lib/python2.7/os.pyc | Bin 0 -> 28508 bytes venv/lib/python2.7/posixpath.py | 1 + venv/lib/python2.7/posixpath.pyc | Bin 0 -> 12639 bytes venv/lib/python2.7/re.py | 1 + venv/lib/python2.7/re.pyc | Bin 0 -> 14379 bytes .../DESCRIPTION.rst | 3 + .../BeautifulSoup-3.2.1.dist-info/INSTALLER | 1 + .../BeautifulSoup-3.2.1.dist-info/METADATA | 23 + .../BeautifulSoup-3.2.1.dist-info/RECORD | 11 + .../BeautifulSoup-3.2.1.dist-info/WHEEL | 5 + .../metadata.json | 1 + .../top_level.txt | 2 + .../python2.7/site-packages/BeautifulSoup.py | 2017 +++++ .../python2.7/site-packages/BeautifulSoup.pyc | Bin 0 -> 76880 bytes .../site-packages/BeautifulSoupTests.py | 902 ++ .../site-packages/BeautifulSoupTests.pyc | Bin 0 -> 46699 bytes .../Flask-0.12.2.dist-info/DESCRIPTION.rst | 46 + .../Flask-0.12.2.dist-info/INSTALLER | 1 + .../Flask-0.12.2.dist-info/LICENSE.txt | 33 + .../Flask-0.12.2.dist-info/METADATA | 75 + .../Flask-0.12.2.dist-info/RECORD | 52 + .../Flask-0.12.2.dist-info/WHEEL | 6 + .../Flask-0.12.2.dist-info/entry_points.txt | 4 + .../Flask-0.12.2.dist-info/metadata.json | 1 + .../Flask-0.12.2.dist-info/top_level.txt | 1 + .../Jinja2-2.10.dist-info/DESCRIPTION.rst | 37 + .../Jinja2-2.10.dist-info/INSTALLER | 1 + .../Jinja2-2.10.dist-info/LICENSE.txt | 31 + .../Jinja2-2.10.dist-info/METADATA | 68 + .../Jinja2-2.10.dist-info/RECORD | 61 + .../site-packages/Jinja2-2.10.dist-info/WHEEL | 6 + .../Jinja2-2.10.dist-info/entry_points.txt | 4 + .../Jinja2-2.10.dist-info/metadata.json | 1 + .../Jinja2-2.10.dist-info/top_level.txt | 1 + .../MarkupSafe-1.0.dist-info/DESCRIPTION.rst | 115 + .../MarkupSafe-1.0.dist-info/INSTALLER | 1 + .../MarkupSafe-1.0.dist-info/LICENSE.txt | 33 + .../MarkupSafe-1.0.dist-info/METADATA | 135 + .../MarkupSafe-1.0.dist-info/RECORD | 18 + .../MarkupSafe-1.0.dist-info/WHEEL | 5 + .../MarkupSafe-1.0.dist-info/metadata.json | 1 + .../MarkupSafe-1.0.dist-info/top_level.txt | 1 + .../python2.7/site-packages/OpenSSL/SSL.py | 2241 +++++ .../python2.7/site-packages/OpenSSL/SSL.pyc | Bin 0 -> 86019 bytes .../site-packages/OpenSSL/__init__.py | 20 + .../site-packages/OpenSSL/__init__.pyc | Bin 0 -> 695 bytes .../python2.7/site-packages/OpenSSL/_util.py | 147 + .../python2.7/site-packages/OpenSSL/_util.pyc | Bin 0 -> 5499 bytes .../python2.7/site-packages/OpenSSL/crypto.py | 3042 +++++++ .../site-packages/OpenSSL/crypto.pyc | Bin 0 -> 110498 bytes .../python2.7/site-packages/OpenSSL/debug.py | 42 + .../python2.7/site-packages/OpenSSL/debug.pyc | Bin 0 -> 1418 bytes .../python2.7/site-packages/OpenSSL/tsafe.py | 31 + .../python2.7/site-packages/OpenSSL/tsafe.pyc | Bin 0 -> 2045 bytes .../site-packages/OpenSSL/version.py | 22 + .../site-packages/OpenSSL/version.pyc | Bin 0 -> 786 bytes .../PyJWT-1.5.3.dist-info/DESCRIPTION.rst | 76 + .../PyJWT-1.5.3.dist-info/INSTALLER | 1 + .../PyJWT-1.5.3.dist-info/METADATA | 110 + .../PyJWT-1.5.3.dist-info/RECORD | 33 + .../site-packages/PyJWT-1.5.3.dist-info/WHEEL | 6 + .../PyJWT-1.5.3.dist-info/entry_points.txt | 3 + .../PyJWT-1.5.3.dist-info/metadata.json | 1 + .../PyJWT-1.5.3.dist-info/top_level.txt | 1 + .../Werkzeug-0.12.2.dist-info/DESCRIPTION.rst | 54 + .../Werkzeug-0.12.2.dist-info/INSTALLER | 1 + .../Werkzeug-0.12.2.dist-info/LICENSE.txt | 29 + .../Werkzeug-0.12.2.dist-info/METADATA | 83 + .../Werkzeug-0.12.2.dist-info/RECORD | 95 + .../Werkzeug-0.12.2.dist-info/WHEEL | 6 + .../Werkzeug-0.12.2.dist-info/metadata.json | 1 + .../Werkzeug-0.12.2.dist-info/top_level.txt | 1 + .../python2.7/site-packages/_cffi_backend.so | Bin 0 -> 365472 bytes .../api-0.0.7.dist-info/DESCRIPTION.rst | 3 + .../api-0.0.7.dist-info/INSTALLER | 1 + .../api-0.0.7.dist-info/METADATA | 16 + .../site-packages/api-0.0.7.dist-info/RECORD | 11 + .../site-packages/api-0.0.7.dist-info/WHEEL | 5 + .../api-0.0.7.dist-info/metadata.json | 1 + .../api-0.0.7.dist-info/top_level.txt | 1 + .../python2.7/site-packages/api/__init__.py | 1 + .../python2.7/site-packages/api/__init__.pyc | Bin 0 -> 214 bytes venv/lib/python2.7/site-packages/api/api.py | 87 + venv/lib/python2.7/site-packages/api/api.pyc | Bin 0 -> 4403 bytes .../DESCRIPTION.rst | 3 + .../asn1crypto-0.23.0.dist-info/INSTALLER | 1 + .../asn1crypto-0.23.0.dist-info/METADATA | 27 + .../asn1crypto-0.23.0.dist-info/RECORD | 61 + .../asn1crypto-0.23.0.dist-info/WHEEL | 6 + .../asn1crypto-0.23.0.dist-info/metadata.json | 1 + .../asn1crypto-0.23.0.dist-info/top_level.txt | 1 + .../site-packages/asn1crypto/__init__.py | 9 + .../site-packages/asn1crypto/__init__.pyc | Bin 0 -> 504 bytes .../asn1crypto/_elliptic_curve.py | 314 + .../asn1crypto/_elliptic_curve.pyc | Bin 0 -> 9525 bytes .../site-packages/asn1crypto/_errors.py | 45 + .../site-packages/asn1crypto/_errors.pyc | Bin 0 -> 1290 bytes .../site-packages/asn1crypto/_ffi.py | 45 + .../site-packages/asn1crypto/_ffi.pyc | Bin 0 -> 1958 bytes .../site-packages/asn1crypto/_inet.py | 170 + .../site-packages/asn1crypto/_inet.pyc | Bin 0 -> 4356 bytes .../site-packages/asn1crypto/_int.py | 159 + .../site-packages/asn1crypto/_int.pyc | Bin 0 -> 4753 bytes .../site-packages/asn1crypto/_iri.py | 288 + .../site-packages/asn1crypto/_iri.pyc | Bin 0 -> 8246 bytes .../site-packages/asn1crypto/_ordereddict.py | 135 + .../site-packages/asn1crypto/_ordereddict.pyc | Bin 0 -> 5529 bytes .../asn1crypto/_perf/__init__.py | 0 .../asn1crypto/_perf/__init__.pyc | Bin 0 -> 200 bytes .../asn1crypto/_perf/_big_num_ctypes.py | 69 + .../asn1crypto/_perf/_big_num_ctypes.pyc | Bin 0 -> 1878 bytes .../asn1crypto/_teletex_codec.py | 331 + .../asn1crypto/_teletex_codec.pyc | Bin 0 -> 4375 bytes .../site-packages/asn1crypto/_types.py | 46 + .../site-packages/asn1crypto/_types.pyc | Bin 0 -> 1714 bytes .../site-packages/asn1crypto/algos.py | 1115 +++ .../site-packages/asn1crypto/algos.pyc | Bin 0 -> 34318 bytes .../python2.7/site-packages/asn1crypto/cms.py | 930 ++ .../site-packages/asn1crypto/cms.pyc | Bin 0 -> 40980 bytes .../site-packages/asn1crypto/core.py | 5234 +++++++++++ .../site-packages/asn1crypto/core.pyc | Bin 0 -> 146373 bytes .../python2.7/site-packages/asn1crypto/crl.py | 536 ++ .../site-packages/asn1crypto/crl.pyc | Bin 0 -> 19997 bytes .../python2.7/site-packages/asn1crypto/csr.py | 96 + .../site-packages/asn1crypto/csr.pyc | Bin 0 -> 4316 bytes .../site-packages/asn1crypto/keys.py | 1245 +++ .../site-packages/asn1crypto/keys.pyc | Bin 0 -> 39233 bytes .../site-packages/asn1crypto/ocsp.py | 652 ++ .../site-packages/asn1crypto/ocsp.pyc | Bin 0 -> 26120 bytes .../site-packages/asn1crypto/parser.py | 289 + .../site-packages/asn1crypto/parser.pyc | Bin 0 -> 8012 bytes .../python2.7/site-packages/asn1crypto/pdf.py | 84 + .../site-packages/asn1crypto/pdf.pyc | Bin 0 -> 3981 bytes .../python2.7/site-packages/asn1crypto/pem.py | 222 + .../site-packages/asn1crypto/pem.pyc | Bin 0 -> 6199 bytes .../site-packages/asn1crypto/pkcs12.py | 193 + .../site-packages/asn1crypto/pkcs12.pyc | Bin 0 -> 8297 bytes .../python2.7/site-packages/asn1crypto/tsp.py | 310 + .../site-packages/asn1crypto/tsp.pyc | Bin 0 -> 13989 bytes .../site-packages/asn1crypto/util.py | 712 ++ .../site-packages/asn1crypto/util.pyc | Bin 0 -> 22571 bytes .../site-packages/asn1crypto/version.py | 6 + .../site-packages/asn1crypto/version.pyc | Bin 0 -> 434 bytes .../site-packages/asn1crypto/x509.py | 2728 ++++++ .../site-packages/asn1crypto/x509.pyc | Bin 0 -> 99727 bytes .../DESCRIPTION.rst | 3 + .../beautifulsoup4-4.6.0.dist-info/INSTALLER | 1 + .../beautifulsoup4-4.6.0.dist-info/METADATA | 28 + .../beautifulsoup4-4.6.0.dist-info/RECORD | 41 + .../beautifulsoup4-4.6.0.dist-info/WHEEL | 5 + .../metadata.json | 1 + .../top_level.txt | 1 + .../bs4-0.0.1.dist-info/DESCRIPTION.rst | 3 + .../bs4-0.0.1.dist-info/INSTALLER | 1 + .../bs4-0.0.1.dist-info/METADATA | 26 + .../site-packages/bs4-0.0.1.dist-info/RECORD | 7 + .../site-packages/bs4-0.0.1.dist-info/WHEEL | 5 + .../bs4-0.0.1.dist-info/metadata.json | 1 + .../bs4-0.0.1.dist-info/top_level.txt | 1 + .../python2.7/site-packages/bs4/__init__.py | 529 ++ .../python2.7/site-packages/bs4/__init__.pyc | Bin 0 -> 18390 bytes .../site-packages/bs4/builder/__init__.py | 333 + .../site-packages/bs4/builder/__init__.pyc | Bin 0 -> 12500 bytes .../site-packages/bs4/builder/_html5lib.py | 426 + .../site-packages/bs4/builder/_html5lib.pyc | Bin 0 -> 17021 bytes .../site-packages/bs4/builder/_htmlparser.py | 314 + .../site-packages/bs4/builder/_htmlparser.pyc | Bin 0 -> 10931 bytes .../site-packages/bs4/builder/_lxml.py | 258 + .../site-packages/bs4/builder/_lxml.pyc | Bin 0 -> 9698 bytes .../lib/python2.7/site-packages/bs4/dammit.py | 842 ++ .../python2.7/site-packages/bs4/dammit.pyc | Bin 0 -> 24040 bytes .../python2.7/site-packages/bs4/diagnose.py | 219 + .../python2.7/site-packages/bs4/diagnose.pyc | Bin 0 -> 10275 bytes .../python2.7/site-packages/bs4/element.py | 1808 ++++ .../python2.7/site-packages/bs4/element.pyc | Bin 0 -> 66068 bytes .../python2.7/site-packages/bs4/testing.py | 770 ++ .../python2.7/site-packages/bs4/testing.pyc | Bin 0 -> 38579 bytes .../site-packages/bs4/tests/__init__.py | 1 + .../site-packages/bs4/tests/__init__.pyc | Bin 0 -> 244 bytes .../bs4/tests/test_builder_registry.py | 147 + .../bs4/tests/test_builder_registry.pyc | Bin 0 -> 6893 bytes .../site-packages/bs4/tests/test_docs.py | 36 + .../site-packages/bs4/tests/test_docs.pyc | Bin 0 -> 530 bytes .../site-packages/bs4/tests/test_html5lib.py | 130 + .../site-packages/bs4/tests/test_html5lib.pyc | Bin 0 -> 6757 bytes .../bs4/tests/test_htmlparser.py | 34 + .../bs4/tests/test_htmlparser.pyc | Bin 0 -> 2522 bytes .../site-packages/bs4/tests/test_lxml.py | 76 + .../site-packages/bs4/tests/test_lxml.pyc | Bin 0 -> 3866 bytes .../site-packages/bs4/tests/test_soup.py | 501 ++ .../site-packages/bs4/tests/test_soup.pyc | Bin 0 -> 28729 bytes .../site-packages/bs4/tests/test_tree.py | 2050 +++++ .../site-packages/bs4/tests/test_tree.pyc | Bin 0 -> 112860 bytes .../DESCRIPTION.rst | 49 + .../certifi-2017.11.5.dist-info/INSTALLER | 1 + .../certifi-2017.11.5.dist-info/METADATA | 71 + .../certifi-2017.11.5.dist-info/RECORD | 16 + .../certifi-2017.11.5.dist-info/WHEEL | 6 + .../certifi-2017.11.5.dist-info/metadata.json | 1 + .../certifi-2017.11.5.dist-info/top_level.txt | 1 + .../site-packages/certifi/__init__.py | 3 + .../site-packages/certifi/__init__.pyc | Bin 0 -> 302 bytes .../site-packages/certifi/__main__.py | 2 + .../site-packages/certifi/__main__.pyc | Bin 0 -> 251 bytes .../site-packages/certifi/cacert.pem | 4605 ++++++++++ .../python2.7/site-packages/certifi/core.py | 37 + .../python2.7/site-packages/certifi/core.pyc | Bin 0 -> 1515 bytes .../site-packages/certifi/old_root.pem | 414 + .../python2.7/site-packages/certifi/weak.pem | 5019 +++++++++++ .../cffi-1.11.2.dist-info/DESCRIPTION.rst | 12 + .../cffi-1.11.2.dist-info/INSTALLER | 1 + .../cffi-1.11.2.dist-info/METADATA | 36 + .../cffi-1.11.2.dist-info/RECORD | 43 + .../site-packages/cffi-1.11.2.dist-info/WHEEL | 5 + .../cffi-1.11.2.dist-info/entry_points.txt | 3 + .../cffi-1.11.2.dist-info/metadata.json | 1 + .../cffi-1.11.2.dist-info/top_level.txt | 2 + .../python2.7/site-packages/cffi/__init__.py | 13 + .../python2.7/site-packages/cffi/__init__.pyc | Bin 0 -> 580 bytes .../site-packages/cffi/_cffi_errors.h | 145 + .../site-packages/cffi/_cffi_include.h | 298 + .../python2.7/site-packages/cffi/_embedding.h | 536 ++ venv/lib/python2.7/site-packages/cffi/api.py | 925 ++ venv/lib/python2.7/site-packages/cffi/api.pyc | Bin 0 -> 40514 bytes .../site-packages/cffi/backend_ctypes.py | 1114 +++ .../site-packages/cffi/backend_ctypes.pyc | Bin 0 -> 54012 bytes .../site-packages/cffi/cffi_opcode.py | 187 + .../site-packages/cffi/cffi_opcode.pyc | Bin 0 -> 6287 bytes .../site-packages/cffi/commontypes.py | 80 + .../site-packages/cffi/commontypes.pyc | Bin 0 -> 2514 bytes .../python2.7/site-packages/cffi/cparser.py | 891 ++ .../python2.7/site-packages/cffi/cparser.pyc | Bin 0 -> 27005 bytes .../lib/python2.7/site-packages/cffi/error.py | 23 + .../python2.7/site-packages/cffi/error.pyc | Bin 0 -> 1794 bytes .../site-packages/cffi/ffiplatform.py | 127 + .../site-packages/cffi/ffiplatform.pyc | Bin 0 -> 5005 bytes venv/lib/python2.7/site-packages/cffi/lock.py | 30 + .../lib/python2.7/site-packages/cffi/lock.pyc | Bin 0 -> 485 bytes .../lib/python2.7/site-packages/cffi/model.py | 612 ++ .../python2.7/site-packages/cffi/model.pyc | Bin 0 -> 27509 bytes .../site-packages/cffi/parse_c_type.h | 181 + .../site-packages/cffi/recompiler.py | 1553 ++++ .../site-packages/cffi/recompiler.pyc | Bin 0 -> 60739 bytes .../site-packages/cffi/setuptools_ext.py | 188 + .../site-packages/cffi/setuptools_ext.pyc | Bin 0 -> 8689 bytes .../site-packages/cffi/vengine_cpy.py | 1015 +++ .../site-packages/cffi/vengine_cpy.pyc | Bin 0 -> 40251 bytes .../site-packages/cffi/vengine_gen.py | 675 ++ .../site-packages/cffi/vengine_gen.pyc | Bin 0 -> 26889 bytes .../python2.7/site-packages/cffi/verifier.py | 307 + .../python2.7/site-packages/cffi/verifier.pyc | Bin 0 -> 12296 bytes .../chardet-3.0.4.dist-info/DESCRIPTION.rst | 70 + .../chardet-3.0.4.dist-info/INSTALLER | 1 + .../chardet-3.0.4.dist-info/METADATA | 96 + .../chardet-3.0.4.dist-info/RECORD | 91 + .../chardet-3.0.4.dist-info/WHEEL | 6 + .../chardet-3.0.4.dist-info/entry_points.txt | 3 + .../chardet-3.0.4.dist-info/metadata.json | 1 + .../chardet-3.0.4.dist-info/top_level.txt | 1 + .../site-packages/chardet/__init__.py | 39 + .../site-packages/chardet/__init__.pyc | Bin 0 -> 1068 bytes .../site-packages/chardet/big5freq.py | 386 + .../site-packages/chardet/big5freq.pyc | Bin 0 -> 54738 bytes .../site-packages/chardet/big5prober.py | 47 + .../site-packages/chardet/big5prober.pyc | Bin 0 -> 1542 bytes .../site-packages/chardet/chardistribution.py | 233 + .../chardet/chardistribution.pyc | Bin 0 -> 8813 bytes .../chardet/charsetgroupprober.py | 106 + .../chardet/charsetgroupprober.pyc | Bin 0 -> 3169 bytes .../site-packages/chardet/charsetprober.py | 145 + .../site-packages/chardet/charsetprober.pyc | Bin 0 -> 4556 bytes .../site-packages/chardet/cli/__init__.py | 1 + .../site-packages/chardet/cli/__init__.pyc | Bin 0 -> 192 bytes .../site-packages/chardet/cli/chardetect.py | 85 + .../site-packages/chardet/cli/chardetect.pyc | Bin 0 -> 3265 bytes .../chardet/codingstatemachine.py | 88 + .../chardet/codingstatemachine.pyc | Bin 0 -> 3656 bytes .../python2.7/site-packages/chardet/compat.py | 34 + .../site-packages/chardet/compat.pyc | Bin 0 -> 441 bytes .../site-packages/chardet/cp949prober.py | 49 + .../site-packages/chardet/cp949prober.pyc | Bin 0 -> 1550 bytes .../python2.7/site-packages/chardet/enums.py | 76 + .../python2.7/site-packages/chardet/enums.pyc | Bin 0 -> 3425 bytes .../site-packages/chardet/escprober.py | 101 + .../site-packages/chardet/escprober.pyc | Bin 0 -> 3527 bytes .../python2.7/site-packages/chardet/escsm.py | 246 + .../python2.7/site-packages/chardet/escsm.pyc | Bin 0 -> 8052 bytes .../site-packages/chardet/eucjpprober.py | 92 + .../site-packages/chardet/eucjpprober.pyc | Bin 0 -> 3342 bytes .../site-packages/chardet/euckrfreq.py | 195 + .../site-packages/chardet/euckrfreq.pyc | Bin 0 -> 24124 bytes .../site-packages/chardet/euckrprober.py | 47 + .../site-packages/chardet/euckrprober.pyc | Bin 0 -> 1551 bytes .../site-packages/chardet/euctwfreq.py | 387 + .../site-packages/chardet/euctwfreq.pyc | Bin 0 -> 54747 bytes .../site-packages/chardet/euctwprober.py | 46 + .../site-packages/chardet/euctwprober.pyc | Bin 0 -> 1551 bytes .../site-packages/chardet/gb2312freq.py | 283 + .../site-packages/chardet/gb2312freq.pyc | Bin 0 -> 38389 bytes .../site-packages/chardet/gb2312prober.py | 46 + .../site-packages/chardet/gb2312prober.pyc | Bin 0 -> 1560 bytes .../site-packages/chardet/hebrewprober.py | 292 + .../site-packages/chardet/hebrewprober.pyc | Bin 0 -> 4221 bytes .../site-packages/chardet/jisfreq.py | 325 + .../site-packages/chardet/jisfreq.pyc | Bin 0 -> 44533 bytes .../python2.7/site-packages/chardet/jpcntx.py | 233 + .../site-packages/chardet/jpcntx.pyc | Bin 0 -> 25848 bytes .../chardet/langbulgarianmodel.py | 228 + .../chardet/langbulgarianmodel.pyc | Bin 0 -> 25001 bytes .../chardet/langcyrillicmodel.py | 333 + .../chardet/langcyrillicmodel.pyc | Bin 0 -> 30721 bytes .../site-packages/chardet/langgreekmodel.py | 225 + .../site-packages/chardet/langgreekmodel.pyc | Bin 0 -> 24676 bytes .../site-packages/chardet/langhebrewmodel.py | 200 + .../site-packages/chardet/langhebrewmodel.pyc | Bin 0 -> 23487 bytes .../chardet/langhungarianmodel.py | 225 + .../chardet/langhungarianmodel.pyc | Bin 0 -> 24971 bytes .../site-packages/chardet/langthaimodel.py | 199 + .../site-packages/chardet/langthaimodel.pyc | Bin 0 -> 23466 bytes .../site-packages/chardet/langturkishmodel.py | 193 + .../chardet/langturkishmodel.pyc | Bin 0 -> 23483 bytes .../site-packages/chardet/latin1prober.py | 145 + .../site-packages/chardet/latin1prober.pyc | Bin 0 -> 4037 bytes .../site-packages/chardet/mbcharsetprober.py | 91 + .../site-packages/chardet/mbcharsetprober.pyc | Bin 0 -> 3091 bytes .../site-packages/chardet/mbcsgroupprober.py | 54 + .../site-packages/chardet/mbcsgroupprober.pyc | Bin 0 -> 1447 bytes .../python2.7/site-packages/chardet/mbcssm.py | 572 ++ .../site-packages/chardet/mbcssm.pyc | Bin 0 -> 19158 bytes .../site-packages/chardet/sbcharsetprober.py | 132 + .../site-packages/chardet/sbcharsetprober.pyc | Bin 0 -> 3970 bytes .../site-packages/chardet/sbcsgroupprober.py | 73 + .../site-packages/chardet/sbcsgroupprober.pyc | Bin 0 -> 2040 bytes .../site-packages/chardet/sjisprober.py | 92 + .../site-packages/chardet/sjisprober.pyc | Bin 0 -> 3363 bytes .../chardet/universaldetector.py | 286 + .../chardet/universaldetector.pyc | Bin 0 -> 7343 bytes .../site-packages/chardet/utf8prober.py | 82 + .../site-packages/chardet/utf8prober.pyc | Bin 0 -> 2812 bytes .../site-packages/chardet/version.py | 9 + .../site-packages/chardet/version.pyc | Bin 0 -> 468 bytes .../click-6.7.dist-info/DESCRIPTION.rst | 3 + .../click-6.7.dist-info/INSTALLER | 1 + .../click-6.7.dist-info/METADATA | 16 + .../site-packages/click-6.7.dist-info/RECORD | 41 + .../site-packages/click-6.7.dist-info/WHEEL | 6 + .../click-6.7.dist-info/metadata.json | 1 + .../click-6.7.dist-info/top_level.txt | 1 + .../python2.7/site-packages/click/__init__.py | 98 + .../site-packages/click/__init__.pyc | Bin 0 -> 3234 bytes .../site-packages/click/_bashcomplete.py | 83 + .../site-packages/click/_bashcomplete.pyc | Bin 0 -> 3339 bytes .../python2.7/site-packages/click/_compat.py | 648 ++ .../python2.7/site-packages/click/_compat.pyc | Bin 0 -> 24163 bytes .../site-packages/click/_termui_impl.py | 547 ++ .../site-packages/click/_termui_impl.pyc | Bin 0 -> 18441 bytes .../site-packages/click/_textwrap.py | 38 + .../site-packages/click/_textwrap.pyc | Bin 0 -> 1845 bytes .../site-packages/click/_unicodefun.py | 118 + .../site-packages/click/_unicodefun.pyc | Bin 0 -> 4168 bytes .../site-packages/click/_winconsole.py | 273 + .../site-packages/click/_winconsole.pyc | Bin 0 -> 10730 bytes .../lib/python2.7/site-packages/click/core.py | 1744 ++++ .../python2.7/site-packages/click/core.pyc | Bin 0 -> 70513 bytes .../site-packages/click/decorators.py | 304 + .../site-packages/click/decorators.pyc | Bin 0 -> 14776 bytes .../site-packages/click/exceptions.py | 201 + .../site-packages/click/exceptions.pyc | Bin 0 -> 10616 bytes .../site-packages/click/formatting.py | 256 + .../site-packages/click/formatting.pyc | Bin 0 -> 11231 bytes .../python2.7/site-packages/click/globals.py | 48 + .../python2.7/site-packages/click/globals.pyc | Bin 0 -> 2427 bytes .../python2.7/site-packages/click/parser.py | 426 + .../python2.7/site-packages/click/parser.pyc | Bin 0 -> 14449 bytes .../python2.7/site-packages/click/termui.py | 539 ++ .../python2.7/site-packages/click/termui.pyc | Bin 0 -> 21815 bytes .../python2.7/site-packages/click/testing.py | 322 + .../python2.7/site-packages/click/testing.pyc | Bin 0 -> 13195 bytes .../python2.7/site-packages/click/types.py | 550 ++ .../python2.7/site-packages/click/types.pyc | Bin 0 -> 23559 bytes .../python2.7/site-packages/click/utils.py | 415 + .../python2.7/site-packages/click/utils.pyc | Bin 0 -> 17703 bytes .../DESCRIPTION.rst | 66 + .../cryptography-2.1.3.dist-info/INSTALLER | 1 + .../cryptography-2.1.3.dist-info/METADATA | 121 + .../cryptography-2.1.3.dist-info/RECORD | 146 + .../cryptography-2.1.3.dist-info/WHEEL | 5 + .../metadata.json | 1 + .../top_level.txt | 4 + .../site-packages/cryptography/__about__.py | 23 + .../site-packages/cryptography/__about__.pyc | Bin 0 -> 913 bytes .../site-packages/cryptography/__init__.py | 27 + .../site-packages/cryptography/__init__.pyc | Bin 0 -> 983 bytes .../site-packages/cryptography/exceptions.py | 57 + .../site-packages/cryptography/exceptions.pyc | Bin 0 -> 3658 bytes .../site-packages/cryptography/fernet.py | 143 + .../site-packages/cryptography/fernet.pyc | Bin 0 -> 5922 bytes .../cryptography/hazmat/__init__.py | 11 + .../cryptography/hazmat/__init__.pyc | Bin 0 -> 581 bytes .../cryptography/hazmat/backends/__init__.py | 18 + .../cryptography/hazmat/backends/__init__.pyc | Bin 0 -> 737 bytes .../hazmat/backends/interfaces.py | 395 + .../hazmat/backends/interfaces.pyc | Bin 0 -> 23614 bytes .../hazmat/backends/openssl/__init__.py | 10 + .../hazmat/backends/openssl/__init__.pyc | Bin 0 -> 459 bytes .../hazmat/backends/openssl/aead.py | 159 + .../hazmat/backends/openssl/aead.pyc | Bin 0 -> 5421 bytes .../hazmat/backends/openssl/backend.py | 1970 +++++ .../hazmat/backends/openssl/backend.pyc | Bin 0 -> 72031 bytes .../hazmat/backends/openssl/ciphers.py | 220 + .../hazmat/backends/openssl/ciphers.pyc | Bin 0 -> 7189 bytes .../hazmat/backends/openssl/cmac.py | 80 + .../hazmat/backends/openssl/cmac.pyc | Bin 0 -> 3808 bytes .../hazmat/backends/openssl/decode_asn1.py | 820 ++ .../hazmat/backends/openssl/decode_asn1.pyc | Bin 0 -> 31791 bytes .../hazmat/backends/openssl/dh.py | 280 + .../hazmat/backends/openssl/dh.pyc | Bin 0 -> 12127 bytes .../hazmat/backends/openssl/dsa.py | 269 + .../hazmat/backends/openssl/dsa.pyc | Bin 0 -> 13239 bytes .../hazmat/backends/openssl/ec.py | 298 + .../hazmat/backends/openssl/ec.pyc | Bin 0 -> 13885 bytes .../hazmat/backends/openssl/encode_asn1.py | 606 ++ .../hazmat/backends/openssl/encode_asn1.pyc | Bin 0 -> 22489 bytes .../hazmat/backends/openssl/hashes.py | 61 + .../hazmat/backends/openssl/hashes.pyc | Bin 0 -> 3311 bytes .../hazmat/backends/openssl/hmac.py | 73 + .../hazmat/backends/openssl/hmac.pyc | Bin 0 -> 3882 bytes .../hazmat/backends/openssl/rsa.py | 476 + .../hazmat/backends/openssl/rsa.pyc | Bin 0 -> 18552 bytes .../hazmat/backends/openssl/utils.py | 45 + .../hazmat/backends/openssl/utils.pyc | Bin 0 -> 2070 bytes .../hazmat/backends/openssl/x25519.py | 71 + .../hazmat/backends/openssl/x25519.pyc | Bin 0 -> 3846 bytes .../hazmat/backends/openssl/x509.py | 499 ++ .../hazmat/backends/openssl/x509.pyc | Bin 0 -> 27728 bytes .../cryptography/hazmat/bindings/__init__.py | 5 + .../cryptography/hazmat/bindings/__init__.pyc | Bin 0 -> 334 bytes .../hazmat/bindings/_constant_time.so | Bin 0 -> 22708 bytes .../cryptography/hazmat/bindings/_openssl.so | Bin 0 -> 3425148 bytes .../cryptography/hazmat/bindings/_padding.so | Bin 0 -> 27268 bytes .../hazmat/bindings/openssl/__init__.py | 5 + .../hazmat/bindings/openssl/__init__.pyc | Bin 0 -> 342 bytes .../hazmat/bindings/openssl/_conditional.py | 303 + .../hazmat/bindings/openssl/_conditional.pyc | Bin 0 -> 11929 bytes .../hazmat/bindings/openssl/binding.py | 156 + .../hazmat/bindings/openssl/binding.pyc | Bin 0 -> 6340 bytes .../hazmat/primitives/__init__.py | 5 + .../hazmat/primitives/__init__.pyc | Bin 0 -> 336 bytes .../hazmat/primitives/asymmetric/__init__.py | 40 + .../hazmat/primitives/asymmetric/__init__.pyc | Bin 0 -> 2452 bytes .../hazmat/primitives/asymmetric/dh.py | 212 + .../hazmat/primitives/asymmetric/dh.pyc | Bin 0 -> 11425 bytes .../hazmat/primitives/asymmetric/dsa.py | 254 + .../hazmat/primitives/asymmetric/dsa.pyc | Bin 0 -> 14350 bytes .../hazmat/primitives/asymmetric/ec.py | 389 + .../hazmat/primitives/asymmetric/ec.pyc | Bin 0 -> 20343 bytes .../hazmat/primitives/asymmetric/padding.py | 79 + .../hazmat/primitives/asymmetric/padding.pyc | Bin 0 -> 4553 bytes .../hazmat/primitives/asymmetric/rsa.py | 368 + .../hazmat/primitives/asymmetric/rsa.pyc | Bin 0 -> 15974 bytes .../hazmat/primitives/asymmetric/utils.py | 60 + .../hazmat/primitives/asymmetric/utils.pyc | Bin 0 -> 3139 bytes .../hazmat/primitives/asymmetric/x25519.py | 54 + .../hazmat/primitives/asymmetric/x25519.pyc | Bin 0 -> 3325 bytes .../hazmat/primitives/ciphers/__init__.py | 21 + .../hazmat/primitives/ciphers/__init__.pyc | Bin 0 -> 722 bytes .../hazmat/primitives/ciphers/aead.py | 162 + .../hazmat/primitives/ciphers/aead.pyc | Bin 0 -> 8237 bytes .../hazmat/primitives/ciphers/algorithms.py | 165 + .../hazmat/primitives/ciphers/algorithms.pyc | Bin 0 -> 9740 bytes .../hazmat/primitives/ciphers/base.py | 235 + .../hazmat/primitives/ciphers/base.pyc | Bin 0 -> 13415 bytes .../hazmat/primitives/ciphers/modes.py | 228 + .../hazmat/primitives/ciphers/modes.pyc | Bin 0 -> 12004 bytes .../cryptography/hazmat/primitives/cmac.py | 66 + .../cryptography/hazmat/primitives/cmac.pyc | Bin 0 -> 3332 bytes .../hazmat/primitives/constant_time.py | 26 + .../hazmat/primitives/constant_time.pyc | Bin 0 -> 1300 bytes .../cryptography/hazmat/primitives/hashes.py | 191 + .../cryptography/hazmat/primitives/hashes.pyc | Bin 0 -> 9167 bytes .../cryptography/hazmat/primitives/hmac.py | 69 + .../cryptography/hazmat/primitives/hmac.pyc | Bin 0 -> 3462 bytes .../hazmat/primitives/kdf/__init__.py | 26 + .../hazmat/primitives/kdf/__init__.pyc | Bin 0 -> 1557 bytes .../hazmat/primitives/kdf/concatkdf.py | 125 + .../hazmat/primitives/kdf/concatkdf.pyc | Bin 0 -> 6198 bytes .../hazmat/primitives/kdf/hkdf.py | 116 + .../hazmat/primitives/kdf/hkdf.pyc | Bin 0 -> 5217 bytes .../hazmat/primitives/kdf/kbkdf.py | 148 + .../hazmat/primitives/kdf/kbkdf.pyc | Bin 0 -> 5803 bytes .../hazmat/primitives/kdf/pbkdf2.py | 58 + .../hazmat/primitives/kdf/pbkdf2.pyc | Bin 0 -> 2918 bytes .../hazmat/primitives/kdf/scrypt.py | 66 + .../hazmat/primitives/kdf/scrypt.pyc | Bin 0 -> 3062 bytes .../hazmat/primitives/kdf/x963kdf.py | 70 + .../hazmat/primitives/kdf/x963kdf.pyc | Bin 0 -> 3418 bytes .../cryptography/hazmat/primitives/keywrap.py | 92 + .../hazmat/primitives/keywrap.pyc | Bin 0 -> 3831 bytes .../cryptography/hazmat/primitives/mac.py | 37 + .../cryptography/hazmat/primitives/mac.pyc | Bin 0 -> 1991 bytes .../cryptography/hazmat/primitives/padding.py | 202 + .../hazmat/primitives/padding.pyc | Bin 0 -> 11206 bytes .../hazmat/primitives/serialization.py | 209 + .../hazmat/primitives/serialization.pyc | Bin 0 -> 9910 bytes .../hazmat/primitives/twofactor/__init__.py | 9 + .../hazmat/primitives/twofactor/__init__.pyc | Bin 0 -> 649 bytes .../hazmat/primitives/twofactor/hotp.py | 68 + .../hazmat/primitives/twofactor/hotp.pyc | Bin 0 -> 3955 bytes .../hazmat/primitives/twofactor/totp.py | 40 + .../hazmat/primitives/twofactor/totp.pyc | Bin 0 -> 2763 bytes .../hazmat/primitives/twofactor/utils.py | 30 + .../hazmat/primitives/twofactor/utils.pyc | Bin 0 -> 1250 bytes .../site-packages/cryptography/utils.py | 162 + .../site-packages/cryptography/utils.pyc | Bin 0 -> 8443 bytes .../cryptography/x509/__init__.py | 184 + .../cryptography/x509/__init__.pyc | Bin 0 -> 7231 bytes .../site-packages/cryptography/x509/base.py | 736 ++ .../site-packages/cryptography/x509/base.pyc | Bin 0 -> 33378 bytes .../x509/certificate_transparency.py | 46 + .../x509/certificate_transparency.pyc | Bin 0 -> 2662 bytes .../cryptography/x509/extensions.py | 1429 +++ .../cryptography/x509/extensions.pyc | Bin 0 -> 77315 bytes .../cryptography/x509/general_name.py | 345 + .../cryptography/x509/general_name.pyc | Bin 0 -> 17560 bytes .../site-packages/cryptography/x509/name.py | 177 + .../site-packages/cryptography/x509/name.pyc | Bin 0 -> 10147 bytes .../site-packages/cryptography/x509/oid.py | 266 + .../site-packages/cryptography/x509/oid.pyc | Bin 0 -> 11867 bytes .../python2.7/site-packages/easy_install.py | 5 + .../python2.7/site-packages/easy_install.pyc | Bin 0 -> 367 bytes venv/lib/python2.7/site-packages/enum/LICENSE | 32 + venv/lib/python2.7/site-packages/enum/README | 3 + .../python2.7/site-packages/enum/__init__.py | 837 ++ .../python2.7/site-packages/enum/__init__.pyc | Bin 0 -> 27552 bytes .../enum34-1.1.6.dist-info/DESCRIPTION.rst | 41 + .../enum34-1.1.6.dist-info/INSTALLER | 1 + .../enum34-1.1.6.dist-info/METADATA | 64 + .../enum34-1.1.6.dist-info/RECORD | 11 + .../enum34-1.1.6.dist-info/WHEEL | 5 + .../enum34-1.1.6.dist-info/metadata.json | 1 + .../enum34-1.1.6.dist-info/top_level.txt | 1 + .../python2.7/site-packages/flask/__init__.py | 49 + .../site-packages/flask/__init__.pyc | Bin 0 -> 2203 bytes .../python2.7/site-packages/flask/__main__.py | 15 + .../site-packages/flask/__main__.pyc | Bin 0 -> 518 bytes .../python2.7/site-packages/flask/_compat.py | 96 + .../python2.7/site-packages/flask/_compat.pyc | Bin 0 -> 4929 bytes venv/lib/python2.7/site-packages/flask/app.py | 2003 +++++ .../lib/python2.7/site-packages/flask/app.pyc | Bin 0 -> 73156 bytes .../site-packages/flask/blueprints.py | 413 + .../site-packages/flask/blueprints.pyc | Bin 0 -> 25370 bytes venv/lib/python2.7/site-packages/flask/cli.py | 517 ++ .../lib/python2.7/site-packages/flask/cli.pyc | Bin 0 -> 19631 bytes .../python2.7/site-packages/flask/config.py | 263 + .../python2.7/site-packages/flask/config.pyc | Bin 0 -> 11638 bytes venv/lib/python2.7/site-packages/flask/ctx.py | 410 + .../lib/python2.7/site-packages/flask/ctx.pyc | Bin 0 -> 15973 bytes .../site-packages/flask/debughelpers.py | 155 + .../site-packages/flask/debughelpers.pyc | Bin 0 -> 7943 bytes .../site-packages/flask/ext/__init__.py | 29 + .../site-packages/flask/ext/__init__.pyc | Bin 0 -> 1229 bytes .../python2.7/site-packages/flask/exthook.py | 143 + .../python2.7/site-packages/flask/exthook.pyc | Bin 0 -> 5663 bytes .../python2.7/site-packages/flask/globals.py | 61 + .../python2.7/site-packages/flask/globals.pyc | Bin 0 -> 2253 bytes .../python2.7/site-packages/flask/helpers.py | 966 +++ .../python2.7/site-packages/flask/helpers.pyc | Bin 0 -> 36245 bytes .../lib/python2.7/site-packages/flask/json.py | 269 + .../python2.7/site-packages/flask/json.pyc | Bin 0 -> 11378 bytes .../python2.7/site-packages/flask/logging.py | 94 + .../python2.7/site-packages/flask/logging.pyc | Bin 0 -> 4407 bytes .../python2.7/site-packages/flask/sessions.py | 366 + .../site-packages/flask/sessions.pyc | Bin 0 -> 15825 bytes .../python2.7/site-packages/flask/signals.py | 56 + .../python2.7/site-packages/flask/signals.pyc | Bin 0 -> 3195 bytes .../site-packages/flask/templating.py | 149 + .../site-packages/flask/templating.pyc | Bin 0 -> 6571 bytes .../python2.7/site-packages/flask/testing.py | 143 + .../python2.7/site-packages/flask/testing.pyc | Bin 0 -> 5760 bytes .../python2.7/site-packages/flask/views.py | 149 + .../python2.7/site-packages/flask/views.pyc | Bin 0 -> 5792 bytes .../python2.7/site-packages/flask/wrappers.py | 205 + .../site-packages/flask/wrappers.pyc | Bin 0 -> 8272 bytes .../idna-2.6.dist-info/DESCRIPTION.rst | 213 + .../idna-2.6.dist-info/INSTALLER | 1 + .../site-packages/idna-2.6.dist-info/METADATA | 239 + .../site-packages/idna-2.6.dist-info/RECORD | 23 + .../site-packages/idna-2.6.dist-info/WHEEL | 6 + .../idna-2.6.dist-info/metadata.json | 1 + .../idna-2.6.dist-info/top_level.txt | 1 + .../python2.7/site-packages/idna/__init__.py | 2 + .../python2.7/site-packages/idna/__init__.pyc | Bin 0 -> 278 bytes .../lib/python2.7/site-packages/idna/codec.py | 118 + .../python2.7/site-packages/idna/codec.pyc | Bin 0 -> 4343 bytes .../python2.7/site-packages/idna/compat.py | 12 + .../python2.7/site-packages/idna/compat.pyc | Bin 0 -> 947 bytes venv/lib/python2.7/site-packages/idna/core.py | 387 + .../lib/python2.7/site-packages/idna/core.pyc | Bin 0 -> 12567 bytes .../python2.7/site-packages/idna/idnadata.py | 1585 ++++ .../python2.7/site-packages/idna/idnadata.pyc | Bin 0 -> 28589 bytes .../python2.7/site-packages/idna/intranges.py | 53 + .../site-packages/idna/intranges.pyc | Bin 0 -> 2387 bytes .../site-packages/idna/package_data.py | 2 + .../site-packages/idna/package_data.pyc | Bin 0 -> 216 bytes .../python2.7/site-packages/idna/uts46data.py | 7634 +++++++++++++++++ .../site-packages/idna/uts46data.pyc | Bin 0 -> 276067 bytes .../DESCRIPTION.rst | 3 + .../ipaddress-1.0.18.dist-info/INSTALLER | 1 + .../ipaddress-1.0.18.dist-info/METADATA | 22 + .../ipaddress-1.0.18.dist-info/RECORD | 9 + .../ipaddress-1.0.18.dist-info/WHEEL | 5 + .../ipaddress-1.0.18.dist-info/metadata.json | 1 + .../ipaddress-1.0.18.dist-info/top_level.txt | 1 + venv/lib/python2.7/site-packages/ipaddress.py | 2425 ++++++ .../lib/python2.7/site-packages/ipaddress.pyc | Bin 0 -> 84286 bytes .../DESCRIPTION.rst | 3 + .../itsdangerous-0.24.dist-info/INSTALLER | 1 + .../itsdangerous-0.24.dist-info/METADATA | 16 + .../itsdangerous-0.24.dist-info/RECORD | 9 + .../itsdangerous-0.24.dist-info/WHEEL | 5 + .../itsdangerous-0.24.dist-info/metadata.json | 1 + .../itsdangerous-0.24.dist-info/top_level.txt | 1 + .../python2.7/site-packages/itsdangerous.py | 872 ++ .../python2.7/site-packages/itsdangerous.pyc | Bin 0 -> 38639 bytes .../site-packages/jinja2/__init__.py | 83 + .../site-packages/jinja2/__init__.pyc | Bin 0 -> 2979 bytes .../python2.7/site-packages/jinja2/_compat.py | 99 + .../site-packages/jinja2/_compat.pyc | Bin 0 -> 5207 bytes .../site-packages/jinja2/_identifier.py | 2 + .../site-packages/jinja2/_identifier.pyc | Bin 0 -> 1871 bytes .../site-packages/jinja2/asyncfilters.py | 146 + .../site-packages/jinja2/asyncsupport.py | 256 + .../python2.7/site-packages/jinja2/bccache.py | 362 + .../site-packages/jinja2/bccache.pyc | Bin 0 -> 15930 bytes .../site-packages/jinja2/compiler.py | 1721 ++++ .../site-packages/jinja2/compiler.pyc | Bin 0 -> 62826 bytes .../site-packages/jinja2/constants.py | 32 + .../site-packages/jinja2/constants.pyc | Bin 0 -> 1742 bytes .../python2.7/site-packages/jinja2/debug.py | 372 + .../python2.7/site-packages/jinja2/debug.pyc | Bin 0 -> 12677 bytes .../site-packages/jinja2/defaults.py | 56 + .../site-packages/jinja2/defaults.pyc | Bin 0 -> 1923 bytes .../site-packages/jinja2/environment.py | 1276 +++ .../site-packages/jinja2/environment.pyc | Bin 0 -> 53085 bytes .../site-packages/jinja2/exceptions.py | 146 + .../site-packages/jinja2/exceptions.pyc | Bin 0 -> 7221 bytes .../lib/python2.7/site-packages/jinja2/ext.py | 627 ++ .../python2.7/site-packages/jinja2/ext.pyc | Bin 0 -> 25494 bytes .../python2.7/site-packages/jinja2/filters.py | 1190 +++ .../site-packages/jinja2/filters.pyc | Bin 0 -> 43474 bytes .../site-packages/jinja2/idtracking.py | 286 + .../site-packages/jinja2/idtracking.pyc | Bin 0 -> 14621 bytes .../python2.7/site-packages/jinja2/lexer.py | 739 ++ .../python2.7/site-packages/jinja2/lexer.pyc | Bin 0 -> 24940 bytes .../python2.7/site-packages/jinja2/loaders.py | 481 ++ .../site-packages/jinja2/loaders.pyc | Bin 0 -> 21307 bytes .../python2.7/site-packages/jinja2/meta.py | 106 + .../python2.7/site-packages/jinja2/meta.pyc | Bin 0 -> 4493 bytes .../site-packages/jinja2/nativetypes.py | 220 + .../site-packages/jinja2/nativetypes.pyc | Bin 0 -> 6555 bytes .../python2.7/site-packages/jinja2/nodes.py | 999 +++ .../python2.7/site-packages/jinja2/nodes.pyc | Bin 0 -> 51396 bytes .../site-packages/jinja2/optimizer.py | 49 + .../site-packages/jinja2/optimizer.pyc | Bin 0 -> 2611 bytes .../python2.7/site-packages/jinja2/parser.py | 903 ++ .../python2.7/site-packages/jinja2/parser.pyc | Bin 0 -> 34458 bytes .../python2.7/site-packages/jinja2/runtime.py | 813 ++ .../site-packages/jinja2/runtime.pyc | Bin 0 -> 34355 bytes .../python2.7/site-packages/jinja2/sandbox.py | 475 + .../site-packages/jinja2/sandbox.pyc | Bin 0 -> 17973 bytes .../python2.7/site-packages/jinja2/tests.py | 175 + .../python2.7/site-packages/jinja2/tests.pyc | Bin 0 -> 6569 bytes .../python2.7/site-packages/jinja2/utils.py | 647 ++ .../python2.7/site-packages/jinja2/utils.pyc | Bin 0 -> 27703 bytes .../python2.7/site-packages/jinja2/visitor.py | 87 + .../site-packages/jinja2/visitor.pyc | Bin 0 -> 4196 bytes .../python2.7/site-packages/jwt/__init__.py | 29 + .../python2.7/site-packages/jwt/__init__.pyc | Bin 0 -> 1241 bytes .../python2.7/site-packages/jwt/__main__.py | 162 + .../python2.7/site-packages/jwt/__main__.pyc | Bin 0 -> 4477 bytes .../python2.7/site-packages/jwt/algorithms.py | 403 + .../site-packages/jwt/algorithms.pyc | Bin 0 -> 15129 bytes .../python2.7/site-packages/jwt/api_jws.py | 226 + .../python2.7/site-packages/jwt/api_jws.pyc | Bin 0 -> 8111 bytes .../python2.7/site-packages/jwt/api_jwt.py | 199 + .../python2.7/site-packages/jwt/api_jwt.pyc | Bin 0 -> 7540 bytes .../lib/python2.7/site-packages/jwt/compat.py | 76 + .../python2.7/site-packages/jwt/compat.pyc | Bin 0 -> 2388 bytes .../site-packages/jwt/contrib/__init__.py | 0 .../site-packages/jwt/contrib/__init__.pyc | Bin 0 -> 190 bytes .../jwt/contrib/algorithms/__init__.py | 0 .../jwt/contrib/algorithms/__init__.pyc | Bin 0 -> 201 bytes .../jwt/contrib/algorithms/py_ecdsa.py | 60 + .../jwt/contrib/algorithms/py_ecdsa.pyc | Bin 0 -> 2568 bytes .../jwt/contrib/algorithms/pycrypto.py | 47 + .../jwt/contrib/algorithms/pycrypto.pyc | Bin 0 -> 2487 bytes .../python2.7/site-packages/jwt/exceptions.py | 48 + .../site-packages/jwt/exceptions.pyc | Bin 0 -> 3128 bytes venv/lib/python2.7/site-packages/jwt/utils.py | 113 + .../lib/python2.7/site-packages/jwt/utils.pyc | Bin 0 -> 4528 bytes .../site-packages/markupsafe/__init__.py | 305 + .../site-packages/markupsafe/__init__.pyc | Bin 0 -> 16235 bytes .../site-packages/markupsafe/_compat.py | 26 + .../site-packages/markupsafe/_compat.pyc | Bin 0 -> 1142 bytes .../site-packages/markupsafe/_constants.py | 267 + .../site-packages/markupsafe/_constants.pyc | Bin 0 -> 6419 bytes .../site-packages/markupsafe/_native.py | 46 + .../site-packages/markupsafe/_native.pyc | Bin 0 -> 1929 bytes .../site-packages/markupsafe/_speedups.c | 239 + .../site-packages/markupsafe/_speedups.so | Bin 0 -> 26892 bytes .../nose-1.3.7.dist-info/DESCRIPTION.rst | 21 + .../nose-1.3.7.dist-info/INSTALLER | 1 + .../nose-1.3.7.dist-info/METADATA | 40 + .../site-packages/nose-1.3.7.dist-info/RECORD | 106 + .../site-packages/nose-1.3.7.dist-info/WHEEL | 5 + .../nose-1.3.7.dist-info/entry_points.txt | 7 + .../nose-1.3.7.dist-info/metadata.json | 1 + .../nose-1.3.7.dist-info/top_level.txt | 1 + .../python2.7/site-packages/nose/__init__.py | 15 + .../python2.7/site-packages/nose/__init__.pyc | Bin 0 -> 735 bytes .../python2.7/site-packages/nose/__main__.py | 8 + .../python2.7/site-packages/nose/__main__.pyc | Bin 0 -> 393 bytes venv/lib/python2.7/site-packages/nose/case.py | 397 + .../lib/python2.7/site-packages/nose/case.pyc | Bin 0 -> 16191 bytes .../python2.7/site-packages/nose/commands.py | 172 + .../python2.7/site-packages/nose/commands.pyc | Bin 0 -> 6371 bytes .../python2.7/site-packages/nose/config.py | 661 ++ .../python2.7/site-packages/nose/config.pyc | Bin 0 -> 25412 bytes venv/lib/python2.7/site-packages/nose/core.py | 341 + .../lib/python2.7/site-packages/nose/core.pyc | Bin 0 -> 14071 bytes venv/lib/python2.7/site-packages/nose/exc.py | 9 + venv/lib/python2.7/site-packages/nose/exc.pyc | Bin 0 -> 622 bytes .../site-packages/nose/ext/__init__.py | 3 + .../site-packages/nose/ext/__init__.pyc | Bin 0 -> 235 bytes .../site-packages/nose/ext/dtcompat.py | 2272 +++++ .../site-packages/nose/ext/dtcompat.pyc | Bin 0 -> 74302 bytes .../python2.7/site-packages/nose/failure.py | 42 + .../python2.7/site-packages/nose/failure.pyc | Bin 0 -> 2194 bytes .../python2.7/site-packages/nose/importer.py | 167 + .../python2.7/site-packages/nose/importer.pyc | Bin 0 -> 6038 bytes .../python2.7/site-packages/nose/inspector.py | 207 + .../site-packages/nose/inspector.pyc | Bin 0 -> 6262 bytes .../python2.7/site-packages/nose/loader.py | 623 ++ .../python2.7/site-packages/nose/loader.pyc | Bin 0 -> 19651 bytes .../site-packages/nose/plugins/__init__.py | 190 + .../site-packages/nose/plugins/__init__.pyc | Bin 0 -> 6587 bytes .../site-packages/nose/plugins/allmodules.py | 45 + .../site-packages/nose/plugins/allmodules.pyc | Bin 0 -> 2605 bytes .../site-packages/nose/plugins/attrib.py | 286 + .../site-packages/nose/plugins/attrib.pyc | Bin 0 -> 9841 bytes .../site-packages/nose/plugins/base.py | 725 ++ .../site-packages/nose/plugins/base.pyc | Bin 0 -> 34381 bytes .../site-packages/nose/plugins/builtin.py | 34 + .../site-packages/nose/plugins/builtin.pyc | Bin 0 -> 1827 bytes .../site-packages/nose/plugins/capture.py | 115 + .../site-packages/nose/plugins/capture.pyc | Bin 0 -> 5742 bytes .../site-packages/nose/plugins/collect.py | 94 + .../site-packages/nose/plugins/collect.pyc | Bin 0 -> 4974 bytes .../site-packages/nose/plugins/cover.py | 271 + .../site-packages/nose/plugins/cover.pyc | Bin 0 -> 10026 bytes .../site-packages/nose/plugins/debug.py | 67 + .../site-packages/nose/plugins/debug.pyc | Bin 0 -> 3201 bytes .../site-packages/nose/plugins/deprecated.py | 45 + .../site-packages/nose/plugins/deprecated.pyc | Bin 0 -> 2480 bytes .../site-packages/nose/plugins/doctests.py | 455 + .../site-packages/nose/plugins/doctests.pyc | Bin 0 -> 18772 bytes .../site-packages/nose/plugins/errorclass.py | 210 + .../site-packages/nose/plugins/errorclass.pyc | Bin 0 -> 9707 bytes .../nose/plugins/failuredetail.py | 49 + .../nose/plugins/failuredetail.pyc | Bin 0 -> 2577 bytes .../site-packages/nose/plugins/isolate.py | 103 + .../site-packages/nose/plugins/isolate.pyc | Bin 0 -> 5124 bytes .../site-packages/nose/plugins/logcapture.py | 245 + .../site-packages/nose/plugins/logcapture.pyc | Bin 0 -> 12675 bytes .../site-packages/nose/plugins/manager.py | 460 + .../site-packages/nose/plugins/manager.pyc | Bin 0 -> 22297 bytes .../nose/plugins/multiprocess.py | 835 ++ .../nose/plugins/multiprocess.pyc | Bin 0 -> 29093 bytes .../site-packages/nose/plugins/plugintest.py | 416 + .../site-packages/nose/plugins/plugintest.pyc | Bin 0 -> 17032 bytes .../site-packages/nose/plugins/prof.py | 154 + .../site-packages/nose/plugins/prof.pyc | Bin 0 -> 5914 bytes .../site-packages/nose/plugins/skip.py | 63 + .../site-packages/nose/plugins/skip.pyc | Bin 0 -> 2767 bytes .../site-packages/nose/plugins/testid.py | 311 + .../site-packages/nose/plugins/testid.pyc | Bin 0 -> 9770 bytes .../site-packages/nose/plugins/xunit.py | 341 + .../site-packages/nose/plugins/xunit.pyc | Bin 0 -> 15000 bytes .../lib/python2.7/site-packages/nose/proxy.py | 188 + .../python2.7/site-packages/nose/proxy.pyc | Bin 0 -> 9088 bytes .../python2.7/site-packages/nose/pyversion.py | 215 + .../site-packages/nose/pyversion.pyc | Bin 0 -> 10685 bytes .../python2.7/site-packages/nose/result.py | 200 + .../python2.7/site-packages/nose/result.pyc | Bin 0 -> 7450 bytes .../python2.7/site-packages/nose/selector.py | 251 + .../python2.7/site-packages/nose/selector.pyc | Bin 0 -> 9669 bytes .../site-packages/nose/sphinx/__init__.py | 1 + .../site-packages/nose/sphinx/__init__.pyc | Bin 0 -> 189 bytes .../site-packages/nose/sphinx/pluginopts.py | 189 + .../site-packages/nose/sphinx/pluginopts.pyc | Bin 0 -> 7266 bytes .../lib/python2.7/site-packages/nose/suite.py | 609 ++ .../python2.7/site-packages/nose/suite.pyc | Bin 0 -> 23938 bytes .../site-packages/nose/tools/__init__.py | 15 + .../site-packages/nose/tools/__init__.pyc | Bin 0 -> 611 bytes .../site-packages/nose/tools/nontrivial.py | 151 + .../site-packages/nose/tools/nontrivial.pyc | Bin 0 -> 6450 bytes .../site-packages/nose/tools/trivial.py | 54 + .../site-packages/nose/tools/trivial.pyc | Bin 0 -> 2452 bytes .../site-packages/nose/twistedtools.py | 173 + .../site-packages/nose/twistedtools.pyc | Bin 0 -> 6664 bytes .../python2.7/site-packages/nose/usage.txt | 115 + venv/lib/python2.7/site-packages/nose/util.py | 668 ++ .../lib/python2.7/site-packages/nose/util.pyc | Bin 0 -> 23044 bytes .../pip-9.0.1.dist-info/DESCRIPTION.rst | 39 + .../pip-9.0.1.dist-info/INSTALLER | 1 + .../pip-9.0.1.dist-info/METADATA | 69 + .../site-packages/pip-9.0.1.dist-info/RECORD | 501 ++ .../site-packages/pip-9.0.1.dist-info/WHEEL | 6 + .../pip-9.0.1.dist-info/entry_points.txt | 5 + .../pip-9.0.1.dist-info/metadata.json | 1 + .../pip-9.0.1.dist-info/top_level.txt | 1 + .../python2.7/site-packages/pip/__init__.py | 331 + .../python2.7/site-packages/pip/__init__.pyc | Bin 0 -> 9787 bytes .../python2.7/site-packages/pip/__main__.py | 19 + .../python2.7/site-packages/pip/__main__.pyc | Bin 0 -> 529 bytes .../site-packages/pip/_vendor/__init__.py | 107 + .../site-packages/pip/_vendor/__init__.pyc | Bin 0 -> 3298 bytes .../site-packages/pip/_vendor/appdirs.py | 552 ++ .../site-packages/pip/_vendor/appdirs.pyc | Bin 0 -> 21605 bytes .../pip/_vendor/cachecontrol/__init__.py | 11 + .../pip/_vendor/cachecontrol/__init__.pyc | Bin 0 -> 628 bytes .../pip/_vendor/cachecontrol/_cmd.py | 60 + .../pip/_vendor/cachecontrol/_cmd.pyc | Bin 0 -> 2284 bytes .../pip/_vendor/cachecontrol/adapter.py | 125 + .../pip/_vendor/cachecontrol/adapter.pyc | Bin 0 -> 3838 bytes .../pip/_vendor/cachecontrol/cache.py | 39 + .../pip/_vendor/cachecontrol/cache.pyc | Bin 0 -> 2896 bytes .../_vendor/cachecontrol/caches/__init__.py | 18 + .../_vendor/cachecontrol/caches/__init__.pyc | Bin 0 -> 659 bytes .../_vendor/cachecontrol/caches/file_cache.py | 116 + .../cachecontrol/caches/file_cache.pyc | Bin 0 -> 4289 bytes .../cachecontrol/caches/redis_cache.py | 41 + .../cachecontrol/caches/redis_cache.pyc | Bin 0 -> 2798 bytes .../pip/_vendor/cachecontrol/compat.py | 20 + .../pip/_vendor/cachecontrol/compat.pyc | Bin 0 -> 699 bytes .../pip/_vendor/cachecontrol/controller.py | 353 + .../pip/_vendor/cachecontrol/controller.pyc | Bin 0 -> 9618 bytes .../pip/_vendor/cachecontrol/filewrapper.py | 78 + .../pip/_vendor/cachecontrol/filewrapper.pyc | Bin 0 -> 3027 bytes .../pip/_vendor/cachecontrol/heuristics.py | 138 + .../pip/_vendor/cachecontrol/heuristics.pyc | Bin 0 -> 6657 bytes .../pip/_vendor/cachecontrol/serialize.py | 196 + .../pip/_vendor/cachecontrol/serialize.pyc | Bin 0 -> 6861 bytes .../pip/_vendor/cachecontrol/wrapper.py | 21 + .../pip/_vendor/cachecontrol/wrapper.pyc | Bin 0 -> 786 bytes .../pip/_vendor/colorama/__init__.py | 7 + .../pip/_vendor/colorama/__init__.pyc | Bin 0 -> 528 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansi.pyc | Bin 0 -> 5152 bytes .../pip/_vendor/colorama/ansitowin32.py | 236 + .../pip/_vendor/colorama/ansitowin32.pyc | Bin 0 -> 10298 bytes .../pip/_vendor/colorama/initialise.py | 82 + .../pip/_vendor/colorama/initialise.pyc | Bin 0 -> 2669 bytes .../pip/_vendor/colorama/win32.py | 154 + .../pip/_vendor/colorama/win32.pyc | Bin 0 -> 5398 bytes .../pip/_vendor/colorama/winterm.py | 162 + .../pip/_vendor/colorama/winterm.pyc | Bin 0 -> 6866 bytes .../pip/_vendor/distlib/__init__.py | 23 + .../pip/_vendor/distlib/__init__.pyc | Bin 0 -> 1611 bytes .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../_vendor/distlib/_backport/__init__.pyc | Bin 0 -> 496 bytes .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/misc.pyc | Bin 0 -> 1608 bytes .../pip/_vendor/distlib/_backport/shutil.py | 761 ++ .../pip/_vendor/distlib/_backport/shutil.pyc | Bin 0 -> 28345 bytes .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 788 ++ .../_vendor/distlib/_backport/sysconfig.pyc | Bin 0 -> 22456 bytes .../pip/_vendor/distlib/_backport/tarfile.py | 2607 ++++++ .../pip/_vendor/distlib/_backport/tarfile.pyc | Bin 0 -> 86648 bytes .../pip/_vendor/distlib/compat.py | 1111 +++ .../pip/_vendor/distlib/compat.pyc | Bin 0 -> 43985 bytes .../pip/_vendor/distlib/database.py | 1312 +++ .../pip/_vendor/distlib/database.pyc | Bin 0 -> 53085 bytes .../pip/_vendor/distlib/index.py | 515 ++ .../pip/_vendor/distlib/index.pyc | Bin 0 -> 20972 bytes .../pip/_vendor/distlib/locators.py | 1283 +++ .../pip/_vendor/distlib/locators.pyc | Bin 0 -> 49371 bytes .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/manifest.pyc | Bin 0 -> 12922 bytes .../pip/_vendor/distlib/markers.py | 190 + .../pip/_vendor/distlib/markers.pyc | Bin 0 -> 9255 bytes .../pip/_vendor/distlib/metadata.py | 1068 +++ .../pip/_vendor/distlib/metadata.pyc | Bin 0 -> 37936 bytes .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/resources.pyc | Bin 0 -> 15814 bytes .../pip/_vendor/distlib/scripts.py | 384 + .../pip/_vendor/distlib/scripts.pyc | Bin 0 -> 13274 bytes .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 89088 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 97792 bytes .../site-packages/pip/_vendor/distlib/util.py | 1611 ++++ .../pip/_vendor/distlib/util.pyc | Bin 0 -> 62898 bytes .../pip/_vendor/distlib/version.py | 742 ++ .../pip/_vendor/distlib/version.pyc | Bin 0 -> 29837 bytes .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 85504 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 94208 bytes .../pip/_vendor/distlib/wheel.py | 978 +++ .../pip/_vendor/distlib/wheel.pyc | Bin 0 -> 32912 bytes .../site-packages/pip/_vendor/distro.py | 1081 +++ .../site-packages/pip/_vendor/distro.pyc | Bin 0 -> 38066 bytes .../pip/_vendor/html5lib/__init__.py | 25 + .../pip/_vendor/html5lib/__init__.pyc | Bin 0 -> 1143 bytes .../pip/_vendor/html5lib/_ihatexml.py | 288 + .../pip/_vendor/html5lib/_ihatexml.pyc | Bin 0 -> 16402 bytes .../pip/_vendor/html5lib/_inputstream.py | 923 ++ .../pip/_vendor/html5lib/_inputstream.pyc | Bin 0 -> 30392 bytes .../pip/_vendor/html5lib/_tokenizer.py | 1721 ++++ .../pip/_vendor/html5lib/_tokenizer.pyc | Bin 0 -> 57245 bytes .../pip/_vendor/html5lib/_trie/__init__.py | 14 + .../pip/_vendor/html5lib/_trie/__init__.pyc | Bin 0 -> 487 bytes .../pip/_vendor/html5lib/_trie/_base.py | 38 + .../pip/_vendor/html5lib/_trie/_base.pyc | Bin 0 -> 2032 bytes .../pip/_vendor/html5lib/_trie/datrie.py | 44 + .../pip/_vendor/html5lib/_trie/datrie.pyc | Bin 0 -> 3274 bytes .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_trie/py.pyc | Bin 0 -> 3469 bytes .../pip/_vendor/html5lib/_utils.py | 127 + .../pip/_vendor/html5lib/_utils.pyc | Bin 0 -> 4903 bytes .../pip/_vendor/html5lib/constants.py | 2945 +++++++ .../pip/_vendor/html5lib/constants.pyc | Bin 0 -> 83079 bytes .../pip/_vendor/html5lib/filters/__init__.py | 0 .../pip/_vendor/html5lib/filters/__init__.pyc | Bin 0 -> 205 bytes .../filters/alphabeticalattributes.py | 20 + .../filters/alphabeticalattributes.pyc | Bin 0 -> 1574 bytes .../pip/_vendor/html5lib/filters/base.py | 12 + .../pip/_vendor/html5lib/filters/base.pyc | Bin 0 -> 1331 bytes .../html5lib/filters/inject_meta_charset.py | 65 + .../html5lib/filters/inject_meta_charset.pyc | Bin 0 -> 2433 bytes .../pip/_vendor/html5lib/filters/lint.py | 81 + .../pip/_vendor/html5lib/filters/lint.pyc | Bin 0 -> 3210 bytes .../_vendor/html5lib/filters/optionaltags.py | 206 + .../_vendor/html5lib/filters/optionaltags.pyc | Bin 0 -> 4674 bytes .../pip/_vendor/html5lib/filters/sanitizer.py | 865 ++ .../_vendor/html5lib/filters/sanitizer.pyc | Bin 0 -> 26131 bytes .../_vendor/html5lib/filters/whitespace.py | 38 + .../_vendor/html5lib/filters/whitespace.pyc | Bin 0 -> 1843 bytes .../pip/_vendor/html5lib/html5parser.py | 2733 ++++++ .../pip/_vendor/html5lib/html5parser.pyc | Bin 0 -> 138901 bytes .../pip/_vendor/html5lib/serializer.py | 334 + .../pip/_vendor/html5lib/serializer.pyc | Bin 0 -> 12345 bytes .../_vendor/html5lib/treeadapters/__init__.py | 12 + .../html5lib/treeadapters/__init__.pyc | Bin 0 -> 531 bytes .../_vendor/html5lib/treeadapters/genshi.py | 47 + .../_vendor/html5lib/treeadapters/genshi.pyc | Bin 0 -> 1815 bytes .../pip/_vendor/html5lib/treeadapters/sax.py | 44 + .../pip/_vendor/html5lib/treeadapters/sax.pyc | Bin 0 -> 1851 bytes .../_vendor/html5lib/treebuilders/__init__.py | 76 + .../html5lib/treebuilders/__init__.pyc | Bin 0 -> 3472 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 383 + .../_vendor/html5lib/treebuilders/base.pyc | Bin 0 -> 15896 bytes .../pip/_vendor/html5lib/treebuilders/dom.py | 236 + .../pip/_vendor/html5lib/treebuilders/dom.pyc | Bin 0 -> 13326 bytes .../_vendor/html5lib/treebuilders/etree.py | 340 + .../_vendor/html5lib/treebuilders/etree.pyc | Bin 0 -> 16679 bytes .../html5lib/treebuilders/etree_lxml.py | 367 + .../html5lib/treebuilders/etree_lxml.pyc | Bin 0 -> 16870 bytes .../_vendor/html5lib/treewalkers/__init__.py | 143 + .../_vendor/html5lib/treewalkers/__init__.pyc | Bin 0 -> 4909 bytes .../pip/_vendor/html5lib/treewalkers/base.py | 150 + .../pip/_vendor/html5lib/treewalkers/base.pyc | Bin 0 -> 7211 bytes .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/dom.pyc | Bin 0 -> 2505 bytes .../pip/_vendor/html5lib/treewalkers/etree.py | 137 + .../_vendor/html5lib/treewalkers/etree.pyc | Bin 0 -> 4879 bytes .../html5lib/treewalkers/etree_lxml.py | 213 + .../html5lib/treewalkers/etree_lxml.pyc | Bin 0 -> 10526 bytes .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../_vendor/html5lib/treewalkers/genshi.pyc | Bin 0 -> 2618 bytes .../site-packages/pip/_vendor/ipaddress.py | 2425 ++++++ .../site-packages/pip/_vendor/ipaddress.pyc | Bin 0 -> 85282 bytes .../pip/_vendor/lockfile/__init__.py | 347 + .../pip/_vendor/lockfile/__init__.pyc | Bin 0 -> 13417 bytes .../pip/_vendor/lockfile/linklockfile.py | 73 + .../pip/_vendor/lockfile/linklockfile.pyc | Bin 0 -> 3224 bytes .../pip/_vendor/lockfile/mkdirlockfile.py | 84 + .../pip/_vendor/lockfile/mkdirlockfile.pyc | Bin 0 -> 3786 bytes .../pip/_vendor/lockfile/pidlockfile.py | 190 + .../pip/_vendor/lockfile/pidlockfile.pyc | Bin 0 -> 6449 bytes .../pip/_vendor/lockfile/sqlitelockfile.py | 156 + .../pip/_vendor/lockfile/sqlitelockfile.pyc | Bin 0 -> 5108 bytes .../pip/_vendor/lockfile/symlinklockfile.py | 70 + .../pip/_vendor/lockfile/symlinklockfile.pyc | Bin 0 -> 3185 bytes .../site-packages/pip/_vendor/ordereddict.py | 127 + .../site-packages/pip/_vendor/ordereddict.pyc | Bin 0 -> 5284 bytes .../pip/_vendor/packaging/__about__.py | 21 + .../pip/_vendor/packaging/__about__.pyc | Bin 0 -> 827 bytes .../pip/_vendor/packaging/__init__.py | 14 + .../pip/_vendor/packaging/__init__.pyc | Bin 0 -> 649 bytes .../pip/_vendor/packaging/_compat.py | 30 + .../pip/_vendor/packaging/_compat.pyc | Bin 0 -> 1396 bytes .../pip/_vendor/packaging/_structures.py | 68 + .../pip/_vendor/packaging/_structures.pyc | Bin 0 -> 4971 bytes .../pip/_vendor/packaging/markers.py | 303 + .../pip/_vendor/packaging/markers.pyc | Bin 0 -> 13288 bytes .../pip/_vendor/packaging/requirements.py | 129 + .../pip/_vendor/packaging/requirements.pyc | Bin 0 -> 5494 bytes .../pip/_vendor/packaging/specifiers.py | 774 ++ .../pip/_vendor/packaging/specifiers.pyc | Bin 0 -> 28025 bytes .../pip/_vendor/packaging/utils.py | 14 + .../pip/_vendor/packaging/utils.pyc | Bin 0 -> 670 bytes .../pip/_vendor/packaging/version.py | 393 + .../pip/_vendor/packaging/version.pyc | Bin 0 -> 16317 bytes .../pip/_vendor/pkg_resources/__init__.py | 3052 +++++++ .../pip/_vendor/pkg_resources/__init__.pyc | Bin 0 -> 131764 bytes .../pip/_vendor/progress/__init__.py | 123 + .../pip/_vendor/progress/__init__.pyc | Bin 0 -> 6290 bytes .../site-packages/pip/_vendor/progress/bar.py | 83 + .../pip/_vendor/progress/bar.pyc | Bin 0 -> 3574 bytes .../pip/_vendor/progress/counter.py | 47 + .../pip/_vendor/progress/counter.pyc | Bin 0 -> 2495 bytes .../pip/_vendor/progress/helpers.py | 91 + .../pip/_vendor/progress/helpers.pyc | Bin 0 -> 4454 bytes .../pip/_vendor/progress/spinner.py | 40 + .../pip/_vendor/progress/spinner.pyc | Bin 0 -> 1868 bytes .../site-packages/pip/_vendor/pyparsing.py | 5696 ++++++++++++ .../site-packages/pip/_vendor/pyparsing.pyc | Bin 0 -> 249643 bytes .../site-packages/pip/_vendor/re-vendor.py | 34 + .../site-packages/pip/_vendor/re-vendor.pyc | Bin 0 -> 1628 bytes .../pip/_vendor/requests/__init__.py | 88 + .../pip/_vendor/requests/__init__.pyc | Bin 0 -> 2848 bytes .../pip/_vendor/requests/adapters.py | 503 ++ .../pip/_vendor/requests/adapters.pyc | Bin 0 -> 19143 bytes .../site-packages/pip/_vendor/requests/api.py | 148 + .../pip/_vendor/requests/api.pyc | Bin 0 -> 7028 bytes .../pip/_vendor/requests/auth.py | 252 + .../pip/_vendor/requests/auth.pyc | Bin 0 -> 10176 bytes .../pip/_vendor/requests/cacert.pem | 5616 ++++++++++++ .../pip/_vendor/requests/certs.py | 25 + .../pip/_vendor/requests/certs.pyc | Bin 0 -> 997 bytes .../pip/_vendor/requests/compat.py | 68 + .../pip/_vendor/requests/compat.pyc | Bin 0 -> 1746 bytes .../pip/_vendor/requests/cookies.py | 540 ++ .../pip/_vendor/requests/cookies.pyc | Bin 0 -> 24686 bytes .../pip/_vendor/requests/exceptions.py | 114 + .../pip/_vendor/requests/exceptions.pyc | Bin 0 -> 7329 bytes .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/hooks.pyc | Bin 0 -> 1415 bytes .../pip/_vendor/requests/models.py | 873 ++ .../pip/_vendor/requests/models.pyc | Bin 0 -> 29026 bytes .../pip/_vendor/requests/packages/__init__.py | 36 + .../_vendor/requests/packages/__init__.pyc | Bin 0 -> 1684 bytes .../requests/packages/chardet/__init__.py | 32 + .../requests/packages/chardet/__init__.pyc | Bin 0 -> 947 bytes .../requests/packages/chardet/big5freq.py | 925 ++ .../requests/packages/chardet/big5freq.pyc | Bin 0 -> 113855 bytes .../requests/packages/chardet/big5prober.py | 42 + .../requests/packages/chardet/big5prober.pyc | Bin 0 -> 1392 bytes .../requests/packages/chardet/chardetect.py | 80 + .../requests/packages/chardet/chardetect.pyc | Bin 0 -> 3196 bytes .../packages/chardet/chardistribution.py | 231 + .../packages/chardet/chardistribution.pyc | Bin 0 -> 9475 bytes .../packages/chardet/charsetgroupprober.py | 106 + .../packages/chardet/charsetgroupprober.pyc | Bin 0 -> 3065 bytes .../packages/chardet/charsetprober.py | 62 + .../packages/chardet/charsetprober.pyc | Bin 0 -> 2952 bytes .../packages/chardet/codingstatemachine.py | 61 + .../packages/chardet/codingstatemachine.pyc | Bin 0 -> 2310 bytes .../requests/packages/chardet/compat.py | 34 + .../requests/packages/chardet/compat.pyc | Bin 0 -> 709 bytes .../requests/packages/chardet/constants.py | 39 + .../requests/packages/chardet/constants.pyc | Bin 0 -> 407 bytes .../requests/packages/chardet/cp949prober.py | 44 + .../requests/packages/chardet/cp949prober.pyc | Bin 0 -> 1400 bytes .../requests/packages/chardet/escprober.py | 86 + .../requests/packages/chardet/escprober.pyc | Bin 0 -> 2894 bytes .../requests/packages/chardet/escsm.py | 242 + .../requests/packages/chardet/escsm.pyc | Bin 0 -> 7379 bytes .../requests/packages/chardet/eucjpprober.py | 90 + .../requests/packages/chardet/eucjpprober.pyc | Bin 0 -> 3303 bytes .../requests/packages/chardet/euckrfreq.py | 596 ++ .../requests/packages/chardet/euckrfreq.pyc | Bin 0 -> 88846 bytes .../requests/packages/chardet/euckrprober.py | 42 + .../requests/packages/chardet/euckrprober.pyc | Bin 0 -> 1401 bytes .../requests/packages/chardet/euctwfreq.py | 428 + .../requests/packages/chardet/euctwfreq.pyc | Bin 0 -> 61244 bytes .../requests/packages/chardet/euctwprober.py | 41 + .../requests/packages/chardet/euctwprober.pyc | Bin 0 -> 1401 bytes .../requests/packages/chardet/gb2312freq.py | 472 + .../requests/packages/chardet/gb2312freq.pyc | Bin 0 -> 68862 bytes .../requests/packages/chardet/gb2312prober.py | 41 + .../packages/chardet/gb2312prober.pyc | Bin 0 -> 1408 bytes .../requests/packages/chardet/hebrewprober.py | 283 + .../packages/chardet/hebrewprober.pyc | Bin 0 -> 4154 bytes .../requests/packages/chardet/jisfreq.py | 569 ++ .../requests/packages/chardet/jisfreq.pyc | Bin 0 -> 84078 bytes .../requests/packages/chardet/jpcntx.py | 227 + .../requests/packages/chardet/jpcntx.pyc | Bin 0 -> 26105 bytes .../packages/chardet/langbulgarianmodel.py | 229 + .../packages/chardet/langbulgarianmodel.pyc | Bin 0 -> 24960 bytes .../packages/chardet/langcyrillicmodel.py | 329 + .../packages/chardet/langcyrillicmodel.pyc | Bin 0 -> 30642 bytes .../packages/chardet/langgreekmodel.py | 225 + .../packages/chardet/langgreekmodel.pyc | Bin 0 -> 24647 bytes .../packages/chardet/langhebrewmodel.py | 201 + .../packages/chardet/langhebrewmodel.pyc | Bin 0 -> 23467 bytes .../packages/chardet/langhungarianmodel.py | 225 + .../packages/chardet/langhungarianmodel.pyc | Bin 0 -> 24944 bytes .../packages/chardet/langthaimodel.py | 200 + .../packages/chardet/langthaimodel.pyc | Bin 0 -> 23453 bytes .../requests/packages/chardet/latin1prober.py | 139 + .../packages/chardet/latin1prober.pyc | Bin 0 -> 3975 bytes .../packages/chardet/mbcharsetprober.py | 86 + .../packages/chardet/mbcharsetprober.pyc | Bin 0 -> 2937 bytes .../packages/chardet/mbcsgroupprober.py | 54 + .../packages/chardet/mbcsgroupprober.pyc | Bin 0 -> 1471 bytes .../requests/packages/chardet/mbcssm.py | 572 ++ .../requests/packages/chardet/mbcssm.pyc | Bin 0 -> 17736 bytes .../packages/chardet/sbcharsetprober.py | 120 + .../packages/chardet/sbcharsetprober.pyc | Bin 0 -> 3822 bytes .../packages/chardet/sbcsgroupprober.py | 69 + .../packages/chardet/sbcsgroupprober.pyc | Bin 0 -> 2156 bytes .../requests/packages/chardet/sjisprober.py | 91 + .../requests/packages/chardet/sjisprober.pyc | Bin 0 -> 3330 bytes .../packages/chardet/universaldetector.py | 170 + .../packages/chardet/universaldetector.pyc | Bin 0 -> 4580 bytes .../requests/packages/chardet/utf8prober.py | 76 + .../requests/packages/chardet/utf8prober.pyc | Bin 0 -> 2720 bytes .../requests/packages/urllib3/__init__.py | 96 + .../requests/packages/urllib3/__init__.pyc | Bin 0 -> 3607 bytes .../requests/packages/urllib3/_collections.py | 324 + .../packages/urllib3/_collections.pyc | Bin 0 -> 15587 bytes .../requests/packages/urllib3/connection.py | 330 + .../requests/packages/urllib3/connection.pyc | Bin 0 -> 11435 bytes .../packages/urllib3/connectionpool.py | 866 ++ .../packages/urllib3/connectionpool.pyc | Bin 0 -> 27763 bytes .../packages/urllib3/contrib/__init__.py | 0 .../packages/urllib3/contrib/__init__.pyc | Bin 0 -> 222 bytes .../packages/urllib3/contrib/appengine.py | 231 + .../packages/urllib3/contrib/appengine.pyc | Bin 0 -> 9251 bytes .../packages/urllib3/contrib/ntlmpool.py | 115 + .../packages/urllib3/contrib/ntlmpool.pyc | Bin 0 -> 4315 bytes .../packages/urllib3/contrib/pyopenssl.py | 358 + .../packages/urllib3/contrib/pyopenssl.pyc | Bin 0 -> 13906 bytes .../packages/urllib3/contrib/socks.py | 172 + .../packages/urllib3/contrib/socks.pyc | Bin 0 -> 5936 bytes .../requests/packages/urllib3/exceptions.py | 209 + .../requests/packages/urllib3/exceptions.pyc | Bin 0 -> 13984 bytes .../requests/packages/urllib3/fields.py | 178 + .../requests/packages/urllib3/fields.pyc | Bin 0 -> 7510 bytes .../requests/packages/urllib3/filepost.py | 94 + .../requests/packages/urllib3/filepost.pyc | Bin 0 -> 3767 bytes .../packages/urllib3/packages/__init__.py | 5 + .../packages/urllib3/packages/__init__.pyc | Bin 0 -> 403 bytes .../packages/urllib3/packages/ordered_dict.py | 259 + .../urllib3/packages/ordered_dict.pyc | Bin 0 -> 11974 bytes .../requests/packages/urllib3/packages/six.py | 868 ++ .../packages/urllib3/packages/six.pyc | Bin 0 -> 37366 bytes .../packages/ssl_match_hostname/__init__.py | 13 + .../packages/ssl_match_hostname/__init__.pyc | Bin 0 -> 585 bytes .../ssl_match_hostname/_implementation.py | 105 + .../ssl_match_hostname/_implementation.pyc | Bin 0 -> 3211 bytes .../requests/packages/urllib3/poolmanager.py | 367 + .../requests/packages/urllib3/poolmanager.pyc | Bin 0 -> 14094 bytes .../requests/packages/urllib3/request.py | 151 + .../requests/packages/urllib3/request.pyc | Bin 0 -> 6593 bytes .../requests/packages/urllib3/response.py | 530 ++ .../requests/packages/urllib3/response.pyc | Bin 0 -> 19156 bytes .../packages/urllib3/util/__init__.py | 46 + .../packages/urllib3/util/__init__.pyc | Bin 0 -> 1383 bytes .../packages/urllib3/util/connection.py | 144 + .../packages/urllib3/util/connection.pyc | Bin 0 -> 4447 bytes .../requests/packages/urllib3/util/request.py | 72 + .../packages/urllib3/util/request.pyc | Bin 0 -> 2353 bytes .../packages/urllib3/util/response.py | 74 + .../packages/urllib3/util/response.pyc | Bin 0 -> 2494 bytes .../requests/packages/urllib3/util/retry.py | 300 + .../requests/packages/urllib3/util/retry.pyc | Bin 0 -> 11386 bytes .../requests/packages/urllib3/util/ssl_.py | 320 + .../requests/packages/urllib3/util/ssl_.pyc | Bin 0 -> 11134 bytes .../requests/packages/urllib3/util/timeout.py | 242 + .../packages/urllib3/util/timeout.pyc | Bin 0 -> 10508 bytes .../requests/packages/urllib3/util/url.py | 217 + .../requests/packages/urllib3/util/url.pyc | Bin 0 -> 6770 bytes .../pip/_vendor/requests/sessions.py | 712 ++ .../pip/_vendor/requests/sessions.pyc | Bin 0 -> 22514 bytes .../pip/_vendor/requests/status_codes.py | 91 + .../pip/_vendor/requests/status_codes.pyc | Bin 0 -> 6241 bytes .../pip/_vendor/requests/structures.py | 105 + .../pip/_vendor/requests/structures.pyc | Bin 0 -> 6274 bytes .../pip/_vendor/requests/utils.py | 817 ++ .../pip/_vendor/requests/utils.pyc | Bin 0 -> 24875 bytes .../site-packages/pip/_vendor/retrying.py | 267 + .../site-packages/pip/_vendor/retrying.pyc | Bin 0 -> 11600 bytes .../site-packages/pip/_vendor/six.py | 868 ++ .../site-packages/pip/_vendor/six.pyc | Bin 0 -> 34601 bytes .../pip/_vendor/webencodings/__init__.py | 342 + .../pip/_vendor/webencodings/__init__.pyc | Bin 0 -> 12324 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/labels.pyc | Bin 0 -> 5359 bytes .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/mklabels.pyc | Bin 0 -> 2476 bytes .../pip/_vendor/webencodings/tests.py | 153 + .../pip/_vendor/webencodings/tests.pyc | Bin 0 -> 7319 bytes .../_vendor/webencodings/x_user_defined.py | 325 + .../_vendor/webencodings/x_user_defined.pyc | Bin 0 -> 3822 bytes .../site-packages/pip/basecommand.py | 337 + .../site-packages/pip/basecommand.pyc | Bin 0 -> 9394 bytes .../python2.7/site-packages/pip/baseparser.py | 293 + .../site-packages/pip/baseparser.pyc | Bin 0 -> 11896 bytes .../python2.7/site-packages/pip/cmdoptions.py | 633 ++ .../site-packages/pip/cmdoptions.pyc | Bin 0 -> 16526 bytes .../site-packages/pip/commands/__init__.py | 86 + .../site-packages/pip/commands/__init__.pyc | Bin 0 -> 2861 bytes .../site-packages/pip/commands/check.py | 39 + .../site-packages/pip/commands/check.pyc | Bin 0 -> 1734 bytes .../site-packages/pip/commands/completion.py | 81 + .../site-packages/pip/commands/completion.pyc | Bin 0 -> 3074 bytes .../site-packages/pip/commands/download.py | 212 + .../site-packages/pip/commands/download.pyc | Bin 0 -> 6353 bytes .../site-packages/pip/commands/freeze.py | 87 + .../site-packages/pip/commands/freeze.pyc | Bin 0 -> 3401 bytes .../site-packages/pip/commands/hash.py | 57 + .../site-packages/pip/commands/hash.pyc | Bin 0 -> 2628 bytes .../site-packages/pip/commands/help.py | 35 + .../site-packages/pip/commands/help.pyc | Bin 0 -> 1487 bytes .../site-packages/pip/commands/install.py | 437 + .../site-packages/pip/commands/install.pyc | Bin 0 -> 11602 bytes .../site-packages/pip/commands/list.py | 337 + .../site-packages/pip/commands/list.pyc | Bin 0 -> 12146 bytes .../site-packages/pip/commands/search.py | 133 + .../site-packages/pip/commands/search.pyc | Bin 0 -> 5315 bytes .../site-packages/pip/commands/show.py | 154 + .../site-packages/pip/commands/show.pyc | Bin 0 -> 6037 bytes .../site-packages/pip/commands/uninstall.py | 76 + .../site-packages/pip/commands/uninstall.pyc | Bin 0 -> 3219 bytes .../site-packages/pip/commands/wheel.py | 208 + .../site-packages/pip/commands/wheel.pyc | Bin 0 -> 6591 bytes .../site-packages/pip/compat/__init__.py | 164 + .../site-packages/pip/compat/__init__.pyc | Bin 0 -> 5723 bytes .../site-packages/pip/compat/dictconfig.py | 565 ++ .../site-packages/pip/compat/dictconfig.pyc | Bin 0 -> 18156 bytes .../python2.7/site-packages/pip/download.py | 906 ++ .../python2.7/site-packages/pip/download.pyc | Bin 0 -> 27360 bytes .../python2.7/site-packages/pip/exceptions.py | 244 + .../site-packages/pip/exceptions.pyc | Bin 0 -> 14158 bytes venv/lib/python2.7/site-packages/pip/index.py | 1102 +++ .../lib/python2.7/site-packages/pip/index.pyc | Bin 0 -> 38840 bytes .../python2.7/site-packages/pip/locations.py | 182 + .../python2.7/site-packages/pip/locations.pyc | Bin 0 -> 4994 bytes .../site-packages/pip/models/__init__.py | 4 + .../site-packages/pip/models/__init__.pyc | Bin 0 -> 305 bytes .../site-packages/pip/models/index.py | 16 + .../site-packages/pip/models/index.pyc | Bin 0 -> 1249 bytes .../site-packages/pip/operations/__init__.py | 0 .../site-packages/pip/operations/__init__.pyc | Bin 0 -> 191 bytes .../site-packages/pip/operations/check.py | 49 + .../site-packages/pip/operations/check.pyc | Bin 0 -> 2048 bytes .../site-packages/pip/operations/freeze.py | 132 + .../site-packages/pip/operations/freeze.pyc | Bin 0 -> 3834 bytes .../python2.7/site-packages/pip/pep425tags.py | 324 + .../site-packages/pip/pep425tags.pyc | Bin 0 -> 10311 bytes .../site-packages/pip/req/__init__.py | 10 + .../site-packages/pip/req/__init__.pyc | Bin 0 -> 527 bytes .../site-packages/pip/req/req_file.py | 342 + .../site-packages/pip/req/req_file.pyc | Bin 0 -> 10681 bytes .../site-packages/pip/req/req_install.py | 1204 +++ .../site-packages/pip/req/req_install.pyc | Bin 0 -> 38238 bytes .../site-packages/pip/req/req_set.py | 798 ++ .../site-packages/pip/req/req_set.pyc | Bin 0 -> 25886 bytes .../site-packages/pip/req/req_uninstall.py | 195 + .../site-packages/pip/req/req_uninstall.pyc | Bin 0 -> 8441 bytes .../site-packages/pip/status_codes.py | 8 + .../site-packages/pip/status_codes.pyc | Bin 0 -> 438 bytes .../site-packages/pip/utils/__init__.py | 852 ++ .../site-packages/pip/utils/__init__.pyc | Bin 0 -> 30335 bytes .../site-packages/pip/utils/appdirs.py | 248 + .../site-packages/pip/utils/appdirs.pyc | Bin 0 -> 8972 bytes .../site-packages/pip/utils/build.py | 42 + .../site-packages/pip/utils/build.pyc | Bin 0 -> 2034 bytes .../site-packages/pip/utils/deprecation.py | 76 + .../site-packages/pip/utils/deprecation.pyc | Bin 0 -> 2677 bytes .../site-packages/pip/utils/encoding.py | 31 + .../site-packages/pip/utils/encoding.pyc | Bin 0 -> 1372 bytes .../site-packages/pip/utils/filesystem.py | 28 + .../site-packages/pip/utils/filesystem.pyc | Bin 0 -> 870 bytes .../site-packages/pip/utils/glibc.py | 81 + .../site-packages/pip/utils/glibc.pyc | Bin 0 -> 2051 bytes .../site-packages/pip/utils/hashes.py | 92 + .../site-packages/pip/utils/hashes.pyc | Bin 0 -> 4501 bytes .../site-packages/pip/utils/logging.py | 130 + .../site-packages/pip/utils/logging.pyc | Bin 0 -> 5562 bytes .../site-packages/pip/utils/outdated.py | 162 + .../site-packages/pip/utils/outdated.pyc | Bin 0 -> 5467 bytes .../site-packages/pip/utils/packaging.py | 63 + .../site-packages/pip/utils/packaging.pyc | Bin 0 -> 2641 bytes .../pip/utils/setuptools_build.py | 8 + .../pip/utils/setuptools_build.pyc | Bin 0 -> 392 bytes .../python2.7/site-packages/pip/utils/ui.py | 344 + .../python2.7/site-packages/pip/utils/ui.pyc | Bin 0 -> 13303 bytes .../site-packages/pip/vcs/__init__.py | 366 + .../site-packages/pip/vcs/__init__.pyc | Bin 0 -> 14712 bytes .../python2.7/site-packages/pip/vcs/bazaar.py | 116 + .../site-packages/pip/vcs/bazaar.pyc | Bin 0 -> 5309 bytes .../python2.7/site-packages/pip/vcs/git.py | 300 + .../python2.7/site-packages/pip/vcs/git.pyc | Bin 0 -> 12114 bytes .../site-packages/pip/vcs/mercurial.py | 103 + .../site-packages/pip/vcs/mercurial.pyc | Bin 0 -> 5103 bytes .../site-packages/pip/vcs/subversion.py | 269 + .../site-packages/pip/vcs/subversion.pyc | Bin 0 -> 9384 bytes venv/lib/python2.7/site-packages/pip/wheel.py | 853 ++ .../lib/python2.7/site-packages/pip/wheel.pyc | Bin 0 -> 26881 bytes .../site-packages/pkg_resources/__init__.py | 3198 +++++++ .../site-packages/pkg_resources/__init__.pyc | Bin 0 -> 134994 bytes .../pkg_resources/_vendor/__init__.py | 0 .../pkg_resources/_vendor/__init__.pyc | Bin 0 -> 205 bytes .../pkg_resources/_vendor/appdirs.py | 552 ++ .../pkg_resources/_vendor/appdirs.pyc | Bin 0 -> 21928 bytes .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__about__.pyc | Bin 0 -> 844 bytes .../_vendor/packaging/__init__.py | 14 + .../_vendor/packaging/__init__.pyc | Bin 0 -> 666 bytes .../_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_compat.pyc | Bin 0 -> 1464 bytes .../_vendor/packaging/_structures.py | 68 + .../_vendor/packaging/_structures.pyc | Bin 0 -> 5328 bytes .../_vendor/packaging/markers.py | 301 + .../_vendor/packaging/markers.pyc | Bin 0 -> 13892 bytes .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/requirements.pyc | Bin 0 -> 5665 bytes .../_vendor/packaging/specifiers.py | 774 ++ .../_vendor/packaging/specifiers.pyc | Bin 0 -> 29232 bytes .../pkg_resources/_vendor/packaging/utils.py | 14 + .../pkg_resources/_vendor/packaging/utils.pyc | Bin 0 -> 704 bytes .../_vendor/packaging/version.py | 393 + .../_vendor/packaging/version.pyc | Bin 0 -> 17150 bytes .../pkg_resources/_vendor/pyparsing.py | 5696 ++++++++++++ .../pkg_resources/_vendor/pyparsing.pyc | Bin 0 -> 257021 bytes .../pkg_resources/_vendor/six.py | 868 ++ .../pkg_resources/_vendor/six.pyc | Bin 0 -> 35944 bytes .../pkg_resources/extern/__init__.py | 73 + .../pkg_resources/extern/__init__.pyc | Bin 0 -> 3324 bytes .../site-packages/pkg_resources/py31compat.py | 22 + .../pkg_resources/py31compat.pyc | Bin 0 -> 916 bytes .../DESCRIPTION.rst | 81 + .../pyOpenSSL-17.3.0.dist-info/INSTALLER | 1 + .../pyOpenSSL-17.3.0.dist-info/LICENSE.txt | 202 + .../pyOpenSSL-17.3.0.dist-info/METADATA | 119 + .../pyOpenSSL-17.3.0.dist-info/RECORD | 22 + .../pyOpenSSL-17.3.0.dist-info/WHEEL | 6 + .../pyOpenSSL-17.3.0.dist-info/metadata.json | 1 + .../pyOpenSSL-17.3.0.dist-info/top_level.txt | 1 + .../pycparser-2.18.dist-info/DESCRIPTION.rst | 6 + .../pycparser-2.18.dist-info/INSTALLER | 1 + .../pycparser-2.18.dist-info/METADATA | 18 + .../pycparser-2.18.dist-info/RECORD | 42 + .../pycparser-2.18.dist-info/WHEEL | 6 + .../pycparser-2.18.dist-info/metadata.json | 1 + .../pycparser-2.18.dist-info/top_level.txt | 1 + .../site-packages/pycparser/__init__.py | 93 + .../site-packages/pycparser/__init__.pyc | Bin 0 -> 2984 bytes .../site-packages/pycparser/_ast_gen.py | 278 + .../site-packages/pycparser/_ast_gen.pyc | Bin 0 -> 10024 bytes .../site-packages/pycparser/_build_tables.py | 33 + .../site-packages/pycparser/_build_tables.pyc | Bin 0 -> 688 bytes .../site-packages/pycparser/_c_ast.cfg | 191 + .../site-packages/pycparser/ast_transforms.py | 105 + .../pycparser/ast_transforms.pyc | Bin 0 -> 2957 bytes .../site-packages/pycparser/c_ast.py | 809 ++ .../site-packages/pycparser/c_ast.pyc | Bin 0 -> 47966 bytes .../site-packages/pycparser/c_generator.py | 411 + .../site-packages/pycparser/c_generator.pyc | Bin 0 -> 22783 bytes .../site-packages/pycparser/c_lexer.py | 485 ++ .../site-packages/pycparser/c_lexer.pyc | Bin 0 -> 17284 bytes .../site-packages/pycparser/c_parser.py | 1782 ++++ .../site-packages/pycparser/c_parser.pyc | Bin 0 -> 77052 bytes .../site-packages/pycparser/lextab.py | 10 + .../site-packages/pycparser/lextab.pyc | Bin 0 -> 6654 bytes .../site-packages/pycparser/ply/__init__.py | 5 + .../site-packages/pycparser/ply/__init__.pyc | Bin 0 -> 269 bytes .../site-packages/pycparser/ply/cpp.py | 907 ++ .../site-packages/pycparser/ply/cpp.pyc | Bin 0 -> 20869 bytes .../site-packages/pycparser/ply/ctokens.py | 133 + .../site-packages/pycparser/ply/ctokens.pyc | Bin 0 -> 3098 bytes .../site-packages/pycparser/ply/lex.py | 1099 +++ .../site-packages/pycparser/ply/lex.pyc | Bin 0 -> 29738 bytes .../site-packages/pycparser/ply/yacc.py | 3494 ++++++++ .../site-packages/pycparser/ply/yacc.pyc | Bin 0 -> 72475 bytes .../site-packages/pycparser/ply/ygen.py | 74 + .../site-packages/pycparser/ply/ygen.pyc | Bin 0 -> 2302 bytes .../site-packages/pycparser/plyparser.py | 116 + .../site-packages/pycparser/plyparser.pyc | Bin 0 -> 6270 bytes .../site-packages/pycparser/yacctab.py | 332 + .../site-packages/pycparser/yacctab.pyc | Bin 0 -> 135616 bytes .../pytz-2017.3.dist-info/DESCRIPTION.rst | 589 ++ .../pytz-2017.3.dist-info/INSTALLER | 1 + .../pytz-2017.3.dist-info/METADATA | 621 ++ .../pytz-2017.3.dist-info/RECORD | 620 ++ .../site-packages/pytz-2017.3.dist-info/WHEEL | 6 + .../pytz-2017.3.dist-info/metadata.json | 1 + .../pytz-2017.3.dist-info/top_level.txt | 1 + .../pytz-2017.3.dist-info/zip-safe | 1 + .../python2.7/site-packages/pytz/__init__.py | 1543 ++++ .../python2.7/site-packages/pytz/__init__.pyc | Bin 0 -> 34949 bytes .../site-packages/pytz/exceptions.py | 48 + .../site-packages/pytz/exceptions.pyc | Bin 0 -> 2279 bytes venv/lib/python2.7/site-packages/pytz/lazy.py | 168 + .../lib/python2.7/site-packages/pytz/lazy.pyc | Bin 0 -> 7338 bytes .../python2.7/site-packages/pytz/reference.py | 127 + .../site-packages/pytz/reference.pyc | Bin 0 -> 5722 bytes .../python2.7/site-packages/pytz/tzfile.py | 137 + .../python2.7/site-packages/pytz/tzfile.pyc | Bin 0 -> 4094 bytes .../python2.7/site-packages/pytz/tzinfo.py | 564 ++ .../python2.7/site-packages/pytz/tzinfo.pyc | Bin 0 -> 18049 bytes .../pytz/zoneinfo/Africa/Abidjan | Bin 0 -> 170 bytes .../site-packages/pytz/zoneinfo/Africa/Accra | Bin 0 -> 842 bytes .../pytz/zoneinfo/Africa/Addis_Ababa | Bin 0 -> 285 bytes .../pytz/zoneinfo/Africa/Algiers | Bin 0 -> 760 bytes .../site-packages/pytz/zoneinfo/Africa/Asmara | Bin 0 -> 285 bytes .../site-packages/pytz/zoneinfo/Africa/Asmera | Bin 0 -> 285 bytes .../site-packages/pytz/zoneinfo/Africa/Bamako | Bin 0 -> 170 bytes .../site-packages/pytz/zoneinfo/Africa/Bangui | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Banjul | Bin 0 -> 170 bytes .../site-packages/pytz/zoneinfo/Africa/Bissau | Bin 0 -> 208 bytes .../pytz/zoneinfo/Africa/Blantyre | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/Brazzaville | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/Bujumbura | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Cairo | Bin 0 -> 1972 bytes .../pytz/zoneinfo/Africa/Casablanca | Bin 0 -> 1643 bytes .../site-packages/pytz/zoneinfo/Africa/Ceuta | Bin 0 -> 2059 bytes .../pytz/zoneinfo/Africa/Conakry | Bin 0 -> 170 bytes .../site-packages/pytz/zoneinfo/Africa/Dakar | Bin 0 -> 170 bytes .../pytz/zoneinfo/Africa/Dar_es_Salaam | Bin 0 -> 285 bytes .../pytz/zoneinfo/Africa/Djibouti | Bin 0 -> 285 bytes .../site-packages/pytz/zoneinfo/Africa/Douala | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/El_Aaiun | Bin 0 -> 1473 bytes .../pytz/zoneinfo/Africa/Freetown | Bin 0 -> 170 bytes .../pytz/zoneinfo/Africa/Gaborone | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Harare | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/Johannesburg | Bin 0 -> 271 bytes .../site-packages/pytz/zoneinfo/Africa/Juba | Bin 0 -> 683 bytes .../pytz/zoneinfo/Africa/Kampala | Bin 0 -> 285 bytes .../pytz/zoneinfo/Africa/Khartoum | Bin 0 -> 713 bytes .../site-packages/pytz/zoneinfo/Africa/Kigali | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/Kinshasa | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Lagos | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/Libreville | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Lome | Bin 0 -> 170 bytes .../site-packages/pytz/zoneinfo/Africa/Luanda | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/Lubumbashi | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Lusaka | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Malabo | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Maputo | Bin 0 -> 171 bytes .../site-packages/pytz/zoneinfo/Africa/Maseru | Bin 0 -> 271 bytes .../pytz/zoneinfo/Africa/Mbabane | Bin 0 -> 271 bytes .../pytz/zoneinfo/Africa/Mogadishu | Bin 0 -> 285 bytes .../pytz/zoneinfo/Africa/Monrovia | Bin 0 -> 233 bytes .../pytz/zoneinfo/Africa/Nairobi | Bin 0 -> 285 bytes .../pytz/zoneinfo/Africa/Ndjamena | Bin 0 -> 225 bytes .../site-packages/pytz/zoneinfo/Africa/Niamey | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/Nouakchott | Bin 0 -> 170 bytes .../pytz/zoneinfo/Africa/Ouagadougou | Bin 0 -> 170 bytes .../pytz/zoneinfo/Africa/Porto-Novo | Bin 0 -> 171 bytes .../pytz/zoneinfo/Africa/Sao_Tome | Bin 0 -> 170 bytes .../pytz/zoneinfo/Africa/Timbuktu | Bin 0 -> 170 bytes .../pytz/zoneinfo/Africa/Tripoli | Bin 0 -> 655 bytes .../site-packages/pytz/zoneinfo/Africa/Tunis | Bin 0 -> 710 bytes .../pytz/zoneinfo/Africa/Windhoek | Bin 0 -> 1030 bytes .../site-packages/pytz/zoneinfo/America/Adak | Bin 0 -> 2365 bytes .../pytz/zoneinfo/America/Anchorage | Bin 0 -> 2380 bytes .../pytz/zoneinfo/America/Anguilla | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Antigua | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Araguaina | Bin 0 -> 910 bytes .../zoneinfo/America/Argentina/Buenos_Aires | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Argentina/Catamarca | Bin 0 -> 1109 bytes .../zoneinfo/America/Argentina/ComodRivadavia | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Argentina/Cordoba | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Argentina/Jujuy | Bin 0 -> 1081 bytes .../pytz/zoneinfo/America/Argentina/La_Rioja | Bin 0 -> 1123 bytes .../pytz/zoneinfo/America/Argentina/Mendoza | Bin 0 -> 1109 bytes .../zoneinfo/America/Argentina/Rio_Gallegos | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Argentina/Salta | Bin 0 -> 1081 bytes .../pytz/zoneinfo/America/Argentina/San_Juan | Bin 0 -> 1123 bytes .../pytz/zoneinfo/America/Argentina/San_Luis | Bin 0 -> 1139 bytes .../pytz/zoneinfo/America/Argentina/Tucuman | Bin 0 -> 1137 bytes .../pytz/zoneinfo/America/Argentina/Ushuaia | Bin 0 -> 1109 bytes .../site-packages/pytz/zoneinfo/America/Aruba | Bin 0 -> 212 bytes .../pytz/zoneinfo/America/Asuncion | Bin 0 -> 2077 bytes .../pytz/zoneinfo/America/Atikokan | Bin 0 -> 345 bytes .../site-packages/pytz/zoneinfo/America/Atka | Bin 0 -> 2365 bytes .../site-packages/pytz/zoneinfo/America/Bahia | Bin 0 -> 1050 bytes .../pytz/zoneinfo/America/Bahia_Banderas | Bin 0 -> 1588 bytes .../pytz/zoneinfo/America/Barbados | Bin 0 -> 344 bytes .../site-packages/pytz/zoneinfo/America/Belem | Bin 0 -> 602 bytes .../pytz/zoneinfo/America/Belize | Bin 0 -> 978 bytes .../pytz/zoneinfo/America/Blanc-Sablon | Bin 0 -> 307 bytes .../pytz/zoneinfo/America/Boa_Vista | Bin 0 -> 658 bytes .../pytz/zoneinfo/America/Bogota | Bin 0 -> 271 bytes .../site-packages/pytz/zoneinfo/America/Boise | Bin 0 -> 2403 bytes .../pytz/zoneinfo/America/Buenos_Aires | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Cambridge_Bay | Bin 0 -> 2098 bytes .../pytz/zoneinfo/America/Campo_Grande | Bin 0 -> 2016 bytes .../pytz/zoneinfo/America/Cancun | Bin 0 -> 816 bytes .../pytz/zoneinfo/America/Caracas | Bin 0 -> 289 bytes .../pytz/zoneinfo/America/Catamarca | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Cayenne | Bin 0 -> 224 bytes .../pytz/zoneinfo/America/Cayman | Bin 0 -> 203 bytes .../pytz/zoneinfo/America/Chicago | Bin 0 -> 3585 bytes .../pytz/zoneinfo/America/Chihuahua | Bin 0 -> 1522 bytes .../pytz/zoneinfo/America/Coral_Harbour | Bin 0 -> 345 bytes .../pytz/zoneinfo/America/Cordoba | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Costa_Rica | Bin 0 -> 341 bytes .../pytz/zoneinfo/America/Creston | Bin 0 -> 233 bytes .../pytz/zoneinfo/America/Cuiaba | Bin 0 -> 1988 bytes .../pytz/zoneinfo/America/Curacao | Bin 0 -> 212 bytes .../pytz/zoneinfo/America/Danmarkshavn | Bin 0 -> 712 bytes .../pytz/zoneinfo/America/Dawson | Bin 0 -> 2093 bytes .../pytz/zoneinfo/America/Dawson_Creek | Bin 0 -> 1059 bytes .../pytz/zoneinfo/America/Denver | Bin 0 -> 2453 bytes .../pytz/zoneinfo/America/Detroit | Bin 0 -> 2188 bytes .../pytz/zoneinfo/America/Dominica | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Edmonton | Bin 0 -> 2402 bytes .../pytz/zoneinfo/America/Eirunepe | Bin 0 -> 690 bytes .../pytz/zoneinfo/America/El_Salvador | Bin 0 -> 250 bytes .../pytz/zoneinfo/America/Ensenada | Bin 0 -> 2356 bytes .../pytz/zoneinfo/America/Fort_Nelson | Bin 0 -> 2249 bytes .../pytz/zoneinfo/America/Fort_Wayne | Bin 0 -> 1675 bytes .../pytz/zoneinfo/America/Fortaleza | Bin 0 -> 742 bytes .../pytz/zoneinfo/America/Glace_Bay | Bin 0 -> 2206 bytes .../pytz/zoneinfo/America/Godthab | Bin 0 -> 1892 bytes .../pytz/zoneinfo/America/Goose_Bay | Bin 0 -> 3219 bytes .../pytz/zoneinfo/America/Grand_Turk | Bin 0 -> 1881 bytes .../pytz/zoneinfo/America/Grenada | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Guadeloupe | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Guatemala | Bin 0 -> 306 bytes .../pytz/zoneinfo/America/Guayaquil | Bin 0 -> 271 bytes .../pytz/zoneinfo/America/Guyana | Bin 0 -> 266 bytes .../pytz/zoneinfo/America/Halifax | Bin 0 -> 3438 bytes .../pytz/zoneinfo/America/Havana | Bin 0 -> 2437 bytes .../pytz/zoneinfo/America/Hermosillo | Bin 0 -> 454 bytes .../zoneinfo/America/Indiana/Indianapolis | Bin 0 -> 1675 bytes .../pytz/zoneinfo/America/Indiana/Knox | Bin 0 -> 2437 bytes .../pytz/zoneinfo/America/Indiana/Marengo | Bin 0 -> 1731 bytes .../pytz/zoneinfo/America/Indiana/Petersburg | Bin 0 -> 1913 bytes .../pytz/zoneinfo/America/Indiana/Tell_City | Bin 0 -> 1735 bytes .../pytz/zoneinfo/America/Indiana/Vevay | Bin 0 -> 1423 bytes .../pytz/zoneinfo/America/Indiana/Vincennes | Bin 0 -> 1703 bytes .../pytz/zoneinfo/America/Indiana/Winamac | Bin 0 -> 1787 bytes .../pytz/zoneinfo/America/Indianapolis | Bin 0 -> 1675 bytes .../pytz/zoneinfo/America/Inuvik | Bin 0 -> 1928 bytes .../pytz/zoneinfo/America/Iqaluit | Bin 0 -> 2046 bytes .../pytz/zoneinfo/America/Jamaica | Bin 0 -> 507 bytes .../site-packages/pytz/zoneinfo/America/Jujuy | Bin 0 -> 1081 bytes .../pytz/zoneinfo/America/Juneau | Bin 0 -> 2362 bytes .../pytz/zoneinfo/America/Kentucky/Louisville | Bin 0 -> 2781 bytes .../pytz/zoneinfo/America/Kentucky/Monticello | Bin 0 -> 2361 bytes .../pytz/zoneinfo/America/Knox_IN | Bin 0 -> 2437 bytes .../pytz/zoneinfo/America/Kralendijk | Bin 0 -> 212 bytes .../pytz/zoneinfo/America/La_Paz | Bin 0 -> 259 bytes .../site-packages/pytz/zoneinfo/America/Lima | Bin 0 -> 431 bytes .../pytz/zoneinfo/America/Los_Angeles | Bin 0 -> 2845 bytes .../pytz/zoneinfo/America/Louisville | Bin 0 -> 2781 bytes .../pytz/zoneinfo/America/Lower_Princes | Bin 0 -> 212 bytes .../pytz/zoneinfo/America/Maceio | Bin 0 -> 770 bytes .../pytz/zoneinfo/America/Managua | Bin 0 -> 463 bytes .../pytz/zoneinfo/America/Manaus | Bin 0 -> 630 bytes .../pytz/zoneinfo/America/Marigot | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Martinique | Bin 0 -> 257 bytes .../pytz/zoneinfo/America/Matamoros | Bin 0 -> 1416 bytes .../pytz/zoneinfo/America/Mazatlan | Bin 0 -> 1564 bytes .../pytz/zoneinfo/America/Mendoza | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Menominee | Bin 0 -> 2283 bytes .../pytz/zoneinfo/America/Merida | Bin 0 -> 1456 bytes .../pytz/zoneinfo/America/Metlakatla | Bin 0 -> 1418 bytes .../pytz/zoneinfo/America/Mexico_City | Bin 0 -> 1618 bytes .../pytz/zoneinfo/America/Miquelon | Bin 0 -> 1696 bytes .../pytz/zoneinfo/America/Moncton | Bin 0 -> 3163 bytes .../pytz/zoneinfo/America/Monterrey | Bin 0 -> 1416 bytes .../pytz/zoneinfo/America/Montevideo | Bin 0 -> 1537 bytes .../pytz/zoneinfo/America/Montreal | Bin 0 -> 3503 bytes .../pytz/zoneinfo/America/Montserrat | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Nassau | Bin 0 -> 2284 bytes .../pytz/zoneinfo/America/New_York | Bin 0 -> 3545 bytes .../pytz/zoneinfo/America/Nipigon | Bin 0 -> 2131 bytes .../site-packages/pytz/zoneinfo/America/Nome | Bin 0 -> 2376 bytes .../pytz/zoneinfo/America/Noronha | Bin 0 -> 742 bytes .../pytz/zoneinfo/America/North_Dakota/Beulah | Bin 0 -> 2389 bytes .../pytz/zoneinfo/America/North_Dakota/Center | Bin 0 -> 2389 bytes .../zoneinfo/America/North_Dakota/New_Salem | Bin 0 -> 2389 bytes .../pytz/zoneinfo/America/Ojinaga | Bin 0 -> 1522 bytes .../pytz/zoneinfo/America/Panama | Bin 0 -> 203 bytes .../pytz/zoneinfo/America/Pangnirtung | Bin 0 -> 2108 bytes .../pytz/zoneinfo/America/Paramaribo | Bin 0 -> 296 bytes .../pytz/zoneinfo/America/Phoenix | Bin 0 -> 353 bytes .../pytz/zoneinfo/America/Port-au-Prince | Bin 0 -> 1455 bytes .../pytz/zoneinfo/America/Port_of_Spain | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Porto_Acre | Bin 0 -> 662 bytes .../pytz/zoneinfo/America/Porto_Velho | Bin 0 -> 602 bytes .../pytz/zoneinfo/America/Puerto_Rico | Bin 0 -> 255 bytes .../pytz/zoneinfo/America/Punta_Arenas | Bin 0 -> 1911 bytes .../pytz/zoneinfo/America/Rainy_River | Bin 0 -> 2131 bytes .../pytz/zoneinfo/America/Rankin_Inlet | Bin 0 -> 1930 bytes .../pytz/zoneinfo/America/Recife | Bin 0 -> 742 bytes .../pytz/zoneinfo/America/Regina | Bin 0 -> 994 bytes .../pytz/zoneinfo/America/Resolute | Bin 0 -> 1930 bytes .../pytz/zoneinfo/America/Rio_Branco | Bin 0 -> 662 bytes .../pytz/zoneinfo/America/Rosario | Bin 0 -> 1109 bytes .../pytz/zoneinfo/America/Santa_Isabel | Bin 0 -> 2356 bytes .../pytz/zoneinfo/America/Santarem | Bin 0 -> 632 bytes .../pytz/zoneinfo/America/Santiago | Bin 0 -> 2538 bytes .../pytz/zoneinfo/America/Santo_Domingo | Bin 0 -> 491 bytes .../pytz/zoneinfo/America/Sao_Paulo | Bin 0 -> 2016 bytes .../pytz/zoneinfo/America/Scoresbysund | Bin 0 -> 1930 bytes .../pytz/zoneinfo/America/Shiprock | Bin 0 -> 2453 bytes .../site-packages/pytz/zoneinfo/America/Sitka | Bin 0 -> 2350 bytes .../pytz/zoneinfo/America/St_Barthelemy | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/St_Johns | Bin 0 -> 3664 bytes .../pytz/zoneinfo/America/St_Kitts | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/St_Lucia | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/St_Thomas | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/St_Vincent | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Swift_Current | Bin 0 -> 574 bytes .../pytz/zoneinfo/America/Tegucigalpa | Bin 0 -> 278 bytes .../site-packages/pytz/zoneinfo/America/Thule | Bin 0 -> 1528 bytes .../pytz/zoneinfo/America/Thunder_Bay | Bin 0 -> 2211 bytes .../pytz/zoneinfo/America/Tijuana | Bin 0 -> 2356 bytes .../pytz/zoneinfo/America/Toronto | Bin 0 -> 3503 bytes .../pytz/zoneinfo/America/Tortola | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Vancouver | Bin 0 -> 2901 bytes .../pytz/zoneinfo/America/Virgin | Bin 0 -> 170 bytes .../pytz/zoneinfo/America/Whitehorse | Bin 0 -> 2093 bytes .../pytz/zoneinfo/America/Winnipeg | Bin 0 -> 2891 bytes .../pytz/zoneinfo/America/Yakutat | Bin 0 -> 2314 bytes .../pytz/zoneinfo/America/Yellowknife | Bin 0 -> 1980 bytes .../pytz/zoneinfo/Antarctica/Casey | Bin 0 -> 314 bytes .../pytz/zoneinfo/Antarctica/Davis | Bin 0 -> 311 bytes .../pytz/zoneinfo/Antarctica/DumontDUrville | Bin 0 -> 216 bytes .../pytz/zoneinfo/Antarctica/Macquarie | Bin 0 -> 1543 bytes .../pytz/zoneinfo/Antarctica/Mawson | Bin 0 -> 225 bytes .../pytz/zoneinfo/Antarctica/McMurdo | Bin 0 -> 2460 bytes .../pytz/zoneinfo/Antarctica/Palmer | Bin 0 -> 1432 bytes .../pytz/zoneinfo/Antarctica/Rothera | Bin 0 -> 186 bytes .../pytz/zoneinfo/Antarctica/South_Pole | Bin 0 -> 2460 bytes .../pytz/zoneinfo/Antarctica/Syowa | Bin 0 -> 187 bytes .../pytz/zoneinfo/Antarctica/Troll | Bin 0 -> 1176 bytes .../pytz/zoneinfo/Antarctica/Vostok | Bin 0 -> 187 bytes .../pytz/zoneinfo/Arctic/Longyearbyen | Bin 0 -> 2251 bytes .../site-packages/pytz/zoneinfo/Asia/Aden | Bin 0 -> 187 bytes .../site-packages/pytz/zoneinfo/Asia/Almaty | Bin 0 -> 1031 bytes .../site-packages/pytz/zoneinfo/Asia/Amman | Bin 0 -> 1877 bytes .../site-packages/pytz/zoneinfo/Asia/Anadyr | Bin 0 -> 1222 bytes .../site-packages/pytz/zoneinfo/Asia/Aqtau | Bin 0 -> 1017 bytes .../site-packages/pytz/zoneinfo/Asia/Aqtobe | Bin 0 -> 1047 bytes .../site-packages/pytz/zoneinfo/Asia/Ashgabat | Bin 0 -> 651 bytes .../pytz/zoneinfo/Asia/Ashkhabad | Bin 0 -> 651 bytes .../site-packages/pytz/zoneinfo/Asia/Atyrau | Bin 0 -> 1025 bytes .../site-packages/pytz/zoneinfo/Asia/Baghdad | Bin 0 -> 1004 bytes .../site-packages/pytz/zoneinfo/Asia/Bahrain | Bin 0 -> 225 bytes .../site-packages/pytz/zoneinfo/Asia/Baku | Bin 0 -> 1269 bytes .../site-packages/pytz/zoneinfo/Asia/Bangkok | Bin 0 -> 220 bytes .../site-packages/pytz/zoneinfo/Asia/Barnaul | Bin 0 -> 1255 bytes .../site-packages/pytz/zoneinfo/Asia/Beirut | Bin 0 -> 2175 bytes .../site-packages/pytz/zoneinfo/Asia/Bishkek | Bin 0 -> 1045 bytes .../site-packages/pytz/zoneinfo/Asia/Brunei | Bin 0 -> 229 bytes .../site-packages/pytz/zoneinfo/Asia/Calcutta | Bin 0 -> 312 bytes .../site-packages/pytz/zoneinfo/Asia/Chita | Bin 0 -> 1257 bytes .../pytz/zoneinfo/Asia/Choibalsan | Bin 0 -> 991 bytes .../pytz/zoneinfo/Asia/Chongqing | Bin 0 -> 414 bytes .../pytz/zoneinfo/Asia/Chungking | Bin 0 -> 414 bytes .../site-packages/pytz/zoneinfo/Asia/Colombo | Bin 0 -> 413 bytes .../site-packages/pytz/zoneinfo/Asia/Dacca | Bin 0 -> 370 bytes .../site-packages/pytz/zoneinfo/Asia/Damascus | Bin 0 -> 2320 bytes .../site-packages/pytz/zoneinfo/Asia/Dhaka | Bin 0 -> 370 bytes .../site-packages/pytz/zoneinfo/Asia/Dili | Bin 0 -> 253 bytes .../site-packages/pytz/zoneinfo/Asia/Dubai | Bin 0 -> 187 bytes .../site-packages/pytz/zoneinfo/Asia/Dushanbe | Bin 0 -> 621 bytes .../pytz/zoneinfo/Asia/Famagusta | Bin 0 -> 2042 bytes .../site-packages/pytz/zoneinfo/Asia/Gaza | Bin 0 -> 2295 bytes .../site-packages/pytz/zoneinfo/Asia/Harbin | Bin 0 -> 414 bytes .../site-packages/pytz/zoneinfo/Asia/Hebron | Bin 0 -> 2323 bytes .../pytz/zoneinfo/Asia/Ho_Chi_Minh | Bin 0 -> 389 bytes .../pytz/zoneinfo/Asia/Hong_Kong | Bin 0 -> 1189 bytes .../site-packages/pytz/zoneinfo/Asia/Hovd | Bin 0 -> 921 bytes .../site-packages/pytz/zoneinfo/Asia/Irkutsk | Bin 0 -> 1276 bytes .../site-packages/pytz/zoneinfo/Asia/Istanbul | Bin 0 -> 2166 bytes .../site-packages/pytz/zoneinfo/Asia/Jakarta | Bin 0 -> 392 bytes .../site-packages/pytz/zoneinfo/Asia/Jayapura | Bin 0 -> 251 bytes .../pytz/zoneinfo/Asia/Jerusalem | Bin 0 -> 2265 bytes .../site-packages/pytz/zoneinfo/Asia/Kabul | Bin 0 -> 229 bytes .../pytz/zoneinfo/Asia/Kamchatka | Bin 0 -> 1198 bytes .../site-packages/pytz/zoneinfo/Asia/Karachi | Bin 0 -> 417 bytes .../site-packages/pytz/zoneinfo/Asia/Kashgar | Bin 0 -> 187 bytes .../pytz/zoneinfo/Asia/Kathmandu | Bin 0 -> 238 bytes .../site-packages/pytz/zoneinfo/Asia/Katmandu | Bin 0 -> 238 bytes .../site-packages/pytz/zoneinfo/Asia/Khandyga | Bin 0 -> 1311 bytes .../site-packages/pytz/zoneinfo/Asia/Kolkata | Bin 0 -> 312 bytes .../pytz/zoneinfo/Asia/Krasnoyarsk | Bin 0 -> 1243 bytes .../pytz/zoneinfo/Asia/Kuala_Lumpur | Bin 0 -> 424 bytes .../site-packages/pytz/zoneinfo/Asia/Kuching | Bin 0 -> 521 bytes .../site-packages/pytz/zoneinfo/Asia/Kuwait | Bin 0 -> 187 bytes .../site-packages/pytz/zoneinfo/Asia/Macao | Bin 0 -> 755 bytes .../site-packages/pytz/zoneinfo/Asia/Macau | Bin 0 -> 755 bytes .../site-packages/pytz/zoneinfo/Asia/Magadan | Bin 0 -> 1258 bytes .../site-packages/pytz/zoneinfo/Asia/Makassar | Bin 0 -> 288 bytes .../site-packages/pytz/zoneinfo/Asia/Manila | Bin 0 -> 367 bytes .../site-packages/pytz/zoneinfo/Asia/Muscat | Bin 0 -> 187 bytes .../site-packages/pytz/zoneinfo/Asia/Nicosia | Bin 0 -> 2016 bytes .../pytz/zoneinfo/Asia/Novokuznetsk | Bin 0 -> 1197 bytes .../pytz/zoneinfo/Asia/Novosibirsk | Bin 0 -> 1255 bytes .../site-packages/pytz/zoneinfo/Asia/Omsk | Bin 0 -> 1243 bytes .../site-packages/pytz/zoneinfo/Asia/Oral | Bin 0 -> 1039 bytes .../pytz/zoneinfo/Asia/Phnom_Penh | Bin 0 -> 220 bytes .../pytz/zoneinfo/Asia/Pontianak | Bin 0 -> 395 bytes .../pytz/zoneinfo/Asia/Pyongyang | Bin 0 -> 272 bytes .../site-packages/pytz/zoneinfo/Asia/Qatar | Bin 0 -> 225 bytes .../pytz/zoneinfo/Asia/Qyzylorda | Bin 0 -> 1047 bytes .../site-packages/pytz/zoneinfo/Asia/Rangoon | Bin 0 -> 297 bytes .../site-packages/pytz/zoneinfo/Asia/Riyadh | Bin 0 -> 187 bytes .../site-packages/pytz/zoneinfo/Asia/Saigon | Bin 0 -> 389 bytes .../site-packages/pytz/zoneinfo/Asia/Sakhalin | Bin 0 -> 1234 bytes .../pytz/zoneinfo/Asia/Samarkand | Bin 0 -> 619 bytes .../site-packages/pytz/zoneinfo/Asia/Seoul | Bin 0 -> 531 bytes .../site-packages/pytz/zoneinfo/Asia/Shanghai | Bin 0 -> 414 bytes .../pytz/zoneinfo/Asia/Singapore | Bin 0 -> 424 bytes .../pytz/zoneinfo/Asia/Srednekolymsk | Bin 0 -> 1244 bytes .../site-packages/pytz/zoneinfo/Asia/Taipei | Bin 0 -> 790 bytes .../site-packages/pytz/zoneinfo/Asia/Tashkent | Bin 0 -> 635 bytes .../site-packages/pytz/zoneinfo/Asia/Tbilisi | Bin 0 -> 1080 bytes .../site-packages/pytz/zoneinfo/Asia/Tehran | Bin 0 -> 1718 bytes .../site-packages/pytz/zoneinfo/Asia/Tel_Aviv | Bin 0 -> 2265 bytes .../site-packages/pytz/zoneinfo/Asia/Thimbu | Bin 0 -> 229 bytes .../site-packages/pytz/zoneinfo/Asia/Thimphu | Bin 0 -> 229 bytes .../site-packages/pytz/zoneinfo/Asia/Tokyo | Bin 0 -> 318 bytes .../site-packages/pytz/zoneinfo/Asia/Tomsk | Bin 0 -> 1255 bytes .../pytz/zoneinfo/Asia/Ujung_Pandang | Bin 0 -> 288 bytes .../pytz/zoneinfo/Asia/Ulaanbaatar | Bin 0 -> 921 bytes .../pytz/zoneinfo/Asia/Ulan_Bator | Bin 0 -> 921 bytes .../site-packages/pytz/zoneinfo/Asia/Urumqi | Bin 0 -> 187 bytes .../site-packages/pytz/zoneinfo/Asia/Ust-Nera | Bin 0 -> 1290 bytes .../pytz/zoneinfo/Asia/Vientiane | Bin 0 -> 220 bytes .../pytz/zoneinfo/Asia/Vladivostok | Bin 0 -> 1244 bytes .../site-packages/pytz/zoneinfo/Asia/Yakutsk | Bin 0 -> 1243 bytes .../site-packages/pytz/zoneinfo/Asia/Yangon | Bin 0 -> 297 bytes .../pytz/zoneinfo/Asia/Yekaterinburg | Bin 0 -> 1281 bytes .../site-packages/pytz/zoneinfo/Asia/Yerevan | Bin 0 -> 1213 bytes .../pytz/zoneinfo/Atlantic/Azores | Bin 0 -> 3477 bytes .../pytz/zoneinfo/Atlantic/Bermuda | Bin 0 -> 2004 bytes .../pytz/zoneinfo/Atlantic/Canary | Bin 0 -> 1911 bytes .../pytz/zoneinfo/Atlantic/Cape_Verde | Bin 0 -> 268 bytes .../pytz/zoneinfo/Atlantic/Faeroe | Bin 0 -> 1829 bytes .../pytz/zoneinfo/Atlantic/Faroe | Bin 0 -> 1829 bytes .../pytz/zoneinfo/Atlantic/Jan_Mayen | Bin 0 -> 2251 bytes .../pytz/zoneinfo/Atlantic/Madeira | Bin 0 -> 3468 bytes .../pytz/zoneinfo/Atlantic/Reykjavik | Bin 0 -> 1188 bytes .../pytz/zoneinfo/Atlantic/South_Georgia | Bin 0 -> 181 bytes .../pytz/zoneinfo/Atlantic/St_Helena | Bin 0 -> 170 bytes .../pytz/zoneinfo/Atlantic/Stanley | Bin 0 -> 1251 bytes .../site-packages/pytz/zoneinfo/Australia/ACT | Bin 0 -> 2223 bytes .../pytz/zoneinfo/Australia/Adelaide | Bin 0 -> 2238 bytes .../pytz/zoneinfo/Australia/Brisbane | Bin 0 -> 452 bytes .../pytz/zoneinfo/Australia/Broken_Hill | Bin 0 -> 2274 bytes .../pytz/zoneinfo/Australia/Canberra | Bin 0 -> 2223 bytes .../pytz/zoneinfo/Australia/Currie | Bin 0 -> 2223 bytes .../pytz/zoneinfo/Australia/Darwin | Bin 0 -> 323 bytes .../pytz/zoneinfo/Australia/Eucla | Bin 0 -> 503 bytes .../pytz/zoneinfo/Australia/Hobart | Bin 0 -> 2335 bytes .../site-packages/pytz/zoneinfo/Australia/LHI | Bin 0 -> 1889 bytes .../pytz/zoneinfo/Australia/Lindeman | Bin 0 -> 522 bytes .../pytz/zoneinfo/Australia/Lord_Howe | Bin 0 -> 1889 bytes .../pytz/zoneinfo/Australia/Melbourne | Bin 0 -> 2223 bytes .../site-packages/pytz/zoneinfo/Australia/NSW | Bin 0 -> 2223 bytes .../pytz/zoneinfo/Australia/North | Bin 0 -> 323 bytes .../pytz/zoneinfo/Australia/Perth | Bin 0 -> 479 bytes .../pytz/zoneinfo/Australia/Queensland | Bin 0 -> 452 bytes .../pytz/zoneinfo/Australia/South | Bin 0 -> 2238 bytes .../pytz/zoneinfo/Australia/Sydney | Bin 0 -> 2223 bytes .../pytz/zoneinfo/Australia/Tasmania | Bin 0 -> 2335 bytes .../pytz/zoneinfo/Australia/Victoria | Bin 0 -> 2223 bytes .../pytz/zoneinfo/Australia/West | Bin 0 -> 479 bytes .../pytz/zoneinfo/Australia/Yancowinna | Bin 0 -> 2274 bytes .../site-packages/pytz/zoneinfo/Brazil/Acre | Bin 0 -> 662 bytes .../pytz/zoneinfo/Brazil/DeNoronha | Bin 0 -> 742 bytes .../site-packages/pytz/zoneinfo/Brazil/East | Bin 0 -> 2016 bytes .../site-packages/pytz/zoneinfo/Brazil/West | Bin 0 -> 630 bytes .../python2.7/site-packages/pytz/zoneinfo/CET | Bin 0 -> 2102 bytes .../site-packages/pytz/zoneinfo/CST6CDT | Bin 0 -> 2294 bytes .../pytz/zoneinfo/Canada/Atlantic | Bin 0 -> 3438 bytes .../pytz/zoneinfo/Canada/Central | Bin 0 -> 2891 bytes .../pytz/zoneinfo/Canada/Eastern | Bin 0 -> 3503 bytes .../pytz/zoneinfo/Canada/Mountain | Bin 0 -> 2402 bytes .../pytz/zoneinfo/Canada/Newfoundland | Bin 0 -> 3664 bytes .../pytz/zoneinfo/Canada/Pacific | Bin 0 -> 2901 bytes .../pytz/zoneinfo/Canada/Saskatchewan | Bin 0 -> 994 bytes .../site-packages/pytz/zoneinfo/Canada/Yukon | Bin 0 -> 2093 bytes .../pytz/zoneinfo/Chile/Continental | Bin 0 -> 2538 bytes .../pytz/zoneinfo/Chile/EasterIsland | Bin 0 -> 2242 bytes .../site-packages/pytz/zoneinfo/Cuba | Bin 0 -> 2437 bytes .../python2.7/site-packages/pytz/zoneinfo/EET | Bin 0 -> 1876 bytes .../python2.7/site-packages/pytz/zoneinfo/EST | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/EST5EDT | Bin 0 -> 2294 bytes .../site-packages/pytz/zoneinfo/Egypt | Bin 0 -> 1972 bytes .../site-packages/pytz/zoneinfo/Eire | Bin 0 -> 3543 bytes .../site-packages/pytz/zoneinfo/Etc/GMT | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+0 | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+1 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+10 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+11 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+12 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+2 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+3 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+4 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+5 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+6 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+7 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+8 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT+9 | Bin 0 -> 148 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-0 | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-1 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-10 | Bin 0 -> 150 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-11 | Bin 0 -> 150 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-12 | Bin 0 -> 150 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-13 | Bin 0 -> 150 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-14 | Bin 0 -> 150 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-2 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-3 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-4 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-5 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-6 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-7 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-8 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT-9 | Bin 0 -> 149 bytes .../site-packages/pytz/zoneinfo/Etc/GMT0 | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Etc/Greenwich | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Etc/UCT | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Etc/UTC | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Etc/Universal | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Etc/Zulu | Bin 0 -> 127 bytes .../pytz/zoneinfo/Europe/Amsterdam | Bin 0 -> 2949 bytes .../pytz/zoneinfo/Europe/Andorra | Bin 0 -> 1751 bytes .../pytz/zoneinfo/Europe/Astrakhan | Bin 0 -> 1197 bytes .../site-packages/pytz/zoneinfo/Europe/Athens | Bin 0 -> 2271 bytes .../pytz/zoneinfo/Europe/Belfast | Bin 0 -> 3687 bytes .../pytz/zoneinfo/Europe/Belgrade | Bin 0 -> 1957 bytes .../site-packages/pytz/zoneinfo/Europe/Berlin | Bin 0 -> 2335 bytes .../pytz/zoneinfo/Europe/Bratislava | Bin 0 -> 2272 bytes .../pytz/zoneinfo/Europe/Brussels | Bin 0 -> 2970 bytes .../pytz/zoneinfo/Europe/Bucharest | Bin 0 -> 2221 bytes .../pytz/zoneinfo/Europe/Budapest | Bin 0 -> 2405 bytes .../pytz/zoneinfo/Europe/Busingen | Bin 0 -> 1918 bytes .../pytz/zoneinfo/Europe/Chisinau | Bin 0 -> 2445 bytes .../pytz/zoneinfo/Europe/Copenhagen | Bin 0 -> 2160 bytes .../site-packages/pytz/zoneinfo/Europe/Dublin | Bin 0 -> 3543 bytes .../pytz/zoneinfo/Europe/Gibraltar | Bin 0 -> 3061 bytes .../pytz/zoneinfo/Europe/Guernsey | Bin 0 -> 3687 bytes .../pytz/zoneinfo/Europe/Helsinki | Bin 0 -> 1909 bytes .../pytz/zoneinfo/Europe/Isle_of_Man | Bin 0 -> 3687 bytes .../pytz/zoneinfo/Europe/Istanbul | Bin 0 -> 2166 bytes .../site-packages/pytz/zoneinfo/Europe/Jersey | Bin 0 -> 3687 bytes .../pytz/zoneinfo/Europe/Kaliningrad | Bin 0 -> 1518 bytes .../site-packages/pytz/zoneinfo/Europe/Kiev | Bin 0 -> 2097 bytes .../site-packages/pytz/zoneinfo/Europe/Kirov | Bin 0 -> 1167 bytes .../site-packages/pytz/zoneinfo/Europe/Lisbon | Bin 0 -> 3453 bytes .../pytz/zoneinfo/Europe/Ljubljana | Bin 0 -> 1957 bytes .../site-packages/pytz/zoneinfo/Europe/London | Bin 0 -> 3687 bytes .../pytz/zoneinfo/Europe/Luxembourg | Bin 0 -> 2974 bytes .../site-packages/pytz/zoneinfo/Europe/Madrid | Bin 0 -> 2637 bytes .../site-packages/pytz/zoneinfo/Europe/Malta | Bin 0 -> 2629 bytes .../pytz/zoneinfo/Europe/Mariehamn | Bin 0 -> 1909 bytes .../site-packages/pytz/zoneinfo/Europe/Minsk | Bin 0 -> 1370 bytes .../site-packages/pytz/zoneinfo/Europe/Monaco | Bin 0 -> 2953 bytes .../site-packages/pytz/zoneinfo/Europe/Moscow | Bin 0 -> 1544 bytes .../pytz/zoneinfo/Europe/Nicosia | Bin 0 -> 2016 bytes .../site-packages/pytz/zoneinfo/Europe/Oslo | Bin 0 -> 2251 bytes .../site-packages/pytz/zoneinfo/Europe/Paris | Bin 0 -> 2971 bytes .../pytz/zoneinfo/Europe/Podgorica | Bin 0 -> 1957 bytes .../site-packages/pytz/zoneinfo/Europe/Prague | Bin 0 -> 2272 bytes .../site-packages/pytz/zoneinfo/Europe/Riga | Bin 0 -> 2235 bytes .../site-packages/pytz/zoneinfo/Europe/Rome | Bin 0 -> 2692 bytes .../site-packages/pytz/zoneinfo/Europe/Samara | Bin 0 -> 1253 bytes .../pytz/zoneinfo/Europe/San_Marino | Bin 0 -> 2692 bytes .../pytz/zoneinfo/Europe/Sarajevo | Bin 0 -> 1957 bytes .../pytz/zoneinfo/Europe/Saratov | Bin 0 -> 1197 bytes .../pytz/zoneinfo/Europe/Simferopol | Bin 0 -> 1490 bytes .../site-packages/pytz/zoneinfo/Europe/Skopje | Bin 0 -> 1957 bytes .../site-packages/pytz/zoneinfo/Europe/Sofia | Bin 0 -> 2130 bytes .../pytz/zoneinfo/Europe/Stockholm | Bin 0 -> 1918 bytes .../pytz/zoneinfo/Europe/Tallinn | Bin 0 -> 2187 bytes .../site-packages/pytz/zoneinfo/Europe/Tirane | Bin 0 -> 2098 bytes .../pytz/zoneinfo/Europe/Tiraspol | Bin 0 -> 2445 bytes .../pytz/zoneinfo/Europe/Ulyanovsk | Bin 0 -> 1281 bytes .../pytz/zoneinfo/Europe/Uzhgorod | Bin 0 -> 2103 bytes .../site-packages/pytz/zoneinfo/Europe/Vaduz | Bin 0 -> 1918 bytes .../pytz/zoneinfo/Europe/Vatican | Bin 0 -> 2692 bytes .../site-packages/pytz/zoneinfo/Europe/Vienna | Bin 0 -> 2237 bytes .../pytz/zoneinfo/Europe/Vilnius | Bin 0 -> 2199 bytes .../pytz/zoneinfo/Europe/Volgograd | Bin 0 -> 1167 bytes .../site-packages/pytz/zoneinfo/Europe/Warsaw | Bin 0 -> 2705 bytes .../site-packages/pytz/zoneinfo/Europe/Zagreb | Bin 0 -> 1957 bytes .../pytz/zoneinfo/Europe/Zaporozhye | Bin 0 -> 2115 bytes .../site-packages/pytz/zoneinfo/Europe/Zurich | Bin 0 -> 1918 bytes .../site-packages/pytz/zoneinfo/Factory | Bin 0 -> 148 bytes .../python2.7/site-packages/pytz/zoneinfo/GB | Bin 0 -> 3687 bytes .../site-packages/pytz/zoneinfo/GB-Eire | Bin 0 -> 3687 bytes .../python2.7/site-packages/pytz/zoneinfo/GMT | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/GMT+0 | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/GMT-0 | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/GMT0 | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Greenwich | Bin 0 -> 127 bytes .../python2.7/site-packages/pytz/zoneinfo/HST | Bin 0 -> 128 bytes .../site-packages/pytz/zoneinfo/Hongkong | Bin 0 -> 1189 bytes .../site-packages/pytz/zoneinfo/Iceland | Bin 0 -> 1188 bytes .../pytz/zoneinfo/Indian/Antananarivo | Bin 0 -> 285 bytes .../site-packages/pytz/zoneinfo/Indian/Chagos | Bin 0 -> 225 bytes .../pytz/zoneinfo/Indian/Christmas | Bin 0 -> 182 bytes .../site-packages/pytz/zoneinfo/Indian/Cocos | Bin 0 -> 191 bytes .../site-packages/pytz/zoneinfo/Indian/Comoro | Bin 0 -> 285 bytes .../pytz/zoneinfo/Indian/Kerguelen | Bin 0 -> 187 bytes .../site-packages/pytz/zoneinfo/Indian/Mahe | Bin 0 -> 187 bytes .../pytz/zoneinfo/Indian/Maldives | Bin 0 -> 220 bytes .../pytz/zoneinfo/Indian/Mauritius | Bin 0 -> 267 bytes .../pytz/zoneinfo/Indian/Mayotte | Bin 0 -> 285 bytes .../pytz/zoneinfo/Indian/Reunion | Bin 0 -> 187 bytes .../site-packages/pytz/zoneinfo/Iran | Bin 0 -> 1718 bytes .../site-packages/pytz/zoneinfo/Israel | Bin 0 -> 2265 bytes .../site-packages/pytz/zoneinfo/Jamaica | Bin 0 -> 507 bytes .../site-packages/pytz/zoneinfo/Japan | Bin 0 -> 318 bytes .../site-packages/pytz/zoneinfo/Kwajalein | Bin 0 -> 259 bytes .../site-packages/pytz/zoneinfo/Libya | Bin 0 -> 655 bytes .../python2.7/site-packages/pytz/zoneinfo/MET | Bin 0 -> 2102 bytes .../python2.7/site-packages/pytz/zoneinfo/MST | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/MST7MDT | Bin 0 -> 2294 bytes .../pytz/zoneinfo/Mexico/BajaNorte | Bin 0 -> 2356 bytes .../pytz/zoneinfo/Mexico/BajaSur | Bin 0 -> 1564 bytes .../pytz/zoneinfo/Mexico/General | Bin 0 -> 1618 bytes .../python2.7/site-packages/pytz/zoneinfo/NZ | Bin 0 -> 2460 bytes .../site-packages/pytz/zoneinfo/NZ-CHAT | Bin 0 -> 2087 bytes .../site-packages/pytz/zoneinfo/Navajo | Bin 0 -> 2453 bytes .../python2.7/site-packages/pytz/zoneinfo/PRC | Bin 0 -> 414 bytes .../site-packages/pytz/zoneinfo/PST8PDT | Bin 0 -> 2294 bytes .../site-packages/pytz/zoneinfo/Pacific/Apia | Bin 0 -> 1134 bytes .../pytz/zoneinfo/Pacific/Auckland | Bin 0 -> 2460 bytes .../pytz/zoneinfo/Pacific/Bougainville | Bin 0 -> 296 bytes .../pytz/zoneinfo/Pacific/Chatham | Bin 0 -> 2087 bytes .../site-packages/pytz/zoneinfo/Pacific/Chuuk | Bin 0 -> 183 bytes .../pytz/zoneinfo/Pacific/Easter | Bin 0 -> 2242 bytes .../site-packages/pytz/zoneinfo/Pacific/Efate | Bin 0 -> 492 bytes .../pytz/zoneinfo/Pacific/Enderbury | Bin 0 -> 259 bytes .../pytz/zoneinfo/Pacific/Fakaofo | Bin 0 -> 221 bytes .../site-packages/pytz/zoneinfo/Pacific/Fiji | Bin 0 -> 1104 bytes .../pytz/zoneinfo/Pacific/Funafuti | Bin 0 -> 183 bytes .../pytz/zoneinfo/Pacific/Galapagos | Bin 0 -> 268 bytes .../pytz/zoneinfo/Pacific/Gambier | Bin 0 -> 186 bytes .../pytz/zoneinfo/Pacific/Guadalcanal | Bin 0 -> 188 bytes .../site-packages/pytz/zoneinfo/Pacific/Guam | Bin 0 -> 225 bytes .../pytz/zoneinfo/Pacific/Honolulu | Bin 0 -> 276 bytes .../pytz/zoneinfo/Pacific/Johnston | Bin 0 -> 276 bytes .../pytz/zoneinfo/Pacific/Kiritimati | Bin 0 -> 263 bytes .../pytz/zoneinfo/Pacific/Kosrae | Bin 0 -> 251 bytes .../pytz/zoneinfo/Pacific/Kwajalein | Bin 0 -> 259 bytes .../pytz/zoneinfo/Pacific/Majuro | Bin 0 -> 221 bytes .../pytz/zoneinfo/Pacific/Marquesas | Bin 0 -> 195 bytes .../pytz/zoneinfo/Pacific/Midway | Bin 0 -> 196 bytes .../site-packages/pytz/zoneinfo/Pacific/Nauru | Bin 0 -> 282 bytes .../site-packages/pytz/zoneinfo/Pacific/Niue | Bin 0 -> 266 bytes .../pytz/zoneinfo/Pacific/Norfolk | Bin 0 -> 323 bytes .../pytz/zoneinfo/Pacific/Noumea | Bin 0 -> 328 bytes .../pytz/zoneinfo/Pacific/Pago_Pago | Bin 0 -> 196 bytes .../site-packages/pytz/zoneinfo/Pacific/Palau | Bin 0 -> 182 bytes .../pytz/zoneinfo/Pacific/Pitcairn | Bin 0 -> 223 bytes .../pytz/zoneinfo/Pacific/Pohnpei | Bin 0 -> 183 bytes .../pytz/zoneinfo/Pacific/Ponape | Bin 0 -> 183 bytes .../pytz/zoneinfo/Pacific/Port_Moresby | Bin 0 -> 206 bytes .../pytz/zoneinfo/Pacific/Rarotonga | Bin 0 -> 602 bytes .../pytz/zoneinfo/Pacific/Saipan | Bin 0 -> 225 bytes .../site-packages/pytz/zoneinfo/Pacific/Samoa | Bin 0 -> 196 bytes .../pytz/zoneinfo/Pacific/Tahiti | Bin 0 -> 187 bytes .../pytz/zoneinfo/Pacific/Tarawa | Bin 0 -> 183 bytes .../pytz/zoneinfo/Pacific/Tongatapu | Bin 0 -> 393 bytes .../site-packages/pytz/zoneinfo/Pacific/Truk | Bin 0 -> 183 bytes .../site-packages/pytz/zoneinfo/Pacific/Wake | Bin 0 -> 183 bytes .../pytz/zoneinfo/Pacific/Wallis | Bin 0 -> 183 bytes .../site-packages/pytz/zoneinfo/Pacific/Yap | Bin 0 -> 183 bytes .../site-packages/pytz/zoneinfo/Poland | Bin 0 -> 2705 bytes .../site-packages/pytz/zoneinfo/Portugal | Bin 0 -> 3453 bytes .../python2.7/site-packages/pytz/zoneinfo/ROC | Bin 0 -> 790 bytes .../python2.7/site-packages/pytz/zoneinfo/ROK | Bin 0 -> 531 bytes .../site-packages/pytz/zoneinfo/Singapore | Bin 0 -> 424 bytes .../site-packages/pytz/zoneinfo/Turkey | Bin 0 -> 2166 bytes .../python2.7/site-packages/pytz/zoneinfo/UCT | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/US/Alaska | Bin 0 -> 2380 bytes .../site-packages/pytz/zoneinfo/US/Aleutian | Bin 0 -> 2365 bytes .../site-packages/pytz/zoneinfo/US/Arizona | Bin 0 -> 353 bytes .../site-packages/pytz/zoneinfo/US/Central | Bin 0 -> 3585 bytes .../pytz/zoneinfo/US/East-Indiana | Bin 0 -> 1675 bytes .../site-packages/pytz/zoneinfo/US/Eastern | Bin 0 -> 3545 bytes .../site-packages/pytz/zoneinfo/US/Hawaii | Bin 0 -> 276 bytes .../pytz/zoneinfo/US/Indiana-Starke | Bin 0 -> 2437 bytes .../site-packages/pytz/zoneinfo/US/Michigan | Bin 0 -> 2188 bytes .../site-packages/pytz/zoneinfo/US/Mountain | Bin 0 -> 2453 bytes .../site-packages/pytz/zoneinfo/US/Pacific | Bin 0 -> 2845 bytes .../pytz/zoneinfo/US/Pacific-New | Bin 0 -> 2845 bytes .../site-packages/pytz/zoneinfo/US/Samoa | Bin 0 -> 196 bytes .../python2.7/site-packages/pytz/zoneinfo/UTC | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/Universal | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/W-SU | Bin 0 -> 1544 bytes .../python2.7/site-packages/pytz/zoneinfo/WET | Bin 0 -> 1873 bytes .../site-packages/pytz/zoneinfo/Zulu | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/iso3166.tab | 274 + .../site-packages/pytz/zoneinfo/leapseconds | 61 + .../site-packages/pytz/zoneinfo/localtime | Bin 0 -> 127 bytes .../site-packages/pytz/zoneinfo/posixrules | Bin 0 -> 3545 bytes .../site-packages/pytz/zoneinfo/tzdata.zi | 4146 +++++++++ .../site-packages/pytz/zoneinfo/zone.tab | 448 + .../site-packages/pytz/zoneinfo/zone1970.tab | 381 + .../requests-2.18.4.dist-info/DESCRIPTION.rst | 1645 ++++ .../requests-2.18.4.dist-info/INSTALLER | 1 + .../requests-2.18.4.dist-info/METADATA | 1680 ++++ .../requests-2.18.4.dist-info/RECORD | 43 + .../requests-2.18.4.dist-info/WHEEL | 6 + .../requests-2.18.4.dist-info/metadata.json | 1 + .../requests-2.18.4.dist-info/top_level.txt | 1 + .../site-packages/requests/__init__.py | 121 + .../site-packages/requests/__init__.pyc | Bin 0 -> 4080 bytes .../site-packages/requests/__version__.py | 14 + .../site-packages/requests/__version__.pyc | Bin 0 -> 625 bytes .../site-packages/requests/_internal_utils.py | 42 + .../requests/_internal_utils.pyc | Bin 0 -> 1649 bytes .../site-packages/requests/adapters.py | 525 ++ .../site-packages/requests/adapters.pyc | Bin 0 -> 19705 bytes .../python2.7/site-packages/requests/api.py | 152 + .../python2.7/site-packages/requests/api.pyc | Bin 0 -> 7402 bytes .../python2.7/site-packages/requests/auth.py | 293 + .../python2.7/site-packages/requests/auth.pyc | Bin 0 -> 10798 bytes .../python2.7/site-packages/requests/certs.py | 18 + .../site-packages/requests/certs.pyc | Bin 0 -> 644 bytes .../site-packages/requests/compat.py | 69 + .../site-packages/requests/compat.pyc | Bin 0 -> 1914 bytes .../site-packages/requests/cookies.py | 542 ++ .../site-packages/requests/cookies.pyc | Bin 0 -> 24418 bytes .../site-packages/requests/exceptions.py | 122 + .../site-packages/requests/exceptions.pyc | Bin 0 -> 7818 bytes .../python2.7/site-packages/requests/help.py | 120 + .../python2.7/site-packages/requests/help.pyc | Bin 0 -> 3489 bytes .../python2.7/site-packages/requests/hooks.py | 34 + .../site-packages/requests/hooks.pyc | Bin 0 -> 1387 bytes .../site-packages/requests/models.py | 948 ++ .../site-packages/requests/models.pyc | Bin 0 -> 31143 bytes .../site-packages/requests/packages.py | 14 + .../site-packages/requests/packages.pyc | Bin 0 -> 527 bytes .../site-packages/requests/sessions.py | 737 ++ .../site-packages/requests/sessions.pyc | Bin 0 -> 22895 bytes .../site-packages/requests/status_codes.py | 91 + .../site-packages/requests/status_codes.pyc | Bin 0 -> 6275 bytes .../site-packages/requests/structures.py | 105 + .../site-packages/requests/structures.pyc | Bin 0 -> 6141 bytes .../python2.7/site-packages/requests/utils.py | 904 ++ .../site-packages/requests/utils.pyc | Bin 0 -> 27106 bytes .../DESCRIPTION.rst | 36 + .../setuptools-36.7.1.dist-info/INSTALLER | 1 + .../setuptools-36.7.1.dist-info/LICENSE.txt | 19 + .../setuptools-36.7.1.dist-info/METADATA | 69 + .../setuptools-36.7.1.dist-info/RECORD | 160 + .../setuptools-36.7.1.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 65 + .../setuptools-36.7.1.dist-info/metadata.json | 1 + .../setuptools-36.7.1.dist-info/top_level.txt | 3 + .../setuptools-36.7.1.dist-info/zip-safe | 1 + .../site-packages/setuptools/__init__.py | 180 + .../site-packages/setuptools/__init__.pyc | Bin 0 -> 8643 bytes .../site-packages/setuptools/archive_util.py | 173 + .../site-packages/setuptools/archive_util.pyc | Bin 0 -> 6581 bytes .../site-packages/setuptools/build_meta.py | 148 + .../site-packages/setuptools/build_meta.pyc | Bin 0 -> 6754 bytes .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 18 + .../setuptools/command/__init__.pyc | Bin 0 -> 934 bytes .../site-packages/setuptools/command/alias.py | 80 + .../setuptools/command/alias.pyc | Bin 0 -> 3468 bytes .../setuptools/command/bdist_egg.py | 496 ++ .../setuptools/command/bdist_egg.pyc | Bin 0 -> 19697 bytes .../setuptools/command/bdist_rpm.py | 43 + .../setuptools/command/bdist_rpm.pyc | Bin 0 -> 2122 bytes .../setuptools/command/bdist_wininst.py | 21 + .../setuptools/command/bdist_wininst.pyc | Bin 0 -> 1417 bytes .../setuptools/command/build_clib.py | 98 + .../setuptools/command/build_clib.pyc | Bin 0 -> 3000 bytes .../setuptools/command/build_ext.py | 328 + .../setuptools/command/build_ext.pyc | Bin 0 -> 13819 bytes .../setuptools/command/build_py.py | 270 + .../setuptools/command/build_py.pyc | Bin 0 -> 11915 bytes .../setuptools/command/develop.py | 216 + .../setuptools/command/develop.pyc | Bin 0 -> 8637 bytes .../setuptools/command/dist_info.py | 40 + .../setuptools/command/dist_info.pyc | Bin 0 -> 2186 bytes .../setuptools/command/easy_install.py | 2301 +++++ .../setuptools/command/easy_install.pyc | Bin 0 -> 86543 bytes .../setuptools/command/egg_info.py | 701 ++ .../setuptools/command/egg_info.pyc | Bin 0 -> 28767 bytes .../setuptools/command/install.py | 125 + .../setuptools/command/install.pyc | Bin 0 -> 5473 bytes .../setuptools/command/install_egg_info.py | 62 + .../setuptools/command/install_egg_info.pyc | Bin 0 -> 3623 bytes .../setuptools/command/install_lib.py | 121 + .../setuptools/command/install_lib.pyc | Bin 0 -> 5494 bytes .../setuptools/command/install_scripts.py | 65 + .../setuptools/command/install_scripts.pyc | Bin 0 -> 3151 bytes .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 136 + .../setuptools/command/py36compat.pyc | Bin 0 -> 6174 bytes .../setuptools/command/register.py | 10 + .../setuptools/command/register.pyc | Bin 0 -> 866 bytes .../setuptools/command/rotate.py | 66 + .../setuptools/command/rotate.pyc | Bin 0 -> 3312 bytes .../setuptools/command/saveopts.py | 22 + .../setuptools/command/saveopts.pyc | Bin 0 -> 1285 bytes .../site-packages/setuptools/command/sdist.py | 207 + .../setuptools/command/sdist.pyc | Bin 0 -> 8838 bytes .../setuptools/command/setopt.py | 149 + .../setuptools/command/setopt.pyc | Bin 0 -> 6576 bytes .../site-packages/setuptools/command/test.py | 258 + .../site-packages/setuptools/command/test.pyc | Bin 0 -> 11329 bytes .../setuptools/command/upload.py | 42 + .../setuptools/command/upload.pyc | Bin 0 -> 1896 bytes .../setuptools/command/upload_docs.py | 206 + .../setuptools/command/upload_docs.pyc | Bin 0 -> 8414 bytes .../site-packages/setuptools/config.py | 554 ++ .../site-packages/setuptools/config.pyc | Bin 0 -> 18673 bytes .../site-packages/setuptools/dep_util.py | 23 + .../site-packages/setuptools/dep_util.pyc | Bin 0 -> 1069 bytes .../site-packages/setuptools/depends.py | 186 + .../site-packages/setuptools/depends.pyc | Bin 0 -> 7142 bytes .../site-packages/setuptools/dist.py | 1010 +++ .../site-packages/setuptools/dist.pyc | Bin 0 -> 43193 bytes .../site-packages/setuptools/extension.py | 57 + .../site-packages/setuptools/extension.pyc | Bin 0 -> 2730 bytes .../setuptools/extern/__init__.py | 4 + .../setuptools/extern/__init__.pyc | Bin 0 -> 390 bytes .../site-packages/setuptools/glob.py | 176 + .../site-packages/setuptools/glob.pyc | Bin 0 -> 5390 bytes .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/launch.pyc | Bin 0 -> 1104 bytes .../site-packages/setuptools/lib2to3_ex.py | 62 + .../site-packages/setuptools/lib2to3_ex.pyc | Bin 0 -> 3472 bytes .../site-packages/setuptools/monkey.py | 197 + .../site-packages/setuptools/monkey.pyc | Bin 0 -> 7025 bytes .../site-packages/setuptools/msvc.py | 1302 +++ .../site-packages/setuptools/msvc.pyc | Bin 0 -> 44569 bytes .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/namespaces.pyc | Bin 0 -> 5657 bytes .../site-packages/setuptools/package_index.py | 1115 +++ .../setuptools/package_index.pyc | Bin 0 -> 44191 bytes .../site-packages/setuptools/py26compat.py | 31 + .../site-packages/setuptools/py26compat.pyc | Bin 0 -> 1505 bytes .../site-packages/setuptools/py27compat.py | 28 + .../site-packages/setuptools/py27compat.pyc | Bin 0 -> 1253 bytes .../site-packages/setuptools/py31compat.py | 56 + .../site-packages/setuptools/py31compat.pyc | Bin 0 -> 2753 bytes .../site-packages/setuptools/py33compat.py | 45 + .../site-packages/setuptools/py33compat.pyc | Bin 0 -> 1710 bytes .../site-packages/setuptools/py36compat.py | 82 + .../site-packages/setuptools/py36compat.pyc | Bin 0 -> 3136 bytes .../site-packages/setuptools/sandbox.py | 495 ++ .../site-packages/setuptools/sandbox.pyc | Bin 0 -> 21938 bytes .../setuptools/script (dev).tmpl | 5 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.py | 74 + .../site-packages/setuptools/site-patch.pyc | Bin 0 -> 1843 bytes .../site-packages/setuptools/ssl_support.py | 255 + .../site-packages/setuptools/ssl_support.pyc | Bin 0 -> 9416 bytes .../site-packages/setuptools/unicode_utils.py | 44 + .../setuptools/unicode_utils.pyc | Bin 0 -> 1680 bytes .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/version.pyc | Bin 0 -> 374 bytes .../setuptools/windows_support.py | 29 + .../setuptools/windows_support.pyc | Bin 0 -> 1482 bytes .../six-1.11.0.dist-info/DESCRIPTION.rst | 27 + .../six-1.11.0.dist-info/INSTALLER | 1 + .../six-1.11.0.dist-info/METADATA | 43 + .../site-packages/six-1.11.0.dist-info/RECORD | 9 + .../site-packages/six-1.11.0.dist-info/WHEEL | 6 + .../six-1.11.0.dist-info/metadata.json | 1 + .../six-1.11.0.dist-info/top_level.txt | 1 + venv/lib/python2.7/site-packages/six.py | 891 ++ venv/lib/python2.7/site-packages/six.pyc | Bin 0 -> 34370 bytes .../twilio-6.8.4.dist-info/DESCRIPTION.rst | 11 + .../twilio-6.8.4.dist-info/INSTALLER | 1 + .../twilio-6.8.4.dist-info/METADATA | 41 + .../twilio-6.8.4.dist-info/RECORD | 631 ++ .../twilio-6.8.4.dist-info/WHEEL | 6 + .../twilio-6.8.4.dist-info/metadata.json | 1 + .../twilio-6.8.4.dist-info/top_level.txt | 1 + .../site-packages/twilio/__init__.py | 3 + .../site-packages/twilio/__init__.pyc | Bin 0 -> 299 bytes .../site-packages/twilio/base/__init__.py | 0 .../site-packages/twilio/base/__init__.pyc | Bin 0 -> 191 bytes .../site-packages/twilio/base/deserialize.py | 69 + .../site-packages/twilio/base/deserialize.pyc | Bin 0 -> 2851 bytes .../site-packages/twilio/base/domain.py | 48 + .../site-packages/twilio/base/domain.pyc | Bin 0 -> 2336 bytes .../site-packages/twilio/base/exceptions.py | 68 + .../site-packages/twilio/base/exceptions.pyc | Bin 0 -> 3826 bytes .../twilio/base/instance_context.py | 8 + .../twilio/base/instance_context.pyc | Bin 0 -> 771 bytes .../twilio/base/instance_resource.py | 8 + .../twilio/base/instance_resource.pyc | Bin 0 -> 775 bytes .../twilio/base/list_resource.py | 7 + .../twilio/base/list_resource.pyc | Bin 0 -> 759 bytes .../site-packages/twilio/base/obsolete.py | 23 + .../site-packages/twilio/base/obsolete.pyc | Bin 0 -> 1402 bytes .../site-packages/twilio/base/page.py | 136 + .../site-packages/twilio/base/page.pyc | Bin 0 -> 5749 bytes .../site-packages/twilio/base/serialize.py | 75 + .../site-packages/twilio/base/serialize.pyc | Bin 0 -> 3261 bytes .../site-packages/twilio/base/values.py | 12 + .../site-packages/twilio/base/values.pyc | Bin 0 -> 876 bytes .../site-packages/twilio/base/version.py | 211 + .../site-packages/twilio/base/version.pyc | Bin 0 -> 6974 bytes .../python2.7/site-packages/twilio/compat.py | 17 + .../python2.7/site-packages/twilio/compat.pyc | Bin 0 -> 547 bytes .../site-packages/twilio/http/__init__.py | 13 + .../site-packages/twilio/http/__init__.pyc | Bin 0 -> 1049 bytes .../site-packages/twilio/http/http_client.py | 75 + .../site-packages/twilio/http/http_client.pyc | Bin 0 -> 3332 bytes .../site-packages/twilio/http/request.py | 77 + .../site-packages/twilio/http/request.pyc | Bin 0 -> 3369 bytes .../site-packages/twilio/http/response.py | 16 + .../site-packages/twilio/http/response.pyc | Bin 0 -> 1300 bytes .../twilio/http/validation_client.py | 95 + .../twilio/http/validation_client.pyc | Bin 0 -> 4694 bytes .../site-packages/twilio/jwt/__init__.py | 155 + .../site-packages/twilio/jwt/__init__.pyc | Bin 0 -> 5946 bytes .../twilio/jwt/access_token/__init__.py | 65 + .../twilio/jwt/access_token/__init__.pyc | Bin 0 -> 4503 bytes .../twilio/jwt/access_token/grants.py | 191 + .../twilio/jwt/access_token/grants.pyc | Bin 0 -> 9467 bytes .../twilio/jwt/client/__init__.py | 105 + .../twilio/jwt/client/__init__.pyc | Bin 0 -> 5620 bytes .../site-packages/twilio/jwt/compat.py | 25 + .../site-packages/twilio/jwt/compat.pyc | Bin 0 -> 1139 bytes .../twilio/jwt/taskrouter/__init__.py | 134 + .../twilio/jwt/taskrouter/__init__.pyc | Bin 0 -> 7723 bytes .../twilio/jwt/taskrouter/capabilities.py | 112 + .../twilio/jwt/taskrouter/capabilities.pyc | Bin 0 -> 7391 bytes .../twilio/jwt/validation/__init__.py | 88 + .../twilio/jwt/validation/__init__.pyc | Bin 0 -> 3942 bytes .../site-packages/twilio/request_validator.py | 79 + .../twilio/request_validator.pyc | Bin 0 -> 3687 bytes .../site-packages/twilio/rest/__init__.py | 585 ++ .../site-packages/twilio/rest/__init__.pyc | Bin 0 -> 24672 bytes .../twilio/rest/accounts/__init__.py | 53 + .../twilio/rest/accounts/__init__.pyc | Bin 0 -> 2264 bytes .../twilio/rest/accounts/v1/__init__.py | 42 + .../twilio/rest/accounts/v1/__init__.pyc | Bin 0 -> 1966 bytes .../rest/accounts/v1/credential/__init__.py | 133 + .../rest/accounts/v1/credential/__init__.pyc | Bin 0 -> 6030 bytes .../twilio/rest/accounts/v1/credential/aws.py | 412 + .../rest/accounts/v1/credential/aws.pyc | Bin 0 -> 18165 bytes .../rest/accounts/v1/credential/public_key.py | 408 + .../accounts/v1/credential/public_key.pyc | Bin 0 -> 19381 bytes .../site-packages/twilio/rest/api/__init__.py | 222 + .../twilio/rest/api/__init__.pyc | Bin 0 -> 9972 bytes .../twilio/rest/api/v2010/__init__.py | 224 + .../twilio/rest/api/v2010/__init__.pyc | Bin 0 -> 10386 bytes .../twilio/rest/api/v2010/account/__init__.py | 1012 +++ .../rest/api/v2010/account/__init__.pyc | Bin 0 -> 45146 bytes .../api/v2010/account/address/__init__.py | 612 ++ .../api/v2010/account/address/__init__.pyc | Bin 0 -> 25419 bytes .../account/address/dependent_phone_number.py | 299 + .../address/dependent_phone_number.pyc | Bin 0 -> 14384 bytes .../rest/api/v2010/account/application.py | 667 ++ .../rest/api/v2010/account/application.pyc | Bin 0 -> 29278 bytes .../v2010/account/authorized_connect_app.py | 401 + .../v2010/account/authorized_connect_app.pyc | Bin 0 -> 19701 bytes .../available_phone_number/__init__.py | 441 + .../available_phone_number/__init__.pyc | Bin 0 -> 21434 bytes .../account/available_phone_number/local.py | 462 + .../account/available_phone_number/local.pyc | Bin 0 -> 19617 bytes .../account/available_phone_number/mobile.py | 462 + .../account/available_phone_number/mobile.pyc | Bin 0 -> 19686 bytes .../available_phone_number/toll_free.py | 462 + .../available_phone_number/toll_free.pyc | Bin 0 -> 19864 bytes .../rest/api/v2010/account/call/__init__.py | 888 ++ .../rest/api/v2010/account/call/__init__.pyc | Bin 0 -> 39509 bytes .../rest/api/v2010/account/call/feedback.py | 364 + .../rest/api/v2010/account/call/feedback.pyc | Bin 0 -> 16251 bytes .../v2010/account/call/feedback_summary.py | 396 + .../v2010/account/call/feedback_summary.pyc | Bin 0 -> 18410 bytes .../api/v2010/account/call/notification.py | 531 ++ .../api/v2010/account/call/notification.pyc | Bin 0 -> 22853 bytes .../rest/api/v2010/account/call/recording.py | 468 + .../rest/api/v2010/account/call/recording.pyc | Bin 0 -> 20231 bytes .../api/v2010/account/conference/__init__.py | 529 ++ .../api/v2010/account/conference/__init__.pyc | Bin 0 -> 23796 bytes .../v2010/account/conference/participant.py | 623 ++ .../v2010/account/conference/participant.pyc | Bin 0 -> 27947 bytes .../rest/api/v2010/account/connect_app.py | 474 + .../rest/api/v2010/account/connect_app.pyc | Bin 0 -> 22196 bytes .../account/incoming_phone_number/__init__.py | 931 ++ .../incoming_phone_number/__init__.pyc | Bin 0 -> 43010 bytes .../assigned_add_on/__init__.py | 496 ++ .../assigned_add_on/__init__.pyc | Bin 0 -> 24570 bytes .../assigned_add_on_extension.py | 424 + .../assigned_add_on_extension.pyc | Bin 0 -> 22539 bytes .../account/incoming_phone_number/local.py | 554 ++ .../account/incoming_phone_number/local.pyc | Bin 0 -> 23600 bytes .../account/incoming_phone_number/mobile.py | 554 ++ .../account/incoming_phone_number/mobile.pyc | Bin 0 -> 23691 bytes .../incoming_phone_number/toll_free.py | 554 ++ .../incoming_phone_number/toll_free.pyc | Bin 0 -> 23931 bytes .../twilio/rest/api/v2010/account/key.py | 385 + .../twilio/rest/api/v2010/account/key.pyc | Bin 0 -> 16919 bytes .../api/v2010/account/message/__init__.py | 716 ++ .../api/v2010/account/message/__init__.pyc | Bin 0 -> 31434 bytes .../api/v2010/account/message/feedback.py | 201 + .../api/v2010/account/message/feedback.pyc | Bin 0 -> 8599 bytes .../rest/api/v2010/account/message/media.py | 432 + .../rest/api/v2010/account/message/media.pyc | Bin 0 -> 19052 bytes .../twilio/rest/api/v2010/account/new_key.py | 176 + .../twilio/rest/api/v2010/account/new_key.pyc | Bin 0 -> 7538 bytes .../rest/api/v2010/account/new_signing_key.py | 176 + .../api/v2010/account/new_signing_key.pyc | Bin 0 -> 7900 bytes .../rest/api/v2010/account/notification.py | 507 ++ .../rest/api/v2010/account/notification.pyc | Bin 0 -> 22791 bytes .../api/v2010/account/outgoing_caller_id.py | 436 + .../api/v2010/account/outgoing_caller_id.pyc | Bin 0 -> 20360 bytes .../rest/api/v2010/account/queue/__init__.py | 482 ++ .../rest/api/v2010/account/queue/__init__.pyc | Bin 0 -> 21385 bytes .../rest/api/v2010/account/queue/member.py | 403 + .../rest/api/v2010/account/queue/member.pyc | Bin 0 -> 17726 bytes .../api/v2010/account/recording/__init__.py | 559 ++ .../api/v2010/account/recording/__init__.pyc | Bin 0 -> 25324 bytes .../recording/add_on_result/__init__.py | 469 + .../recording/add_on_result/__init__.pyc | Bin 0 -> 22266 bytes .../add_on_result/payload/__init__.py | 456 + .../add_on_result/payload/__init__.pyc | Bin 0 -> 21537 bytes .../v2010/account/recording/transcription.py | 460 + .../v2010/account/recording/transcription.pyc | Bin 0 -> 21197 bytes .../rest/api/v2010/account/short_code.py | 487 ++ .../rest/api/v2010/account/short_code.pyc | Bin 0 -> 21679 bytes .../rest/api/v2010/account/signing_key.py | 385 + .../rest/api/v2010/account/signing_key.pyc | Bin 0 -> 17773 bytes .../rest/api/v2010/account/sip/__init__.py | 153 + .../rest/api/v2010/account/sip/__init__.pyc | Bin 0 -> 7017 bytes .../account/sip/credential_list/__init__.py | 461 + .../account/sip/credential_list/__init__.pyc | Bin 0 -> 21887 bytes .../account/sip/credential_list/credential.py | 463 + .../sip/credential_list/credential.pyc | Bin 0 -> 20986 bytes .../api/v2010/account/sip/domain/__init__.py | 649 ++ .../api/v2010/account/sip/domain/__init__.pyc | Bin 0 -> 28992 bytes .../sip/domain/credential_list_mapping.py | 425 + .../sip/domain/credential_list_mapping.pyc | Bin 0 -> 20557 bytes .../domain/ip_access_control_list_mapping.py | 425 + .../domain/ip_access_control_list_mapping.pyc | Bin 0 -> 21257 bytes .../sip/ip_access_control_list/__init__.py | 461 + .../sip/ip_access_control_list/__init__.pyc | Bin 0 -> 22820 bytes .../sip/ip_access_control_list/ip_address.py | 481 ++ .../sip/ip_access_control_list/ip_address.pyc | Bin 0 -> 21996 bytes .../twilio/rest/api/v2010/account/token.py | 194 + .../twilio/rest/api/v2010/account/token.pyc | Bin 0 -> 8315 bytes .../rest/api/v2010/account/transcription.py | 436 + .../rest/api/v2010/account/transcription.pyc | Bin 0 -> 20631 bytes .../rest/api/v2010/account/usage/__init__.py | 135 + .../rest/api/v2010/account/usage/__init__.pyc | Bin 0 -> 6264 bytes .../v2010/account/usage/record/__init__.py | 689 ++ .../v2010/account/usage/record/__init__.pyc | Bin 0 -> 35946 bytes .../v2010/account/usage/record/all_time.py | 575 ++ .../v2010/account/usage/record/all_time.pyc | Bin 0 -> 30404 bytes .../api/v2010/account/usage/record/daily.py | 575 ++ .../api/v2010/account/usage/record/daily.pyc | Bin 0 -> 30212 bytes .../v2010/account/usage/record/last_month.py | 575 ++ .../v2010/account/usage/record/last_month.pyc | Bin 0 -> 30554 bytes .../api/v2010/account/usage/record/monthly.py | 575 ++ .../v2010/account/usage/record/monthly.pyc | Bin 0 -> 30362 bytes .../v2010/account/usage/record/this_month.py | 575 ++ .../v2010/account/usage/record/this_month.pyc | Bin 0 -> 30554 bytes .../api/v2010/account/usage/record/today.py | 575 ++ .../api/v2010/account/usage/record/today.pyc | Bin 0 -> 30212 bytes .../api/v2010/account/usage/record/yearly.py | 575 ++ .../api/v2010/account/usage/record/yearly.pyc | Bin 0 -> 30287 bytes .../v2010/account/usage/record/yesterday.py | 575 ++ .../v2010/account/usage/record/yesterday.pyc | Bin 0 -> 30512 bytes .../rest/api/v2010/account/usage/trigger.py | 808 ++ .../rest/api/v2010/account/usage/trigger.pyc | Bin 0 -> 40872 bytes .../api/v2010/account/validation_request.py | 190 + .../api/v2010/account/validation_request.pyc | Bin 0 -> 8496 bytes .../twilio/rest/chat/__init__.py | 72 + .../twilio/rest/chat/__init__.pyc | Bin 0 -> 2932 bytes .../twilio/rest/chat/v1/__init__.py | 53 + .../twilio/rest/chat/v1/__init__.pyc | Bin 0 -> 2368 bytes .../twilio/rest/chat/v1/credential.py | 472 + .../twilio/rest/chat/v1/credential.pyc | Bin 0 -> 20119 bytes .../twilio/rest/chat/v1/service/__init__.py | 1027 +++ .../twilio/rest/chat/v1/service/__init__.pyc | Bin 0 -> 46296 bytes .../rest/chat/v1/service/channel/__init__.py | 608 ++ .../rest/chat/v1/service/channel/__init__.pyc | Bin 0 -> 26196 bytes .../rest/chat/v1/service/channel/invite.py | 462 + .../rest/chat/v1/service/channel/invite.pyc | Bin 0 -> 19900 bytes .../rest/chat/v1/service/channel/member.py | 511 ++ .../rest/chat/v1/service/channel/member.pyc | Bin 0 -> 21715 bytes .../rest/chat/v1/service/channel/message.py | 531 ++ .../rest/chat/v1/service/channel/message.pyc | Bin 0 -> 22443 bytes .../twilio/rest/chat/v1/service/role.py | 460 + .../twilio/rest/chat/v1/service/role.pyc | Bin 0 -> 19954 bytes .../rest/chat/v1/service/user/__init__.py | 539 ++ .../rest/chat/v1/service/user/__init__.pyc | Bin 0 -> 22782 bytes .../rest/chat/v1/service/user/user_channel.py | 277 + .../chat/v1/service/user/user_channel.pyc | Bin 0 -> 12915 bytes .../twilio/rest/chat/v2/__init__.py | 53 + .../twilio/rest/chat/v2/__init__.pyc | Bin 0 -> 2368 bytes .../twilio/rest/chat/v2/credential.py | 472 + .../twilio/rest/chat/v2/credential.pyc | Bin 0 -> 20119 bytes .../twilio/rest/chat/v2/service/__init__.py | 829 ++ .../twilio/rest/chat/v2/service/__init__.pyc | Bin 0 -> 36057 bytes .../twilio/rest/chat/v2/service/binding.py | 448 + .../twilio/rest/chat/v2/service/binding.pyc | Bin 0 -> 20020 bytes .../rest/chat/v2/service/channel/__init__.py | 638 ++ .../rest/chat/v2/service/channel/__init__.pyc | Bin 0 -> 27005 bytes .../rest/chat/v2/service/channel/invite.py | 462 + .../rest/chat/v2/service/channel/invite.pyc | Bin 0 -> 19900 bytes .../rest/chat/v2/service/channel/member.py | 547 ++ .../rest/chat/v2/service/channel/member.pyc | Bin 0 -> 22771 bytes .../rest/chat/v2/service/channel/message.py | 596 ++ .../rest/chat/v2/service/channel/message.pyc | Bin 0 -> 24443 bytes .../twilio/rest/chat/v2/service/role.py | 460 + .../twilio/rest/chat/v2/service/role.pyc | Bin 0 -> 19954 bytes .../rest/chat/v2/service/user/__init__.py | 567 ++ .../rest/chat/v2/service/user/__init__.pyc | Bin 0 -> 23915 bytes .../rest/chat/v2/service/user/user_binding.py | 460 + .../chat/v2/service/user/user_binding.pyc | Bin 0 -> 20741 bytes .../rest/chat/v2/service/user/user_channel.py | 277 + .../chat/v2/service/user/user_channel.pyc | Bin 0 -> 12915 bytes .../site-packages/twilio/rest/fax/__init__.py | 53 + .../twilio/rest/fax/__init__.pyc | Bin 0 -> 2159 bytes .../twilio/rest/fax/v1/__init__.py | 42 + .../twilio/rest/fax/v1/__init__.pyc | Bin 0 -> 1871 bytes .../twilio/rest/fax/v1/fax/__init__.py | 626 ++ .../twilio/rest/fax/v1/fax/__init__.pyc | Bin 0 -> 26678 bytes .../twilio/rest/fax/v1/fax/fax_media.py | 381 + .../twilio/rest/fax/v1/fax/fax_media.pyc | Bin 0 -> 17443 bytes .../twilio/rest/ip_messaging/__init__.py | 72 + .../twilio/rest/ip_messaging/__init__.pyc | Bin 0 -> 3095 bytes .../twilio/rest/ip_messaging/v1/__init__.py | 53 + .../twilio/rest/ip_messaging/v1/__init__.pyc | Bin 0 -> 2461 bytes .../twilio/rest/ip_messaging/v1/credential.py | 472 + .../rest/ip_messaging/v1/credential.pyc | Bin 0 -> 20459 bytes .../rest/ip_messaging/v1/service/__init__.py | 1027 +++ .../rest/ip_messaging/v1/service/__init__.pyc | Bin 0 -> 46812 bytes .../v1/service/channel/__init__.py | 608 ++ .../v1/service/channel/__init__.pyc | Bin 0 -> 26664 bytes .../ip_messaging/v1/service/channel/invite.py | 462 + .../v1/service/channel/invite.pyc | Bin 0 -> 20240 bytes .../ip_messaging/v1/service/channel/member.py | 511 ++ .../v1/service/channel/member.pyc | Bin 0 -> 22079 bytes .../v1/service/channel/message.py | 531 ++ .../v1/service/channel/message.pyc | Bin 0 -> 22823 bytes .../rest/ip_messaging/v1/service/role.py | 460 + .../rest/ip_messaging/v1/service/role.pyc | Bin 0 -> 20318 bytes .../ip_messaging/v1/service/user/__init__.py | 539 ++ .../ip_messaging/v1/service/user/__init__.pyc | Bin 0 -> 23186 bytes .../v1/service/user/user_channel.py | 277 + .../v1/service/user/user_channel.pyc | Bin 0 -> 13128 bytes .../twilio/rest/ip_messaging/v2/__init__.py | 53 + .../twilio/rest/ip_messaging/v2/__init__.pyc | Bin 0 -> 2461 bytes .../twilio/rest/ip_messaging/v2/credential.py | 472 + .../rest/ip_messaging/v2/credential.pyc | Bin 0 -> 20459 bytes .../rest/ip_messaging/v2/service/__init__.py | 829 ++ .../rest/ip_messaging/v2/service/__init__.pyc | Bin 0 -> 36613 bytes .../rest/ip_messaging/v2/service/binding.py | 448 + .../rest/ip_messaging/v2/service/binding.pyc | Bin 0 -> 20384 bytes .../v2/service/channel/__init__.py | 638 ++ .../v2/service/channel/__init__.pyc | Bin 0 -> 27473 bytes .../ip_messaging/v2/service/channel/invite.py | 462 + .../v2/service/channel/invite.pyc | Bin 0 -> 20240 bytes .../ip_messaging/v2/service/channel/member.py | 547 ++ .../v2/service/channel/member.pyc | Bin 0 -> 23135 bytes .../v2/service/channel/message.py | 596 ++ .../v2/service/channel/message.pyc | Bin 0 -> 24847 bytes .../rest/ip_messaging/v2/service/role.py | 460 + .../rest/ip_messaging/v2/service/role.pyc | Bin 0 -> 20318 bytes .../ip_messaging/v2/service/user/__init__.py | 567 ++ .../ip_messaging/v2/service/user/__init__.pyc | Bin 0 -> 24343 bytes .../v2/service/user/user_binding.py | 460 + .../v2/service/user/user_binding.pyc | Bin 0 -> 21097 bytes .../v2/service/user/user_channel.py | 277 + .../v2/service/user/user_channel.pyc | Bin 0 -> 13128 bytes .../twilio/rest/lookups/__init__.py | 53 + .../twilio/rest/lookups/__init__.pyc | Bin 0 -> 2252 bytes .../twilio/rest/lookups/v1/__init__.py | 42 + .../twilio/rest/lookups/v1/__init__.pyc | Bin 0 -> 1965 bytes .../twilio/rest/lookups/v1/phone_number.py | 292 + .../twilio/rest/lookups/v1/phone_number.pyc | Bin 0 -> 13423 bytes .../twilio/rest/messaging/__init__.py | 53 + .../twilio/rest/messaging/__init__.pyc | Bin 0 -> 2272 bytes .../twilio/rest/messaging/v1/__init__.py | 42 + .../twilio/rest/messaging/v1/__init__.pyc | Bin 0 -> 1959 bytes .../rest/messaging/v1/service/__init__.py | 716 ++ .../rest/messaging/v1/service/__init__.pyc | Bin 0 -> 30855 bytes .../rest/messaging/v1/service/alpha_sender.py | 409 + .../messaging/v1/service/alpha_sender.pyc | Bin 0 -> 19185 bytes .../rest/messaging/v1/service/phone_number.py | 418 + .../messaging/v1/service/phone_number.pyc | Bin 0 -> 19563 bytes .../rest/messaging/v1/service/short_code.py | 418 + .../rest/messaging/v1/service/short_code.pyc | Bin 0 -> 19320 bytes .../twilio/rest/monitor/__init__.py | 60 + .../twilio/rest/monitor/__init__.pyc | Bin 0 -> 2534 bytes .../twilio/rest/monitor/v1/__init__.py | 53 + .../twilio/rest/monitor/v1/__init__.pyc | Bin 0 -> 2368 bytes .../twilio/rest/monitor/v1/alert.py | 486 ++ .../twilio/rest/monitor/v1/alert.pyc | Bin 0 -> 20294 bytes .../twilio/rest/monitor/v1/event.py | 465 + .../twilio/rest/monitor/v1/event.pyc | Bin 0 -> 19255 bytes .../twilio/rest/notify/__init__.py | 60 + .../twilio/rest/notify/__init__.pyc | Bin 0 -> 2536 bytes .../twilio/rest/notify/v1/__init__.py | 53 + .../twilio/rest/notify/v1/__init__.pyc | Bin 0 -> 2396 bytes .../twilio/rest/notify/v1/credential.py | 476 + .../twilio/rest/notify/v1/credential.pyc | Bin 0 -> 20673 bytes .../twilio/rest/notify/v1/service/__init__.py | 719 ++ .../rest/notify/v1/service/__init__.pyc | Bin 0 -> 31041 bytes .../twilio/rest/notify/v1/service/binding.py | 524 ++ .../twilio/rest/notify/v1/service/binding.pyc | Bin 0 -> 23098 bytes .../rest/notify/v1/service/notification.py | 358 + .../rest/notify/v1/service/notification.pyc | Bin 0 -> 15469 bytes .../twilio/rest/notify/v1/service/segment.py | 250 + .../twilio/rest/notify/v1/service/segment.pyc | Bin 0 -> 11577 bytes .../rest/notify/v1/service/user/__init__.py | 493 ++ .../rest/notify/v1/service/user/__init__.pyc | Bin 0 -> 22191 bytes .../v1/service/user/segment_memberships.py | 329 + .../v1/service/user/segment_memberships.pyc | Bin 0 -> 14885 bytes .../notify/v1/service/user/user_binding.py | 540 ++ .../notify/v1/service/user/user_binding.pyc | Bin 0 -> 23824 bytes .../twilio/rest/preview/__init__.py | 238 + .../twilio/rest/preview/__init__.pyc | Bin 0 -> 10424 bytes .../rest/preview/acc_security/__init__.py | 42 + .../rest/preview/acc_security/__init__.pyc | Bin 0 -> 2081 bytes .../preview/acc_security/service/__init__.py | 466 + .../preview/acc_security/service/__init__.pyc | Bin 0 -> 22367 bytes .../acc_security/service/verification.py | 224 + .../acc_security/service/verification.pyc | Bin 0 -> 10602 bytes .../service/verification_check.py | 223 + .../service/verification_check.pyc | Bin 0 -> 10815 bytes .../rest/preview/bulk_exports/__init__.py | 53 + .../rest/preview/bulk_exports/__init__.pyc | Bin 0 -> 2622 bytes .../preview/bulk_exports/export/__init__.py | 262 + .../preview/bulk_exports/export/__init__.pyc | Bin 0 -> 12631 bytes .../rest/preview/bulk_exports/export/day.py | 235 + .../rest/preview/bulk_exports/export/day.pyc | Bin 0 -> 11286 bytes .../bulk_exports/export_configuration.py | 301 + .../bulk_exports/export_configuration.pyc | Bin 0 -> 14745 bytes .../rest/preview/deployed_devices/__init__.py | 42 + .../preview/deployed_devices/__init__.pyc | Bin 0 -> 2113 bytes .../deployed_devices/fleet/__init__.py | 542 ++ .../deployed_devices/fleet/__init__.pyc | Bin 0 -> 25677 bytes .../deployed_devices/fleet/certificate.py | 474 + .../deployed_devices/fleet/certificate.pyc | Bin 0 -> 23012 bytes .../deployed_devices/fleet/deployment.py | 451 + .../deployed_devices/fleet/deployment.pyc | Bin 0 -> 22057 bytes .../preview/deployed_devices/fleet/device.py | 522 ++ .../preview/deployed_devices/fleet/device.pyc | Bin 0 -> 23929 bytes .../preview/deployed_devices/fleet/key.py | 468 + .../preview/deployed_devices/fleet/key.pyc | Bin 0 -> 21772 bytes .../rest/preview/hosted_numbers/__init__.py | 53 + .../rest/preview/hosted_numbers/__init__.pyc | Bin 0 -> 2744 bytes .../hosted_numbers/authorization_document.py | 454 + .../hosted_numbers/authorization_document.pyc | Bin 0 -> 23552 bytes .../hosted_numbers/hosted_number_order.py | 625 ++ .../hosted_numbers/hosted_number_order.pyc | Bin 0 -> 29956 bytes .../rest/preview/marketplace/__init__.py | 53 + .../rest/preview/marketplace/__init__.pyc | Bin 0 -> 2654 bytes .../marketplace/available_add_on/__init__.py | 383 + .../marketplace/available_add_on/__init__.pyc | Bin 0 -> 19575 bytes .../available_add_on_extension.py | 372 + .../available_add_on_extension.pyc | Bin 0 -> 19835 bytes .../marketplace/installed_add_on/__init__.py | 490 ++ .../marketplace/installed_add_on/__init__.pyc | Bin 0 -> 24393 bytes .../installed_add_on_extension.py | 416 + .../installed_add_on_extension.pyc | Bin 0 -> 21641 bytes .../twilio/rest/preview/proxy/__init__.py | 42 + .../twilio/rest/preview/proxy/__init__.pyc | Bin 0 -> 1977 bytes .../rest/preview/proxy/service/__init__.py | 535 ++ .../rest/preview/proxy/service/__init__.pyc | Bin 0 -> 24394 bytes .../preview/proxy/service/phone_number.py | 422 + .../preview/proxy/service/phone_number.pyc | Bin 0 -> 20189 bytes .../preview/proxy/service/session/__init__.py | 584 ++ .../proxy/service/session/__init__.pyc | Bin 0 -> 27193 bytes .../proxy/service/session/interaction.py | 537 ++ .../proxy/service/session/interaction.pyc | Bin 0 -> 25330 bytes .../service/session/participant/__init__.py | 595 ++ .../service/session/participant/__init__.pyc | Bin 0 -> 27204 bytes .../participant/message_interaction.py | 567 ++ .../participant/message_interaction.pyc | Bin 0 -> 27967 bytes .../rest/preview/proxy/service/short_code.py | 422 + .../rest/preview/proxy/service/short_code.pyc | Bin 0 -> 19952 bytes .../twilio/rest/preview/studio/__init__.py | 42 + .../twilio/rest/preview/studio/__init__.pyc | Bin 0 -> 1973 bytes .../rest/preview/studio/flow/__init__.py | 430 + .../rest/preview/studio/flow/__init__.pyc | Bin 0 -> 20017 bytes .../studio/flow/engagement/__init__.py | 476 + .../studio/flow/engagement/__init__.pyc | Bin 0 -> 22446 bytes .../preview/studio/flow/engagement/step.py | 427 + .../preview/studio/flow/engagement/step.pyc | Bin 0 -> 19445 bytes .../twilio/rest/preview/sync/__init__.py | 42 + .../twilio/rest/preview/sync/__init__.pyc | Bin 0 -> 1963 bytes .../rest/preview/sync/service/__init__.py | 553 ++ .../rest/preview/sync/service/__init__.pyc | Bin 0 -> 24397 bytes .../preview/sync/service/document/__init__.py | 507 ++ .../sync/service/document/__init__.pyc | Bin 0 -> 23036 bytes .../service/document/document_permission.py | 457 + .../service/document/document_permission.pyc | Bin 0 -> 22210 bytes .../sync/service/sync_list/__init__.py | 489 ++ .../sync/service/sync_list/__init__.pyc | Bin 0 -> 22778 bytes .../sync/service/sync_list/sync_list_item.py | 524 ++ .../sync/service/sync_list/sync_list_item.pyc | Bin 0 -> 24057 bytes .../service/sync_list/sync_list_permission.py | 457 + .../sync_list/sync_list_permission.pyc | Bin 0 -> 22262 bytes .../preview/sync/service/sync_map/__init__.py | 489 ++ .../sync/service/sync_map/__init__.pyc | Bin 0 -> 22620 bytes .../sync/service/sync_map/sync_map_item.py | 525 ++ .../sync/service/sync_map/sync_map_item.pyc | Bin 0 -> 23865 bytes .../service/sync_map/sync_map_permission.py | 457 + .../service/sync_map/sync_map_permission.pyc | Bin 0 -> 22069 bytes .../rest/preview/understand/__init__.py | 42 + .../rest/preview/understand/__init__.pyc | Bin 0 -> 2057 bytes .../preview/understand/service/__init__.py | 583 ++ .../preview/understand/service/__init__.pyc | Bin 0 -> 26186 bytes .../understand/service/field_type/__init__.py | 490 ++ .../service/field_type/__init__.pyc | Bin 0 -> 23080 bytes .../service/field_type/field_value.py | 460 + .../service/field_type/field_value.pyc | Bin 0 -> 21473 bytes .../understand/service/intent/__init__.py | 518 ++ .../understand/service/intent/__init__.pyc | Bin 0 -> 23679 bytes .../understand/service/intent/field.py | 452 + .../understand/service/intent/field.pyc | Bin 0 -> 20387 bytes .../understand/service/intent/sample.py | 498 ++ .../understand/service/intent/sample.pyc | Bin 0 -> 22030 bytes .../preview/understand/service/model_build.py | 456 + .../understand/service/model_build.pyc | Bin 0 -> 21563 bytes .../rest/preview/understand/service/query.py | 529 ++ .../rest/preview/understand/service/query.pyc | Bin 0 -> 22883 bytes .../twilio/rest/preview/wireless/__init__.py | 64 + .../twilio/rest/preview/wireless/__init__.pyc | Bin 0 -> 2959 bytes .../twilio/rest/preview/wireless/command.py | 462 + .../twilio/rest/preview/wireless/command.pyc | Bin 0 -> 20069 bytes .../twilio/rest/preview/wireless/rate_plan.py | 513 ++ .../rest/preview/wireless/rate_plan.pyc | Bin 0 -> 23202 bytes .../rest/preview/wireless/sim/__init__.py | 671 ++ .../rest/preview/wireless/sim/__init__.pyc | Bin 0 -> 27857 bytes .../twilio/rest/preview/wireless/sim/usage.py | 294 + .../rest/preview/wireless/sim/usage.pyc | Bin 0 -> 13583 bytes .../twilio/rest/pricing/__init__.py | 67 + .../twilio/rest/pricing/__init__.pyc | Bin 0 -> 2866 bytes .../twilio/rest/pricing/v1/__init__.py | 64 + .../twilio/rest/pricing/v1/__init__.pyc | Bin 0 -> 2871 bytes .../rest/pricing/v1/messaging/__init__.py | 146 + .../rest/pricing/v1/messaging/__init__.pyc | Bin 0 -> 6393 bytes .../rest/pricing/v1/messaging/country.py | 337 + .../rest/pricing/v1/messaging/country.pyc | Bin 0 -> 15875 bytes .../rest/pricing/v1/phone_number/__init__.py | 146 + .../rest/pricing/v1/phone_number/__init__.pyc | Bin 0 -> 6507 bytes .../rest/pricing/v1/phone_number/country.py | 328 + .../rest/pricing/v1/phone_number/country.pyc | Bin 0 -> 15674 bytes .../twilio/rest/pricing/v1/voice/__init__.py | 160 + .../twilio/rest/pricing/v1/voice/__init__.pyc | Bin 0 -> 6785 bytes .../twilio/rest/pricing/v1/voice/country.py | 337 + .../twilio/rest/pricing/v1/voice/country.pyc | Bin 0 -> 15667 bytes .../twilio/rest/pricing/v1/voice/number.py | 264 + .../twilio/rest/pricing/v1/voice/number.pyc | Bin 0 -> 11696 bytes .../twilio/rest/proxy/__init__.py | 53 + .../twilio/rest/proxy/__init__.pyc | Bin 0 -> 2204 bytes .../twilio/rest/proxy/v1/__init__.py | 42 + .../twilio/rest/proxy/v1/__init__.pyc | Bin 0 -> 1915 bytes .../twilio/rest/proxy/v1/service/__init__.py | 610 ++ .../twilio/rest/proxy/v1/service/__init__.pyc | Bin 0 -> 27585 bytes .../rest/proxy/v1/service/phone_number.py | 428 + .../rest/proxy/v1/service/phone_number.pyc | Bin 0 -> 20007 bytes .../rest/proxy/v1/service/session/__init__.py | 644 ++ .../proxy/v1/service/session/__init__.pyc | Bin 0 -> 28995 bytes .../proxy/v1/service/session/interaction.py | 548 ++ .../proxy/v1/service/session/interaction.pyc | Bin 0 -> 25078 bytes .../service/session/participant/__init__.py | 585 ++ .../service/session/participant/__init__.pyc | Bin 0 -> 26037 bytes .../participant/message_interaction.py | 578 ++ .../participant/message_interaction.pyc | Bin 0 -> 27698 bytes .../rest/proxy/v1/service/short_code.py | 418 + .../rest/proxy/v1/service/short_code.pyc | Bin 0 -> 19285 bytes .../twilio/rest/sync/__init__.py | 53 + .../twilio/rest/sync/__init__.pyc | Bin 0 -> 2187 bytes .../twilio/rest/sync/v1/__init__.py | 42 + .../twilio/rest/sync/v1/__init__.pyc | Bin 0 -> 1904 bytes .../twilio/rest/sync/v1/service/__init__.py | 582 ++ .../twilio/rest/sync/v1/service/__init__.pyc | Bin 0 -> 24973 bytes .../rest/sync/v1/service/document/__init__.py | 503 ++ .../sync/v1/service/document/__init__.pyc | Bin 0 -> 22280 bytes .../service/document/document_permission.py | 453 + .../service/document/document_permission.pyc | Bin 0 -> 21514 bytes .../sync/v1/service/sync_list/__init__.py | 485 ++ .../sync/v1/service/sync_list/__init__.pyc | Bin 0 -> 22012 bytes .../v1/service/sync_list/sync_list_item.py | 520 ++ .../v1/service/sync_list/sync_list_item.pyc | Bin 0 -> 23331 bytes .../service/sync_list/sync_list_permission.py | 453 + .../sync_list/sync_list_permission.pyc | Bin 0 -> 21566 bytes .../rest/sync/v1/service/sync_map/__init__.py | 485 ++ .../sync/v1/service/sync_map/__init__.pyc | Bin 0 -> 21854 bytes .../sync/v1/service/sync_map/sync_map_item.py | 521 ++ .../v1/service/sync_map/sync_map_item.pyc | Bin 0 -> 23139 bytes .../service/sync_map/sync_map_permission.py | 453 + .../service/sync_map/sync_map_permission.pyc | Bin 0 -> 21373 bytes .../sync/v1/service/sync_stream/__init__.py | 448 + .../sync/v1/service/sync_stream/__init__.pyc | Bin 0 -> 20811 bytes .../v1/service/sync_stream/stream_message.py | 161 + .../v1/service/sync_stream/stream_message.pyc | Bin 0 -> 7420 bytes .../twilio/rest/taskrouter/__init__.py | 53 + .../twilio/rest/taskrouter/__init__.pyc | Bin 0 -> 2295 bytes .../twilio/rest/taskrouter/v1/__init__.py | 42 + .../twilio/rest/taskrouter/v1/__init__.pyc | Bin 0 -> 1982 bytes .../rest/taskrouter/v1/workspace/__init__.py | 796 ++ .../rest/taskrouter/v1/workspace/__init__.pyc | Bin 0 -> 35402 bytes .../rest/taskrouter/v1/workspace/activity.py | 461 + .../rest/taskrouter/v1/workspace/activity.pyc | Bin 0 -> 20274 bytes .../rest/taskrouter/v1/workspace/event.py | 507 ++ .../rest/taskrouter/v1/workspace/event.pyc | Bin 0 -> 21530 bytes .../taskrouter/v1/workspace/task/__init__.py | 698 ++ .../taskrouter/v1/workspace/task/__init__.pyc | Bin 0 -> 29198 bytes .../v1/workspace/task/reservation.py | 743 ++ .../v1/workspace/task/reservation.pyc | Bin 0 -> 33052 bytes .../taskrouter/v1/workspace/task_channel.py | 368 + .../taskrouter/v1/workspace/task_channel.pyc | Bin 0 -> 17532 bytes .../v1/workspace/task_queue/__init__.py | 689 ++ .../v1/workspace/task_queue/__init__.pyc | Bin 0 -> 30581 bytes .../task_queue_cumulative_statistics.py | 443 + .../task_queue_cumulative_statistics.pyc | Bin 0 -> 21732 bytes .../task_queue_real_time_statistics.py | 328 + .../task_queue_real_time_statistics.pyc | Bin 0 -> 16799 bytes .../task_queue/task_queue_statistics.py | 307 + .../task_queue/task_queue_statistics.pyc | Bin 0 -> 14733 bytes .../task_queue/task_queues_statistics.py | 296 + .../task_queue/task_queues_statistics.pyc | Bin 0 -> 13910 bytes .../v1/workspace/worker/__init__.py | 725 ++ .../v1/workspace/worker/__init__.pyc | Bin 0 -> 31127 bytes .../v1/workspace/worker/reservation.py | 743 ++ .../v1/workspace/worker/reservation.pyc | Bin 0 -> 33206 bytes .../v1/workspace/worker/worker_channel.py | 484 ++ .../v1/workspace/worker/worker_channel.pyc | Bin 0 -> 22106 bytes .../v1/workspace/worker/worker_statistics.py | 292 + .../v1/workspace/worker/worker_statistics.pyc | Bin 0 -> 13658 bytes .../worker/workers_cumulative_statistics.py | 348 + .../worker/workers_cumulative_statistics.pyc | Bin 0 -> 17200 bytes .../worker/workers_real_time_statistics.py | 260 + .../worker/workers_real_time_statistics.pyc | Bin 0 -> 13709 bytes .../v1/workspace/worker/workers_statistics.py | 294 + .../workspace/worker/workers_statistics.pyc | Bin 0 -> 14021 bytes .../v1/workspace/workflow/__init__.py | 618 ++ .../v1/workspace/workflow/__init__.pyc | Bin 0 -> 27647 bytes .../workflow_cumulative_statistics.py | 452 + .../workflow_cumulative_statistics.pyc | Bin 0 -> 21856 bytes .../workflow/workflow_real_time_statistics.py | 301 + .../workflow_real_time_statistics.pyc | Bin 0 -> 15344 bytes .../workspace/workflow/workflow_statistics.py | 307 + .../workflow/workflow_statistics.pyc | Bin 0 -> 14500 bytes .../workspace_cumulative_statistics.py | 435 + .../workspace_cumulative_statistics.pyc | Bin 0 -> 20735 bytes .../workspace_real_time_statistics.py | 302 + .../workspace_real_time_statistics.pyc | Bin 0 -> 15096 bytes .../v1/workspace/workspace_statistics.py | 284 + .../v1/workspace/workspace_statistics.pyc | Bin 0 -> 13510 bytes .../twilio/rest/trunking/__init__.py | 53 + .../twilio/rest/trunking/__init__.pyc | Bin 0 -> 2249 bytes .../twilio/rest/trunking/v1/__init__.py | 42 + .../twilio/rest/trunking/v1/__init__.pyc | Bin 0 -> 1936 bytes .../twilio/rest/trunking/v1/trunk/__init__.py | 623 ++ .../rest/trunking/v1/trunk/__init__.pyc | Bin 0 -> 26511 bytes .../rest/trunking/v1/trunk/credential_list.py | 396 + .../trunking/v1/trunk/credential_list.pyc | Bin 0 -> 18598 bytes .../v1/trunk/ip_access_control_list.py | 396 + .../v1/trunk/ip_access_control_list.pyc | Bin 0 -> 19298 bytes .../rest/trunking/v1/trunk/origination_url.py | 501 ++ .../trunking/v1/trunk/origination_url.pyc | Bin 0 -> 21969 bytes .../rest/trunking/v1/trunk/phone_number.py | 573 ++ .../rest/trunking/v1/trunk/phone_number.pyc | Bin 0 -> 25307 bytes .../twilio/rest/video/__init__.py | 60 + .../twilio/rest/video/__init__.pyc | Bin 0 -> 2505 bytes .../twilio/rest/video/v1/__init__.py | 53 + .../twilio/rest/video/v1/__init__.pyc | Bin 0 -> 2358 bytes .../rest/video/v1/recording/__init__.py | 486 ++ .../rest/video/v1/recording/__init__.pyc | Bin 0 -> 21889 bytes .../twilio/rest/video/v1/room/__init__.py | 611 ++ .../twilio/rest/video/v1/room/__init__.pyc | Bin 0 -> 25958 bytes .../rest/video/v1/room/recording/__init__.py | 483 ++ .../rest/video/v1/room/recording/__init__.pyc | Bin 0 -> 21826 bytes .../v1/room/room_participant/__init__.py | 513 ++ .../v1/room/room_participant/__init__.pyc | Bin 0 -> 23185 bytes .../room_participant_published_track.py | 406 + .../room_participant_published_track.pyc | Bin 0 -> 20183 bytes .../twilio/rest/wireless/__init__.py | 67 + .../twilio/rest/wireless/__init__.pyc | Bin 0 -> 2868 bytes .../twilio/rest/wireless/v1/__init__.py | 64 + .../twilio/rest/wireless/v1/__init__.pyc | Bin 0 -> 2850 bytes .../twilio/rest/wireless/v1/command.py | 445 + .../twilio/rest/wireless/v1/command.pyc | Bin 0 -> 19910 bytes .../twilio/rest/wireless/v1/rate_plan.py | 530 ++ .../twilio/rest/wireless/v1/rate_plan.pyc | Bin 0 -> 23389 bytes .../twilio/rest/wireless/v1/sim/__init__.py | 710 ++ .../twilio/rest/wireless/v1/sim/__init__.pyc | Bin 0 -> 29149 bytes .../rest/wireless/v1/sim/data_session.py | 346 + .../rest/wireless/v1/sim/data_session.pyc | Bin 0 -> 15374 bytes .../rest/wireless/v1/sim/usage_record.py | 271 + .../rest/wireless/v1/sim/usage_record.pyc | Bin 0 -> 12458 bytes .../site-packages/twilio/twiml/__init__.py | 124 + .../site-packages/twilio/twiml/__init__.pyc | Bin 0 -> 5175 bytes .../twilio/twiml/fax_response.py | 41 + .../twilio/twiml/fax_response.pyc | Bin 0 -> 2099 bytes .../twilio/twiml/messaging_response.py | 108 + .../twilio/twiml/messaging_response.pyc | Bin 0 -> 5397 bytes .../twilio/twiml/voice_response.py | 706 ++ .../twilio/twiml/voice_response.pyc | Bin 0 -> 30130 bytes .../urllib3-1.22.dist-info/DESCRIPTION.rst | 995 +++ .../urllib3-1.22.dist-info/INSTALLER | 1 + .../urllib3-1.22.dist-info/METADATA | 1031 +++ .../urllib3-1.22.dist-info/RECORD | 79 + .../urllib3-1.22.dist-info/WHEEL | 6 + .../urllib3-1.22.dist-info/metadata.json | 1 + .../urllib3-1.22.dist-info/top_level.txt | 1 + .../site-packages/urllib3/__init__.py | 97 + .../site-packages/urllib3/__init__.pyc | Bin 0 -> 3477 bytes .../site-packages/urllib3/_collections.py | 319 + .../site-packages/urllib3/_collections.pyc | Bin 0 -> 14564 bytes .../site-packages/urllib3/connection.py | 373 + .../site-packages/urllib3/connection.pyc | Bin 0 -> 11485 bytes .../site-packages/urllib3/connectionpool.py | 905 ++ .../site-packages/urllib3/connectionpool.pyc | Bin 0 -> 28351 bytes .../site-packages/urllib3/contrib/__init__.py | 0 .../urllib3/contrib/__init__.pyc | Bin 0 -> 196 bytes .../contrib/_securetransport/__init__.py | 0 .../contrib/_securetransport/__init__.pyc | Bin 0 -> 213 bytes .../contrib/_securetransport/bindings.py | 593 ++ .../contrib/_securetransport/bindings.pyc | Bin 0 -> 12329 bytes .../contrib/_securetransport/low_level.py | 343 + .../contrib/_securetransport/low_level.pyc | Bin 0 -> 9947 bytes .../urllib3/contrib/appengine.py | 296 + .../urllib3/contrib/appengine.pyc | Bin 0 -> 11084 bytes .../site-packages/urllib3/contrib/ntlmpool.py | 112 + .../urllib3/contrib/ntlmpool.pyc | Bin 0 -> 4128 bytes .../urllib3/contrib/pyopenssl.py | 455 + .../urllib3/contrib/pyopenssl.pyc | Bin 0 -> 18997 bytes .../urllib3/contrib/securetransport.py | 810 ++ .../urllib3/contrib/securetransport.pyc | Bin 0 -> 24230 bytes .../site-packages/urllib3/contrib/socks.py | 188 + .../site-packages/urllib3/contrib/socks.pyc | Bin 0 -> 6059 bytes .../site-packages/urllib3/exceptions.py | 246 + .../site-packages/urllib3/exceptions.pyc | Bin 0 -> 15041 bytes .../python2.7/site-packages/urllib3/fields.py | 178 + .../site-packages/urllib3/fields.pyc | Bin 0 -> 7236 bytes .../site-packages/urllib3/filepost.py | 94 + .../site-packages/urllib3/filepost.pyc | Bin 0 -> 3586 bytes .../urllib3/packages/__init__.py | 5 + .../urllib3/packages/__init__.pyc | Bin 0 -> 377 bytes .../urllib3/packages/backports/__init__.py | 0 .../urllib3/packages/backports/__init__.pyc | Bin 0 -> 207 bytes .../urllib3/packages/backports/makefile.py | 53 + .../urllib3/packages/backports/makefile.pyc | Bin 0 -> 1699 bytes .../urllib3/packages/ordered_dict.py | 259 + .../urllib3/packages/ordered_dict.pyc | Bin 0 -> 11272 bytes .../site-packages/urllib3/packages/six.py | 868 ++ .../site-packages/urllib3/packages/six.pyc | Bin 0 -> 35312 bytes .../packages/ssl_match_hostname/__init__.py | 19 + .../packages/ssl_match_hostname/__init__.pyc | Bin 0 -> 687 bytes .../ssl_match_hostname/_implementation.py | 157 + .../ssl_match_hostname/_implementation.pyc | Bin 0 -> 4508 bytes .../site-packages/urllib3/poolmanager.py | 440 + .../site-packages/urllib3/poolmanager.pyc | Bin 0 -> 15790 bytes .../site-packages/urllib3/request.py | 148 + .../site-packages/urllib3/request.pyc | Bin 0 -> 6357 bytes .../site-packages/urllib3/response.py | 626 ++ .../site-packages/urllib3/response.pyc | Bin 0 -> 21031 bytes .../site-packages/urllib3/util/__init__.py | 54 + .../site-packages/urllib3/util/__init__.pyc | Bin 0 -> 1557 bytes .../site-packages/urllib3/util/connection.py | 130 + .../site-packages/urllib3/util/connection.pyc | Bin 0 -> 4093 bytes .../site-packages/urllib3/util/request.py | 118 + .../site-packages/urllib3/util/request.pyc | Bin 0 -> 3905 bytes .../site-packages/urllib3/util/response.py | 81 + .../site-packages/urllib3/util/response.pyc | Bin 0 -> 2445 bytes .../site-packages/urllib3/util/retry.py | 401 + .../site-packages/urllib3/util/retry.pyc | Bin 0 -> 15073 bytes .../site-packages/urllib3/util/selectors.py | 581 ++ .../site-packages/urllib3/util/selectors.pyc | Bin 0 -> 22983 bytes .../site-packages/urllib3/util/ssl_.py | 341 + .../site-packages/urllib3/util/ssl_.pyc | Bin 0 -> 11076 bytes .../site-packages/urllib3/util/timeout.py | 242 + .../site-packages/urllib3/util/timeout.pyc | Bin 0 -> 10123 bytes .../site-packages/urllib3/util/url.py | 230 + .../site-packages/urllib3/util/url.pyc | Bin 0 -> 6800 bytes .../site-packages/urllib3/util/wait.py | 40 + .../site-packages/urllib3/util/wait.pyc | Bin 0 -> 1990 bytes .../site-packages/werkzeug/__init__.py | 151 + .../site-packages/werkzeug/__init__.pyc | Bin 0 -> 5997 bytes .../site-packages/werkzeug/_compat.py | 206 + .../site-packages/werkzeug/_compat.pyc | Bin 0 -> 11804 bytes .../site-packages/werkzeug/_internal.py | 418 + .../site-packages/werkzeug/_internal.pyc | Bin 0 -> 16355 bytes .../site-packages/werkzeug/_reloader.py | 267 + .../site-packages/werkzeug/_reloader.pyc | Bin 0 -> 11930 bytes .../werkzeug/contrib/__init__.py | 16 + .../werkzeug/contrib/__init__.pyc | Bin 0 -> 813 bytes .../site-packages/werkzeug/contrib/atom.py | 355 + .../site-packages/werkzeug/contrib/atom.pyc | Bin 0 -> 17285 bytes .../site-packages/werkzeug/contrib/cache.py | 858 ++ .../site-packages/werkzeug/contrib/cache.pyc | Bin 0 -> 39891 bytes .../site-packages/werkzeug/contrib/fixers.py | 254 + .../site-packages/werkzeug/contrib/fixers.pyc | Bin 0 -> 12577 bytes .../site-packages/werkzeug/contrib/iterio.py | 352 + .../site-packages/werkzeug/contrib/iterio.pyc | Bin 0 -> 15384 bytes .../werkzeug/contrib/jsrouting.py | 264 + .../werkzeug/contrib/jsrouting.pyc | Bin 0 -> 9453 bytes .../site-packages/werkzeug/contrib/limiter.py | 41 + .../werkzeug/contrib/limiter.pyc | Bin 0 -> 2157 bytes .../site-packages/werkzeug/contrib/lint.py | 343 + .../site-packages/werkzeug/contrib/lint.pyc | Bin 0 -> 16311 bytes .../werkzeug/contrib/profiler.py | 147 + .../werkzeug/contrib/profiler.pyc | Bin 0 -> 6795 bytes .../werkzeug/contrib/securecookie.py | 323 + .../werkzeug/contrib/securecookie.pyc | Bin 0 -> 12255 bytes .../werkzeug/contrib/sessions.py | 352 + .../werkzeug/contrib/sessions.pyc | Bin 0 -> 17035 bytes .../werkzeug/contrib/testtools.py | 73 + .../werkzeug/contrib/testtools.pyc | Bin 0 -> 3477 bytes .../werkzeug/contrib/wrappers.py | 284 + .../werkzeug/contrib/wrappers.pyc | Bin 0 -> 12757 bytes .../site-packages/werkzeug/datastructures.py | 2740 ++++++ .../site-packages/werkzeug/datastructures.pyc | Bin 0 -> 135858 bytes .../site-packages/werkzeug/debug/__init__.py | 466 + .../site-packages/werkzeug/debug/__init__.pyc | Bin 0 -> 16655 bytes .../site-packages/werkzeug/debug/console.py | 215 + .../site-packages/werkzeug/debug/console.pyc | Bin 0 -> 11358 bytes .../site-packages/werkzeug/debug/repr.py | 280 + .../site-packages/werkzeug/debug/repr.pyc | Bin 0 -> 11568 bytes .../werkzeug/debug/shared/FONT_LICENSE | 96 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 205 + .../werkzeug/debug/shared/jquery.js | 5 + .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/source.png | Bin 0 -> 818 bytes .../werkzeug/debug/shared/style.css | 143 + .../werkzeug/debug/shared/ubuntu.ttf | Bin 0 -> 70220 bytes .../site-packages/werkzeug/debug/tbtools.py | 556 ++ .../site-packages/werkzeug/debug/tbtools.pyc | Bin 0 -> 20352 bytes .../site-packages/werkzeug/exceptions.py | 719 ++ .../site-packages/werkzeug/exceptions.pyc | Bin 0 -> 29254 bytes .../site-packages/werkzeug/filesystem.py | 66 + .../site-packages/werkzeug/filesystem.pyc | Bin 0 -> 2756 bytes .../site-packages/werkzeug/formparser.py | 522 ++ .../site-packages/werkzeug/formparser.pyc | Bin 0 -> 20210 bytes .../python2.7/site-packages/werkzeug/http.py | 1054 +++ .../python2.7/site-packages/werkzeug/http.pyc | Bin 0 -> 37275 bytes .../python2.7/site-packages/werkzeug/local.py | 420 + .../site-packages/werkzeug/local.pyc | Bin 0 -> 29134 bytes .../site-packages/werkzeug/posixemulation.py | 106 + .../site-packages/werkzeug/posixemulation.pyc | Bin 0 -> 3765 bytes .../site-packages/werkzeug/routing.py | 1784 ++++ .../site-packages/werkzeug/routing.pyc | Bin 0 -> 72500 bytes .../site-packages/werkzeug/script.py | 332 + .../site-packages/werkzeug/script.pyc | Bin 0 -> 12718 bytes .../site-packages/werkzeug/security.py | 270 + .../site-packages/werkzeug/security.pyc | Bin 0 -> 10893 bytes .../site-packages/werkzeug/serving.py | 787 ++ .../site-packages/werkzeug/serving.pyc | Bin 0 -> 31903 bytes .../python2.7/site-packages/werkzeug/test.py | 909 ++ .../python2.7/site-packages/werkzeug/test.pyc | Bin 0 -> 37895 bytes .../site-packages/werkzeug/testapp.py | 230 + .../site-packages/werkzeug/testapp.pyc | Bin 0 -> 10759 bytes .../python2.7/site-packages/werkzeug/urls.py | 1004 +++ .../python2.7/site-packages/werkzeug/urls.pyc | Bin 0 -> 40426 bytes .../site-packages/werkzeug/useragents.py | 202 + .../site-packages/werkzeug/useragents.pyc | Bin 0 -> 7305 bytes .../python2.7/site-packages/werkzeug/utils.py | 628 ++ .../site-packages/werkzeug/utils.pyc | Bin 0 -> 25726 bytes .../site-packages/werkzeug/wrappers.py | 1970 +++++ .../site-packages/werkzeug/wrappers.pyc | Bin 0 -> 90502 bytes .../python2.7/site-packages/werkzeug/wsgi.py | 1195 +++ .../python2.7/site-packages/werkzeug/wsgi.pyc | Bin 0 -> 47932 bytes .../wheel-0.30.0.dist-info/DESCRIPTION.rst | 340 + .../wheel-0.30.0.dist-info/INSTALLER | 1 + .../wheel-0.30.0.dist-info/LICENSE.txt | 22 + .../wheel-0.30.0.dist-info/METADATA | 374 + .../wheel-0.30.0.dist-info/RECORD | 46 + .../wheel-0.30.0.dist-info/WHEEL | 6 + .../wheel-0.30.0.dist-info/entry_points.txt | 6 + .../wheel-0.30.0.dist-info/metadata.json | 1 + .../wheel-0.30.0.dist-info/top_level.txt | 1 + .../python2.7/site-packages/wheel/__init__.py | 2 + .../site-packages/wheel/__init__.pyc | Bin 0 -> 217 bytes .../python2.7/site-packages/wheel/__main__.py | 19 + .../site-packages/wheel/__main__.pyc | Bin 0 -> 809 bytes .../python2.7/site-packages/wheel/archive.py | 80 + .../python2.7/site-packages/wheel/archive.pyc | Bin 0 -> 2762 bytes .../site-packages/wheel/bdist_wheel.py | 482 ++ .../site-packages/wheel/bdist_wheel.pyc | Bin 0 -> 18079 bytes .../site-packages/wheel/decorator.py | 19 + .../site-packages/wheel/decorator.pyc | Bin 0 -> 1229 bytes .../site-packages/wheel/egg2wheel.py | 90 + .../site-packages/wheel/egg2wheel.pyc | Bin 0 -> 3453 bytes .../python2.7/site-packages/wheel/install.py | 494 ++ .../python2.7/site-packages/wheel/install.pyc | Bin 0 -> 19444 bytes .../python2.7/site-packages/wheel/metadata.py | 338 + .../site-packages/wheel/metadata.pyc | Bin 0 -> 11311 bytes .../python2.7/site-packages/wheel/paths.py | 43 + .../python2.7/site-packages/wheel/paths.pyc | Bin 0 -> 1486 bytes .../site-packages/wheel/pep425tags.py | 180 + .../site-packages/wheel/pep425tags.pyc | Bin 0 -> 6502 bytes .../python2.7/site-packages/wheel/pkginfo.py | 43 + .../python2.7/site-packages/wheel/pkginfo.pyc | Bin 0 -> 2389 bytes .../wheel/signatures/__init__.py | 110 + .../wheel/signatures/__init__.pyc | Bin 0 -> 3993 bytes .../site-packages/wheel/signatures/djbec.py | 323 + .../site-packages/wheel/signatures/djbec.pyc | Bin 0 -> 13139 bytes .../wheel/signatures/ed25519py.py | 50 + .../wheel/signatures/ed25519py.pyc | Bin 0 -> 2319 bytes .../site-packages/wheel/signatures/keys.py | 101 + .../site-packages/wheel/signatures/keys.pyc | Bin 0 -> 5164 bytes .../site-packages/wheel/tool/__init__.py | 376 + .../site-packages/wheel/tool/__init__.pyc | Bin 0 -> 15272 bytes .../lib/python2.7/site-packages/wheel/util.py | 176 + .../python2.7/site-packages/wheel/util.pyc | Bin 0 -> 8630 bytes .../site-packages/wheel/wininst2wheel.py | 217 + .../site-packages/wheel/wininst2wheel.pyc | Bin 0 -> 6833 bytes venv/lib/python2.7/site.py | 758 ++ venv/lib/python2.7/site.pyc | Bin 0 -> 25957 bytes venv/lib/python2.7/sre.py | 1 + venv/lib/python2.7/sre_compile.py | 1 + venv/lib/python2.7/sre_compile.pyc | Bin 0 -> 13249 bytes venv/lib/python2.7/sre_constants.py | 1 + venv/lib/python2.7/sre_constants.pyc | Bin 0 -> 6425 bytes venv/lib/python2.7/sre_parse.py | 1 + venv/lib/python2.7/sre_parse.pyc | Bin 0 -> 21673 bytes venv/lib/python2.7/stat.py | 1 + venv/lib/python2.7/stat.pyc | Bin 0 -> 3281 bytes venv/lib/python2.7/types.py | 1 + venv/lib/python2.7/types.pyc | Bin 0 -> 3096 bytes venv/lib/python2.7/warnings.py | 1 + venv/lib/python2.7/warnings.pyc | Bin 0 -> 14833 bytes venv/man/man1/nosetests.1 | 581 ++ venv/pip-selfcheck.json | 1 + 3116 files changed, 430644 insertions(+) create mode 100644 services/sports/__init__.py create mode 100644 services/sports/__init__.pyc create mode 100644 services/sports/sports.py create mode 100644 services/sports/sports.pyc create mode 120000 venv/.Python create mode 100644 venv/bin/activate create mode 100644 venv/bin/activate.csh create mode 100644 venv/bin/activate.fish create mode 100644 venv/bin/activate_this.py create mode 100755 venv/bin/chardetect create mode 100755 venv/bin/easy_install create mode 100755 venv/bin/easy_install-2.7 create mode 100755 venv/bin/flask create mode 100755 venv/bin/nosetests create mode 100755 venv/bin/nosetests-2.7 create mode 100755 venv/bin/pip create mode 100755 venv/bin/pip2 create mode 100755 venv/bin/pip2.7 create mode 100755 venv/bin/pyjwt create mode 100755 venv/bin/python create mode 100755 venv/bin/python-config create mode 120000 venv/bin/python2 create mode 120000 venv/bin/python2.7 create mode 100755 venv/bin/wheel create mode 120000 venv/include/python2.7 create mode 120000 venv/lib/python2.7/UserDict.py create mode 100644 venv/lib/python2.7/UserDict.pyc create mode 120000 venv/lib/python2.7/_abcoll.py create mode 100644 venv/lib/python2.7/_abcoll.pyc create mode 120000 venv/lib/python2.7/_weakrefset.py create mode 100644 venv/lib/python2.7/_weakrefset.pyc create mode 120000 venv/lib/python2.7/abc.py create mode 100644 venv/lib/python2.7/abc.pyc create mode 120000 venv/lib/python2.7/codecs.py create mode 100644 venv/lib/python2.7/codecs.pyc create mode 120000 venv/lib/python2.7/config create mode 120000 venv/lib/python2.7/copy_reg.py create mode 100644 venv/lib/python2.7/copy_reg.pyc create mode 100644 venv/lib/python2.7/distutils/__init__.py create mode 100644 venv/lib/python2.7/distutils/__init__.pyc create mode 100644 venv/lib/python2.7/distutils/distutils.cfg create mode 120000 venv/lib/python2.7/encodings create mode 120000 venv/lib/python2.7/fnmatch.py create mode 100644 venv/lib/python2.7/fnmatch.pyc create mode 120000 venv/lib/python2.7/genericpath.py create mode 100644 venv/lib/python2.7/genericpath.pyc create mode 120000 venv/lib/python2.7/lib-dynload create mode 120000 venv/lib/python2.7/linecache.py create mode 100644 venv/lib/python2.7/linecache.pyc create mode 120000 venv/lib/python2.7/locale.py create mode 100644 venv/lib/python2.7/locale.pyc create mode 100644 venv/lib/python2.7/no-global-site-packages.txt create mode 120000 venv/lib/python2.7/ntpath.py create mode 100644 venv/lib/python2.7/orig-prefix.txt create mode 120000 venv/lib/python2.7/os.py create mode 100644 venv/lib/python2.7/os.pyc create mode 120000 venv/lib/python2.7/posixpath.py create mode 100644 venv/lib/python2.7/posixpath.pyc create mode 120000 venv/lib/python2.7/re.py create mode 100644 venv/lib/python2.7/re.pyc create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup-3.2.1.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup-3.2.1.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup-3.2.1.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup-3.2.1.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup-3.2.1.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup-3.2.1.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup-3.2.1.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup.py create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoup.pyc create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoupTests.py create mode 100644 venv/lib/python2.7/site-packages/BeautifulSoupTests.pyc create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/LICENSE.txt create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/LICENSE.txt create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/SSL.py create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/SSL.pyc create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/__init__.py create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/_util.py create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/_util.pyc create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/crypto.py create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/crypto.pyc create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/debug.py create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/debug.pyc create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/tsafe.py create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/tsafe.pyc create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/version.py create mode 100644 venv/lib/python2.7/site-packages/OpenSSL/version.pyc create mode 100644 venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/LICENSE.txt create mode 100644 venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/top_level.txt create mode 100755 venv/lib/python2.7/site-packages/_cffi_backend.so create mode 100644 venv/lib/python2.7/site-packages/api-0.0.7.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/api-0.0.7.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/api-0.0.7.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/api-0.0.7.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/api-0.0.7.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/api-0.0.7.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/api-0.0.7.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/api/__init__.py create mode 100644 venv/lib/python2.7/site-packages/api/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/api/api.py create mode 100644 venv/lib/python2.7/site-packages/api/api.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/__init__.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_elliptic_curve.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_elliptic_curve.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_errors.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_errors.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_ffi.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_ffi.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_inet.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_inet.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_int.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_int.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_iri.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_iri.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_ordereddict.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_ordereddict.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_perf/__init__.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_perf/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_perf/_big_num_ctypes.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_perf/_big_num_ctypes.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_teletex_codec.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_teletex_codec.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_types.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/_types.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/algos.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/algos.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/cms.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/cms.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/core.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/core.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/crl.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/crl.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/csr.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/csr.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/keys.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/keys.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/ocsp.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/ocsp.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/parser.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/parser.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/pdf.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/pdf.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/pem.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/pem.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/pkcs12.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/pkcs12.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/tsp.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/tsp.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/util.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/util.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/version.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/version.pyc create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/x509.py create mode 100644 venv/lib/python2.7/site-packages/asn1crypto/x509.pyc create mode 100644 venv/lib/python2.7/site-packages/beautifulsoup4-4.6.0.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/beautifulsoup4-4.6.0.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/beautifulsoup4-4.6.0.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/beautifulsoup4-4.6.0.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/beautifulsoup4-4.6.0.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/beautifulsoup4-4.6.0.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/beautifulsoup4-4.6.0.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/bs4/__init__.py create mode 100644 venv/lib/python2.7/site-packages/bs4/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/builder/__init__.py create mode 100644 venv/lib/python2.7/site-packages/bs4/builder/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/builder/_html5lib.py create mode 100644 venv/lib/python2.7/site-packages/bs4/builder/_html5lib.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/builder/_htmlparser.py create mode 100644 venv/lib/python2.7/site-packages/bs4/builder/_htmlparser.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/builder/_lxml.py create mode 100644 venv/lib/python2.7/site-packages/bs4/builder/_lxml.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/dammit.py create mode 100644 venv/lib/python2.7/site-packages/bs4/dammit.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/diagnose.py create mode 100644 venv/lib/python2.7/site-packages/bs4/diagnose.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/element.py create mode 100644 venv/lib/python2.7/site-packages/bs4/element.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/testing.py create mode 100644 venv/lib/python2.7/site-packages/bs4/testing.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/__init__.py create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_builder_registry.py create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_builder_registry.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_docs.py create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_docs.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_html5lib.py create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_html5lib.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_htmlparser.py create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_htmlparser.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_lxml.py create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_lxml.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_soup.py create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_soup.pyc create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_tree.py create mode 100644 venv/lib/python2.7/site-packages/bs4/tests/test_tree.pyc create mode 100644 venv/lib/python2.7/site-packages/certifi-2017.11.5.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/certifi-2017.11.5.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/certifi-2017.11.5.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/certifi-2017.11.5.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/certifi-2017.11.5.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/certifi-2017.11.5.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/certifi-2017.11.5.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/certifi/__init__.py create mode 100644 venv/lib/python2.7/site-packages/certifi/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/certifi/__main__.py create mode 100644 venv/lib/python2.7/site-packages/certifi/__main__.pyc create mode 100644 venv/lib/python2.7/site-packages/certifi/cacert.pem create mode 100644 venv/lib/python2.7/site-packages/certifi/core.py create mode 100644 venv/lib/python2.7/site-packages/certifi/core.pyc create mode 100644 venv/lib/python2.7/site-packages/certifi/old_root.pem create mode 100644 venv/lib/python2.7/site-packages/certifi/weak.pem create mode 100644 venv/lib/python2.7/site-packages/cffi-1.11.2.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/cffi-1.11.2.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/cffi-1.11.2.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/cffi-1.11.2.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/cffi-1.11.2.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/cffi-1.11.2.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/cffi-1.11.2.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/cffi-1.11.2.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/cffi/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cffi/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/_cffi_errors.h create mode 100644 venv/lib/python2.7/site-packages/cffi/_cffi_include.h create mode 100644 venv/lib/python2.7/site-packages/cffi/_embedding.h create mode 100644 venv/lib/python2.7/site-packages/cffi/api.py create mode 100644 venv/lib/python2.7/site-packages/cffi/api.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/backend_ctypes.py create mode 100644 venv/lib/python2.7/site-packages/cffi/backend_ctypes.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/cffi_opcode.py create mode 100644 venv/lib/python2.7/site-packages/cffi/cffi_opcode.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/commontypes.py create mode 100644 venv/lib/python2.7/site-packages/cffi/commontypes.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/cparser.py create mode 100644 venv/lib/python2.7/site-packages/cffi/cparser.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/error.py create mode 100644 venv/lib/python2.7/site-packages/cffi/error.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/ffiplatform.py create mode 100644 venv/lib/python2.7/site-packages/cffi/ffiplatform.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/lock.py create mode 100644 venv/lib/python2.7/site-packages/cffi/lock.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/model.py create mode 100644 venv/lib/python2.7/site-packages/cffi/model.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/parse_c_type.h create mode 100644 venv/lib/python2.7/site-packages/cffi/recompiler.py create mode 100644 venv/lib/python2.7/site-packages/cffi/recompiler.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/setuptools_ext.py create mode 100644 venv/lib/python2.7/site-packages/cffi/setuptools_ext.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/vengine_cpy.py create mode 100644 venv/lib/python2.7/site-packages/cffi/vengine_cpy.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/vengine_gen.py create mode 100644 venv/lib/python2.7/site-packages/cffi/vengine_gen.pyc create mode 100644 venv/lib/python2.7/site-packages/cffi/verifier.py create mode 100644 venv/lib/python2.7/site-packages/cffi/verifier.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet-3.0.4.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/chardet-3.0.4.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/chardet-3.0.4.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/chardet-3.0.4.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/chardet-3.0.4.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/chardet-3.0.4.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/chardet-3.0.4.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/chardet-3.0.4.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/chardet/__init__.py create mode 100644 venv/lib/python2.7/site-packages/chardet/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/big5freq.py create mode 100644 venv/lib/python2.7/site-packages/chardet/big5freq.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/big5prober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/big5prober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/chardistribution.py create mode 100644 venv/lib/python2.7/site-packages/chardet/chardistribution.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/charsetgroupprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/charsetgroupprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/charsetprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/charsetprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/cli/__init__.py create mode 100644 venv/lib/python2.7/site-packages/chardet/cli/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/cli/chardetect.py create mode 100644 venv/lib/python2.7/site-packages/chardet/cli/chardetect.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/codingstatemachine.py create mode 100644 venv/lib/python2.7/site-packages/chardet/codingstatemachine.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/compat.py create mode 100644 venv/lib/python2.7/site-packages/chardet/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/cp949prober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/cp949prober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/enums.py create mode 100644 venv/lib/python2.7/site-packages/chardet/enums.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/escprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/escprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/escsm.py create mode 100644 venv/lib/python2.7/site-packages/chardet/escsm.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/eucjpprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/eucjpprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/euckrfreq.py create mode 100644 venv/lib/python2.7/site-packages/chardet/euckrfreq.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/euckrprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/euckrprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/euctwfreq.py create mode 100644 venv/lib/python2.7/site-packages/chardet/euctwfreq.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/euctwprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/euctwprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/gb2312freq.py create mode 100644 venv/lib/python2.7/site-packages/chardet/gb2312freq.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/gb2312prober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/gb2312prober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/hebrewprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/hebrewprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/jisfreq.py create mode 100644 venv/lib/python2.7/site-packages/chardet/jisfreq.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/jpcntx.py create mode 100644 venv/lib/python2.7/site-packages/chardet/jpcntx.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/langbulgarianmodel.py create mode 100644 venv/lib/python2.7/site-packages/chardet/langbulgarianmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/langcyrillicmodel.py create mode 100644 venv/lib/python2.7/site-packages/chardet/langcyrillicmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/langgreekmodel.py create mode 100644 venv/lib/python2.7/site-packages/chardet/langgreekmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/langhebrewmodel.py create mode 100644 venv/lib/python2.7/site-packages/chardet/langhebrewmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/langhungarianmodel.py create mode 100644 venv/lib/python2.7/site-packages/chardet/langhungarianmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/langthaimodel.py create mode 100644 venv/lib/python2.7/site-packages/chardet/langthaimodel.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/langturkishmodel.py create mode 100644 venv/lib/python2.7/site-packages/chardet/langturkishmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/latin1prober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/latin1prober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/mbcharsetprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/mbcharsetprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/mbcsgroupprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/mbcsgroupprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/mbcssm.py create mode 100644 venv/lib/python2.7/site-packages/chardet/mbcssm.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/sbcharsetprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/sbcharsetprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/sbcsgroupprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/sbcsgroupprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/sjisprober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/sjisprober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/universaldetector.py create mode 100644 venv/lib/python2.7/site-packages/chardet/universaldetector.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/utf8prober.py create mode 100644 venv/lib/python2.7/site-packages/chardet/utf8prober.pyc create mode 100644 venv/lib/python2.7/site-packages/chardet/version.py create mode 100644 venv/lib/python2.7/site-packages/chardet/version.pyc create mode 100644 venv/lib/python2.7/site-packages/click-6.7.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/click-6.7.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/click-6.7.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/click-6.7.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/click-6.7.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/click-6.7.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/click-6.7.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/click/__init__.py create mode 100644 venv/lib/python2.7/site-packages/click/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/click/_bashcomplete.py create mode 100644 venv/lib/python2.7/site-packages/click/_bashcomplete.pyc create mode 100644 venv/lib/python2.7/site-packages/click/_compat.py create mode 100644 venv/lib/python2.7/site-packages/click/_compat.pyc create mode 100644 venv/lib/python2.7/site-packages/click/_termui_impl.py create mode 100644 venv/lib/python2.7/site-packages/click/_termui_impl.pyc create mode 100644 venv/lib/python2.7/site-packages/click/_textwrap.py create mode 100644 venv/lib/python2.7/site-packages/click/_textwrap.pyc create mode 100644 venv/lib/python2.7/site-packages/click/_unicodefun.py create mode 100644 venv/lib/python2.7/site-packages/click/_unicodefun.pyc create mode 100644 venv/lib/python2.7/site-packages/click/_winconsole.py create mode 100644 venv/lib/python2.7/site-packages/click/_winconsole.pyc create mode 100644 venv/lib/python2.7/site-packages/click/core.py create mode 100644 venv/lib/python2.7/site-packages/click/core.pyc create mode 100644 venv/lib/python2.7/site-packages/click/decorators.py create mode 100644 venv/lib/python2.7/site-packages/click/decorators.pyc create mode 100644 venv/lib/python2.7/site-packages/click/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/click/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/click/formatting.py create mode 100644 venv/lib/python2.7/site-packages/click/formatting.pyc create mode 100644 venv/lib/python2.7/site-packages/click/globals.py create mode 100644 venv/lib/python2.7/site-packages/click/globals.pyc create mode 100644 venv/lib/python2.7/site-packages/click/parser.py create mode 100644 venv/lib/python2.7/site-packages/click/parser.pyc create mode 100644 venv/lib/python2.7/site-packages/click/termui.py create mode 100644 venv/lib/python2.7/site-packages/click/termui.pyc create mode 100644 venv/lib/python2.7/site-packages/click/testing.py create mode 100644 venv/lib/python2.7/site-packages/click/testing.pyc create mode 100644 venv/lib/python2.7/site-packages/click/types.py create mode 100644 venv/lib/python2.7/site-packages/click/types.pyc create mode 100644 venv/lib/python2.7/site-packages/click/utils.py create mode 100644 venv/lib/python2.7/site-packages/click/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography-2.1.3.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/cryptography-2.1.3.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/cryptography-2.1.3.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/cryptography-2.1.3.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/cryptography-2.1.3.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/cryptography-2.1.3.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/cryptography-2.1.3.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/cryptography/__about__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/__about__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/fernet.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/fernet.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/interfaces.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/interfaces.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/aead.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/aead.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/cmac.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/cmac.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/decode_asn1.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/decode_asn1.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/dh.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/dh.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/dsa.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/dsa.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/ec.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/ec.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/hashes.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/hashes.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/hmac.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/hmac.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/rsa.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/rsa.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/utils.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/x25519.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/x25519.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/x509.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/x509.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/__init__.pyc create mode 100755 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/_constant_time.so create mode 100755 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/_openssl.so create mode 100755 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/_padding.so create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/openssl/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/openssl/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/openssl/_conditional.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/openssl/_conditional.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/openssl/binding.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/bindings/openssl/binding.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/dh.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/dh.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/ec.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/padding.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/padding.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/utils.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/aead.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/aead.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/modes.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/modes.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/cmac.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/cmac.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/constant_time.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/constant_time.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/hashes.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/hashes.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/hmac.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/hmac.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/concatkdf.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/hkdf.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/hkdf.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/kbkdf.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/scrypt.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/scrypt.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/kdf/x963kdf.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/keywrap.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/keywrap.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/mac.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/mac.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/padding.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/padding.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/serialization.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/serialization.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/twofactor/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/twofactor/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/twofactor/hotp.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/twofactor/hotp.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/twofactor/totp.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/twofactor/totp.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/twofactor/utils.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/hazmat/primitives/twofactor/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/utils.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/__init__.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/base.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/base.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/certificate_transparency.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/certificate_transparency.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/extensions.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/extensions.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/general_name.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/general_name.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/name.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/name.pyc create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/oid.py create mode 100644 venv/lib/python2.7/site-packages/cryptography/x509/oid.pyc create mode 100644 venv/lib/python2.7/site-packages/easy_install.py create mode 100644 venv/lib/python2.7/site-packages/easy_install.pyc create mode 100644 venv/lib/python2.7/site-packages/enum/LICENSE create mode 100644 venv/lib/python2.7/site-packages/enum/README create mode 100644 venv/lib/python2.7/site-packages/enum/__init__.py create mode 100644 venv/lib/python2.7/site-packages/enum/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/enum34-1.1.6.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/enum34-1.1.6.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/enum34-1.1.6.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/enum34-1.1.6.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/enum34-1.1.6.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/enum34-1.1.6.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/enum34-1.1.6.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/flask/__init__.py create mode 100644 venv/lib/python2.7/site-packages/flask/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/__main__.py create mode 100644 venv/lib/python2.7/site-packages/flask/__main__.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/_compat.py create mode 100644 venv/lib/python2.7/site-packages/flask/_compat.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/app.py create mode 100644 venv/lib/python2.7/site-packages/flask/app.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/blueprints.py create mode 100644 venv/lib/python2.7/site-packages/flask/blueprints.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/cli.py create mode 100644 venv/lib/python2.7/site-packages/flask/cli.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/config.py create mode 100644 venv/lib/python2.7/site-packages/flask/config.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/ctx.py create mode 100644 venv/lib/python2.7/site-packages/flask/ctx.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/debughelpers.py create mode 100644 venv/lib/python2.7/site-packages/flask/debughelpers.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/ext/__init__.py create mode 100644 venv/lib/python2.7/site-packages/flask/ext/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/exthook.py create mode 100644 venv/lib/python2.7/site-packages/flask/exthook.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/globals.py create mode 100644 venv/lib/python2.7/site-packages/flask/globals.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/helpers.py create mode 100644 venv/lib/python2.7/site-packages/flask/helpers.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/json.py create mode 100644 venv/lib/python2.7/site-packages/flask/json.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/logging.py create mode 100644 venv/lib/python2.7/site-packages/flask/logging.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/sessions.py create mode 100644 venv/lib/python2.7/site-packages/flask/sessions.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/signals.py create mode 100644 venv/lib/python2.7/site-packages/flask/signals.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/templating.py create mode 100644 venv/lib/python2.7/site-packages/flask/templating.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/testing.py create mode 100644 venv/lib/python2.7/site-packages/flask/testing.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/views.py create mode 100644 venv/lib/python2.7/site-packages/flask/views.pyc create mode 100644 venv/lib/python2.7/site-packages/flask/wrappers.py create mode 100644 venv/lib/python2.7/site-packages/flask/wrappers.pyc create mode 100644 venv/lib/python2.7/site-packages/idna-2.6.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/idna-2.6.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/idna-2.6.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/idna-2.6.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/idna-2.6.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/idna-2.6.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/idna-2.6.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/idna/__init__.py create mode 100644 venv/lib/python2.7/site-packages/idna/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/idna/codec.py create mode 100644 venv/lib/python2.7/site-packages/idna/codec.pyc create mode 100644 venv/lib/python2.7/site-packages/idna/compat.py create mode 100644 venv/lib/python2.7/site-packages/idna/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/idna/core.py create mode 100644 venv/lib/python2.7/site-packages/idna/core.pyc create mode 100644 venv/lib/python2.7/site-packages/idna/idnadata.py create mode 100644 venv/lib/python2.7/site-packages/idna/idnadata.pyc create mode 100644 venv/lib/python2.7/site-packages/idna/intranges.py create mode 100644 venv/lib/python2.7/site-packages/idna/intranges.pyc create mode 100644 venv/lib/python2.7/site-packages/idna/package_data.py create mode 100644 venv/lib/python2.7/site-packages/idna/package_data.pyc create mode 100644 venv/lib/python2.7/site-packages/idna/uts46data.py create mode 100644 venv/lib/python2.7/site-packages/idna/uts46data.pyc create mode 100644 venv/lib/python2.7/site-packages/ipaddress-1.0.18.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/ipaddress-1.0.18.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/ipaddress-1.0.18.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/ipaddress-1.0.18.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/ipaddress-1.0.18.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/ipaddress-1.0.18.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/ipaddress-1.0.18.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/ipaddress.py create mode 100644 venv/lib/python2.7/site-packages/ipaddress.pyc create mode 100644 venv/lib/python2.7/site-packages/itsdangerous-0.24.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/itsdangerous-0.24.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/itsdangerous-0.24.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/itsdangerous-0.24.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/itsdangerous-0.24.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/itsdangerous-0.24.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/itsdangerous-0.24.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/itsdangerous.py create mode 100644 venv/lib/python2.7/site-packages/itsdangerous.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/__init__.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/_compat.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/_compat.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/_identifier.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/_identifier.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/asyncfilters.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/asyncsupport.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/bccache.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/bccache.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/compiler.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/compiler.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/constants.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/constants.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/debug.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/debug.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/defaults.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/defaults.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/environment.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/environment.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/ext.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/ext.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/filters.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/filters.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/idtracking.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/idtracking.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/lexer.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/lexer.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/loaders.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/loaders.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/meta.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/meta.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/nativetypes.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/nativetypes.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/nodes.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/nodes.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/optimizer.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/optimizer.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/parser.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/parser.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/runtime.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/runtime.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/sandbox.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/sandbox.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/tests.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/tests.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/utils.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/jinja2/visitor.py create mode 100644 venv/lib/python2.7/site-packages/jinja2/visitor.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/__init__.py create mode 100644 venv/lib/python2.7/site-packages/jwt/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/__main__.py create mode 100644 venv/lib/python2.7/site-packages/jwt/__main__.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/algorithms.py create mode 100644 venv/lib/python2.7/site-packages/jwt/algorithms.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/api_jws.py create mode 100644 venv/lib/python2.7/site-packages/jwt/api_jws.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/api_jwt.py create mode 100644 venv/lib/python2.7/site-packages/jwt/api_jwt.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/compat.py create mode 100644 venv/lib/python2.7/site-packages/jwt/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/contrib/__init__.py create mode 100644 venv/lib/python2.7/site-packages/jwt/contrib/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/contrib/algorithms/__init__.py create mode 100644 venv/lib/python2.7/site-packages/jwt/contrib/algorithms/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/contrib/algorithms/py_ecdsa.py create mode 100644 venv/lib/python2.7/site-packages/jwt/contrib/algorithms/py_ecdsa.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/contrib/algorithms/pycrypto.py create mode 100644 venv/lib/python2.7/site-packages/jwt/contrib/algorithms/pycrypto.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/jwt/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/jwt/utils.py create mode 100644 venv/lib/python2.7/site-packages/jwt/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/markupsafe/__init__.py create mode 100644 venv/lib/python2.7/site-packages/markupsafe/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/markupsafe/_compat.py create mode 100644 venv/lib/python2.7/site-packages/markupsafe/_compat.pyc create mode 100644 venv/lib/python2.7/site-packages/markupsafe/_constants.py create mode 100644 venv/lib/python2.7/site-packages/markupsafe/_constants.pyc create mode 100644 venv/lib/python2.7/site-packages/markupsafe/_native.py create mode 100644 venv/lib/python2.7/site-packages/markupsafe/_native.pyc create mode 100644 venv/lib/python2.7/site-packages/markupsafe/_speedups.c create mode 100755 venv/lib/python2.7/site-packages/markupsafe/_speedups.so create mode 100644 venv/lib/python2.7/site-packages/nose-1.3.7.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/nose-1.3.7.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/nose-1.3.7.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/nose-1.3.7.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/nose-1.3.7.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/nose-1.3.7.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/nose-1.3.7.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/nose-1.3.7.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/nose/__init__.py create mode 100644 venv/lib/python2.7/site-packages/nose/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/__main__.py create mode 100644 venv/lib/python2.7/site-packages/nose/__main__.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/case.py create mode 100644 venv/lib/python2.7/site-packages/nose/case.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/commands.py create mode 100644 venv/lib/python2.7/site-packages/nose/commands.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/config.py create mode 100644 venv/lib/python2.7/site-packages/nose/config.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/core.py create mode 100644 venv/lib/python2.7/site-packages/nose/core.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/exc.py create mode 100644 venv/lib/python2.7/site-packages/nose/exc.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/ext/__init__.py create mode 100644 venv/lib/python2.7/site-packages/nose/ext/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/ext/dtcompat.py create mode 100644 venv/lib/python2.7/site-packages/nose/ext/dtcompat.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/failure.py create mode 100644 venv/lib/python2.7/site-packages/nose/failure.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/importer.py create mode 100644 venv/lib/python2.7/site-packages/nose/importer.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/inspector.py create mode 100644 venv/lib/python2.7/site-packages/nose/inspector.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/loader.py create mode 100644 venv/lib/python2.7/site-packages/nose/loader.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/__init__.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/allmodules.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/allmodules.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/attrib.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/attrib.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/base.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/base.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/builtin.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/builtin.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/capture.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/capture.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/collect.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/collect.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/cover.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/cover.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/debug.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/debug.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/deprecated.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/deprecated.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/doctests.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/doctests.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/errorclass.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/errorclass.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/failuredetail.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/failuredetail.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/isolate.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/isolate.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/logcapture.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/logcapture.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/manager.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/manager.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/multiprocess.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/multiprocess.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/plugintest.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/plugintest.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/prof.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/prof.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/skip.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/skip.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/testid.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/testid.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/xunit.py create mode 100644 venv/lib/python2.7/site-packages/nose/plugins/xunit.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/proxy.py create mode 100644 venv/lib/python2.7/site-packages/nose/proxy.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/pyversion.py create mode 100644 venv/lib/python2.7/site-packages/nose/pyversion.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/result.py create mode 100644 venv/lib/python2.7/site-packages/nose/result.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/selector.py create mode 100644 venv/lib/python2.7/site-packages/nose/selector.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/sphinx/__init__.py create mode 100644 venv/lib/python2.7/site-packages/nose/sphinx/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/sphinx/pluginopts.py create mode 100644 venv/lib/python2.7/site-packages/nose/sphinx/pluginopts.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/suite.py create mode 100644 venv/lib/python2.7/site-packages/nose/suite.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/tools/__init__.py create mode 100644 venv/lib/python2.7/site-packages/nose/tools/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/tools/nontrivial.py create mode 100644 venv/lib/python2.7/site-packages/nose/tools/nontrivial.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/tools/trivial.py create mode 100644 venv/lib/python2.7/site-packages/nose/tools/trivial.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/twistedtools.py create mode 100644 venv/lib/python2.7/site-packages/nose/twistedtools.pyc create mode 100644 venv/lib/python2.7/site-packages/nose/usage.txt create mode 100644 venv/lib/python2.7/site-packages/nose/util.py create mode 100644 venv/lib/python2.7/site-packages/nose/util.pyc create mode 100644 venv/lib/python2.7/site-packages/pip-9.0.1.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/pip-9.0.1.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/pip-9.0.1.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/pip-9.0.1.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/pip-9.0.1.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/pip-9.0.1.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/pip-9.0.1.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/pip-9.0.1.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/pip/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/__main__.py create mode 100644 venv/lib/python2.7/site-packages/pip/__main__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/appdirs.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/appdirs.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/_cmd.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/adapter.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/cache.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/controller.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/filewrapper.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/heuristics.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/serialize.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/cachecontrol/wrapper.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/ansi.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/ansitowin32.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/initialise.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/win32.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/win32.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/colorama/winterm.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/misc.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/misc.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/shutil.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/shutil.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/_backport/tarfile.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/compat.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/database.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/database.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/index.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/index.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/locators.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/locators.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/manifest.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/markers.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/markers.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/metadata.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/resources.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/resources.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/scripts.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/util.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/util.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/version.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/version.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distlib/wheel.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distro.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/distro.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_ihatexml.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_inputstream.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_tokenizer.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/_base.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/datrie.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/py.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/_utils.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/constants.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/base.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/lint.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/filters/whitespace.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/html5parser.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/serializer.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/base.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/base.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/ipaddress.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/ipaddress.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/linklockfile.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/linklockfile.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/pidlockfile.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/pidlockfile.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/lockfile/symlinklockfile.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/ordereddict.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/ordereddict.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/__about__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/_compat.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/_compat.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/_structures.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/markers.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/markers.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/requirements.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/specifiers.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/utils.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/version.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/packaging/version.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/pkg_resources/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/bar.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/bar.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/counter.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/counter.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/helpers.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/helpers.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/spinner.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/progress/spinner.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/pyparsing.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/pyparsing.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/re-vendor.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/re-vendor.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/adapters.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/adapters.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/api.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/api.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/auth.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/auth.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/cacert.pem create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/certs.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/certs.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/compat.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/cookies.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/cookies.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/hooks.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/hooks.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/models.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/models.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/big5freq.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/big5freq.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/big5prober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/big5prober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/chardetect.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/chardetect.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/chardistribution.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/chardistribution.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/charsetgroupprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/charsetgroupprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/charsetprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/charsetprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/codingstatemachine.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/codingstatemachine.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/compat.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/constants.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/constants.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/cp949prober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/cp949prober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/escprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/escprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/escsm.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/escsm.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/eucjpprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/eucjpprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/euckrfreq.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/euckrfreq.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/euckrprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/euckrprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/euctwfreq.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/euctwfreq.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/euctwprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/euctwprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/gb2312freq.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/gb2312freq.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/gb2312prober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/gb2312prober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/hebrewprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/hebrewprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/jisfreq.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/jisfreq.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/jpcntx.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/jpcntx.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langbulgarianmodel.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langbulgarianmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langcyrillicmodel.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langcyrillicmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langgreekmodel.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langgreekmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langhebrewmodel.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langhebrewmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langhungarianmodel.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langhungarianmodel.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langthaimodel.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/langthaimodel.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/latin1prober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/latin1prober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/mbcharsetprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/mbcharsetprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/mbcsgroupprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/mbcsgroupprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/mbcssm.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/mbcssm.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/sbcharsetprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/sbcharsetprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/sbcsgroupprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/sbcsgroupprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/sjisprober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/sjisprober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/universaldetector.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/universaldetector.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/utf8prober.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/chardet/utf8prober.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/_collections.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/_collections.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/connection.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/connection.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/connectionpool.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/connectionpool.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/appengine.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/appengine.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/socks.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/contrib/socks.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/fields.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/fields.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/filepost.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/filepost.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/ordered_dict.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/ordered_dict.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/six.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/six.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/poolmanager.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/poolmanager.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/request.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/request.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/response.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/response.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/connection.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/connection.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/request.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/request.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/response.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/response.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/retry.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/retry.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/timeout.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/timeout.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/url.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/url.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/sessions.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/sessions.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/status_codes.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/structures.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/structures.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/utils.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/requests/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/retrying.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/retrying.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/six.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/six.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/labels.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/mklabels.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/tests.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 venv/lib/python2.7/site-packages/pip/_vendor/webencodings/x_user_defined.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/basecommand.py create mode 100644 venv/lib/python2.7/site-packages/pip/basecommand.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/baseparser.py create mode 100644 venv/lib/python2.7/site-packages/pip/baseparser.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/cmdoptions.py create mode 100644 venv/lib/python2.7/site-packages/pip/cmdoptions.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/check.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/check.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/completion.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/completion.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/download.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/download.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/freeze.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/freeze.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/hash.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/hash.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/help.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/help.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/install.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/install.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/list.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/list.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/search.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/search.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/show.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/show.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/uninstall.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/uninstall.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/commands/wheel.py create mode 100644 venv/lib/python2.7/site-packages/pip/commands/wheel.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/compat/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/compat/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/compat/dictconfig.py create mode 100644 venv/lib/python2.7/site-packages/pip/compat/dictconfig.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/download.py create mode 100644 venv/lib/python2.7/site-packages/pip/download.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/pip/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/index.py create mode 100644 venv/lib/python2.7/site-packages/pip/index.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/locations.py create mode 100644 venv/lib/python2.7/site-packages/pip/locations.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/models/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/models/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/models/index.py create mode 100644 venv/lib/python2.7/site-packages/pip/models/index.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/operations/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/operations/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/operations/check.py create mode 100644 venv/lib/python2.7/site-packages/pip/operations/check.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/operations/freeze.py create mode 100644 venv/lib/python2.7/site-packages/pip/operations/freeze.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/pep425tags.py create mode 100644 venv/lib/python2.7/site-packages/pip/pep425tags.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/req/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/req/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/req/req_file.py create mode 100644 venv/lib/python2.7/site-packages/pip/req/req_file.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/req/req_install.py create mode 100644 venv/lib/python2.7/site-packages/pip/req/req_install.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/req/req_set.py create mode 100644 venv/lib/python2.7/site-packages/pip/req/req_set.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/req/req_uninstall.py create mode 100644 venv/lib/python2.7/site-packages/pip/req/req_uninstall.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/status_codes.py create mode 100644 venv/lib/python2.7/site-packages/pip/status_codes.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/appdirs.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/appdirs.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/build.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/build.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/deprecation.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/deprecation.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/encoding.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/encoding.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/filesystem.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/filesystem.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/glibc.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/glibc.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/hashes.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/hashes.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/logging.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/logging.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/outdated.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/outdated.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/packaging.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/packaging.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/setuptools_build.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/setuptools_build.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/utils/ui.py create mode 100644 venv/lib/python2.7/site-packages/pip/utils/ui.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/bazaar.py create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/bazaar.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/git.py create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/git.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/mercurial.py create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/mercurial.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/subversion.py create mode 100644 venv/lib/python2.7/site-packages/pip/vcs/subversion.pyc create mode 100644 venv/lib/python2.7/site-packages/pip/wheel.py create mode 100644 venv/lib/python2.7/site-packages/pip/wheel.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/appdirs.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/__about__.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/_compat.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/_structures.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/markers.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/requirements.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/specifiers.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/packaging/version.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/pyparsing.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/six.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/_vendor/six.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/extern/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/extern/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/py31compat.py create mode 100644 venv/lib/python2.7/site-packages/pkg_resources/py31compat.pyc create mode 100644 venv/lib/python2.7/site-packages/pyOpenSSL-17.3.0.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/pyOpenSSL-17.3.0.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/pyOpenSSL-17.3.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python2.7/site-packages/pyOpenSSL-17.3.0.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/pyOpenSSL-17.3.0.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/pyOpenSSL-17.3.0.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/pyOpenSSL-17.3.0.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/pyOpenSSL-17.3.0.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/pycparser-2.18.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/pycparser-2.18.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/pycparser-2.18.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/pycparser-2.18.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/pycparser-2.18.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/pycparser-2.18.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/pycparser-2.18.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/pycparser/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/_ast_gen.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/_ast_gen.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/_build_tables.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/_build_tables.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/_c_ast.cfg create mode 100644 venv/lib/python2.7/site-packages/pycparser/ast_transforms.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/ast_transforms.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/c_ast.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/c_ast.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/c_generator.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/c_generator.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/c_lexer.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/c_lexer.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/c_parser.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/c_parser.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/lextab.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/lextab.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/cpp.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/cpp.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/ctokens.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/ctokens.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/lex.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/lex.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/yacc.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/yacc.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/ygen.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/ply/ygen.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/plyparser.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/plyparser.pyc create mode 100644 venv/lib/python2.7/site-packages/pycparser/yacctab.py create mode 100644 venv/lib/python2.7/site-packages/pycparser/yacctab.pyc create mode 100644 venv/lib/python2.7/site-packages/pytz-2017.3.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/pytz-2017.3.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/pytz-2017.3.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/pytz-2017.3.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/pytz-2017.3.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/pytz-2017.3.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/pytz-2017.3.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/pytz-2017.3.dist-info/zip-safe create mode 100644 venv/lib/python2.7/site-packages/pytz/__init__.py create mode 100644 venv/lib/python2.7/site-packages/pytz/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/pytz/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/pytz/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/pytz/lazy.py create mode 100644 venv/lib/python2.7/site-packages/pytz/lazy.pyc create mode 100644 venv/lib/python2.7/site-packages/pytz/reference.py create mode 100644 venv/lib/python2.7/site-packages/pytz/reference.pyc create mode 100644 venv/lib/python2.7/site-packages/pytz/tzfile.py create mode 100644 venv/lib/python2.7/site-packages/pytz/tzfile.pyc create mode 100644 venv/lib/python2.7/site-packages/pytz/tzinfo.py create mode 100644 venv/lib/python2.7/site-packages/pytz/tzinfo.pyc create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Abidjan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Accra create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Addis_Ababa create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Algiers create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Asmara create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Asmera create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Bamako create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Bangui create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Banjul create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Bissau create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Blantyre create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Brazzaville create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Bujumbura create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Cairo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Casablanca create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Ceuta create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Conakry create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Dakar create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Dar_es_Salaam create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Djibouti create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Douala create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/El_Aaiun create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Freetown create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Gaborone create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Harare create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Johannesburg create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Juba create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Kampala create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Khartoum create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Kigali create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Kinshasa create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Lagos create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Libreville create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Lome create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Luanda create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Lubumbashi create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Lusaka create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Malabo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Maputo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Maseru create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Mbabane create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Mogadishu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Monrovia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Nairobi create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Ndjamena create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Niamey create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Nouakchott create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Ouagadougou create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Porto-Novo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Sao_Tome create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Timbuktu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Tripoli create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Tunis create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Africa/Windhoek create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Adak create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Anchorage create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Anguilla create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Antigua create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Araguaina create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Buenos_Aires create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Catamarca create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/ComodRivadavia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Cordoba create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Jujuy create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/La_Rioja create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Mendoza create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Rio_Gallegos create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Salta create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/San_Juan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/San_Luis create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Tucuman create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Argentina/Ushuaia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Aruba create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Asuncion create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Atikokan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Atka create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Bahia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Bahia_Banderas create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Barbados create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Belem create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Belize create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Blanc-Sablon create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Boa_Vista create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Bogota create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Boise create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Buenos_Aires create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Cambridge_Bay create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Campo_Grande create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Cancun create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Caracas create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Catamarca create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Cayenne create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Cayman create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Chicago create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Chihuahua create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Coral_Harbour create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Cordoba create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Costa_Rica create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Creston create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Cuiaba create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Curacao create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Danmarkshavn create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Dawson create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Dawson_Creek create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Denver create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Detroit create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Dominica create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Edmonton create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Eirunepe create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/El_Salvador create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Ensenada create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Fort_Nelson create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Fort_Wayne create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Fortaleza create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Glace_Bay create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Godthab create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Goose_Bay create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Grand_Turk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Grenada create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Guadeloupe create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Guatemala create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Guayaquil create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Guyana create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Halifax create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Havana create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Hermosillo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indiana/Indianapolis create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indiana/Knox create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indiana/Marengo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indiana/Petersburg create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indiana/Tell_City create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indiana/Vevay create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indiana/Vincennes create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indiana/Winamac create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Indianapolis create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Inuvik create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Iqaluit create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Jamaica create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Jujuy create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Juneau create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Kentucky/Louisville create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Kentucky/Monticello create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Knox_IN create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Kralendijk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/La_Paz create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Lima create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Los_Angeles create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Louisville create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Lower_Princes create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Maceio create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Managua create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Manaus create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Marigot create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Martinique create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Matamoros create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Mazatlan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Mendoza create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Menominee create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Merida create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Metlakatla create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Mexico_City create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Miquelon create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Moncton create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Monterrey create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Montevideo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Montreal create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Montserrat create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Nassau create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/New_York create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Nipigon create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Nome create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Noronha create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/North_Dakota/Beulah create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/North_Dakota/Center create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/North_Dakota/New_Salem create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Ojinaga create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Panama create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Pangnirtung create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Paramaribo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Phoenix create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Port-au-Prince create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Port_of_Spain create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Porto_Acre create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Porto_Velho create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Puerto_Rico create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Punta_Arenas create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Rainy_River create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Rankin_Inlet create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Recife create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Regina create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Resolute create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Rio_Branco create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Rosario create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Santa_Isabel create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Santarem create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Santiago create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Santo_Domingo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Sao_Paulo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Scoresbysund create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Shiprock create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Sitka create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/St_Barthelemy create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/St_Johns create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/St_Kitts create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/St_Lucia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/St_Thomas create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/St_Vincent create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Swift_Current create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Tegucigalpa create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Thule create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Thunder_Bay create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Tijuana create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Toronto create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Tortola create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Vancouver create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Virgin create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Whitehorse create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Winnipeg create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Yakutat create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/America/Yellowknife create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Casey create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Davis create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/DumontDUrville create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Macquarie create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Mawson create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/McMurdo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Palmer create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Rothera create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/South_Pole create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Syowa create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Troll create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Antarctica/Vostok create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Arctic/Longyearbyen create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Aden create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Almaty create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Amman create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Anadyr create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Aqtau create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Aqtobe create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Ashgabat create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Ashkhabad create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Atyrau create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Baghdad create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Bahrain create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Baku create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Bangkok create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Barnaul create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Beirut create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Bishkek create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Brunei create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Calcutta create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Chita create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Choibalsan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Chongqing create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Chungking create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Colombo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Dacca create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Damascus create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Dhaka create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Dili create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Dubai create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Dushanbe create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Famagusta create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Gaza create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Harbin create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Hebron create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Ho_Chi_Minh create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Hong_Kong create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Hovd create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Irkutsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Istanbul create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Jakarta create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Jayapura create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Jerusalem create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Kabul create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Kamchatka create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Karachi create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Kashgar create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Kathmandu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Katmandu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Khandyga create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Kolkata create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Krasnoyarsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Kuala_Lumpur create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Kuching create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Kuwait create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Macao create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Macau create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Magadan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Makassar create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Manila create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Muscat create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Nicosia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Novokuznetsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Novosibirsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Omsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Oral create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Phnom_Penh create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Pontianak create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Pyongyang create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Qatar create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Qyzylorda create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Rangoon create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Riyadh create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Saigon create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Sakhalin create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Samarkand create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Seoul create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Shanghai create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Singapore create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Srednekolymsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Taipei create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Tashkent create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Tbilisi create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Tehran create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Tel_Aviv create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Thimbu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Thimphu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Tokyo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Tomsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Ujung_Pandang create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Ulaanbaatar create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Ulan_Bator create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Urumqi create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Ust-Nera create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Vientiane create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Vladivostok create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Yakutsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Yangon create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Yekaterinburg create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Asia/Yerevan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Azores create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Bermuda create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Canary create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Cape_Verde create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Faeroe create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Faroe create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Jan_Mayen create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Madeira create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Reykjavik create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/South_Georgia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/St_Helena create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Atlantic/Stanley create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/ACT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Adelaide create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Brisbane create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Broken_Hill create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Canberra create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Currie create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Darwin create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Eucla create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Hobart create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/LHI create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Lindeman create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Lord_Howe create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Melbourne create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/NSW create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/North create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Perth create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Queensland create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/South create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Sydney create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Tasmania create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Victoria create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/West create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Australia/Yancowinna create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Brazil/Acre create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Brazil/DeNoronha create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Brazil/East create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Brazil/West create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/CET create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/CST6CDT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Canada/Atlantic create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Canada/Central create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Canada/Eastern create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Canada/Mountain create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Canada/Newfoundland create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Canada/Pacific create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Canada/Saskatchewan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Canada/Yukon create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Chile/Continental create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Chile/EasterIsland create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Cuba create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/EET create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/EST create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/EST5EDT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Egypt create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Eire create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+0 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+1 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+10 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+11 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+12 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+2 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+3 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+4 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+5 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+6 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+7 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+8 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT+9 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-0 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-1 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-10 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-11 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-12 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-13 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-14 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-2 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-3 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-4 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-5 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-6 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-7 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-8 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT-9 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/GMT0 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/Greenwich create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/UCT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/UTC create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/Universal create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Etc/Zulu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Amsterdam create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Andorra create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Astrakhan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Athens create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Belfast create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Belgrade create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Berlin create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Bratislava create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Brussels create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Bucharest create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Budapest create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Busingen create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Chisinau create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Copenhagen create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Dublin create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Gibraltar create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Guernsey create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Helsinki create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Isle_of_Man create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Istanbul create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Jersey create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Kaliningrad create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Kiev create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Kirov create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Lisbon create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Ljubljana create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/London create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Luxembourg create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Madrid create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Malta create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Mariehamn create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Minsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Monaco create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Moscow create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Nicosia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Oslo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Paris create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Podgorica create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Prague create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Riga create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Rome create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Samara create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/San_Marino create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Sarajevo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Saratov create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Simferopol create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Skopje create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Sofia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Stockholm create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Tallinn create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Tirane create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Tiraspol create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Ulyanovsk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Uzhgorod create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Vaduz create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Vatican create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Vienna create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Vilnius create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Volgograd create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Warsaw create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Zagreb create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Zaporozhye create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Europe/Zurich create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Factory create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/GB create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/GB-Eire create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/GMT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/GMT+0 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/GMT-0 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/GMT0 create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Greenwich create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/HST create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Hongkong create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Iceland create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Antananarivo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Chagos create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Christmas create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Cocos create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Comoro create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Kerguelen create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Mahe create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Maldives create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Mauritius create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Mayotte create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Indian/Reunion create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Iran create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Israel create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Jamaica create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Japan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Kwajalein create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Libya create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/MET create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/MST create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/MST7MDT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Mexico/BajaNorte create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Mexico/BajaSur create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Mexico/General create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/NZ create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/NZ-CHAT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Navajo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/PRC create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/PST8PDT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Apia create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Auckland create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Bougainville create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Chatham create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Chuuk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Easter create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Efate create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Enderbury create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Fakaofo create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Fiji create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Funafuti create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Galapagos create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Gambier create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Guadalcanal create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Guam create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Honolulu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Johnston create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Kiritimati create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Kosrae create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Kwajalein create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Majuro create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Marquesas create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Midway create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Nauru create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Niue create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Norfolk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Noumea create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Pago_Pago create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Palau create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Pitcairn create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Pohnpei create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Ponape create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Port_Moresby create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Rarotonga create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Saipan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Samoa create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Tahiti create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Tarawa create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Tongatapu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Truk create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Wake create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Wallis create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Pacific/Yap create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Poland create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Portugal create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/ROC create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/ROK create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Singapore create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Turkey create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/UCT create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Alaska create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Aleutian create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Arizona create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Central create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/East-Indiana create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Eastern create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Hawaii create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Indiana-Starke create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Michigan create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Mountain create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Pacific create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Pacific-New create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/US/Samoa create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/UTC create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Universal create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/W-SU create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/WET create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/Zulu create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/iso3166.tab create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/leapseconds create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/localtime create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/posixrules create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/tzdata.zi create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/zone.tab create mode 100644 venv/lib/python2.7/site-packages/pytz/zoneinfo/zone1970.tab create mode 100644 venv/lib/python2.7/site-packages/requests-2.18.4.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/requests-2.18.4.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/requests-2.18.4.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/requests-2.18.4.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/requests-2.18.4.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/requests-2.18.4.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/requests-2.18.4.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/requests/__init__.py create mode 100644 venv/lib/python2.7/site-packages/requests/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/__version__.py create mode 100644 venv/lib/python2.7/site-packages/requests/__version__.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/_internal_utils.py create mode 100644 venv/lib/python2.7/site-packages/requests/_internal_utils.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/adapters.py create mode 100644 venv/lib/python2.7/site-packages/requests/adapters.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/api.py create mode 100644 venv/lib/python2.7/site-packages/requests/api.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/auth.py create mode 100644 venv/lib/python2.7/site-packages/requests/auth.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/certs.py create mode 100644 venv/lib/python2.7/site-packages/requests/certs.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/compat.py create mode 100644 venv/lib/python2.7/site-packages/requests/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/cookies.py create mode 100644 venv/lib/python2.7/site-packages/requests/cookies.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/requests/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/help.py create mode 100644 venv/lib/python2.7/site-packages/requests/help.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/hooks.py create mode 100644 venv/lib/python2.7/site-packages/requests/hooks.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/models.py create mode 100644 venv/lib/python2.7/site-packages/requests/models.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/packages.py create mode 100644 venv/lib/python2.7/site-packages/requests/packages.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/sessions.py create mode 100644 venv/lib/python2.7/site-packages/requests/sessions.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/status_codes.py create mode 100644 venv/lib/python2.7/site-packages/requests/status_codes.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/structures.py create mode 100644 venv/lib/python2.7/site-packages/requests/structures.pyc create mode 100644 venv/lib/python2.7/site-packages/requests/utils.py create mode 100644 venv/lib/python2.7/site-packages/requests/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/LICENSE.txt create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/dependency_links.txt create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/setuptools-36.7.1.dist-info/zip-safe create mode 100644 venv/lib/python2.7/site-packages/setuptools/__init__.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/archive_util.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/archive_util.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/build_meta.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/build_meta.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/cli-32.exe create mode 100644 venv/lib/python2.7/site-packages/setuptools/cli-64.exe create mode 100644 venv/lib/python2.7/site-packages/setuptools/cli.exe create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/__init__.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/alias.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/alias.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/bdist_egg.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/bdist_egg.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/bdist_rpm.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/bdist_rpm.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/bdist_wininst.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/bdist_wininst.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/build_clib.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/build_clib.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/build_ext.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/build_ext.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/build_py.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/build_py.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/develop.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/develop.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/dist_info.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/dist_info.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/easy_install.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/easy_install.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/egg_info.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/egg_info.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/install.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/install.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/install_egg_info.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/install_egg_info.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/install_lib.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/install_lib.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/install_scripts.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/install_scripts.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/launcher manifest.xml create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/py36compat.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/py36compat.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/register.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/register.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/rotate.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/rotate.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/saveopts.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/saveopts.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/sdist.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/sdist.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/setopt.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/setopt.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/test.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/test.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/upload.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/upload.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/upload_docs.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/command/upload_docs.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/config.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/config.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/dep_util.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/dep_util.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/depends.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/depends.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/dist.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/dist.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/extension.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/extension.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/extern/__init__.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/extern/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/glob.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/glob.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/gui-32.exe create mode 100644 venv/lib/python2.7/site-packages/setuptools/gui-64.exe create mode 100644 venv/lib/python2.7/site-packages/setuptools/gui.exe create mode 100644 venv/lib/python2.7/site-packages/setuptools/launch.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/launch.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/lib2to3_ex.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/lib2to3_ex.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/monkey.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/monkey.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/msvc.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/msvc.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/namespaces.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/namespaces.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/package_index.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/package_index.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/py26compat.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/py26compat.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/py27compat.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/py27compat.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/py31compat.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/py31compat.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/py33compat.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/py33compat.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/py36compat.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/py36compat.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/sandbox.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/sandbox.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/script (dev).tmpl create mode 100644 venv/lib/python2.7/site-packages/setuptools/script.tmpl create mode 100644 venv/lib/python2.7/site-packages/setuptools/site-patch.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/site-patch.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/ssl_support.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/ssl_support.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/unicode_utils.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/unicode_utils.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/version.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/version.pyc create mode 100644 venv/lib/python2.7/site-packages/setuptools/windows_support.py create mode 100644 venv/lib/python2.7/site-packages/setuptools/windows_support.pyc create mode 100644 venv/lib/python2.7/site-packages/six-1.11.0.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/six-1.11.0.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/six-1.11.0.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/six-1.11.0.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/six-1.11.0.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/six-1.11.0.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/six-1.11.0.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/six.py create mode 100644 venv/lib/python2.7/site-packages/six.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio-6.8.4.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/twilio-6.8.4.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/twilio-6.8.4.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/twilio-6.8.4.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/twilio-6.8.4.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/twilio-6.8.4.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/twilio-6.8.4.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/twilio/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/deserialize.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/deserialize.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/domain.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/domain.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/instance_context.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/instance_context.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/instance_resource.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/instance_resource.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/list_resource.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/list_resource.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/obsolete.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/obsolete.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/page.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/page.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/serialize.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/serialize.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/values.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/values.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/base/version.py create mode 100644 venv/lib/python2.7/site-packages/twilio/base/version.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/compat.py create mode 100644 venv/lib/python2.7/site-packages/twilio/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/http/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/http/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/http/http_client.py create mode 100644 venv/lib/python2.7/site-packages/twilio/http/http_client.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/http/request.py create mode 100644 venv/lib/python2.7/site-packages/twilio/http/request.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/http/response.py create mode 100644 venv/lib/python2.7/site-packages/twilio/http/response.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/http/validation_client.py create mode 100644 venv/lib/python2.7/site-packages/twilio/http/validation_client.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/access_token/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/access_token/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/access_token/grants.py create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/access_token/grants.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/client/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/client/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/compat.py create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/compat.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/taskrouter/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/taskrouter/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/taskrouter/capabilities.py create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/taskrouter/capabilities.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/validation/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/jwt/validation/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/request_validator.py create mode 100644 venv/lib/python2.7/site-packages/twilio/request_validator.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/v1/credential/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/v1/credential/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/v1/credential/aws.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/v1/credential/aws.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/v1/credential/public_key.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/accounts/v1/credential/public_key.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/address/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/address/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/address/dependent_phone_number.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/address/dependent_phone_number.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/application.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/application.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/authorized_connect_app.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/authorized_connect_app.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/available_phone_number/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/available_phone_number/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/available_phone_number/local.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/available_phone_number/local.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/available_phone_number/mobile.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/available_phone_number/mobile.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/available_phone_number/toll_free.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/available_phone_number/toll_free.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/feedback.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/feedback.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/feedback_summary.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/feedback_summary.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/notification.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/notification.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/recording.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/call/recording.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/conference/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/conference/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/conference/participant.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/conference/participant.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/connect_app.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/connect_app.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/assigned_add_on/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/assigned_add_on/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/assigned_add_on/assigned_add_on_extension.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/assigned_add_on/assigned_add_on_extension.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/local.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/local.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/mobile.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/mobile.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/toll_free.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/incoming_phone_number/toll_free.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/key.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/key.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/message/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/message/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/message/feedback.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/message/feedback.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/message/media.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/message/media.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/new_key.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/new_key.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/new_signing_key.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/new_signing_key.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/notification.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/notification.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/outgoing_caller_id.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/outgoing_caller_id.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/queue/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/queue/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/queue/member.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/queue/member.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/recording/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/recording/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/recording/add_on_result/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/recording/add_on_result/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/recording/add_on_result/payload/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/recording/add_on_result/payload/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/recording/transcription.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/recording/transcription.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/short_code.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/short_code.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/signing_key.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/signing_key.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/credential_list/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/credential_list/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/credential_list/credential.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/credential_list/credential.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/domain/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/domain/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/domain/credential_list_mapping.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/domain/credential_list_mapping.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/domain/ip_access_control_list_mapping.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/domain/ip_access_control_list_mapping.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/ip_access_control_list/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/ip_access_control_list/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/ip_access_control_list/ip_address.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/sip/ip_access_control_list/ip_address.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/token.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/token.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/transcription.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/transcription.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/all_time.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/all_time.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/daily.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/daily.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/last_month.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/last_month.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/monthly.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/monthly.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/this_month.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/this_month.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/today.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/today.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/yearly.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/yearly.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/yesterday.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/record/yesterday.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/trigger.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/usage/trigger.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/validation_request.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/api/v2010/account/validation_request.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/credential.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/credential.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/channel/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/channel/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/channel/invite.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/channel/invite.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/channel/member.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/channel/member.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/channel/message.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/channel/message.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/role.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/role.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/user/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/user/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/user/user_channel.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v1/service/user/user_channel.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/credential.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/credential.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/binding.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/binding.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/channel/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/channel/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/channel/invite.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/channel/invite.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/channel/member.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/channel/member.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/channel/message.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/channel/message.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/role.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/role.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/user/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/user/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/user/user_binding.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/user/user_binding.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/user/user_channel.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/chat/v2/service/user/user_channel.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/fax/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/fax/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/fax/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/fax/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/fax/v1/fax/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/fax/v1/fax/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/fax/v1/fax/fax_media.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/fax/v1/fax/fax_media.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/credential.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/credential.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/channel/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/channel/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/channel/invite.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/channel/invite.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/channel/member.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/channel/member.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/channel/message.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/channel/message.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/role.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/role.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/user/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/user/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/user/user_channel.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v1/service/user/user_channel.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/credential.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/credential.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/binding.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/binding.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/channel/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/channel/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/channel/invite.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/channel/invite.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/channel/member.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/channel/member.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/channel/message.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/channel/message.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/role.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/role.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/user/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/user/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/user/user_binding.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/user/user_binding.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/user/user_channel.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/ip_messaging/v2/service/user/user_channel.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/lookups/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/lookups/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/lookups/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/lookups/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/lookups/v1/phone_number.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/lookups/v1/phone_number.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/service/alpha_sender.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/service/alpha_sender.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/service/phone_number.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/service/phone_number.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/service/short_code.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/messaging/v1/service/short_code.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/monitor/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/monitor/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/monitor/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/monitor/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/monitor/v1/alert.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/monitor/v1/alert.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/monitor/v1/event.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/monitor/v1/event.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/credential.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/credential.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/binding.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/binding.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/notification.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/notification.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/segment.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/segment.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/user/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/user/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/user/segment_memberships.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/user/segment_memberships.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/user/user_binding.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/notify/v1/service/user/user_binding.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/acc_security/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/acc_security/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/acc_security/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/acc_security/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/acc_security/service/verification.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/acc_security/service/verification.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/acc_security/service/verification_check.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/acc_security/service/verification_check.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/bulk_exports/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/bulk_exports/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/bulk_exports/export/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/bulk_exports/export/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/bulk_exports/export/day.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/bulk_exports/export/day.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/bulk_exports/export_configuration.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/bulk_exports/export_configuration.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/certificate.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/certificate.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/deployment.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/deployment.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/device.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/device.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/key.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/deployed_devices/fleet/key.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/hosted_numbers/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/hosted_numbers/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/hosted_numbers/authorization_document.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/hosted_numbers/authorization_document.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/hosted_numbers/hosted_number_order.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/hosted_numbers/hosted_number_order.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/available_add_on/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/available_add_on/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/available_add_on/available_add_on_extension.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/available_add_on/available_add_on_extension.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/installed_add_on/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/installed_add_on/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/installed_add_on/installed_add_on_extension.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/marketplace/installed_add_on/installed_add_on_extension.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/phone_number.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/phone_number.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/session/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/session/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/session/interaction.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/session/interaction.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/session/participant/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/session/participant/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/session/participant/message_interaction.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/session/participant/message_interaction.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/short_code.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/proxy/service/short_code.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/studio/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/studio/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/studio/flow/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/studio/flow/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/studio/flow/engagement/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/studio/flow/engagement/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/studio/flow/engagement/step.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/studio/flow/engagement/step.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/document/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/document/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/document/document_permission.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/document/document_permission.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_list/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_list/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_list/sync_list_item.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_list/sync_list_item.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_list/sync_list_permission.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_list/sync_list_permission.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_map/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_map/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_map/sync_map_item.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_map/sync_map_item.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_map/sync_map_permission.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/sync/service/sync_map/sync_map_permission.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/field_type/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/field_type/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/field_type/field_value.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/field_type/field_value.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/intent/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/intent/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/intent/field.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/intent/field.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/intent/sample.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/intent/sample.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/model_build.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/model_build.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/query.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/understand/service/query.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/command.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/command.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/rate_plan.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/rate_plan.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/sim/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/sim/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/sim/usage.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/preview/wireless/sim/usage.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/messaging/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/messaging/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/messaging/country.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/messaging/country.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/phone_number/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/phone_number/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/phone_number/country.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/phone_number/country.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/voice/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/voice/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/voice/country.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/voice/country.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/voice/number.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/pricing/v1/voice/number.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/phone_number.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/phone_number.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/session/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/session/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/session/interaction.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/session/interaction.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/session/participant/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/session/participant/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/session/participant/message_interaction.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/session/participant/message_interaction.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/short_code.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/proxy/v1/service/short_code.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/document/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/document/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/document/document_permission.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/document/document_permission.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_list/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_list/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_list/sync_list_item.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_list/sync_list_item.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_list/sync_list_permission.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_list/sync_list_permission.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_map/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_map/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_map/sync_map_item.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_map/sync_map_item.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_map/sync_map_permission.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_map/sync_map_permission.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_stream/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_stream/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_stream/stream_message.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/sync/v1/service/sync_stream/stream_message.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/activity.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/activity.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/event.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/event.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task/reservation.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task/reservation.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_channel.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_channel.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_cumulative_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_cumulative_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_real_time_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_real_time_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/task_queues_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/task_queue/task_queues_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/reservation.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/reservation.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/worker_channel.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/worker_channel.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/worker_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/worker_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/workers_cumulative_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/workers_cumulative_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/workers_real_time_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/workers_real_time_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/workers_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/worker/workers_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workflow/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workflow/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workflow/workflow_cumulative_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workflow/workflow_cumulative_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workflow/workflow_real_time_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workflow/workflow_real_time_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workflow/workflow_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workflow/workflow_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workspace_cumulative_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workspace_cumulative_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workspace_real_time_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workspace_real_time_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workspace_statistics.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/taskrouter/v1/workspace/workspace_statistics.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/credential_list.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/credential_list.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/ip_access_control_list.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/ip_access_control_list.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/origination_url.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/origination_url.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/phone_number.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/trunking/v1/trunk/phone_number.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/recording/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/recording/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/room/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/room/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/room/recording/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/room/recording/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/room/room_participant/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/room/room_participant/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/room/room_participant/room_participant_published_track.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/video/v1/room/room_participant/room_participant_published_track.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/command.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/command.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/rate_plan.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/rate_plan.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/sim/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/sim/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/sim/data_session.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/sim/data_session.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/sim/usage_record.py create mode 100644 venv/lib/python2.7/site-packages/twilio/rest/wireless/v1/sim/usage_record.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/twiml/__init__.py create mode 100644 venv/lib/python2.7/site-packages/twilio/twiml/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/twiml/fax_response.py create mode 100644 venv/lib/python2.7/site-packages/twilio/twiml/fax_response.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/twiml/messaging_response.py create mode 100644 venv/lib/python2.7/site-packages/twilio/twiml/messaging_response.pyc create mode 100644 venv/lib/python2.7/site-packages/twilio/twiml/voice_response.py create mode 100644 venv/lib/python2.7/site-packages/twilio/twiml/voice_response.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3-1.22.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/urllib3-1.22.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/urllib3-1.22.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/urllib3-1.22.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/urllib3-1.22.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/urllib3-1.22.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/urllib3-1.22.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/urllib3/__init__.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/_collections.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/_collections.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/connection.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/connection.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/connectionpool.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/connectionpool.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/__init__.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/__init__.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/bindings.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/bindings.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/appengine.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/appengine.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/ntlmpool.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/ntlmpool.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/securetransport.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/securetransport.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/socks.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/contrib/socks.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/fields.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/fields.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/filepost.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/filepost.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/__init__.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/backports/__init__.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/backports/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/backports/makefile.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/backports/makefile.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/ordered_dict.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/ordered_dict.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/six.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/six.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/ssl_match_hostname/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/packages/ssl_match_hostname/_implementation.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/poolmanager.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/poolmanager.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/request.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/request.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/response.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/response.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/__init__.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/connection.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/connection.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/request.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/request.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/response.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/response.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/retry.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/retry.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/selectors.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/selectors.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/ssl_.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/ssl_.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/timeout.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/timeout.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/url.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/url.pyc create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/wait.py create mode 100644 venv/lib/python2.7/site-packages/urllib3/util/wait.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/__init__.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/_compat.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/_compat.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/_internal.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/_internal.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/_reloader.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/_reloader.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/__init__.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/atom.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/atom.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/cache.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/cache.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/fixers.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/fixers.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/iterio.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/iterio.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/jsrouting.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/jsrouting.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/limiter.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/limiter.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/lint.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/lint.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/profiler.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/profiler.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/securecookie.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/securecookie.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/sessions.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/sessions.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/testtools.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/testtools.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/wrappers.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/contrib/wrappers.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/datastructures.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/datastructures.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/__init__.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/console.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/console.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/repr.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/repr.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/FONT_LICENSE create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/console.png create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/jquery.js create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/less.png create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/more.png create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/source.png create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/style.css create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/shared/ubuntu.ttf create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/tbtools.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/debug/tbtools.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/exceptions.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/exceptions.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/filesystem.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/filesystem.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/formparser.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/formparser.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/http.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/http.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/local.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/local.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/posixemulation.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/posixemulation.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/routing.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/routing.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/script.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/script.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/security.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/security.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/serving.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/serving.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/test.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/test.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/testapp.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/testapp.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/urls.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/urls.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/useragents.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/useragents.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/utils.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/utils.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/wrappers.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/wrappers.pyc create mode 100644 venv/lib/python2.7/site-packages/werkzeug/wsgi.py create mode 100644 venv/lib/python2.7/site-packages/werkzeug/wsgi.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/INSTALLER create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/METADATA create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/RECORD create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/WHEEL create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/entry_points.txt create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/metadata.json create mode 100644 venv/lib/python2.7/site-packages/wheel-0.30.0.dist-info/top_level.txt create mode 100644 venv/lib/python2.7/site-packages/wheel/__init__.py create mode 100644 venv/lib/python2.7/site-packages/wheel/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/__main__.py create mode 100644 venv/lib/python2.7/site-packages/wheel/__main__.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/archive.py create mode 100644 venv/lib/python2.7/site-packages/wheel/archive.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/bdist_wheel.py create mode 100644 venv/lib/python2.7/site-packages/wheel/bdist_wheel.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/decorator.py create mode 100644 venv/lib/python2.7/site-packages/wheel/decorator.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/egg2wheel.py create mode 100644 venv/lib/python2.7/site-packages/wheel/egg2wheel.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/install.py create mode 100644 venv/lib/python2.7/site-packages/wheel/install.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/metadata.py create mode 100644 venv/lib/python2.7/site-packages/wheel/metadata.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/paths.py create mode 100644 venv/lib/python2.7/site-packages/wheel/paths.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/pep425tags.py create mode 100644 venv/lib/python2.7/site-packages/wheel/pep425tags.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/pkginfo.py create mode 100644 venv/lib/python2.7/site-packages/wheel/pkginfo.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/signatures/__init__.py create mode 100644 venv/lib/python2.7/site-packages/wheel/signatures/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/signatures/djbec.py create mode 100644 venv/lib/python2.7/site-packages/wheel/signatures/djbec.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/signatures/ed25519py.py create mode 100644 venv/lib/python2.7/site-packages/wheel/signatures/ed25519py.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/signatures/keys.py create mode 100644 venv/lib/python2.7/site-packages/wheel/signatures/keys.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/tool/__init__.py create mode 100644 venv/lib/python2.7/site-packages/wheel/tool/__init__.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/util.py create mode 100644 venv/lib/python2.7/site-packages/wheel/util.pyc create mode 100644 venv/lib/python2.7/site-packages/wheel/wininst2wheel.py create mode 100644 venv/lib/python2.7/site-packages/wheel/wininst2wheel.pyc create mode 100644 venv/lib/python2.7/site.py create mode 100644 venv/lib/python2.7/site.pyc create mode 120000 venv/lib/python2.7/sre.py create mode 120000 venv/lib/python2.7/sre_compile.py create mode 100644 venv/lib/python2.7/sre_compile.pyc create mode 120000 venv/lib/python2.7/sre_constants.py create mode 100644 venv/lib/python2.7/sre_constants.pyc create mode 120000 venv/lib/python2.7/sre_parse.py create mode 100644 venv/lib/python2.7/sre_parse.pyc create mode 120000 venv/lib/python2.7/stat.py create mode 100644 venv/lib/python2.7/stat.pyc create mode 120000 venv/lib/python2.7/types.py create mode 100644 venv/lib/python2.7/types.pyc create mode 120000 venv/lib/python2.7/warnings.py create mode 100644 venv/lib/python2.7/warnings.pyc create mode 100644 venv/man/man1/nosetests.1 create mode 100644 venv/pip-selfcheck.json diff --git a/app.py b/app.py index 78c7b8f..4a0cec5 100644 --- a/app.py +++ b/app.py @@ -2,6 +2,8 @@ import twilio.twiml import data from services import * +import urllib2 +from bs4 import BeautifulSoup app = Flask(__name__) @@ -18,6 +20,8 @@ def eval(cmd, input=None): return shuttle.eval(cmd['args']) elif cmd['service'] == 'W': ## Weather return weather.eval(input) + elif cmd['service'] == 'SP': + return sports.eval(input) else: return "ERROR 42: service not recognized" @@ -33,6 +37,8 @@ def special(incoming): body = laundry.special elif incoming.upper() == "WEATHER": body = weather.special + elif incoming.upper() == "UPCOMING SPORTS GAMES": + body = sports.special elif incoming.upper() == "DEMO": ## welcome/instructions body = 'Thanks for using Harvard Now!\n' @@ -82,5 +88,7 @@ def response(): resp.message(body) return str(resp) + + if __name__ == "__main__": app.run(debug=True) diff --git a/data.py b/data.py index 2fdf85b..f81698f 100755 --- a/data.py +++ b/data.py @@ -2,6 +2,7 @@ ## a command is a dictionary containing a list of tags that uniquely identify it ## along with all the information needed to run the command box = [ + {'service': 'SP', 'args':{}, 'tags': ['SPORTS', 'UPCOMING SPORTS', 'GAMES']}, {'service': 'L', 'args':{ 'roomid':'1362520', 'machinetype':'washer', 'label': 'DUNSTER HOUSE K Washers'}, 'tags': ['DUNSTER', 'HOUSE', 'K', 'LAUNDRY', 'WASHERS', 'WASHER']}, {'service': 'L', 'args':{ 'roomid':'1362520', 'machinetype':'dryer', 'label': 'DUNSTER HOUSE K Dryers'}, 'tags': ['DUNSTER', 'HOUSE', 'K', 'LAUNDRY', 'DRYER', 'DRYERS']}, {'service': 'L', 'args':{ 'roomid':'1362521', 'machinetype':'washer', 'label': 'DUNSTER HOUSE G Washers'}, 'tags': ['DUNSTER', 'HOUSE', 'G', 'LAUNDRY', 'WASHERS', 'WASHER']}, diff --git a/data.pyc b/data.pyc index 7c5337f4bca502da068603c268a825e5a992e981..6f1261055ab0c08612e845285dd7952275d9602a 100644 GIT binary patch literal 16709 zcmbVS2Vfh=mEE;mWjpRoZYvjwvP}`4V4_%F080QOniha4DizYeBqEZav7ky4r?)G) z)a#erCD(gN@44Q4Z@J$4<$C|~|Lo4rVisV|w2kHNfA7Ef|IeS<0r!3W#{Hjr_L?*2 z4Dru9;PWZ?&$AvjjKMyG83r?r+yFkVFmeoTTxqbYjCHuU8g9eKHDmx+*Bb0Pu-R|0 z>*3=DgWU)p9Q7Q7-DI$v4R(vcZZ+6##`@Lq@Y@M~haP^X!S2$-?^e9u6NMj`;a$Lm z_j~p5c<=Wq-tU+22MqS0!K@kH1zdPPsE5aUe@OBEu!KKiut!6#uhN8FV1?^L8Z7zM zVGk>Q=Op$BX8bXOJ+2CX5}7C)K_Ub^F^z=YCwMM+XJm}9VIUr$-p1D#|dEP_htsm!J#RXVDwqUwaCS}|D7 zV0D8vR6V+(2@;{FIgKPfK5F&0B*{sGxdv;8N=4T>)uQd_;pANh?<#RPCE=@>m(w%6 z3%H2DnjRkS{fy%M1ri>qjTfr9&?Qt*2_-L@O+~77R4-Oky(E_ErL$EDDxs=3n<`$_ zSw+>kSSn_)ekg0Y0SYRi>gm~3@v7DpRU48j=raQ~O1gO@NQ9o3O(P*CI+F8>l1)jn zg_Rs^KXhxEzzPA|8Z7zMVTX#}9f^Gg{m$BZ2)J-P(!!;|o_zxM6^Ki0kr zGk8dkZtYWN^hL>YX;0luoyC{+@c3xFT*<{NB>a^Idv^9tOu$7hUZsb}dw;d!{WTI! zz4U;=UK^U2x>Z{+2m!B)WgrbYhSw_^-XIy?s7^y&B@3+Z{w58U{OYi8R{Xw2VvqRi z`xmJKbW>Q62mxO_jf9lwNWMf-@}-jGtp@utgS{=30^NiXaG~MtdU$*dyhHK+P6>Y( z#^K#FybHMS{^fdjy!WqAynm&H(|UT7!5%Z%SE-56&0@hLWPJ4u9@3-Z`5Hyf*GeAh zjbAq-8Uik4yhjg@kH&iy?_V$B!P@iG<_wSVO?^1)W>nZ{(Tz|I) zOMZ3O?@|1Iuf%@ep5Dp@T)6&zJv@HYKcIO3fP~Xp@WI(@fnX2YgSv5+UF(r;(5n9m!uQ zO8#1s{Efl>)?k09zO3oiCcz+N{Cz9~Y0xqJgQDRdB?EQ8&(Ekm0T%-PNe?IQx{348 ziuZq!@PEb1|2KpEdq{vzzhDpo{v(zlJ_7%#X!tM55Om=GRtr*>N1&<>yo-Q$OW-{wJFo}fy#%~Z0`E83115XW$I7NRq1GboL5Y3HWDonmDQX`f;G+@< z^At9*GvjlJfQKcJifSfsj(|rb@G+A;z6YsK5O7`skD6@3WCb55(|OdOYtlduq=TUlU03>QzCPMfGZNn46b%&@ze-dmp}+g9wS2f-7baqR zlHjg{KL}evoMj#8CnoFqB(j}OkenitRY^jfA(-P+LVcRBYZA-*7z#Lp7Ziah4ebTQ z@IuM(B9p&o?WIe+n6NLA*q}&)tWAmDO9|eS@Utd6XENpoO*im9_5Y_$whsM&Lt>%- z4-oh=b6r;|0(hQ)n-aJM&EH_#K6Z-JAz^o-*k|^D9TC=(SP(o8X`bSDm#`NkmNZ}7 zgWpSpy)3aWH`yzE;FLhUl7P=jAY=zp0||nnf*?;3{3^n}T4G_aFtdULO~Jl~u&)!ZkeAaY3ZSN+y?6!){dbLru+AV%>d==a)+jXanh;a`Pz-ZKvESb)wvZ(}e zjE2Ll0mI9SJ#V8w8eb1~TfK7|gYEwK@=o8o3w|$k8|{wcT9szE?N}?;Dw=xeX0vy; zzlprU3h$yN`dq>%c5{gc;y)$ zRdB22a$9x53k0n&NAoxWvhytek(MCpF_}d`GL=YKb-UfR>{E`F=~S%cnrp$oeyQ-v z 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 Pa#VSeo`tMzd&2%-$4rmg diff --git a/services/__init__.py b/services/__init__.py index f598ef5..d354994 100755 --- a/services/__init__.py +++ b/services/__init__.py @@ -1,3 +1,4 @@ from laundry import laundry from shuttle import shuttle from weather import weather +from sports import sports diff --git a/services/__init__.pyc b/services/__init__.pyc index 96182f93fd21a6a9fc1ec9cf0319c384374d3028..fe7b6bd51ebf30c7d30e765b035686dd2a8c185c 100644 GIT binary patch delta 170 zcmaFHxR*(q`7$qZ1y1f(5+xY%T(v91TlgL akU9+z7eN$@0J)QS8PzygfD8df0Y(5o>v4D J`I^HyQ~`DOga`lt delta 86 zcmbOu{6~O;`7AFic|k0;Od(yRa%U!Z?$+vK@r76(*lzp9dG; M!I2MVmvgED0L7{lcK`qY diff --git a/services/shuttle/__init__.pyc b/services/shuttle/__init__.pyc index 98661757ed6e9b28d0e8f485b1bf7a4cd405d13e..fde3340db6e56dd2fe64ed12b4b70fd7b47d964b 100644 GIT binary patch delta 71 zcmXS3%*es~nU`xO2V2xc4pS2!1_lQG(BjmhVtwz#qLPfvY<-vfvfu2>_xAEbjmS delta 39 pcmey#I+K-y`7^l7$z6;%53&zVnpyJ&tlGpOHGbsnSs4PA{GcU6w bK3=b&vV;R@o=t9kN@-529mv*VAZ7pn#%(3; literal 0 HcmV?d00001 diff --git a/services/sports/sports.py b/services/sports/sports.py new file mode 100644 index 0000000..c466d8f --- /dev/null +++ b/services/sports/sports.py @@ -0,0 +1,27 @@ +import urllib2 +from bs4 import BeautifulSoup + +def getSportsGames(input): + url = 'http://www.gocrimson.com/landing/index' + page = urllib2.urlopen(url) + soup = BeautifulSoup(page) + five_events = [] + + upcoming = soup.find_all('div', class_='event-box upcoming clearfix') + + for i in range(5): + five_events.append(upcoming[i].find('div', class_='sport').text + " on " + + upcoming[i].find('div', class_='date clearfix')['title'] + " at " + + upcoming[i].find('div', class_='status').text) + + return getSportsGames + +def makeSpecial(): + s = 'To get the next five upcoming sports game type \'Upcoming Sports Games\'.' + return s + +## return proper format to use for getting weather +special = makeSpecial() + +def eval(input): + return getSportsGames(input) diff --git a/services/sports/sports.pyc b/services/sports/sports.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7702a056e302422c5d40b64c6c195a83ed280bc9 GIT binary patch literal 1398 zcmcIj&2G~`5T13Mr0EYuR1g&|KG9r=rHT_m2+>Myh15erg;WWut-VP$UH{-+JE@eM z$~*B2yblimGvl;9z>!+^?09!(=li~$ZT#9=|2b=)N3eQ49N*(-57ET<3NQfYweNuu zka%$JfruOM9Tyr9`|S9je7M1xCd5siX;Jd9*TRkTZ+uRB0$sO-=7W-@)1%T1voeop zy1n`iaI`awEjD33CU|Cm5J@ z_+lSf}Gqr?Hy529ed3Bb_26t-Y`>&{dU6 z-K)!N9-u;5g7HCQlq^PiuA8{-$k;q9ob}NQvNW(HZ7iL-i{v1uol$j=bOG0~PP)?e zI9fy3}Bb>pQA!9p| ziLyPa!Rb29OUIP4B&XyOV`&qMt>89zw@O_wearQ4`8(w8Xa96fN(m zw}bYp$2Wu!(8pc6jt+Gxzyk2#>E@i;Beb8g067J2qJk6!2}Zh7_orAF4#p@<;I4BO z?48{na4lKDn(g&#rc{oZ+lOM#q9^i74RaM~X?Cz8w+o5Dmy<9My*t`?Es-NOnE1Tl6*V*ngJKi62)Iv4@ literal 0 HcmV?d00001 diff --git a/services/weather/__init__.pyc b/services/weather/__init__.pyc index 6bf0a06e10760eda5515e285e2eb0e5fc55070c2..270e71687cea469e85635174f42f7a27fdac3d43 100644 GIT binary patch delta 71 zcmXS3%*es~nU`xO2V2xc4pS2!1_lQG(BjmhVtwz#qLPfvY<-vf5K^#!H? diff --git a/services/weather/weather.pyc b/services/weather/weather.pyc index 62a8a6111c8497e87c92e57b875add152dce9beb..745b8d54a843f8b5d4781cb18efc728e798f068a 100644 GIT binary patch delta 787 zcmbtRPiqrV5TAM3|LJa;rZEaD#)1$;+0;}KJ=SWV2)d=0USylMkZjr{-F>DWT6)Mu z1cmS}EqKxo;K7rhz;7XlAHgr+yp4Y%c&a>R_|3eT-|x-5Po=kItMJ`*&MaeRYMpr= z0O(}vWZCWMhgZ)M3phaEhV(rg89-s;0AGOGpa9&3V>8bde-(ZC872$BJ(wV*zca4N zT$*dOKzQ;LTX!5tO2EsiJXr+3q=+XBYIC(V)#lVD@Ct}BBuf%my{Q23Wz{+XwAUK~DU2KBAa~g&p`OdiexJk)|nkHOPi0uC+@@B?O=bkzD%rN)aXV=u;ozzY9b-QEUWgGyytW{azc<14& z5(-2nE(i_aEQ!DZ2M#Q>9>3ba22Ug3(7+v>8?l;3;DBe)CbYWWN=7NeJzf)$D{g6F z$wn{$o>lfB3qGil+6?&~uO+>4kO7`UG>9N4h!y4(0UuJMZ4kHnE=c_|w8;wj&mpg8 zC>TOui%Yhwn;@d6E?Xz^L@}}DSn?~@PO7zLw13zTr->t0as<<_-I6>&4B?1mqGFDU zH$6W)qjXAAjvVsHC68$|$&zHTBAcci+8|$csd!~b6N|}C;wQi}T$&a|qdcZ!N+iLb zP)ydJ%dCWyYR9|v1@U4OR>ox)X%hCrMPF|4Rf0b!Au=R{&02MTx9-nN{+rhK{<1!0 H=@$C{fU;J0 diff --git a/venv/.Python b/venv/.Python new file mode 120000 index 0000000..98af03e --- /dev/null +++ b/venv/.Python @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/Python \ No newline at end of file diff --git a/venv/bin/activate b/venv/bin/activate new file mode 100644 index 0000000..bd63f63 --- /dev/null +++ b/venv/bin/activate @@ -0,0 +1,78 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + unset -f pydoc >/dev/null 2>&1 + + # reset old environment variables + # ! [ -z ${VAR+_} ] returns true if VAR is declared at all + if ! [ -z "${_OLD_VIRTUAL_PATH+_}" ] ; then + PATH="$_OLD_VIRTUAL_PATH" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if ! [ -z "${_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-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null + fi + + if ! [ -z "${_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/Karthik/Documents/Harvard/HCS/harvardnow/venv" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +if ! [ -z "${PYTHONHOME+_}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then + _OLD_VIRTUAL_PS1="$PS1" + if [ "x" != x ] ; then + PS1="$PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`) $PS1" + fi + export PS1 +fi + +# Make sure to unalias pydoc if it's already there +alias pydoc 2>/dev/null >/dev/null && unalias pydoc + +pydoc () { + python -m pydoc "$@" +} + +# 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-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null +fi diff --git a/venv/bin/activate.csh b/venv/bin/activate.csh new file mode 100644 index 0000000..58db536 --- /dev/null +++ b/venv/bin/activate.csh @@ -0,0 +1,36 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . + +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 && unalias pydoc' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + + +if ("" != "") then + set env_name = "" +else + set env_name = `basename "$VIRTUAL_ENV"` +endif + +# Could be in a non-interactive environment, +# in which case, $prompt is undefined and we wouldn't +# care about the prompt anyway. +if ( $?prompt ) then + set _OLD_VIRTUAL_PROMPT="$prompt" + set prompt = "[$env_name] $prompt" +endif + +unset env_name + +alias pydoc python -m pydoc + +rehash + diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish new file mode 100644 index 0000000..ec18793 --- /dev/null +++ b/venv/bin/activate.fish @@ -0,0 +1,76 @@ +# This file must be used using `. bin/activate.fish` *within a running fish ( http://fishshell.com ) session*. +# Do not run it directly. + +function deactivate -d 'Exit virtualenv mode and return to the normal 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" + # Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`. + set -l fish_function_path + + # Erase virtualenv's `fish_prompt` and restore the original. + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + end + + set -e VIRTUAL_ENV + + if test "$argv[1]" != 'nondestructive' + # Self-destruct! + functions -e pydoc + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/Karthik/Documents/Harvard/HCS/harvardnow/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 + +function pydoc + python -m pydoc $argv +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # Copy the current `fish_prompt` function as `_old_fish_prompt`. + functions -c fish_prompt _old_fish_prompt + + function fish_prompt + # Save the current $status, for fish_prompts that display it. + set -l old_status $status + + # Prompt override provided? + # If not, just prepend the environment name. + if test -n "" + printf '%s%s' "" (set_color normal) + else + printf '%s(%s) ' (set_color normal) (basename "$VIRTUAL_ENV") + end + + # Restore the original $status + echo "exit $old_status" | source + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/venv/bin/activate_this.py b/venv/bin/activate_this.py new file mode 100644 index 0000000..f18193b --- /dev/null +++ b/venv/bin/activate_this.py @@ -0,0 +1,34 @@ +"""By using execfile(this_file, dict(__file__=this_file)) you will +activate this virtualenv environment. + +This can be used when you must use an existing Python interpreter, not +the virtualenv bin/python +""" + +try: + __file__ +except NameError: + raise AssertionError( + "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))") +import sys +import os + +old_os_path = os.environ.get('PATH', '') +os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path +base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +if sys.platform == 'win32': + site_packages = os.path.join(base, 'Lib', 'site-packages') +else: + site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages') +prev_sys_path = list(sys.path) +import site +site.addsitedir(site_packages) +sys.real_prefix = sys.prefix +sys.prefix = base +# Move the added items to the front of the path: +new_sys_path = [] +for item in list(sys.path): + if item not in prev_sys_path: + new_sys_path.append(item) + sys.path.remove(item) +sys.path[:0] = new_sys_path diff --git a/venv/bin/chardetect b/venv/bin/chardetect new file mode 100755 index 0000000..b941106 --- /dev/null +++ b/venv/bin/chardetect @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from chardet.cli.chardetect import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/easy_install b/venv/bin/easy_install new file mode 100755 index 0000000..e08a6f4 --- /dev/null +++ b/venv/bin/easy_install @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/easy_install-2.7 b/venv/bin/easy_install-2.7 new file mode 100755 index 0000000..e08a6f4 --- /dev/null +++ b/venv/bin/easy_install-2.7 @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/flask b/venv/bin/flask new file mode 100755 index 0000000..020a7a3 --- /dev/null +++ b/venv/bin/flask @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from flask.cli import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/nosetests b/venv/bin/nosetests new file mode 100755 index 0000000..1f56564 --- /dev/null +++ b/venv/bin/nosetests @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from nose import run_exit + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_exit()) diff --git a/venv/bin/nosetests-2.7 b/venv/bin/nosetests-2.7 new file mode 100755 index 0000000..1f56564 --- /dev/null +++ b/venv/bin/nosetests-2.7 @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from nose import run_exit + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_exit()) diff --git a/venv/bin/pip b/venv/bin/pip new file mode 100755 index 0000000..3fe3c26 --- /dev/null +++ b/venv/bin/pip @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from pip import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip2 b/venv/bin/pip2 new file mode 100755 index 0000000..3fe3c26 --- /dev/null +++ b/venv/bin/pip2 @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from pip import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip2.7 b/venv/bin/pip2.7 new file mode 100755 index 0000000..3fe3c26 --- /dev/null +++ b/venv/bin/pip2.7 @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from pip import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pyjwt b/venv/bin/pyjwt new file mode 100755 index 0000000..5c292b1 --- /dev/null +++ b/venv/bin/pyjwt @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from jwt.__main__ import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/python b/venv/bin/python new file mode 100755 index 0000000000000000000000000000000000000000..64d60daa6c4d4df22c49091bed85893eac11f28f GIT binary patch literal 24960 zcmeHOU2IfE6rODt*y))grw}lddp~iF4 zbI+W)GiPSLx!cUoIiFwu@MEP^19&;OQK=|I>wY|%LdY9;^AgNMQZ<2v1OY)n5D)|e z0YN|z5CjAPK|l}?1Ox#=;6H}Im)Cx|t~dVfA;3!XziF9L$04!*SKVOS?(5l+d?mT( z1t^AiOmG8Yy%Zj{-Jjgo?<>SQrXD2QMN=xQi`aH4Gg{ILM6iD6BTDT=e&_019k+B? zjk^*L+b)g`4-|&%VyQgf>h*m%3L8AcI0_r=r=f_paSt+J1C{M;W@seixO%;f6R=?+ z{{(E*QC&aE`6IdfpqA#JeKIO5>OhvSG- zc+E)<+i#?uBHNx{znSJxmj^!!k!|OJp$Fwi$(d)P*-|Qkip>EV#Lw8Y?VhNj?H+AI%>wtx*&o{~6v-*NBG=buY%+iAYZPNnwqrR7PsOV!Y$ zN{ypPjVz_s)-<&idJFU}NPe~)H{ZVxoj62Vm10x(g8RTE+BeMdW}JK%q$`$ZCz!tq z8Elu|alBk~;zPNC_~6*kAoPd9?89$I9`Bu8Ir#Q_TXw9veDPhIzccoMZAZbkO8m_& zL~NU5V_WWgFUJ#{$c$zVmP_e@p^QC}E@k7fSUlD@R>~Ig3SVUANWpnM{&L1C<_h^@ zd{gX+xPA#cwAtmi*>DV6s5VB7bMIKOlo^g~jbXgG0k2NhUuWH8=*XKY?iGyp<_4U! zGZx=&8ZXA5EjXF&g>oJr7CI3-WZu-e)e|TK`$B?%ARq_`0)l`bAP5Ko|4#%CtIG7m z_g5xDa$4?7*nMO6?sP7%pjvAZ zc4jnJLK;_cwmqDM%A39n?#a`v_Mka}_*VvHj|h=jG$N zdk;a~m ztbIQEEK(OQuyKC>*29m2_UM~TGP5fhw7Xa=LwCR)b-z7-OoM0d=5Y-v zZO>w15Ox1Nc)7J_?ROf8aj?937|emgM_7V3B7F$&2s@(k__bYj-gs?`qoFMqaU11w|@O=Vl%&yvta%v)`Rahng36V z^@HOij>Ojej_yEw1>2=-hXWsnGAK%Eh0;sflxu)Wnmj{3la0Tpv|Fn|S~N-um#@ zNA(M{99XqI65?|Op1qUn{y1@`X^xE>>i zu*N4b&9#0Lo@*6rqRwg+;@%VFW;DA=C`b3G&}cLiZCW0g!kZ1qXIwxEJs_>na%Px$@+IgGmy1HfjJU=s&Go%ecfEC3|WF?c@($)ro| jc!rc06Tl3ATmW@{Yyfp0j_CXI1d<7#jyvExA0O}!t*|jj literal 0 HcmV?d00001 diff --git a/venv/bin/python-config b/venv/bin/python-config new file mode 100755 index 0000000..db3faab --- /dev/null +++ b/venv/bin/python-config @@ -0,0 +1,78 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +import sys +import getopt +import sysconfig + +valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', + 'ldflags', 'help'] + +if sys.version_info >= (3, 2): + valid_opts.insert(-1, 'extension-suffix') + valid_opts.append('abiflags') +if sys.version_info >= (3, 3): + valid_opts.append('configdir') + + +def exit_with_usage(code=1): + sys.stderr.write("Usage: {0} [{1}]\n".format( + sys.argv[0], '|'.join('--'+opt for opt in valid_opts))) + sys.exit(code) + +try: + opts, args = getopt.getopt(sys.argv[1:], '', valid_opts) +except getopt.error: + exit_with_usage() + +if not opts: + exit_with_usage() + +pyver = sysconfig.get_config_var('VERSION') +getvar = sysconfig.get_config_var + +opt_flags = [flag for (flag, val) in opts] + +if '--help' in opt_flags: + exit_with_usage(code=0) + +for opt in opt_flags: + if opt == '--prefix': + print(sysconfig.get_config_var('prefix')) + + elif opt == '--exec-prefix': + print(sysconfig.get_config_var('exec_prefix')) + + elif opt in ('--includes', '--cflags'): + flags = ['-I' + sysconfig.get_path('include'), + '-I' + sysconfig.get_path('platinclude')] + if opt == '--cflags': + flags.extend(getvar('CFLAGS').split()) + print(' '.join(flags)) + + elif opt in ('--libs', '--ldflags'): + abiflags = getattr(sys, 'abiflags', '') + libs = ['-lpython' + pyver + abiflags] + libs += getvar('LIBS').split() + libs += getvar('SYSLIBS').split() + # add the prefix/lib/pythonX.Y/config dir, but only if there is no + # shared library in prefix/lib/. + if opt == '--ldflags': + if not getvar('Py_ENABLE_SHARED'): + libs.insert(0, '-L' + getvar('LIBPL')) + if not getvar('PYTHONFRAMEWORK'): + libs.extend(getvar('LINKFORSHARED').split()) + print(' '.join(libs)) + + elif opt == '--extension-suffix': + ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') + if ext_suffix is None: + ext_suffix = sysconfig.get_config_var('SO') + print(ext_suffix) + + elif opt == '--abiflags': + if not getattr(sys, 'abiflags', None): + exit_with_usage() + print(sys.abiflags) + + elif opt == '--configdir': + print(sysconfig.get_config_var('LIBPL')) diff --git a/venv/bin/python2 b/venv/bin/python2 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/venv/bin/python2 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/venv/bin/python2.7 b/venv/bin/python2.7 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/venv/bin/python2.7 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/venv/bin/wheel b/venv/bin/wheel new file mode 100755 index 0000000..f2b8d37 --- /dev/null +++ b/venv/bin/wheel @@ -0,0 +1,11 @@ +#!/Users/Karthik/Documents/Harvard/HCS/harvardnow/venv/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from wheel.tool import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/include/python2.7 b/venv/include/python2.7 new file mode 120000 index 0000000..e2e4741 --- /dev/null +++ b/venv/include/python2.7 @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 \ No newline at end of file diff --git a/venv/lib/python2.7/UserDict.py b/venv/lib/python2.7/UserDict.py new file mode 120000 index 0000000..4a87ad7 --- /dev/null +++ b/venv/lib/python2.7/UserDict.py @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/UserDict.py \ No newline at end of file diff --git a/venv/lib/python2.7/UserDict.pyc b/venv/lib/python2.7/UserDict.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdd39485f31bf87c46f0f889a171ecb8300fe78e GIT binary patch literal 12096 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 S<`vu<^f687lbJ$xX8zyEI{^3q literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/abc.py b/venv/lib/python2.7/abc.py new file mode 120000 index 0000000..a057763 --- /dev/null +++ b/venv/lib/python2.7/abc.py @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/abc.py \ No newline at end of file diff --git a/venv/lib/python2.7/abc.pyc b/venv/lib/python2.7/abc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a06a5cdf3889e59a750373f33a85282ec3e0957f GIT binary patch literal 6726 zcmdT}TXP&o74F$xt+ldzRg%iZR5g_tt-#(T7YH~Z6ye3f){Juv zl%tjDZrOhqkDbNKK+QmfYh9F8mm?jUqo|07CW_pgREA|b%2D;B(4?efKSZhjku{a= z|1z%JR<_f>S0Tm6|HsH>uvJ%Aw9& zPwQoo;K$1Jt=Q`Llz=l+YEemC6s6MxBeS!@y0~yz>>zqn-Cn-F2^O&Dk3~!TfoD^YGm9qC`3_aYf)YjU`zOjOKgmaq#SIY;P_l1>@H)y zvr1e+i>0FKS|@Ntg-WzG{&jnV1630IIL7W1;$T+|!j3i3uRnFO21VA!lI{u|6d@82};aI)vA zYtzm7!+u-$-_rYWJ~B&pzBKF*#8dC4R<%pHw`BH`r;8alPRKYC!g)L+L{VBMQ54cQ zL-wC=!#T#dSuFGl9-)Nx3++JIX%Zz8bjS}iy^F`*!|OB?AR|E{f`s7-hymG1QwlRo zH`11Rf?gCPKUtrxlaUUYgX`K1azB^`IvCjFgF#}s4mn?ubxeXL!aafr@CSCC#7ZO~ z2{7moi3-v`!=n@gfe1u)G?36?Qn5pdpqsdSd<)}KMkK&AVZbAphuPuntni@*f<8Ho z45Aj{B$QI@-@EW^AB%T1?=5NIpwF79WQ8^!sF zs&-M|zD?z@--((TPs%2yND;NIKFD$(L>X$!!e$8h2)EPC+B)9WYRd`VUD1QFgyC90 zQ6#hVyzY`_n4*K-!XA8L^0bJ9vRHK5Zj}dmw2M?nWI$P{_(AwUcVS-yQDiu_%tsWZ zA5>6piLqZ4r};3#uRYw&4U;zU>Y7>7TF;bVg*ziSK7IwvTYuU0RyJ zB?IDALhmB>+IUv**uUe29L`Ascid3h4Q6tWQAMGtj$7)er5rFG5ZY+jmh}1_@@xDZ z&8Wixhu-^iT^+U6;jfgNQIC;$H#q4Sd3Y0jchpfJ9W6>urS<57w7@@_Bmj)7K2wip z)b=dLKz6YAnZn#z%rk6S95Q|=-~vpj#QeCbsAGIz9nMaEp^d#%f@uO-NKwgY4SRk#K(59;@g|1Fo(OrQ#-0QjQ96 zk$b7`Jv%ExqHf`M!nva9Fv)Gm)KIoDz`f3jt~8O|jT0j~z#wU@qnVYt933)=JZB4r z*RjUOc|y0$Nza#9>oYa4gwmU^=R z&y>5f_}2HJL^uf(I@V9qIw^S)q%6(4f{J8LHObX6WEDzN(uTi1oe6PSv4#5}u5Jm4 zf1KndqkDG+l7w!C3m0#8uqY45jd#5Zvfz!o!aL?ewiB!@yjN9aC4fAM1dgx{fwFAq z`@`qi@El)UCnWSdFKCqH=01%gXgJ4Px~x^789Cn4&r|~l!EdX1rEw*=8VE*s1XJFB zf(k6(0vKpg;lS;HIC-vd{}<8&A{6Yf;V>j}I1&uq7Ge)T>~E1S!Igl72T8Te-4j0o zxFey?7SMq@g2zPs-m=2qBV5!tyGbWsUGT-i zf$n%@J7#PJ4?t4o>_O(Xg!Ck!gc>7c*hZEcA(d}~9pqvgrK92QltT}=1)hy+yck>q zPtg8TyK^JL4Sz+!a|0|7Z$*6bCPaCsqpDZMQm`|sZC1gBYc#!(2JMM(J)?GJRTXk5 zT0kRcL>Y~Cn+3|kfIkUf+KeEG>N}v5&t)W}cSQQ<3J1GJR9$2TNT#kpu|VzqMFdRy zB&G^h9{7(hhPNVoA*#K+TNiGDJ?v6XoH~jm8;zn>`KTwh3!lX?gybE6-*|u=+cJNRMm6g~LCf^%UV${BJV$^mK0I@C|9c0xnx3mhnZ1+XWV};ul{z zW$z31=Kn$S75GE?ug)uNfzD4qHxZB5&j74{E=(@7%$Z%=&!>G zBu*kq&IixJ85SB>(f&MQW(y_8&e_JoTm;&gJ<|=NZ4gSV}a$i4kxyz~BJ?H&K}lCg`Xt z`RE^#4#PM2BG4ox*57i%SvK<&zKuP}(r^3!^>{~cB71AhH?B5em1gJJ=f3lA!q#Tw literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/codecs.py b/venv/lib/python2.7/codecs.py new file mode 120000 index 0000000..e6ea092 --- /dev/null +++ b/venv/lib/python2.7/codecs.py @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/codecs.py \ No newline at end of file diff --git a/venv/lib/python2.7/codecs.pyc b/venv/lib/python2.7/codecs.pyc new file mode 100644 index 0000000000000000000000000000000000000000..272abde4c29b355937bdf4a33cef8669c2d56d1d GIT binary patch literal 41166 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/genericpath.py b/venv/lib/python2.7/genericpath.py new file mode 120000 index 0000000..deace5b --- /dev/null +++ b/venv/lib/python2.7/genericpath.py @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/genericpath.py \ No newline at end of file diff --git a/venv/lib/python2.7/genericpath.pyc b/venv/lib/python2.7/genericpath.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c14e207280e45485e4b5f529dd491d9aa4d871e GIT binary patch literal 4100 zcmcgvTW{P%6h7Wtx|^iAQA$CGQ3PU(%C6c6`p|N1+ERg9^qM2i=$Xb$$lvd=a}Xp-W|Am+HcbMCZ9KgwrC|MhUkS7eW_G z+!=J%v?#O_Bddf=jY?cL?g?>sizkIGRgwOkiKR(^tJ`4$BQ1QZUs;Hg^!@%Keh z5$7t3Tn8gjRK0iUsWdGA^gZ@^< z7y40uR~5VcjkM_Zdi^Zj=$B)+rHf0w%l%DND3c~7)YdDrK`%zcg0B=6 z_E3AM+{nOQZp0bvVW^GRFnUK7!jAI|oxu>YwAis-7R0e|+TwJa425|;C}UtBJnfJ0 zlXuNX`TKp3FFXYEcyZ*HKFi{egjAK-Zfo$<;Oc2;HvwObRt@Ew}i<{aOZ>~I(BMu+HIG+?4?0uKf ze3YZwL6rLsATUNpK*(amG&l;UDxdKLCyD(WuQr?Lh z>2oy8p_yteY6NrmJBNfg7bL6;jvo9z*U;?mAW*|Ls7IV}u910fI#^>h>^HrJFoik- z>S$1Lu&eGDwCFMZ8?@6P^D8sZ@Y($t+WU|m&+yz1k@ZIl(MYjN%;>O;E*iwVS#MTHlYf6L8P07HdyA5n3@F^*(0UrYS(D(E+D_V^Q%|* zA@X=EHgH521oY(tj1inVYgWky&1d=dD6w zfHPyYr0Vk|K*R^Q)4swtw-$m{un;WQ7J|822i#(? z94ytkOPKSSJ&L4GqUfo7A4PGN;k$-wy2*!;|IqN)+=gne``VpL6uq&H55dqQ&C5ey zurksi8+yp`Ib>50(J17vkwZ*8cdTWU*WK0X%j^S|%C3U6*dKw(LcJbzg8BNZ&Gu}2 NuH9}o{a>rS^bg8_&LRK+ literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/lib-dynload b/venv/lib/python2.7/lib-dynload new file mode 120000 index 0000000..925e61a --- /dev/null +++ b/venv/lib/python2.7/lib-dynload @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload \ No newline at end of file diff --git a/venv/lib/python2.7/linecache.py b/venv/lib/python2.7/linecache.py new file mode 120000 index 0000000..c69a144 --- /dev/null +++ b/venv/lib/python2.7/linecache.py @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/linecache.py \ No newline at end of file diff --git a/venv/lib/python2.7/linecache.pyc b/venv/lib/python2.7/linecache.pyc new file mode 100644 index 0000000000000000000000000000000000000000..104f8c9e856d0ad68a4df0e07bbe567bd4169d16 GIT binary patch literal 3590 zcmcgv-Hsc@60V-{&w65KH@hK;140cFijg+91Q!Ug3Fjz_NOZ*JFedCOO0Z^U#`dho zGv4WT79;yATycYhkhtV2xZs8h9suzO=M|3518}~o@n-V^!Sb}LyKB0;s=oTV?EbIi z{rWKcGNkp##qU4xm>HUg=rLMFkwdAX#}G={p~ntIE=3iJsx)%xF=UL?=v$~&DIp4K z6xHcltWcM!4Vl^yxgl~xWKU#|<$mW9@B9mzdqFskb(&S2<`rt5iMj1!~z zo7p&v;z-+E7jY21tUJx4Ika^$o#lmv&h6WJ9A{yylc5e|sVtbr9+t^+tB3hKi*|Kl z^;wdpI?eNmj`FiiTO6TWOPe?-!m*wOb`1Suy^20wcy=6E&C7MY4xm=3LgHwhsS(^#u6>@b?CW6E4WqBQc=a7D9U%qqUX|cMd)S@ zIjXqB1JHopjdq{Ch^X~DyyQWm%Jqmk4oe$o)+aNTHPSfi@Bw6oUCf5q8qeVLaL#3j zr3(h5G(QefW2@^~(}6(Jm@gsq9+|i>y?+IT9Ve6Cejd)Jab`{Leo#CMil}%0UcWak z3oWs`0%!M_t+$7%kCLY5M+l2kYqZ@*rmlnvI2oe zx&lTzNI5AN-GuEr5RCa8BFh;*m!)Md>3j2>}5@Kqebhyv`9hLBbNPkd|*q>@bDcz0dMU z$vC)DQUB{7ICA?>zoQl0fpjKnKdI14l6?iC$_c$*Ii=IPlo2g<2w^>`(6Y+OzpBw; z_9nuPv8qJ=XNkP5c86b4bOZ)j*65^06PL_y!V>7#xm(;_@65XR9`eD;oOuMx_7f8# zVM{bfcoVRx5M5BjI-gse4>iN1gi7a}l$lLIbKwM>JD=r%23QZvr0HAl9&|XCmfd`i zXK{%J?oHx_0e*>cBeTW^R!AmhKnR-}J21&Nv9J{6sZFMFhXW!Yu?4)lQiL#&}sq|ms6N42ngx4^NKID@oXV?DIEm}2biOQiy z*S~V;)Kh@@u(Ec`UU_%6QFyfbr+W%s;uLAo$z^s7yTlh_{Q4WRn>?}qbVMtU7VUFI zoY|u#OhrCAIP*=M8H~Gqe&(OpQKwH7XV~KEc~+jg^xub=lC<0r3x8j0A7S{AEtA(e zWUulCAHhb4zTcr0?7c)MuL*-Rk&X@e{OB;-#@?Q+bIHL%{Ql9hNyUc_+Q_3eI0ue^ zS+Uw-3TC{>2TC_ylaqVDlRF7suB|%msOboAu=bA38*+y^6byZvKICac#sw#9goDIm^pyw9)H}TF6WchC* zRu2YI9u5XR8z=}_kK&rcC<8%?Rza84Gd_FIXD9i5+zZEu^a_g_3GQB5zu)EH8wNy8 RE+AY(Ud?UPo0psI{{tk@9&i8v literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/locale.py b/venv/lib/python2.7/locale.py new file mode 120000 index 0000000..64e3460 --- /dev/null +++ b/venv/lib/python2.7/locale.py @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/locale.py \ No newline at end of file diff --git a/venv/lib/python2.7/locale.pyc b/venv/lib/python2.7/locale.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12ae6e131b2ec0a5da637848ab551dcf32f0ee0d GIT binary patch literal 56560 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 B`O*LY literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/posixpath.py b/venv/lib/python2.7/posixpath.py new file mode 120000 index 0000000..fe09f51 --- /dev/null +++ b/venv/lib/python2.7/posixpath.py @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.py \ No newline at end of file diff --git a/venv/lib/python2.7/posixpath.pyc b/venv/lib/python2.7/posixpath.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e43cc8be88ff9e24789e96218b2b11f99f7048e GIT binary patch literal 12639 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" } + + XML_SPECIAL_CHARS_TO_ENTITIES = _invert(XML_ENTITIES_TO_SPECIAL_CHARS) + + def setup(self, parent=None, previous=None): + """Sets up the initial relations between this element and + other elements.""" + self.parent = parent + self.previous = previous + self.next = None + self.previousSibling = None + self.nextSibling = None + if self.parent and self.parent.contents: + self.previousSibling = self.parent.contents[-1] + self.previousSibling.nextSibling = self + + def replaceWith(self, replaceWith): + oldParent = self.parent + myIndex = self.parent.index(self) + if hasattr(replaceWith, "parent")\ + and replaceWith.parent is self.parent: + # We're replacing this element with one of its siblings. + index = replaceWith.parent.index(replaceWith) + if index and index < myIndex: + # Furthermore, it comes before this element. That + # means that when we extract it, the index of this + # element will change. + myIndex = myIndex - 1 + self.extract() + oldParent.insert(myIndex, replaceWith) + + def replaceWithChildren(self): + myParent = self.parent + myIndex = self.parent.index(self) + self.extract() + reversedChildren = list(self.contents) + reversedChildren.reverse() + for child in reversedChildren: + myParent.insert(myIndex, child) + + def extract(self): + """Destructively rips this element out of the tree.""" + if self.parent: + try: + del self.parent.contents[self.parent.index(self)] + except ValueError: + pass + + #Find the two elements that would be next to each other if + #this element (and any children) hadn't been parsed. Connect + #the two. + lastChild = self._lastRecursiveChild() + nextElement = lastChild.next + + if self.previous: + self.previous.next = nextElement + if nextElement: + nextElement.previous = self.previous + self.previous = None + lastChild.next = None + + self.parent = None + if self.previousSibling: + self.previousSibling.nextSibling = self.nextSibling + if self.nextSibling: + self.nextSibling.previousSibling = self.previousSibling + self.previousSibling = self.nextSibling = None + return self + + def _lastRecursiveChild(self): + "Finds the last element beneath this object to be parsed." + lastChild = self + while hasattr(lastChild, 'contents') and lastChild.contents: + lastChild = lastChild.contents[-1] + return lastChild + + def insert(self, position, newChild): + if isinstance(newChild, basestring) \ + and not isinstance(newChild, NavigableString): + newChild = NavigableString(newChild) + + position = min(position, len(self.contents)) + if hasattr(newChild, 'parent') and newChild.parent is not None: + # We're 'inserting' an element that's already one + # of this object's children. + if newChild.parent is self: + index = self.index(newChild) + if index > position: + # Furthermore we're moving it further down the + # list of this object's children. That means that + # when we extract this element, our target index + # will jump down one. + position = position - 1 + newChild.extract() + + newChild.parent = self + previousChild = None + if position == 0: + newChild.previousSibling = None + newChild.previous = self + else: + previousChild = self.contents[position-1] + newChild.previousSibling = previousChild + newChild.previousSibling.nextSibling = newChild + newChild.previous = previousChild._lastRecursiveChild() + if newChild.previous: + newChild.previous.next = newChild + + newChildsLastElement = newChild._lastRecursiveChild() + + if position >= len(self.contents): + newChild.nextSibling = None + + parent = self + parentsNextSibling = None + while not parentsNextSibling: + parentsNextSibling = parent.nextSibling + parent = parent.parent + if not parent: # This is the last element in the document. + break + if parentsNextSibling: + newChildsLastElement.next = parentsNextSibling + else: + newChildsLastElement.next = None + else: + nextChild = self.contents[position] + newChild.nextSibling = nextChild + if newChild.nextSibling: + newChild.nextSibling.previousSibling = newChild + newChildsLastElement.next = nextChild + + if newChildsLastElement.next: + newChildsLastElement.next.previous = newChildsLastElement + self.contents.insert(position, newChild) + + def append(self, tag): + """Appends the given tag to the contents of this tag.""" + self.insert(len(self.contents), tag) + + def findNext(self, name=None, attrs={}, text=None, **kwargs): + """Returns the first item that matches the given criteria and + appears after this Tag in the document.""" + return self._findOne(self.findAllNext, name, attrs, text, **kwargs) + + def findAllNext(self, name=None, attrs={}, text=None, limit=None, + **kwargs): + """Returns all items that match the given criteria and appear + after this Tag in the document.""" + return self._findAll(name, attrs, text, limit, self.nextGenerator, + **kwargs) + + def findNextSibling(self, name=None, attrs={}, text=None, **kwargs): + """Returns the closest sibling to this Tag that matches the + given criteria and appears after this Tag in the document.""" + return self._findOne(self.findNextSiblings, name, attrs, text, + **kwargs) + + def findNextSiblings(self, name=None, attrs={}, text=None, limit=None, + **kwargs): + """Returns the siblings of this Tag that match the given + criteria and appear after this Tag in the document.""" + return self._findAll(name, attrs, text, limit, + self.nextSiblingGenerator, **kwargs) + fetchNextSiblings = findNextSiblings # Compatibility with pre-3.x + + def findPrevious(self, name=None, attrs={}, text=None, **kwargs): + """Returns the first item that matches the given criteria and + appears before this Tag in the document.""" + return self._findOne(self.findAllPrevious, name, attrs, text, **kwargs) + + def findAllPrevious(self, name=None, attrs={}, text=None, limit=None, + **kwargs): + """Returns all items that match the given criteria and appear + before this Tag in the document.""" + return self._findAll(name, attrs, text, limit, self.previousGenerator, + **kwargs) + fetchPrevious = findAllPrevious # Compatibility with pre-3.x + + def findPreviousSibling(self, name=None, attrs={}, text=None, **kwargs): + """Returns the closest sibling to this Tag that matches the + given criteria and appears before this Tag in the document.""" + return self._findOne(self.findPreviousSiblings, name, attrs, text, + **kwargs) + + def findPreviousSiblings(self, name=None, attrs={}, text=None, + limit=None, **kwargs): + """Returns the siblings of this Tag that match the given + criteria and appear before this Tag in the document.""" + return self._findAll(name, attrs, text, limit, + self.previousSiblingGenerator, **kwargs) + fetchPreviousSiblings = findPreviousSiblings # Compatibility with pre-3.x + + def findParent(self, name=None, attrs={}, **kwargs): + """Returns the closest parent of this Tag that matches the given + criteria.""" + # NOTE: We can't use _findOne because findParents takes a different + # set of arguments. + r = None + l = self.findParents(name, attrs, 1) + if l: + r = l[0] + return r + + def findParents(self, name=None, attrs={}, limit=None, **kwargs): + """Returns the parents of this Tag that match the given + criteria.""" + + return self._findAll(name, attrs, None, limit, self.parentGenerator, + **kwargs) + fetchParents = findParents # Compatibility with pre-3.x + + #These methods do the real heavy lifting. + + def _findOne(self, method, name, attrs, text, **kwargs): + r = None + l = method(name, attrs, text, 1, **kwargs) + if l: + r = l[0] + return r + + def _findAll(self, name, attrs, text, limit, generator, **kwargs): + "Iterates over a generator looking for things that match." + + if isinstance(name, SoupStrainer): + strainer = name + # (Possibly) special case some findAll*(...) searches + elif text is None and not limit and not attrs and not kwargs: + # findAll*(True) + if name is True: + return [element for element in generator() + if isinstance(element, Tag)] + # findAll*('tag-name') + elif isinstance(name, basestring): + return [element for element in generator() + if isinstance(element, Tag) and + element.name == name] + else: + strainer = SoupStrainer(name, attrs, text, **kwargs) + # Build a SoupStrainer + else: + strainer = SoupStrainer(name, attrs, text, **kwargs) + results = ResultSet(strainer) + g = generator() + while True: + try: + i = g.next() + except StopIteration: + break + if i: + found = strainer.search(i) + if found: + results.append(found) + if limit and len(results) >= limit: + break + return results + + #These Generators can be used to navigate starting from both + #NavigableStrings and Tags. + def nextGenerator(self): + i = self + while i is not None: + i = i.next + yield i + + def nextSiblingGenerator(self): + i = self + while i is not None: + i = i.nextSibling + yield i + + def previousGenerator(self): + i = self + while i is not None: + i = i.previous + yield i + + def previousSiblingGenerator(self): + i = self + while i is not None: + i = i.previousSibling + yield i + + def parentGenerator(self): + i = self + while i is not None: + i = i.parent + yield i + + # Utility methods + def substituteEncoding(self, str, encoding=None): + encoding = encoding or "utf-8" + return str.replace("%SOUP-ENCODING%", encoding) + + def toEncoding(self, s, encoding=None): + """Encodes an object to a string in some encoding, or to Unicode. + .""" + if isinstance(s, unicode): + if encoding: + s = s.encode(encoding) + elif isinstance(s, str): + if encoding: + s = s.encode(encoding) + else: + s = unicode(s) + else: + if encoding: + s = self.toEncoding(str(s), encoding) + else: + s = unicode(s) + return s + + BARE_AMPERSAND_OR_BRACKET = re.compile("([<>]|" + + "&(?!#\d+;|#x[0-9a-fA-F]+;|\w+;)" + + ")") + + def _sub_entity(self, x): + """Used with a regular expression to substitute the + appropriate XML entity for an XML special character.""" + return "&" + self.XML_SPECIAL_CHARS_TO_ENTITIES[x.group(0)[0]] + ";" + + +class NavigableString(unicode, PageElement): + + def __new__(cls, value): + """Create a new NavigableString. + + When unpickling a NavigableString, this method is called with + the string in DEFAULT_OUTPUT_ENCODING. That encoding needs to be + passed in to the superclass's __new__ or the superclass won't know + how to handle non-ASCII characters. + """ + if isinstance(value, unicode): + return unicode.__new__(cls, value) + return unicode.__new__(cls, value, DEFAULT_OUTPUT_ENCODING) + + def __getnewargs__(self): + return (NavigableString.__str__(self),) + + def __getattr__(self, attr): + """text.string gives you text. This is for backwards + compatibility for Navigable*String, but for CData* it lets you + get the string without the CData wrapper.""" + if attr == 'string': + return self + else: + raise AttributeError, "'%s' object has no attribute '%s'" % (self.__class__.__name__, attr) + + def __unicode__(self): + return str(self).decode(DEFAULT_OUTPUT_ENCODING) + + def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): + # Substitute outgoing XML entities. + data = self.BARE_AMPERSAND_OR_BRACKET.sub(self._sub_entity, self) + if encoding: + return data.encode(encoding) + else: + return data + +class CData(NavigableString): + + def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): + return "" % NavigableString.__str__(self, encoding) + +class ProcessingInstruction(NavigableString): + def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): + output = self + if "%SOUP-ENCODING%" in output: + output = self.substituteEncoding(output, encoding) + return "" % self.toEncoding(output, encoding) + +class Comment(NavigableString): + def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): + return "" % NavigableString.__str__(self, encoding) + +class Declaration(NavigableString): + def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): + return "" % NavigableString.__str__(self, encoding) + +class Tag(PageElement): + + """Represents a found HTML tag with its attributes and contents.""" + + def _convertEntities(self, match): + """Used in a call to re.sub to replace HTML, XML, and numeric + entities with the appropriate Unicode characters. If HTML + entities are being converted, any unrecognized entities are + escaped.""" + x = match.group(1) + if self.convertHTMLEntities and x in name2codepoint: + return unichr(name2codepoint[x]) + elif x in self.XML_ENTITIES_TO_SPECIAL_CHARS: + if self.convertXMLEntities: + return self.XML_ENTITIES_TO_SPECIAL_CHARS[x] + else: + return u'&%s;' % x + elif len(x) > 0 and x[0] == '#': + # Handle numeric entities + if len(x) > 1 and x[1] == 'x': + return unichr(int(x[2:], 16)) + else: + return unichr(int(x[1:])) + + elif self.escapeUnrecognizedEntities: + return u'&%s;' % x + else: + return u'&%s;' % x + + def __init__(self, parser, name, attrs=None, parent=None, + previous=None): + "Basic constructor." + + # We don't actually store the parser object: that lets extracted + # chunks be garbage-collected + self.parserClass = parser.__class__ + self.isSelfClosing = parser.isSelfClosingTag(name) + self.name = name + if attrs is None: + attrs = [] + elif isinstance(attrs, dict): + attrs = attrs.items() + self.attrs = attrs + self.contents = [] + self.setup(parent, previous) + self.hidden = False + self.containsSubstitutions = False + self.convertHTMLEntities = parser.convertHTMLEntities + self.convertXMLEntities = parser.convertXMLEntities + self.escapeUnrecognizedEntities = parser.escapeUnrecognizedEntities + + # Convert any HTML, XML, or numeric entities in the attribute values. + convert = lambda(k, val): (k, + re.sub("&(#\d+|#x[0-9a-fA-F]+|\w+);", + self._convertEntities, + val)) + self.attrs = map(convert, self.attrs) + + def getString(self): + if (len(self.contents) == 1 + and isinstance(self.contents[0], NavigableString)): + return self.contents[0] + + def setString(self, string): + """Replace the contents of the tag with a string""" + self.clear() + self.append(string) + + string = property(getString, setString) + + def getText(self, separator=u""): + if not len(self.contents): + return u"" + stopNode = self._lastRecursiveChild().next + strings = [] + current = self.contents[0] + while current is not stopNode: + if isinstance(current, NavigableString): + strings.append(current.strip()) + current = current.next + return separator.join(strings) + + text = property(getText) + + def get(self, key, default=None): + """Returns the value of the 'key' attribute for the tag, or + the value given for 'default' if it doesn't have that + attribute.""" + return self._getAttrMap().get(key, default) + + def clear(self): + """Extract all children.""" + for child in self.contents[:]: + child.extract() + + def index(self, element): + for i, child in enumerate(self.contents): + if child is element: + return i + raise ValueError("Tag.index: element not in tag") + + def has_key(self, key): + return self._getAttrMap().has_key(key) + + def __getitem__(self, key): + """tag[key] returns the value of the 'key' attribute for the tag, + and throws an exception if it's not there.""" + return self._getAttrMap()[key] + + def __iter__(self): + "Iterating over a tag iterates over its contents." + return iter(self.contents) + + def __len__(self): + "The length of a tag is the length of its list of contents." + return len(self.contents) + + def __contains__(self, x): + return x in self.contents + + def __nonzero__(self): + "A tag is non-None even if it has no contents." + return True + + def __setitem__(self, key, value): + """Setting tag[key] sets the value of the 'key' attribute for the + tag.""" + self._getAttrMap() + self.attrMap[key] = value + found = False + for i in range(0, len(self.attrs)): + if self.attrs[i][0] == key: + self.attrs[i] = (key, value) + found = True + if not found: + self.attrs.append((key, value)) + self._getAttrMap()[key] = value + + def __delitem__(self, key): + "Deleting tag[key] deletes all 'key' attributes for the tag." + for item in self.attrs: + if item[0] == key: + self.attrs.remove(item) + #We don't break because bad HTML can define the same + #attribute multiple times. + self._getAttrMap() + if self.attrMap.has_key(key): + del self.attrMap[key] + + def __call__(self, *args, **kwargs): + """Calling a tag like a function is the same as calling its + findAll() method. Eg. tag('a') returns a list of all the A tags + found within this tag.""" + return apply(self.findAll, args, kwargs) + + def __getattr__(self, tag): + #print "Getattr %s.%s" % (self.__class__, tag) + if len(tag) > 3 and tag.rfind('Tag') == len(tag)-3: + return self.find(tag[:-3]) + elif tag.find('__') != 0: + return self.find(tag) + raise AttributeError, "'%s' object has no attribute '%s'" % (self.__class__, tag) + + def __eq__(self, other): + """Returns true iff this tag has the same name, the same attributes, + and the same contents (recursively) as the given tag. + + NOTE: right now this will return false if two tags have the + same attributes in a different order. Should this be fixed?""" + if other is self: + return True + if not hasattr(other, 'name') or not hasattr(other, 'attrs') or not hasattr(other, 'contents') or self.name != other.name or self.attrs != other.attrs or len(self) != len(other): + return False + for i in range(0, len(self.contents)): + if self.contents[i] != other.contents[i]: + return False + return True + + def __ne__(self, other): + """Returns true iff this tag is not identical to the other tag, + as defined in __eq__.""" + return not self == other + + def __repr__(self, encoding=DEFAULT_OUTPUT_ENCODING): + """Renders this tag as a string.""" + return self.__str__(encoding) + + def __unicode__(self): + return self.__str__(None) + + def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING, + prettyPrint=False, indentLevel=0): + """Returns a string or Unicode representation of this tag and + its contents. To get Unicode, pass None for encoding. + + NOTE: since Python's HTML parser consumes whitespace, this + method is not certain to reproduce the whitespace present in + the original string.""" + + encodedName = self.toEncoding(self.name, encoding) + + attrs = [] + if self.attrs: + for key, val in self.attrs: + fmt = '%s="%s"' + if isinstance(val, basestring): + if self.containsSubstitutions and '%SOUP-ENCODING%' in val: + val = self.substituteEncoding(val, encoding) + + # The attribute value either: + # + # * Contains no embedded double quotes or single quotes. + # No problem: we enclose it in double quotes. + # * Contains embedded single quotes. No problem: + # double quotes work here too. + # * Contains embedded double quotes. No problem: + # we enclose it in single quotes. + # * Embeds both single _and_ double quotes. This + # can't happen naturally, but it can happen if + # you modify an attribute value after parsing + # the document. Now we have a bit of a + # problem. We solve it by enclosing the + # attribute in single quotes, and escaping any + # embedded single quotes to XML entities. + if '"' in val: + fmt = "%s='%s'" + if "'" in val: + # TODO: replace with apos when + # appropriate. + val = val.replace("'", "&squot;") + + # Now we're okay w/r/t quotes. But the attribute + # value might also contain angle brackets, or + # ampersands that aren't part of entities. We need + # to escape those to XML entities too. + val = self.BARE_AMPERSAND_OR_BRACKET.sub(self._sub_entity, val) + + attrs.append(fmt % (self.toEncoding(key, encoding), + self.toEncoding(val, encoding))) + close = '' + closeTag = '' + if self.isSelfClosing: + close = ' /' + else: + closeTag = '' % encodedName + + indentTag, indentContents = 0, 0 + if prettyPrint: + indentTag = indentLevel + space = (' ' * (indentTag-1)) + indentContents = indentTag + 1 + contents = self.renderContents(encoding, prettyPrint, indentContents) + if self.hidden: + s = contents + else: + s = [] + attributeString = '' + if attrs: + attributeString = ' ' + ' '.join(attrs) + if prettyPrint: + s.append(space) + s.append('<%s%s%s>' % (encodedName, attributeString, close)) + if prettyPrint: + s.append("\n") + s.append(contents) + if prettyPrint and contents and contents[-1] != "\n": + s.append("\n") + if prettyPrint and closeTag: + s.append(space) + s.append(closeTag) + if prettyPrint and closeTag and self.nextSibling: + s.append("\n") + s = ''.join(s) + return s + + def decompose(self): + """Recursively destroys the contents of this tree.""" + self.extract() + if len(self.contents) == 0: + return + current = self.contents[0] + while current is not None: + next = current.next + if isinstance(current, Tag): + del current.contents[:] + current.parent = None + current.previous = None + current.previousSibling = None + current.next = None + current.nextSibling = None + current = next + + def prettify(self, encoding=DEFAULT_OUTPUT_ENCODING): + return self.__str__(encoding, True) + + def renderContents(self, encoding=DEFAULT_OUTPUT_ENCODING, + prettyPrint=False, indentLevel=0): + """Renders the contents of this tag as a string in the given + encoding. If encoding is None, returns a Unicode string..""" + s=[] + for c in self: + text = None + if isinstance(c, NavigableString): + text = c.__str__(encoding) + elif isinstance(c, Tag): + s.append(c.__str__(encoding, prettyPrint, indentLevel)) + if text and prettyPrint: + text = text.strip() + if text: + if prettyPrint: + s.append(" " * (indentLevel-1)) + s.append(text) + if prettyPrint: + s.append("\n") + return ''.join(s) + + #Soup methods + + def find(self, name=None, attrs={}, recursive=True, text=None, + **kwargs): + """Return only the first child of this Tag matching the given + criteria.""" + r = None + l = self.findAll(name, attrs, recursive, text, 1, **kwargs) + if l: + r = l[0] + return r + findChild = find + + def findAll(self, name=None, attrs={}, recursive=True, text=None, + limit=None, **kwargs): + """Extracts a list of Tag objects that match the given + criteria. You can specify the name of the Tag and any + attributes you want the Tag to have. + + The value of a key-value pair in the 'attrs' map can be a + string, a list of strings, a regular expression object, or a + callable that takes a string and returns whether or not the + string matches for some custom definition of 'matches'. The + same is true of the tag name.""" + generator = self.recursiveChildGenerator + if not recursive: + generator = self.childGenerator + return self._findAll(name, attrs, text, limit, generator, **kwargs) + findChildren = findAll + + # Pre-3.x compatibility methods + first = find + fetch = findAll + + def fetchText(self, text=None, recursive=True, limit=None): + return self.findAll(text=text, recursive=recursive, limit=limit) + + def firstText(self, text=None, recursive=True): + return self.find(text=text, recursive=recursive) + + #Private methods + + def _getAttrMap(self): + """Initializes a map representation of this tag's attributes, + if not already initialized.""" + if not getattr(self, 'attrMap'): + self.attrMap = {} + for (key, value) in self.attrs: + self.attrMap[key] = value + return self.attrMap + + #Generator methods + def childGenerator(self): + # Just use the iterator from the contents + return iter(self.contents) + + def recursiveChildGenerator(self): + if not len(self.contents): + raise StopIteration + stopNode = self._lastRecursiveChild().next + current = self.contents[0] + while current is not stopNode: + yield current + current = current.next + + +# Next, a couple classes to represent queries and their results. +class SoupStrainer: + """Encapsulates a number of ways of matching a markup element (tag or + text).""" + + def __init__(self, name=None, attrs={}, text=None, **kwargs): + self.name = name + if isinstance(attrs, basestring): + kwargs['class'] = _match_css_class(attrs) + attrs = None + if kwargs: + if attrs: + attrs = attrs.copy() + attrs.update(kwargs) + else: + attrs = kwargs + self.attrs = attrs + self.text = text + + def __str__(self): + if self.text: + return self.text + else: + return "%s|%s" % (self.name, self.attrs) + + def searchTag(self, markupName=None, markupAttrs={}): + found = None + markup = None + if isinstance(markupName, Tag): + markup = markupName + markupAttrs = markup + callFunctionWithTagData = callable(self.name) \ + and not isinstance(markupName, Tag) + + if (not self.name) \ + or callFunctionWithTagData \ + or (markup and self._matches(markup, self.name)) \ + or (not markup and self._matches(markupName, self.name)): + if callFunctionWithTagData: + match = self.name(markupName, markupAttrs) + else: + match = True + markupAttrMap = None + for attr, matchAgainst in self.attrs.items(): + if not markupAttrMap: + if hasattr(markupAttrs, 'get'): + markupAttrMap = markupAttrs + else: + markupAttrMap = {} + for k,v in markupAttrs: + markupAttrMap[k] = v + attrValue = markupAttrMap.get(attr) + if not self._matches(attrValue, matchAgainst): + match = False + break + if match: + if markup: + found = markup + else: + found = markupName + return found + + def search(self, markup): + #print 'looking for %s in %s' % (self, markup) + found = None + # If given a list of items, scan it for a text element that + # matches. + if hasattr(markup, "__iter__") \ + and not isinstance(markup, Tag): + for element in markup: + if isinstance(element, NavigableString) \ + and self.search(element): + found = element + break + # If it's a Tag, make sure its name or attributes match. + # Don't bother with Tags if we're searching for text. + elif isinstance(markup, Tag): + if not self.text: + found = self.searchTag(markup) + # If it's text, make sure the text matches. + elif isinstance(markup, NavigableString) or \ + isinstance(markup, basestring): + if self._matches(markup, self.text): + found = markup + else: + raise Exception, "I don't know how to match against a %s" \ + % markup.__class__ + return found + + def _matches(self, markup, matchAgainst): + #print "Matching %s against %s" % (markup, matchAgainst) + result = False + if matchAgainst is True: + result = markup is not None + elif callable(matchAgainst): + result = matchAgainst(markup) + else: + #Custom match methods take the tag as an argument, but all + #other ways of matching match the tag name as a string. + if isinstance(markup, Tag): + markup = markup.name + if markup and not isinstance(markup, basestring): + markup = unicode(markup) + #Now we know that chunk is either a string, or None. + if hasattr(matchAgainst, 'match'): + # It's a regexp object. + result = markup and matchAgainst.search(markup) + elif hasattr(matchAgainst, '__iter__'): # list-like + result = markup in matchAgainst + elif hasattr(matchAgainst, 'items'): + result = markup.has_key(matchAgainst) + elif matchAgainst and isinstance(markup, basestring): + if isinstance(markup, unicode): + matchAgainst = unicode(matchAgainst) + else: + matchAgainst = str(matchAgainst) + + if not result: + result = matchAgainst == markup + return result + +class ResultSet(list): + """A ResultSet is just a list that keeps track of the SoupStrainer + that created it.""" + def __init__(self, source): + list.__init__([]) + self.source = source + +# Now, some helper functions. + +def buildTagMap(default, *args): + """Turns a list of maps, lists, or scalars into a single map. + Used to build the SELF_CLOSING_TAGS, NESTABLE_TAGS, and + NESTING_RESET_TAGS maps out of lists and partial maps.""" + built = {} + for portion in args: + if hasattr(portion, 'items'): + #It's a map. Merge it. + for k,v in portion.items(): + built[k] = v + elif hasattr(portion, '__iter__'): # is a list + #It's a list. Map each item to the default. + for k in portion: + built[k] = default + else: + #It's a scalar. Map it to the default. + built[portion] = default + return built + +# Now, the parser classes. + +class BeautifulStoneSoup(Tag, SGMLParser): + + """This class contains the basic parser and search code. It defines + a parser that knows nothing about tag behavior except for the + following: + + You can't close a tag without closing all the tags it encloses. + That is, "" actually means + "". + + [Another possible explanation is "", but since + this class defines no SELF_CLOSING_TAGS, it will never use that + explanation.] + + This class is useful for parsing XML or made-up markup languages, + or when BeautifulSoup makes an assumption counter to what you were + expecting.""" + + SELF_CLOSING_TAGS = {} + NESTABLE_TAGS = {} + RESET_NESTING_TAGS = {} + QUOTE_TAGS = {} + PRESERVE_WHITESPACE_TAGS = [] + + MARKUP_MASSAGE = [(re.compile('(<[^<>]*)/>'), + lambda x: x.group(1) + ' />'), + (re.compile(']*)>'), + lambda x: '') + ] + + ROOT_TAG_NAME = u'[document]' + + HTML_ENTITIES = "html" + XML_ENTITIES = "xml" + XHTML_ENTITIES = "xhtml" + # TODO: This only exists for backwards-compatibility + ALL_ENTITIES = XHTML_ENTITIES + + # Used when determining whether a text node is all whitespace and + # can be replaced with a single space. A text node that contains + # fancy Unicode spaces (usually non-breaking) should be left + # alone. + STRIP_ASCII_SPACES = { 9: None, 10: None, 12: None, 13: None, 32: None, } + + def __init__(self, markup="", parseOnlyThese=None, fromEncoding=None, + markupMassage=True, smartQuotesTo=XML_ENTITIES, + convertEntities=None, selfClosingTags=None, isHTML=False): + """The Soup object is initialized as the 'root tag', and the + provided markup (which can be a string or a file-like object) + is fed into the underlying parser. + + sgmllib will process most bad HTML, and the BeautifulSoup + class has some tricks for dealing with some HTML that kills + sgmllib, but Beautiful Soup can nonetheless choke or lose data + if your data uses self-closing tags or declarations + incorrectly. + + By default, Beautiful Soup uses regexes to sanitize input, + avoiding the vast majority of these problems. If the problems + don't apply to you, pass in False for markupMassage, and + you'll get better performance. + + The default parser massage techniques fix the two most common + instances of invalid HTML that choke sgmllib: + +
(No space between name of closing tag and tag close) + (Extraneous whitespace in declaration) + + You can pass in a custom list of (RE object, replace method) + tuples to get Beautiful Soup to scrub your input the way you + want.""" + + self.parseOnlyThese = parseOnlyThese + self.fromEncoding = fromEncoding + self.smartQuotesTo = smartQuotesTo + self.convertEntities = convertEntities + # Set the rules for how we'll deal with the entities we + # encounter + if self.convertEntities: + # It doesn't make sense to convert encoded characters to + # entities even while you're converting entities to Unicode. + # Just convert it all to Unicode. + self.smartQuotesTo = None + if convertEntities == self.HTML_ENTITIES: + self.convertXMLEntities = False + self.convertHTMLEntities = True + self.escapeUnrecognizedEntities = True + elif convertEntities == self.XHTML_ENTITIES: + self.convertXMLEntities = True + self.convertHTMLEntities = True + self.escapeUnrecognizedEntities = False + elif convertEntities == self.XML_ENTITIES: + self.convertXMLEntities = True + self.convertHTMLEntities = False + self.escapeUnrecognizedEntities = False + else: + self.convertXMLEntities = False + self.convertHTMLEntities = False + self.escapeUnrecognizedEntities = False + + self.instanceSelfClosingTags = buildTagMap(None, selfClosingTags) + SGMLParser.__init__(self) + + if hasattr(markup, 'read'): # It's a file-type object. + markup = markup.read() + self.markup = markup + self.markupMassage = markupMassage + try: + self._feed(isHTML=isHTML) + except StopParsing: + pass + self.markup = None # The markup can now be GCed + + def convert_charref(self, name): + """This method fixes a bug in Python's SGMLParser.""" + try: + n = int(name) + except ValueError: + return + if not 0 <= n <= 127 : # ASCII ends at 127, not 255 + return + return self.convert_codepoint(n) + + def _feed(self, inDocumentEncoding=None, isHTML=False): + # Convert the document to Unicode. + markup = self.markup + if isinstance(markup, unicode): + if not hasattr(self, 'originalEncoding'): + self.originalEncoding = None + else: + dammit = UnicodeDammit\ + (markup, [self.fromEncoding, inDocumentEncoding], + smartQuotesTo=self.smartQuotesTo, isHTML=isHTML) + markup = dammit.unicode + self.originalEncoding = dammit.originalEncoding + self.declaredHTMLEncoding = dammit.declaredHTMLEncoding + if markup: + if self.markupMassage: + if not hasattr(self.markupMassage, "__iter__"): + self.markupMassage = self.MARKUP_MASSAGE + for fix, m in self.markupMassage: + markup = fix.sub(m, markup) + # TODO: We get rid of markupMassage so that the + # soup object can be deepcopied later on. Some + # Python installations can't copy regexes. If anyone + # was relying on the existence of markupMassage, this + # might cause problems. + del(self.markupMassage) + self.reset() + + SGMLParser.feed(self, markup) + # Close out any unfinished strings and close all the open tags. + self.endData() + while self.currentTag.name != self.ROOT_TAG_NAME: + self.popTag() + + def __getattr__(self, methodName): + """This method routes method call requests to either the SGMLParser + superclass or the Tag superclass, depending on the method name.""" + #print "__getattr__ called on %s.%s" % (self.__class__, methodName) + + if methodName.startswith('start_') or methodName.startswith('end_') \ + or methodName.startswith('do_'): + return SGMLParser.__getattr__(self, methodName) + elif not methodName.startswith('__'): + return Tag.__getattr__(self, methodName) + else: + raise AttributeError + + def isSelfClosingTag(self, name): + """Returns true iff the given string is the name of a + self-closing tag according to this parser.""" + return self.SELF_CLOSING_TAGS.has_key(name) \ + or self.instanceSelfClosingTags.has_key(name) + + def reset(self): + Tag.__init__(self, self, self.ROOT_TAG_NAME) + self.hidden = 1 + SGMLParser.reset(self) + self.currentData = [] + self.currentTag = None + self.tagStack = [] + self.quoteStack = [] + self.pushTag(self) + + def popTag(self): + tag = self.tagStack.pop() + + #print "Pop", tag.name + if self.tagStack: + self.currentTag = self.tagStack[-1] + return self.currentTag + + def pushTag(self, tag): + #print "Push", tag.name + if self.currentTag: + self.currentTag.contents.append(tag) + self.tagStack.append(tag) + self.currentTag = self.tagStack[-1] + + def endData(self, containerClass=NavigableString): + if self.currentData: + currentData = u''.join(self.currentData) + if (currentData.translate(self.STRIP_ASCII_SPACES) == '' and + not set([tag.name for tag in self.tagStack]).intersection( + self.PRESERVE_WHITESPACE_TAGS)): + if '\n' in currentData: + currentData = '\n' + else: + currentData = ' ' + self.currentData = [] + if self.parseOnlyThese and len(self.tagStack) <= 1 and \ + (not self.parseOnlyThese.text or \ + not self.parseOnlyThese.search(currentData)): + return + o = containerClass(currentData) + o.setup(self.currentTag, self.previous) + if self.previous: + self.previous.next = o + self.previous = o + self.currentTag.contents.append(o) + + + def _popToTag(self, name, inclusivePop=True): + """Pops the tag stack up to and including the most recent + instance of the given tag. If inclusivePop is false, pops the tag + stack up to but *not* including the most recent instqance of + the given tag.""" + #print "Popping to %s" % name + if name == self.ROOT_TAG_NAME: + return + + numPops = 0 + mostRecentTag = None + for i in range(len(self.tagStack)-1, 0, -1): + if name == self.tagStack[i].name: + numPops = len(self.tagStack)-i + break + if not inclusivePop: + numPops = numPops - 1 + + for i in range(0, numPops): + mostRecentTag = self.popTag() + return mostRecentTag + + def _smartPop(self, name): + + """We need to pop up to the previous tag of this type, unless + one of this tag's nesting reset triggers comes between this + tag and the previous tag of this type, OR unless this tag is a + generic nesting trigger and another generic nesting trigger + comes between this tag and the previous tag of this type. + + Examples: +

FooBar *

* should pop to 'p', not 'b'. +

FooBar *

* should pop to 'table', not 'p'. +

Foo

Bar *

* should pop to 'tr', not 'p'. + +

    • *
    • * should pop to 'ul', not the first 'li'. +
  • ** should pop to 'table', not the first 'tr' + tag should + implicitly close the previous tag within the same
    ** should pop to 'tr', not the first 'td' + """ + + nestingResetTriggers = self.NESTABLE_TAGS.get(name) + isNestable = nestingResetTriggers != None + isResetNesting = self.RESET_NESTING_TAGS.has_key(name) + popTo = None + inclusive = True + for i in range(len(self.tagStack)-1, 0, -1): + p = self.tagStack[i] + if (not p or p.name == name) and not isNestable: + #Non-nestable tags get popped to the top or to their + #last occurance. + popTo = name + break + if (nestingResetTriggers is not None + and p.name in nestingResetTriggers) \ + or (nestingResetTriggers is None and isResetNesting + and self.RESET_NESTING_TAGS.has_key(p.name)): + + #If we encounter one of the nesting reset triggers + #peculiar to this tag, or we encounter another tag + #that causes nesting to reset, pop up to but not + #including that tag. + popTo = p.name + inclusive = False + break + p = p.parent + if popTo: + self._popToTag(popTo, inclusive) + + def unknown_starttag(self, name, attrs, selfClosing=0): + #print "Start tag %s: %s" % (name, attrs) + if self.quoteStack: + #This is not a real tag. + #print "<%s> is not real!" % name + attrs = ''.join([' %s="%s"' % (x, y) for x, y in attrs]) + self.handle_data('<%s%s>' % (name, attrs)) + return + self.endData() + + if not self.isSelfClosingTag(name) and not selfClosing: + self._smartPop(name) + + if self.parseOnlyThese and len(self.tagStack) <= 1 \ + and (self.parseOnlyThese.text or not self.parseOnlyThese.searchTag(name, attrs)): + return + + tag = Tag(self, name, attrs, self.currentTag, self.previous) + if self.previous: + self.previous.next = tag + self.previous = tag + self.pushTag(tag) + if selfClosing or self.isSelfClosingTag(name): + self.popTag() + if name in self.QUOTE_TAGS: + #print "Beginning quote (%s)" % name + self.quoteStack.append(name) + self.literal = 1 + return tag + + def unknown_endtag(self, name): + #print "End tag %s" % name + if self.quoteStack and self.quoteStack[-1] != name: + #This is not a real end tag. + #print " is not real!" % name + self.handle_data('' % name) + return + self.endData() + self._popToTag(name) + if self.quoteStack and self.quoteStack[-1] == name: + self.quoteStack.pop() + self.literal = (len(self.quoteStack) > 0) + + def handle_data(self, data): + self.currentData.append(data) + + def _toStringSubclass(self, text, subclass): + """Adds a certain piece of text to the tree as a NavigableString + subclass.""" + self.endData() + self.handle_data(text) + self.endData(subclass) + + def handle_pi(self, text): + """Handle a processing instruction as a ProcessingInstruction + object, possibly one with a %SOUP-ENCODING% slot into which an + encoding will be plugged later.""" + if text[:3] == "xml": + text = u"xml version='1.0' encoding='%SOUP-ENCODING%'" + self._toStringSubclass(text, ProcessingInstruction) + + def handle_comment(self, text): + "Handle comments as Comment objects." + self._toStringSubclass(text, Comment) + + def handle_charref(self, ref): + "Handle character references as data." + if self.convertEntities: + data = unichr(int(ref)) + else: + data = '&#%s;' % ref + self.handle_data(data) + + def handle_entityref(self, ref): + """Handle entity references as data, possibly converting known + HTML and/or XML entity references to the corresponding Unicode + characters.""" + data = None + if self.convertHTMLEntities: + try: + data = unichr(name2codepoint[ref]) + except KeyError: + pass + + if not data and self.convertXMLEntities: + data = self.XML_ENTITIES_TO_SPECIAL_CHARS.get(ref) + + if not data and self.convertHTMLEntities and \ + not self.XML_ENTITIES_TO_SPECIAL_CHARS.get(ref): + # TODO: We've got a problem here. We're told this is + # an entity reference, but it's not an XML entity + # reference or an HTML entity reference. Nonetheless, + # the logical thing to do is to pass it through as an + # unrecognized entity reference. + # + # Except: when the input is "&carol;" this function + # will be called with input "carol". When the input is + # "AT&T", this function will be called with input + # "T". We have no way of knowing whether a semicolon + # was present originally, so we don't know whether + # this is an unknown entity or just a misplaced + # ampersand. + # + # The more common case is a misplaced ampersand, so I + # escape the ampersand and omit the trailing semicolon. + data = "&%s" % ref + if not data: + # This case is different from the one above, because we + # haven't already gone through a supposedly comprehensive + # mapping of entities to Unicode characters. We might not + # have gone through any mapping at all. So the chances are + # very high that this is a real entity, and not a + # misplaced ampersand. + data = "&%s;" % ref + self.handle_data(data) + + def handle_decl(self, data): + "Handle DOCTYPEs and the like as Declaration objects." + self._toStringSubclass(data, Declaration) + + def parse_declaration(self, i): + """Treat a bogus SGML declaration as raw data. Treat a CDATA + declaration as a CData object.""" + j = None + if self.rawdata[i:i+9] == '', i) + if k == -1: + k = len(self.rawdata) + data = self.rawdata[i+9:k] + j = k+3 + self._toStringSubclass(data, CData) + else: + try: + j = SGMLParser.parse_declaration(self, i) + except SGMLParseError: + toHandle = self.rawdata[i:] + self.handle_data(toHandle) + j = i + len(toHandle) + return j + +class BeautifulSoup(BeautifulStoneSoup): + + """This parser knows the following facts about HTML: + + * Some tags have no closing tag and should be interpreted as being + closed as soon as they are encountered. + + * The text inside some tags (ie. 'script') may contain tags which + are not really part of the document and which should be parsed + as text, not tags. If you want to parse the text as tags, you can + always fetch it and parse it explicitly. + + * Tag nesting rules: + + Most tags can't be nested at all. For instance, the occurance of + a

    tag should implicitly close the previous

    tag. + +

    Para1

    Para2 + should be transformed into: +

    Para1

    Para2 + + Some tags can be nested arbitrarily. For instance, the occurance + of a

    tag should _not_ implicitly close the previous +
    tag. + + Alice said:
    Bob said:
    Blah + should NOT be transformed into: + Alice said:
    Bob said:
    Blah + + Some tags can be nested, but the nesting is reset by the + interposition of other tags. For instance, a
    , + but not close a tag in another table. + +
    BlahBlah + should be transformed into: +
    BlahBlah + but, + Blah
    Blah + should NOT be transformed into + Blah
    Blah + + Differing assumptions about tag nesting rules are a major source + of problems with the BeautifulSoup class. If BeautifulSoup is not + treating as nestable a tag your page author treats as nestable, + try ICantBelieveItsBeautifulSoup, MinimalSoup, or + BeautifulStoneSoup before writing your own subclass.""" + + def __init__(self, *args, **kwargs): + if not kwargs.has_key('smartQuotesTo'): + kwargs['smartQuotesTo'] = self.HTML_ENTITIES + kwargs['isHTML'] = True + BeautifulStoneSoup.__init__(self, *args, **kwargs) + + SELF_CLOSING_TAGS = buildTagMap(None, + ('br' , 'hr', 'input', 'img', 'meta', + 'spacer', 'link', 'frame', 'base', 'col')) + + PRESERVE_WHITESPACE_TAGS = set(['pre', 'textarea']) + + QUOTE_TAGS = {'script' : None, 'textarea' : None} + + #According to the HTML standard, each of these inline tags can + #contain another tag of the same type. Furthermore, it's common + #to actually use these tags this way. + NESTABLE_INLINE_TAGS = ('span', 'font', 'q', 'object', 'bdo', 'sub', 'sup', + 'center') + + #According to the HTML standard, these block tags can contain + #another tag of the same type. Furthermore, it's common + #to actually use these tags this way. + NESTABLE_BLOCK_TAGS = ('blockquote', 'div', 'fieldset', 'ins', 'del') + + #Lists can contain other lists, but there are restrictions. + NESTABLE_LIST_TAGS = { 'ol' : [], + 'ul' : [], + 'li' : ['ul', 'ol'], + 'dl' : [], + 'dd' : ['dl'], + 'dt' : ['dl'] } + + #Tables can contain other tables, but there are restrictions. + NESTABLE_TABLE_TAGS = {'table' : [], + 'tr' : ['table', 'tbody', 'tfoot', 'thead'], + 'td' : ['tr'], + 'th' : ['tr'], + 'thead' : ['table'], + 'tbody' : ['table'], + 'tfoot' : ['table'], + } + + NON_NESTABLE_BLOCK_TAGS = ('address', 'form', 'p', 'pre') + + #If one of these tags is encountered, all tags up to the next tag of + #this type are popped. + RESET_NESTING_TAGS = buildTagMap(None, NESTABLE_BLOCK_TAGS, 'noscript', + NON_NESTABLE_BLOCK_TAGS, + NESTABLE_LIST_TAGS, + NESTABLE_TABLE_TAGS) + + NESTABLE_TAGS = buildTagMap([], NESTABLE_INLINE_TAGS, NESTABLE_BLOCK_TAGS, + NESTABLE_LIST_TAGS, NESTABLE_TABLE_TAGS) + + # Used to detect the charset in a META tag; see start_meta + CHARSET_RE = re.compile("((^|;)\s*charset=)([^;]*)", re.M) + + def start_meta(self, attrs): + """Beautiful Soup can detect a charset included in a META tag, + try to convert the document to that charset, and re-parse the + document from the beginning.""" + httpEquiv = None + contentType = None + contentTypeIndex = None + tagNeedsEncodingSubstitution = False + + for i in range(0, len(attrs)): + key, value = attrs[i] + key = key.lower() + if key == 'http-equiv': + httpEquiv = value + elif key == 'content': + contentType = value + contentTypeIndex = i + + if httpEquiv and contentType: # It's an interesting meta tag. + match = self.CHARSET_RE.search(contentType) + if match: + if (self.declaredHTMLEncoding is not None or + self.originalEncoding == self.fromEncoding): + # An HTML encoding was sniffed while converting + # the document to Unicode, or an HTML encoding was + # sniffed during a previous pass through the + # document, or an encoding was specified + # explicitly and it worked. Rewrite the meta tag. + def rewrite(match): + return match.group(1) + "%SOUP-ENCODING%" + newAttr = self.CHARSET_RE.sub(rewrite, contentType) + attrs[contentTypeIndex] = (attrs[contentTypeIndex][0], + newAttr) + tagNeedsEncodingSubstitution = True + else: + # This is our first pass through the document. + # Go through it again with the encoding information. + newCharset = match.group(3) + if newCharset and newCharset != self.originalEncoding: + self.declaredHTMLEncoding = newCharset + self._feed(self.declaredHTMLEncoding) + raise StopParsing + pass + tag = self.unknown_starttag("meta", attrs) + if tag and tagNeedsEncodingSubstitution: + tag.containsSubstitutions = True + +class StopParsing(Exception): + pass + +class ICantBelieveItsBeautifulSoup(BeautifulSoup): + + """The BeautifulSoup class is oriented towards skipping over + common HTML errors like unclosed tags. However, sometimes it makes + errors of its own. For instance, consider this fragment: + + FooBar + + This is perfectly valid (if bizarre) HTML. However, the + BeautifulSoup class will implicitly close the first b tag when it + encounters the second 'b'. It will think the author wrote + "FooBar", and didn't close the first 'b' tag, because + there's no real-world reason to bold something that's already + bold. When it encounters '' it will close two more 'b' + tags, for a grand total of three tags closed instead of two. This + can throw off the rest of your document structure. The same is + true of a number of other tags, listed below. + + It's much more common for someone to forget to close a 'b' tag + than to actually use nested 'b' tags, and the BeautifulSoup class + handles the common case. This class handles the not-co-common + case: where you can't believe someone wrote what they did, but + it's valid HTML and BeautifulSoup screwed up by assuming it + wouldn't be.""" + + I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS = \ + ('em', 'big', 'i', 'small', 'tt', 'abbr', 'acronym', 'strong', + 'cite', 'code', 'dfn', 'kbd', 'samp', 'strong', 'var', 'b', + 'big') + + I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS = ('noscript',) + + NESTABLE_TAGS = buildTagMap([], BeautifulSoup.NESTABLE_TAGS, + I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS, + I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS) + +class MinimalSoup(BeautifulSoup): + """The MinimalSoup class is for parsing HTML that contains + pathologically bad markup. It makes no assumptions about tag + nesting, but it does know which tags are self-closing, that + Foo" + soup = BeautifulSoup(text) + self.assertEqual(soup.script.contents[0], "if (iThis is an example of an HTML tag<&<&") + +class OperatorOverload(SoupTest): + "Our operators do it all! Call now!" + + def testTagNameAsFind(self): + "Tests that referencing a tag name as a member delegates to find()." + soup = BeautifulSoup('foobarRed herring') + self.assertEqual(soup.b.i, soup.find('b').find('i')) + self.assertEqual(soup.b.i.string, 'bar') + self.assertEqual(soup.b['id'], '1') + self.assertEqual(soup.b.contents[0], 'foo') + self.assert_(not soup.a) + + #Test the .fooTag variant of .foo. + self.assertEqual(soup.bTag.iTag.string, 'bar') + self.assertEqual(soup.b.iTag.string, 'bar') + self.assertEqual(soup.find('b').find('i'), soup.bTag.iTag) + +class NestableEgg(SoupTest): + """Here we test tag nesting. TEST THE NEST, DUDE! X-TREME!""" + + def testParaInsideBlockquote(self): + soup = BeautifulSoup('

    Foo

    Bar') + self.assertEqual(soup.blockquote.p.b.string, 'Foo') + self.assertEqual(soup.blockquote.b.string, 'Foo') + self.assertEqual(soup.find('p', recursive=False).string, 'Bar') + + def testNestedTables(self): + text = """

    Here's another table: +
    Juicy text
    """ + soup = BeautifulSoup(text) + self.assertEquals(soup.table.table.td.string, 'Juicy text') + self.assertEquals(len(soup.findAll('table')), 2) + self.assertEquals(len(soup.table.findAll('table')), 1) + self.assertEquals(soup.find('table', {'id' : 2}).parent.parent.parent.name, + 'table') + + text = "
    Foo
    " + soup = BeautifulSoup(text) + self.assertEquals(soup.table.tr.td.div.table.contents[0], "Foo") + + text = """FooBar + Baz
    """ + soup = BeautifulSoup(text) + self.assertEquals(soup.table.thead.tr.contents[0], "Foo") + + def testBadNestedTables(self): + soup = BeautifulSoup("
    ") + self.assertEquals(soup.table.tr.table.tr['id'], 'nested') + +class CleanupOnAisleFour(SoupTest): + """Here we test cleanup of text that breaks SGMLParser or is just + obnoxious.""" + + def testSelfClosingtag(self): + self.assertEqual(str(BeautifulSoup("Foo
    Bar").find('br')), + '
    ') + + self.assertSoupEquals('

    test1
    test2

    ', + '

    test1
    test2

    ') + + text = '

    test1test2' + soup = BeautifulStoneSoup(text) + self.assertEqual(str(soup), + '

    test1test2

    ') + + soup = BeautifulStoneSoup(text, selfClosingTags='selfclosing') + self.assertEqual(str(soup), + '

    test1test2

    ') + + def testSelfClosingTagOrNot(self): + text = "http://foo.com/" + self.assertEqual(BeautifulStoneSoup(text).renderContents(), text) + self.assertEqual(BeautifulSoup(text).renderContents(), + 'http://foo.com/') + + def testCData(self): + xml = "foobar" + self.assertSoupEquals(xml, xml) + r = re.compile("foo.*bar") + soup = BeautifulSoup(xml) + self.assertEquals(soup.find(text=r).string, "foobar") + self.assertEquals(soup.find(text=r).__class__, CData) + + def testComments(self): + xml = "foobaz" + self.assertSoupEquals(xml) + r = re.compile("foo.*bar") + soup = BeautifulSoup(xml) + self.assertEquals(soup.find(text=r).string, "foobar") + self.assertEquals(soup.find(text="foobar").__class__, Comment) + + def testDeclaration(self): + xml = "foobaz" + self.assertSoupEquals(xml) + r = re.compile(".*foo.*bar") + soup = BeautifulSoup(xml) + text = "DOCTYPE foobar" + self.assertEquals(soup.find(text=r).string, text) + self.assertEquals(soup.find(text=text).__class__, Declaration) + + namespaced_doctype = ('' + 'foo') + soup = BeautifulSoup(namespaced_doctype) + self.assertEquals(soup.contents[0], + 'DOCTYPE xsl:stylesheet SYSTEM "htmlent.dtd"') + self.assertEquals(soup.html.contents[0], 'foo') + + def testEntityConversions(self): + text = "<<sacré bleu!>>" + soup = BeautifulStoneSoup(text) + self.assertSoupEquals(text) + + xmlEnt = BeautifulStoneSoup.XML_ENTITIES + htmlEnt = BeautifulStoneSoup.HTML_ENTITIES + xhtmlEnt = BeautifulStoneSoup.XHTML_ENTITIES + + soup = BeautifulStoneSoup(text, convertEntities=xmlEnt) + self.assertEquals(str(soup), "<<sacré bleu!>>") + + soup = BeautifulStoneSoup(text, convertEntities=htmlEnt) + self.assertEquals(unicode(soup), u"<<sacr\xe9 bleu!>>") + + # Make sure the "XML", "HTML", and "XHTML" settings work. + text = "<™'" + soup = BeautifulStoneSoup(text, convertEntities=xmlEnt) + self.assertEquals(unicode(soup), u"<™'") + + soup = BeautifulStoneSoup(text, convertEntities=htmlEnt) + self.assertEquals(unicode(soup), u"<\u2122'") + + soup = BeautifulStoneSoup(text, convertEntities=xhtmlEnt) + self.assertEquals(unicode(soup), u"<\u2122'") + + invalidEntity = "foo&#bar;baz" + soup = BeautifulStoneSoup\ + (invalidEntity, + convertEntities=htmlEnt) + self.assertEquals(str(soup), "foo&#bar;baz") + + nonexistentEntity = "foo&bar;baz" + soup = BeautifulStoneSoup\ + (nonexistentEntity, + convertEntities="xml") + self.assertEquals(str(soup), nonexistentEntity) + + + def testNonBreakingSpaces(self): + soup = BeautifulSoup("  ", + convertEntities=BeautifulStoneSoup.HTML_ENTITIES) + self.assertEquals(unicode(soup), u"\xa0\xa0") + + def testWhitespaceInDeclaration(self): + self.assertSoupEquals('', '') + + def testJunkInDeclaration(self): + self.assertSoupEquals('a', '<!Foo = -8>a') + + def testIncompleteDeclaration(self): + self.assertSoupEquals('ac', 'a<!b <p>c') + + def testEntityReplacement(self): + self.assertSoupEquals('hello there') + + def testEntitiesInAttributeValues(self): + self.assertSoupEquals('', '') + self.assertSoupEquals('', '') + + soup = BeautifulSoup('', + convertEntities=BeautifulStoneSoup.HTML_ENTITIES) + self.assertEquals(unicode(soup), u'') + + uri = "http://crummy.com?sacré&bleu" + link = '' % uri + soup = BeautifulSoup(link) + self.assertEquals(unicode(soup), link) + #self.assertEquals(unicode(soup.a['href']), uri) + + soup = BeautifulSoup(link, convertEntities=BeautifulSoup.HTML_ENTITIES) + self.assertEquals(unicode(soup), + link.replace("é", u"\xe9")) + + uri = "http://crummy.com?sacré&bleu" + link = '' % uri + soup = BeautifulSoup(link, convertEntities=BeautifulSoup.HTML_ENTITIES) + self.assertEquals(unicode(soup.a['href']), + uri.replace("é", u"\xe9")) + + def testNakedAmpersands(self): + html = {'convertEntities':BeautifulStoneSoup.HTML_ENTITIES} + soup = BeautifulStoneSoup("AT&T ", **html) + self.assertEquals(str(soup), 'AT&T ') + + nakedAmpersandInASentence = "AT&T was Ma Bell" + soup = BeautifulStoneSoup(nakedAmpersandInASentence,**html) + self.assertEquals(str(soup), \ + nakedAmpersandInASentence.replace('&','&')) + + invalidURL = 'foo' + validURL = invalidURL.replace('&','&') + soup = BeautifulStoneSoup(invalidURL) + self.assertEquals(str(soup), validURL) + + soup = BeautifulStoneSoup(validURL) + self.assertEquals(str(soup), validURL) + + +class EncodeRed(SoupTest): + """Tests encoding conversion, Unicode conversion, and Microsoft + smart quote fixes.""" + + def testUnicodeDammitStandalone(self): + markup = "\x92" + dammit = UnicodeDammit(markup) + self.assertEquals(dammit.unicode, "") + + hebrew = "\xed\xe5\xec\xf9" + dammit = UnicodeDammit(hebrew, ["iso-8859-8"]) + self.assertEquals(dammit.unicode, u'\u05dd\u05d5\u05dc\u05e9') + self.assertEquals(dammit.originalEncoding, 'iso-8859-8') + + def testGarbageInGarbageOut(self): + ascii = "a" + asciiSoup = BeautifulStoneSoup(ascii) + self.assertEquals(ascii, str(asciiSoup)) + + unicodeData = u"\u00FC" + utf8 = unicodeData.encode("utf-8") + self.assertEquals(utf8, '\xc3\xbc') + + unicodeSoup = BeautifulStoneSoup(unicodeData) + self.assertEquals(unicodeData, unicode(unicodeSoup)) + self.assertEquals(unicode(unicodeSoup.foo.string), u'\u00FC') + + utf8Soup = BeautifulStoneSoup(utf8, fromEncoding='utf-8') + self.assertEquals(utf8, str(utf8Soup)) + self.assertEquals(utf8Soup.originalEncoding, "utf-8") + + utf8Soup = BeautifulStoneSoup(unicodeData) + self.assertEquals(utf8, str(utf8Soup)) + self.assertEquals(utf8Soup.originalEncoding, None) + + + def testHandleInvalidCodec(self): + for bad_encoding in ['.utf8', '...', 'utF---16.!']: + soup = BeautifulSoup("Räksmörgås", fromEncoding=bad_encoding) + self.assertEquals(soup.originalEncoding, 'utf-8') + + def testUnicodeSearch(self): + html = u'

    Räksmörgås

    ' + soup = BeautifulSoup(html) + self.assertEqual(soup.find(text=u'Räksmörgås'),u'Räksmörgås') + + def testRewrittenXMLHeader(self): + euc_jp = '\n\n\xa4\xb3\xa4\xec\xa4\xcfEUC-JP\xa4\xc7\xa5\xb3\xa1\xbc\xa5\xc7\xa5\xa3\xa5\xf3\xa5\xb0\xa4\xb5\xa4\xec\xa4\xbf\xc6\xfc\xcb\xdc\xb8\xec\xa4\xce\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xa4\xc7\xa4\xb9\xa1\xa3\n\n' + utf8 = "\n\n\xe3\x81\x93\xe3\x82\x8c\xe3\x81\xafEUC-JP\xe3\x81\xa7\xe3\x82\xb3\xe3\x83\xbc\xe3\x83\x87\xe3\x82\xa3\xe3\x83\xb3\xe3\x82\xb0\xe3\x81\x95\xe3\x82\x8c\xe3\x81\x9f\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e\xe3\x81\xae\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xe3\x81\xa7\xe3\x81\x99\xe3\x80\x82\n\n" + soup = BeautifulStoneSoup(euc_jp) + if soup.originalEncoding != "euc-jp": + raise Exception("Test failed when parsing euc-jp document. " + "If you're running Python >=2.4, or you have " + "cjkcodecs installed, this is a real problem. " + "Otherwise, ignore it.") + + self.assertEquals(soup.originalEncoding, "euc-jp") + self.assertEquals(str(soup), utf8) + + old_text = "\x92" + new_text = "" + self.assertSoupEquals(old_text, new_text) + + def testRewrittenMetaTag(self): + no_shift_jis_html = '''\n
    \n\x82\xb1\x82\xea\x82\xcdShift-JIS\x82\xc5\x83R\x81[\x83f\x83B\x83\x93\x83O\x82\xb3\x82\xea\x82\xbd\x93\xfa\x96{\x8c\xea\x82\xcc\x83t\x83@\x83C\x83\x8b\x82\xc5\x82\xb7\x81B\n
    ''' + soup = BeautifulSoup(no_shift_jis_html) + + # Beautiful Soup used to try to rewrite the meta tag even if the + # meta tag got filtered out by the strainer. This test makes + # sure that doesn't happen. + strainer = SoupStrainer('pre') + soup = BeautifulSoup(no_shift_jis_html, parseOnlyThese=strainer) + self.assertEquals(soup.contents[0].name, 'pre') + + meta_tag = ('') + shift_jis_html = ( + '\n%s\n' + '' + '
    \n'
    +            '\x82\xb1\x82\xea\x82\xcdShift-JIS\x82\xc5\x83R\x81[\x83f'
    +            '\x83B\x83\x93\x83O\x82\xb3\x82\xea\x82\xbd\x93\xfa\x96{\x8c'
    +            '\xea\x82\xcc\x83t\x83@\x83C\x83\x8b\x82\xc5\x82\xb7\x81B\n'
    +            '
    ') % meta_tag + soup = BeautifulSoup(shift_jis_html) + if soup.originalEncoding != "shift-jis": + raise Exception("Test failed when parsing shift-jis document " + "with meta tag '%s'." + "If you're running Python >=2.4, or you have " + "cjkcodecs installed, this is a real problem. " + "Otherwise, ignore it." % meta_tag) + self.assertEquals(soup.originalEncoding, "shift-jis") + + content_type_tag = soup.meta['content'] + self.assertEquals(content_type_tag[content_type_tag.find('charset='):], + 'charset=%SOUP-ENCODING%') + content_type = str(soup.meta) + index = content_type.find('charset=') + self.assertEqual(content_type[index:index+len('charset=utf8')+1], + 'charset=utf-8') + content_type = soup.meta.__str__('shift-jis') + index = content_type.find('charset=') + self.assertEqual(content_type[index:index+len('charset=shift-jis')], + 'charset=shift-jis') + + self.assertEquals(str(soup), ( + '\n' + '\n' + '' + '
    \n'
    +                '\xe3\x81\x93\xe3\x82\x8c\xe3\x81\xafShift-JIS\xe3\x81\xa7\xe3'
    +                '\x82\xb3\xe3\x83\xbc\xe3\x83\x87\xe3\x82\xa3\xe3\x83\xb3\xe3'
    +                '\x82\xb0\xe3\x81\x95\xe3\x82\x8c\xe3\x81\x9f\xe6\x97\xa5\xe6'
    +                '\x9c\xac\xe8\xaa\x9e\xe3\x81\xae\xe3\x83\x95\xe3\x82\xa1\xe3'
    +                '\x82\xa4\xe3\x83\xab\xe3\x81\xa7\xe3\x81\x99\xe3\x80\x82\n'
    +                '
    ')) + self.assertEquals(soup.renderContents("shift-jis"), + shift_jis_html.replace('x-sjis', 'shift-jis')) + + isolatin ="""Sacr\xe9 bleu!""" + soup = BeautifulSoup(isolatin) + self.assertSoupEquals(soup.__str__("utf-8"), + isolatin.replace("ISO-Latin-1", "utf-8").replace("\xe9", "\xc3\xa9")) + + def testHebrew(self): + iso_8859_8= '\nHebrew (ISO 8859-8) in Visual Directionality\n\n\n\n\n\n

    Hebrew (ISO 8859-8) in Visual Directionality

    \n\xed\xe5\xec\xf9\n\n' + utf8 = '\nHebrew (ISO 8859-8) in Visual Directionality\n\n\n

    Hebrew (ISO 8859-8) in Visual Directionality

    \n\xd7\x9d\xd7\x95\xd7\x9c\xd7\xa9\n\n' + soup = BeautifulStoneSoup(iso_8859_8, fromEncoding="iso-8859-8") + self.assertEquals(str(soup), utf8) + + def testSmartQuotesNotSoSmartAnymore(self): + self.assertSoupEquals("\x91Foo\x92 ", + '‘Foo’ ') + + def testDontConvertSmartQuotesWhenAlsoConvertingEntities(self): + smartQuotes = "Il a dit, \x8BSacré bleu!\x9b" + soup = BeautifulSoup(smartQuotes) + self.assertEquals(str(soup), + 'Il a dit, ‹Sacré bleu!›') + soup = BeautifulSoup(smartQuotes, convertEntities="html") + self.assertEquals(str(soup), + 'Il a dit, \xe2\x80\xb9Sacr\xc3\xa9 bleu!\xe2\x80\xba') + + def testDontSeeSmartQuotesWhereThereAreNone(self): + utf_8 = "\343\202\261\343\203\274\343\202\277\343\202\244 Watch" + self.assertSoupEquals(utf_8) + + +class Whitewash(SoupTest): + """Test whitespace preservation.""" + + def testPreservedWhitespace(self): + self.assertSoupEquals("
       
    ") + self.assertSoupEquals("
     woo  
    ") + + def testCollapsedWhitespace(self): + self.assertSoupEquals("

    ", "

    ") + + +if __name__ == '__main__': + unittest.main() diff --git a/venv/lib/python2.7/site-packages/BeautifulSoupTests.pyc b/venv/lib/python2.7/site-packages/BeautifulSoupTests.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2efd72a643d37062a4aec8aad0489bbd2ee67771 GIT binary patch literal 46699 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. + +Links +````` + +* `website `_ +* `documentation `_ +* `development version + `_ + + + diff --git a/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/INSTALLER b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/LICENSE.txt b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..a7da10e --- /dev/null +++ b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/LICENSE.txt @@ -0,0 +1,33 @@ +Copyright (c) 2015 by Armin Ronacher and contributors. See AUTHORS +for more details. + +Some rights reserved. + +Redistribution and use in source and binary forms of the software as well +as documentation, with or without modification, are permitted provided +that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +* The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/METADATA b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/METADATA new file mode 100644 index 0000000..8c43205 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/METADATA @@ -0,0 +1,75 @@ +Metadata-Version: 2.0 +Name: Flask +Version: 0.12.2 +Summary: A microframework based on Werkzeug, Jinja2 and good intentions +Home-page: http://github.com/pallets/flask/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Platform: any +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Dist: Jinja2 (>=2.4) +Requires-Dist: Werkzeug (>=0.7) +Requires-Dist: click (>=2.0) +Requires-Dist: itsdangerous (>=0.21) + +Flask +----- + +Flask is a microframework for Python based on Werkzeug, Jinja 2 and good +intentions. And before you ask: It's BSD licensed! + +Flask is Fun +```````````` + +Save in a hello.py: + +.. code:: python + + from flask import Flask + app = Flask(__name__) + + @app.route("/") + def hello(): + return "Hello World!" + + if __name__ == "__main__": + app.run() + +And Easy to Setup +````````````````` + +And run it: + +.. code:: bash + + $ pip install Flask + $ python hello.py + * Running on http://localhost:5000/ + + Ready for production? `Read this first `. + +Links +````` + +* `website `_ +* `documentation `_ +* `development version + `_ + + + diff --git a/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/RECORD b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/RECORD new file mode 100644 index 0000000..de3b364 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/RECORD @@ -0,0 +1,52 @@ +Flask-0.12.2.dist-info/DESCRIPTION.rst,sha256=DmJm8IBlBjl3wkm0Ly23jYvWbvK_mCuE5oUseYCijbI,810 +Flask-0.12.2.dist-info/LICENSE.txt,sha256=hLgKluMRHSnxG-L0EmrqjmKgG5cHlff6pIh3rCNINeI,1582 +Flask-0.12.2.dist-info/METADATA,sha256=OgSkJQ_kmrz4qEkS-OzYtL75uZmXAThymkOcGR4kXRQ,1948 +Flask-0.12.2.dist-info/RECORD,, +Flask-0.12.2.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 +Flask-0.12.2.dist-info/entry_points.txt,sha256=jzk2Wy2h30uEcqqzd4CVnlzsMXB-vaD5GXjuPMXmTmI,60 +Flask-0.12.2.dist-info/metadata.json,sha256=By8kZ1vY9lLEAGnRiWNBhudqKvLPo0HkZVXTYECyPKk,1389 +Flask-0.12.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6 +flask/__init__.py,sha256=sHdK1v6WRbVmCN0fEv990EE7rOT2UlamQkSof2d0Dt0,1673 +flask/__main__.py,sha256=cldbNi5zpjE68XzIWI8uYHNWwBHHVJmwtlXWk6P4CO4,291 +flask/_compat.py,sha256=VlfjUuLjufsTHJIjr_ZsnnOesSbAXIslBBgRe5tfOok,2802 +flask/app.py,sha256=6DPjtb5jUJWgL5fXksG5boA49EB3l-k9pWyftitbNNk,83169 +flask/blueprints.py,sha256=6HVasMcPcaq7tk36kCrgX4bnhTkky4G5WIWCyyJL8HY,16872 +flask/cli.py,sha256=2NXEdCOu5-4ymklxX4Lf6bjb-89I4VHYeP6xScR3i8E,18328 +flask/config.py,sha256=Ym5Jenyu6zAZ1fdVLeKekY9-EsKmq8183qnRgauwCMY,9905 +flask/ctx.py,sha256=UPA0YwoIlHP0txOGanC9lQLSGv6eCqV5Fmw2cVJRmgQ,14739 +flask/debughelpers.py,sha256=z-uQavKIymOZl0WQDLXsnacA00ERIlCx3S3Tnb_OYsE,6024 +flask/exthook.py,sha256=SvXs5jwpcOjogwJ7SNquiWTxowoN1-MHFoqAejWnk2o,5762 +flask/globals.py,sha256=I3m_4RssLhWW1R11zuEI8oFryHUHX3NQwjMkGXOZzg8,1645 +flask/helpers.py,sha256=KrsQ2Yo3lOVHvBTgQCLvpubgmTOpQdTTyiCOOYlwDuQ,38452 +flask/json.py,sha256=1zPM-NPLiWoOfGd0P14FxnEkeKtjtUZxMC9pyYyDBYI,9183 +flask/logging.py,sha256=UG-77jPkRClk9w1B-_ArjjXPuj9AmZz9mG0IRGvptW0,2751 +flask/sessions.py,sha256=QBKXVYKJ-HKbx9m6Yb5yan_EPq84a5yevVLgAzNKFQY,14394 +flask/signals.py,sha256=MfZk5qTRj_R_O3aGYlTEnx2g3SvlZncz8Ii73eKK59g,2209 +flask/templating.py,sha256=u7FbN6j56H_q6CrdJJyJ6gZtqaMa0vh1_GP12gEHRQQ,4912 +flask/testing.py,sha256=II8EO_NjOT1LvL8Hh_SdIFL_BdlwVPcB9yot5pbltxE,5630 +flask/views.py,sha256=6OPv7gwu3h14JhqpeeMRWwrxoGHsUr4_nOGSyTRAxAI,5630 +flask/wrappers.py,sha256=1S_5mmuA1Tlx7D9lXV6xMblrg-PdAauNWahe-henMEE,7612 +flask/ext/__init__.py,sha256=UEezCApsG4ZJWqwUnX9YmWcNN4OVENgph_9L05n0eOM,842 +../../../bin/flask,sha256=-PyLtvfHFATbnVFUezKr80w7pXrxrWYrrwbZqLk103g,259 +Flask-0.12.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask/config.pyc,, +flask/testing.pyc,, +flask/wrappers.pyc,, +flask/views.pyc,, +flask/logging.pyc,, +flask/json.pyc,, +flask/helpers.pyc,, +flask/__main__.pyc,, +flask/blueprints.pyc,, +flask/signals.pyc,, +flask/__init__.pyc,, +flask/exthook.pyc,, +flask/debughelpers.pyc,, +flask/templating.pyc,, +flask/ctx.pyc,, +flask/cli.pyc,, +flask/_compat.pyc,, +flask/app.pyc,, +flask/globals.pyc,, +flask/ext/__init__.pyc,, +flask/sessions.pyc,, diff --git a/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/WHEEL b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/WHEEL new file mode 100644 index 0000000..8b6dd1b --- /dev/null +++ b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.29.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/entry_points.txt b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/entry_points.txt new file mode 100644 index 0000000..14adf18 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/entry_points.txt @@ -0,0 +1,4 @@ + + [console_scripts] + flask=flask.cli:main + \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/metadata.json b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/metadata.json new file mode 100644 index 0000000..4d814b8 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 4 - Beta", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules"], "extensions": {"python.commands": {"wrap_console": {"flask": "flask.cli:main"}}, "python.details": {"contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "http://github.com/pallets/flask/"}}, "python.exports": {"console_scripts": {"flask": "flask.cli:main"}}}, "extras": [], "generator": "bdist_wheel (0.29.0)", "license": "BSD", "metadata_version": "2.0", "name": "Flask", "platform": "any", "run_requires": [{"requires": ["Jinja2 (>=2.4)", "Werkzeug (>=0.7)", "click (>=2.0)", "itsdangerous (>=0.21)"]}], "summary": "A microframework based on Werkzeug, Jinja2 and good intentions", "version": "0.12.2"} \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/top_level.txt b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/top_level.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Flask-0.12.2.dist-info/top_level.txt @@ -0,0 +1 @@ +flask diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..1594da5 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst @@ -0,0 +1,37 @@ + +Jinja2 +~~~~~~ + +Jinja2 is a template engine written in pure Python. It provides a +`Django`_ inspired non-XML syntax but supports inline expressions and +an optional `sandboxed`_ environment. + +Nutshell +-------- + +Here a small example of a Jinja template:: + + {% extends 'base.html' %} + {% block title %}Memberlist{% endblock %} + {% block content %} + + {% endblock %} + +Philosophy +---------- + +Application logic is for the controller but don't try to make the life +for the template designer too hard by giving him too few functionality. + +For more informations visit the new `Jinja2 webpage`_ and `documentation`_. + +.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) +.. _Django: https://www.djangoproject.com/ +.. _Jinja2 webpage: http://jinja.pocoo.org/ +.. _documentation: http://jinja.pocoo.org/2/documentation/ + + diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/INSTALLER b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/LICENSE.txt b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/LICENSE.txt new file mode 100644 index 0000000..10145a2 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/LICENSE.txt @@ -0,0 +1,31 @@ +Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/METADATA b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/METADATA new file mode 100644 index 0000000..40f2b46 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/METADATA @@ -0,0 +1,68 @@ +Metadata-Version: 2.0 +Name: Jinja2 +Version: 2.10 +Summary: A small but fast and easy to use stand-alone template engine written in pure python. +Home-page: http://jinja.pocoo.org/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Description-Content-Type: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Dist: MarkupSafe (>=0.23) +Provides-Extra: i18n +Requires-Dist: Babel (>=0.8); extra == 'i18n' + + +Jinja2 +~~~~~~ + +Jinja2 is a template engine written in pure Python. It provides a +`Django`_ inspired non-XML syntax but supports inline expressions and +an optional `sandboxed`_ environment. + +Nutshell +-------- + +Here a small example of a Jinja template:: + + {% extends 'base.html' %} + {% block title %}Memberlist{% endblock %} + {% block content %} + + {% endblock %} + +Philosophy +---------- + +Application logic is for the controller but don't try to make the life +for the template designer too hard by giving him too few functionality. + +For more informations visit the new `Jinja2 webpage`_ and `documentation`_. + +.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) +.. _Django: https://www.djangoproject.com/ +.. _Jinja2 webpage: http://jinja.pocoo.org/ +.. _documentation: http://jinja.pocoo.org/2/documentation/ + + diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/RECORD b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/RECORD new file mode 100644 index 0000000..146a7ff --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/RECORD @@ -0,0 +1,61 @@ +Jinja2-2.10.dist-info/DESCRIPTION.rst,sha256=b5ckFDoM7vVtz_mAsJD4OPteFKCqE7beu353g4COoYI,978 +Jinja2-2.10.dist-info/LICENSE.txt,sha256=JvzUNv3Io51EiWrAPm8d_SXjhJnEjyDYvB3Tvwqqils,1554 +Jinja2-2.10.dist-info/METADATA,sha256=18EgU8zR6-av-0-5y_gXebzK4GnBB_76lALUsl-6QHM,2258 +Jinja2-2.10.dist-info/RECORD,, +Jinja2-2.10.dist-info/WHEEL,sha256=kdsN-5OJAZIiHN-iO4Rhl82KyS0bDWf4uBwMbkNafr8,110 +Jinja2-2.10.dist-info/entry_points.txt,sha256=NdzVcOrqyNyKDxD09aERj__3bFx2paZhizFDsKmVhiA,72 +Jinja2-2.10.dist-info/metadata.json,sha256=NPUJ9TMBxVQAv_kTJzvU8HwmP-4XZvbK9mz6_4YUVl4,1473 +Jinja2-2.10.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=xJHjaMoy51_KXn1wf0cysH6tUUifUxZCwSOfcJGEYZw,2614 +jinja2/_compat.py,sha256=xP60CE5Qr8FTYcDE1f54tbZLKGvMwYml4-8T7Q4KG9k,2596 +jinja2/_identifier.py,sha256=W1QBSY-iJsyt6oR_nKSuNNCzV95vLIOYgUNPUI1d5gU,1726 +jinja2/asyncfilters.py,sha256=cTDPvrS8Hp_IkwsZ1m9af_lr5nHysw7uTa5gV0NmZVE,4144 +jinja2/asyncsupport.py,sha256=UErQ3YlTLaSjFb94P4MVn08-aVD9jJxty2JVfMRb-1M,7878 +jinja2/bccache.py,sha256=nQldx0ZRYANMyfvOihRoYFKSlUdd5vJkS7BjxNwlOZM,12794 +jinja2/compiler.py,sha256=BqC5U6JxObSRhblyT_a6Tp5GtEU5z3US1a4jLQaxxgo,65386 +jinja2/constants.py,sha256=uwwV8ZUhHhacAuz5PTwckfsbqBaqM7aKfyJL7kGX5YQ,1626 +jinja2/debug.py,sha256=WTVeUFGUa4v6ReCsYv-iVPa3pkNB75OinJt3PfxNdXs,12045 +jinja2/defaults.py,sha256=Em-95hmsJxIenDCZFB1YSvf9CNhe9rBmytN3yUrBcWA,1400 +jinja2/environment.py,sha256=VnkAkqw8JbjZct4tAyHlpBrka2vqB-Z58RAP-32P1ZY,50849 +jinja2/exceptions.py,sha256=_Rj-NVi98Q6AiEjYQOsP8dEIdu5AlmRHzcSNOPdWix4,4428 +jinja2/ext.py,sha256=atMQydEC86tN1zUsdQiHw5L5cF62nDbqGue25Yiu3N4,24500 +jinja2/filters.py,sha256=yOAJk0MsH-_gEC0i0U6NweVQhbtYaC-uE8xswHFLF4w,36528 +jinja2/idtracking.py,sha256=2GbDSzIvGArEBGLkovLkqEfmYxmWsEf8c3QZwM4uNsw,9197 +jinja2/lexer.py,sha256=ySEPoXd1g7wRjsuw23uimS6nkGN5aqrYwcOKxCaVMBQ,28559 +jinja2/loaders.py,sha256=xiTuURKAEObyym0nU8PCIXu_Qp8fn0AJ5oIADUUm-5Q,17382 +jinja2/meta.py,sha256=fmKHxkmZYAOm9QyWWy8EMd6eefAIh234rkBMW2X4ZR8,4340 +jinja2/nativetypes.py,sha256=_sJhS8f-8Q0QMIC0dm1YEdLyxEyoO-kch8qOL5xUDfE,7308 +jinja2/nodes.py,sha256=L10L_nQDfubLhO3XjpF9qz46FSh2clL-3e49ogVlMmA,30853 +jinja2/optimizer.py,sha256=MsdlFACJ0FRdPtjmCAdt7JQ9SGrXFaDNUaslsWQaG3M,1722 +jinja2/parser.py,sha256=lPzTEbcpTRBLw8ii6OYyExHeAhaZLMA05Hpv4ll3ULk,35875 +jinja2/runtime.py,sha256=DHdD38Pq8gj7uWQC5usJyWFoNWL317A9AvXOW_CLB34,27755 +jinja2/sandbox.py,sha256=TVyZHlNqqTzsv9fv2NvJNmSdWRHTguhyMHdxjWms32U,16708 +jinja2/tests.py,sha256=iJQLwbapZr-EKquTG_fVOVdwHUUKf3SX9eNkjQDF8oU,4237 +jinja2/utils.py,sha256=q24VupGZotQ-uOyrJxCaXtDWhZC1RgsQG7kcdmjck2Q,20629 +jinja2/visitor.py,sha256=JD1H1cANA29JcntFfN5fPyqQxB4bI4wC00BzZa-XHks,3316 +Jinja2-2.10.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2/_compat.pyc,, +jinja2/defaults.pyc,, +jinja2/sandbox.pyc,, +jinja2/environment.pyc,, +jinja2/runtime.pyc,, +jinja2/utils.pyc,, +jinja2/parser.pyc,, +jinja2/debug.pyc,, +jinja2/visitor.pyc,, +jinja2/bccache.pyc,, +jinja2/lexer.pyc,, +jinja2/_identifier.pyc,, +jinja2/nodes.pyc,, +jinja2/compiler.pyc,, +jinja2/nativetypes.pyc,, +jinja2/exceptions.pyc,, +jinja2/__init__.pyc,, +jinja2/meta.pyc,, +jinja2/ext.pyc,, +jinja2/optimizer.pyc,, +jinja2/filters.pyc,, +jinja2/tests.pyc,, +jinja2/loaders.pyc,, +jinja2/idtracking.pyc,, +jinja2/constants.pyc,, diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/WHEEL b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/WHEEL new file mode 100644 index 0000000..7332a41 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/entry_points.txt b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/entry_points.txt new file mode 100644 index 0000000..32e6b75 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/entry_points.txt @@ -0,0 +1,4 @@ + + [babel.extractors] + jinja2 = jinja2.ext:babel_extract[i18n] + \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/metadata.json b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/metadata.json new file mode 100644 index 0000000..7f5dc38 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup :: HTML"], "description_content_type": "UNKNOWN", "extensions": {"python.details": {"contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "http://jinja.pocoo.org/"}}, "python.exports": {"babel.extractors": {"jinja2": "jinja2.ext:babel_extract [i18n]"}}}, "extras": ["i18n"], "generator": "bdist_wheel (0.30.0)", "license": "BSD", "metadata_version": "2.0", "name": "Jinja2", "run_requires": [{"extra": "i18n", "requires": ["Babel (>=0.8)"]}, {"requires": ["MarkupSafe (>=0.23)"]}], "summary": "A small but fast and easy to use stand-alone template engine written in pure python.", "version": "2.10"} \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/top_level.txt b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/venv/lib/python2.7/site-packages/Jinja2-2.10.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/DESCRIPTION.rst b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..495211b --- /dev/null +++ b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/DESCRIPTION.rst @@ -0,0 +1,115 @@ +MarkupSafe +========== + +Implements a unicode subclass that supports HTML strings: + +.. code-block:: python + + >>> from markupsafe import Markup, escape + >>> escape("") + Markup(u'<script>alert(document.cookie);</script>') + >>> tmpl = Markup("%s") + >>> tmpl % "Peter > Lustig" + Markup(u'Peter > Lustig') + +If you want to make an object unicode that is not yet unicode +but don't want to lose the taint information, you can use the +``soft_unicode`` function. (On Python 3 you can also use ``soft_str`` which +is a different name for the same function). + +.. code-block:: python + + >>> from markupsafe import soft_unicode + >>> soft_unicode(42) + u'42' + >>> soft_unicode(Markup('foo')) + Markup(u'foo') + +HTML Representations +-------------------- + +Objects can customize their HTML markup equivalent by overriding +the ``__html__`` function: + +.. code-block:: python + + >>> class Foo(object): + ... def __html__(self): + ... return 'Nice' + ... + >>> escape(Foo()) + Markup(u'Nice') + >>> Markup(Foo()) + Markup(u'Nice') + +Silent Escapes +-------------- + +Since MarkupSafe 0.10 there is now also a separate escape function +called ``escape_silent`` that returns an empty string for ``None`` for +consistency with other systems that return empty strings for ``None`` +when escaping (for instance Pylons' webhelpers). + +If you also want to use this for the escape method of the Markup +object, you can create your own subclass that does that: + +.. code-block:: python + + from markupsafe import Markup, escape_silent as escape + + class SilentMarkup(Markup): + __slots__ = () + + @classmethod + def escape(cls, s): + return cls(escape(s)) + +New-Style String Formatting +--------------------------- + +Starting with MarkupSafe 0.21 new style string formats from Python 2.6 and +3.x are now fully supported. Previously the escape behavior of those +functions was spotty at best. The new implementations operates under the +following algorithm: + +1. if an object has an ``__html_format__`` method it is called as + replacement for ``__format__`` with the format specifier. It either + has to return a string or markup object. +2. if an object has an ``__html__`` method it is called. +3. otherwise the default format system of Python kicks in and the result + is HTML escaped. + +Here is how you can implement your own formatting: + +.. code-block:: python + + class User(object): + + def __init__(self, id, username): + self.id = id + self.username = username + + def __html_format__(self, format_spec): + if format_spec == 'link': + return Markup('{1}').format( + self.id, + self.__html__(), + ) + elif format_spec: + raise ValueError('Invalid format spec') + return self.__html__() + + def __html__(self): + return Markup('{0}').format(self.username) + +And to format that user: + +.. code-block:: python + + >>> user = User(1, 'foo') + >>> Markup('

    User: {0:link}').format(user) + Markup(u'

    User: foo') + +Markupsafe supports Python 2.6, 2.7 and Python 3.3 and higher. + + diff --git a/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/INSTALLER b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/LICENSE.txt b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..5d26938 --- /dev/null +++ b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/LICENSE.txt @@ -0,0 +1,33 @@ +Copyright (c) 2010 by Armin Ronacher and contributors. See AUTHORS +for more details. + +Some rights reserved. + +Redistribution and use in source and binary forms of the software as well +as documentation, with or without modification, are permitted provided +that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +* The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/METADATA b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/METADATA new file mode 100644 index 0000000..725be08 --- /dev/null +++ b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/METADATA @@ -0,0 +1,135 @@ +Metadata-Version: 2.0 +Name: MarkupSafe +Version: 1.0 +Summary: Implements a XML/HTML/XHTML Markup safe string for Python +Home-page: http://github.com/pallets/markupsafe +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup :: HTML + +MarkupSafe +========== + +Implements a unicode subclass that supports HTML strings: + +.. code-block:: python + + >>> from markupsafe import Markup, escape + >>> escape("") + Markup(u'<script>alert(document.cookie);</script>') + >>> tmpl = Markup("%s") + >>> tmpl % "Peter > Lustig" + Markup(u'Peter > Lustig') + +If you want to make an object unicode that is not yet unicode +but don't want to lose the taint information, you can use the +``soft_unicode`` function. (On Python 3 you can also use ``soft_str`` which +is a different name for the same function). + +.. code-block:: python + + >>> from markupsafe import soft_unicode + >>> soft_unicode(42) + u'42' + >>> soft_unicode(Markup('foo')) + Markup(u'foo') + +HTML Representations +-------------------- + +Objects can customize their HTML markup equivalent by overriding +the ``__html__`` function: + +.. code-block:: python + + >>> class Foo(object): + ... def __html__(self): + ... return 'Nice' + ... + >>> escape(Foo()) + Markup(u'Nice') + >>> Markup(Foo()) + Markup(u'Nice') + +Silent Escapes +-------------- + +Since MarkupSafe 0.10 there is now also a separate escape function +called ``escape_silent`` that returns an empty string for ``None`` for +consistency with other systems that return empty strings for ``None`` +when escaping (for instance Pylons' webhelpers). + +If you also want to use this for the escape method of the Markup +object, you can create your own subclass that does that: + +.. code-block:: python + + from markupsafe import Markup, escape_silent as escape + + class SilentMarkup(Markup): + __slots__ = () + + @classmethod + def escape(cls, s): + return cls(escape(s)) + +New-Style String Formatting +--------------------------- + +Starting with MarkupSafe 0.21 new style string formats from Python 2.6 and +3.x are now fully supported. Previously the escape behavior of those +functions was spotty at best. The new implementations operates under the +following algorithm: + +1. if an object has an ``__html_format__`` method it is called as + replacement for ``__format__`` with the format specifier. It either + has to return a string or markup object. +2. if an object has an ``__html__`` method it is called. +3. otherwise the default format system of Python kicks in and the result + is HTML escaped. + +Here is how you can implement your own formatting: + +.. code-block:: python + + class User(object): + + def __init__(self, id, username): + self.id = id + self.username = username + + def __html_format__(self, format_spec): + if format_spec == 'link': + return Markup('{1}').format( + self.id, + self.__html__(), + ) + elif format_spec: + raise ValueError('Invalid format spec') + return self.__html__() + + def __html__(self): + return Markup('{0}').format(self.username) + +And to format that user: + +.. code-block:: python + + >>> user = User(1, 'foo') + >>> Markup('

    User: {0:link}').format(user) + Markup(u'

    User: foo') + +Markupsafe supports Python 2.6, 2.7 and Python 3.3 and higher. + + diff --git a/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/RECORD b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/RECORD new file mode 100644 index 0000000..e2ea0ee --- /dev/null +++ b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/RECORD @@ -0,0 +1,18 @@ +MarkupSafe-1.0.dist-info/DESCRIPTION.rst,sha256=3B3J0YLzzmJQVaWQ_XlVMhGeHA_DvBqysABvul_5fko,3397 +MarkupSafe-1.0.dist-info/LICENSE.txt,sha256=C76IIo_WPSDsCX9k5Y1aCkZRI64TkUChjUBsYLSIJLU,1582 +MarkupSafe-1.0.dist-info/METADATA,sha256=EUwvRzJbtRP3hBMc8Z2TDT44TBDeZdIurbGzIc7FOkg,4182 +MarkupSafe-1.0.dist-info/RECORD,, +MarkupSafe-1.0.dist-info/WHEEL,sha256=wuofTmOE8nXIq3BJgbj6nlvhnup4MfTp3_eVScoY-R8,112 +MarkupSafe-1.0.dist-info/metadata.json,sha256=AsmfB46NkORFRWRdbLqJvDPrRp2BZlihOOs4aiO4SmY,927 +MarkupSafe-1.0.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=xtkRdxhzJzgp65wUo1D4DjnazxHU88pPldaAuDekBeY,10697 +markupsafe/_compat.py,sha256=r1HE0CpcAZeb-AiTV9wITR91PeLHn0CzZ_XHkYoozpI,565 +markupsafe/_constants.py,sha256=U_xybFQsyXKCgHSfranJnFzo-z9nn9fuBeSk243sE5Q,4795 +markupsafe/_native.py,sha256=E2Un1ysOf-w45d18YCj8UelT5UP7Vt__IuFPYJ7YRIs,1187 +markupsafe/_speedups.c,sha256=B6Mf6Fn33WqkagfwY7q5ZBSm_vJoHDYxDB0Jp_DP7Jw,5936 +markupsafe/_speedups.so,sha256=R-PcGOu7X0BXrOHgyp0WEvWRB8aCmmXGTirNg76Cvs8,26892 +MarkupSafe-1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +markupsafe/_native.pyc,, +markupsafe/_constants.pyc,, +markupsafe/_compat.pyc,, +markupsafe/__init__.pyc,, diff --git a/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/WHEEL b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/WHEEL new file mode 100644 index 0000000..2c46d75 --- /dev/null +++ b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0.a0) +Root-Is-Purelib: false +Tag: cp27-cp27m-macosx_10_6_intel + diff --git a/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/metadata.json b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/metadata.json new file mode 100644 index 0000000..5e4f3e0 --- /dev/null +++ b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup :: HTML"], "extensions": {"python.details": {"contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "http://github.com/pallets/markupsafe"}}}, "generator": "bdist_wheel (0.30.0.a0)", "license": "BSD", "metadata_version": "2.0", "name": "MarkupSafe", "summary": "Implements a XML/HTML/XHTML Markup safe string for Python", "version": "1.0"} \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/top_level.txt b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/venv/lib/python2.7/site-packages/MarkupSafe-1.0.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/venv/lib/python2.7/site-packages/OpenSSL/SSL.py b/venv/lib/python2.7/site-packages/OpenSSL/SSL.py new file mode 100644 index 0000000..8d94bd8 --- /dev/null +++ b/venv/lib/python2.7/site-packages/OpenSSL/SSL.py @@ -0,0 +1,2241 @@ +import os +import socket +from sys import platform +from functools import wraps, partial +from itertools import count, chain +from weakref import WeakValueDictionary +from errno import errorcode + +from cryptography.utils import deprecated + +from six import ( + binary_type as _binary_type, integer_types as integer_types, int2byte, + indexbytes) + +from OpenSSL._util import ( + UNSPECIFIED as _UNSPECIFIED, + exception_from_error_queue as _exception_from_error_queue, + ffi as _ffi, + lib as _lib, + make_assert as _make_assert, + native as _native, + path_string as _path_string, + text_to_bytes_and_warn as _text_to_bytes_and_warn, + no_zero_allocator as _no_zero_allocator, +) + +from OpenSSL.crypto import ( + FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store) + +try: + _memoryview = memoryview +except NameError: + class _memoryview(object): + pass + +try: + _buffer = buffer +except NameError: + class _buffer(object): + pass + +OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER +SSLEAY_VERSION = _lib.SSLEAY_VERSION +SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS +SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM +SSLEAY_DIR = _lib.SSLEAY_DIR +SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON + +SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN +RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN + +SSLv2_METHOD = 1 +SSLv3_METHOD = 2 +SSLv23_METHOD = 3 +TLSv1_METHOD = 4 +TLSv1_1_METHOD = 5 +TLSv1_2_METHOD = 6 + +OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2 +OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3 +OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1 +OP_NO_TLSv1_1 = _lib.SSL_OP_NO_TLSv1_1 +OP_NO_TLSv1_2 = _lib.SSL_OP_NO_TLSv1_2 + +MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS + +OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE +OP_SINGLE_ECDH_USE = _lib.SSL_OP_SINGLE_ECDH_USE +OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA +OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG +OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG +OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = ( + _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG +) +OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG +OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER +OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING +OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG +OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG +OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG +OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS +OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE +OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG +OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1 +OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2 +OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG +OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = ( + _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG +) +OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION + +OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU +OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE +OP_NO_TICKET = _lib.SSL_OP_NO_TICKET + +OP_ALL = _lib.SSL_OP_ALL + +VERIFY_PEER = _lib.SSL_VERIFY_PEER +VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT +VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE +VERIFY_NONE = _lib.SSL_VERIFY_NONE + +SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF +SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT +SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER +SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH +SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR +SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP +SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE +SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL + +SSL_ST_CONNECT = _lib.SSL_ST_CONNECT +SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT +SSL_ST_MASK = _lib.SSL_ST_MASK +if _lib.Cryptography_HAS_SSL_ST: + SSL_ST_INIT = _lib.SSL_ST_INIT + SSL_ST_BEFORE = _lib.SSL_ST_BEFORE + SSL_ST_OK = _lib.SSL_ST_OK + SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE + +SSL_CB_LOOP = _lib.SSL_CB_LOOP +SSL_CB_EXIT = _lib.SSL_CB_EXIT +SSL_CB_READ = _lib.SSL_CB_READ +SSL_CB_WRITE = _lib.SSL_CB_WRITE +SSL_CB_ALERT = _lib.SSL_CB_ALERT +SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT +SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT +SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP +SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT +SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP +SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT +SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START +SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE + +# Taken from https://golang.org/src/crypto/x509/root_linux.go +_CERTIFICATE_FILE_LOCATIONS = [ + "/etc/ssl/certs/ca-certificates.crt", # Debian/Ubuntu/Gentoo etc. + "/etc/pki/tls/certs/ca-bundle.crt", # Fedora/RHEL 6 + "/etc/ssl/ca-bundle.pem", # OpenSUSE + "/etc/pki/tls/cacert.pem", # OpenELEC + "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", # CentOS/RHEL 7 +] + +_CERTIFICATE_PATH_LOCATIONS = [ + "/etc/ssl/certs", # SLES10/SLES11 +] + +# These values are compared to output from cffi's ffi.string so they must be +# byte strings. +_CRYPTOGRAPHY_MANYLINUX1_CA_DIR = b"/opt/pyca/cryptography/openssl/certs" +_CRYPTOGRAPHY_MANYLINUX1_CA_FILE = b"/opt/pyca/cryptography/openssl/cert.pem" + + +class Error(Exception): + """ + An error occurred in an `OpenSSL.SSL` API. + """ + + +_raise_current_error = partial(_exception_from_error_queue, Error) +_openssl_assert = _make_assert(Error) + + +class WantReadError(Error): + pass + + +class WantWriteError(Error): + pass + + +class WantX509LookupError(Error): + pass + + +class ZeroReturnError(Error): + pass + + +class SysCallError(Error): + pass + + +class _CallbackExceptionHelper(object): + """ + A base class for wrapper classes that allow for intelligent exception + handling in OpenSSL callbacks. + + :ivar list _problems: Any exceptions that occurred while executing in a + context where they could not be raised in the normal way. Typically + this is because OpenSSL has called into some Python code and requires a + return value. The exceptions are saved to be raised later when it is + possible to do so. + """ + + def __init__(self): + self._problems = [] + + def raise_if_problem(self): + """ + Raise an exception from the OpenSSL error queue or that was previously + captured whe running a callback. + """ + if self._problems: + try: + _raise_current_error() + except Error: + pass + raise self._problems.pop(0) + + +class _VerifyHelper(_CallbackExceptionHelper): + """ + Wrap a callback such that it can be used as a certificate verification + callback. + """ + + def __init__(self, callback): + _CallbackExceptionHelper.__init__(self) + + @wraps(callback) + def wrapper(ok, store_ctx): + cert = X509.__new__(X509) + cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx) + error_number = _lib.X509_STORE_CTX_get_error(store_ctx) + error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx) + + index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx() + ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index) + connection = Connection._reverse_mapping[ssl] + + try: + result = callback( + connection, cert, error_number, error_depth, ok + ) + except Exception as e: + self._problems.append(e) + return 0 + else: + if result: + _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK) + return 1 + else: + return 0 + + self.callback = _ffi.callback( + "int (*)(int, X509_STORE_CTX *)", wrapper) + + +class _NpnAdvertiseHelper(_CallbackExceptionHelper): + """ + Wrap a callback such that it can be used as an NPN advertisement callback. + """ + + def __init__(self, callback): + _CallbackExceptionHelper.__init__(self) + + @wraps(callback) + def wrapper(ssl, out, outlen, arg): + try: + conn = Connection._reverse_mapping[ssl] + protos = callback(conn) + + # Join the protocols into a Python bytestring, length-prefixing + # each element. + protostr = b''.join( + chain.from_iterable((int2byte(len(p)), p) for p in protos) + ) + + # Save our callback arguments on the connection object. This is + # done to make sure that they don't get freed before OpenSSL + # uses them. Then, return them appropriately in the output + # parameters. + conn._npn_advertise_callback_args = [ + _ffi.new("unsigned int *", len(protostr)), + _ffi.new("unsigned char[]", protostr), + ] + outlen[0] = conn._npn_advertise_callback_args[0][0] + out[0] = conn._npn_advertise_callback_args[1] + return 0 + except Exception as e: + self._problems.append(e) + return 2 # SSL_TLSEXT_ERR_ALERT_FATAL + + self.callback = _ffi.callback( + "int (*)(SSL *, const unsigned char **, unsigned int *, void *)", + wrapper + ) + + +class _NpnSelectHelper(_CallbackExceptionHelper): + """ + Wrap a callback such that it can be used as an NPN selection callback. + """ + + def __init__(self, callback): + _CallbackExceptionHelper.__init__(self) + + @wraps(callback) + def wrapper(ssl, out, outlen, in_, inlen, arg): + try: + conn = Connection._reverse_mapping[ssl] + + # The string passed to us is actually made up of multiple + # length-prefixed bytestrings. We need to split that into a + # list. + instr = _ffi.buffer(in_, inlen)[:] + protolist = [] + while instr: + l = indexbytes(instr, 0) + proto = instr[1:l + 1] + protolist.append(proto) + instr = instr[l + 1:] + + # Call the callback + outstr = callback(conn, protolist) + + # Save our callback arguments on the connection object. This is + # done to make sure that they don't get freed before OpenSSL + # uses them. Then, return them appropriately in the output + # parameters. + conn._npn_select_callback_args = [ + _ffi.new("unsigned char *", len(outstr)), + _ffi.new("unsigned char[]", outstr), + ] + outlen[0] = conn._npn_select_callback_args[0][0] + out[0] = conn._npn_select_callback_args[1] + return 0 + except Exception as e: + self._problems.append(e) + return 2 # SSL_TLSEXT_ERR_ALERT_FATAL + + self.callback = _ffi.callback( + ("int (*)(SSL *, unsigned char **, unsigned char *, " + "const unsigned char *, unsigned int, void *)"), + wrapper + ) + + +class _ALPNSelectHelper(_CallbackExceptionHelper): + """ + Wrap a callback such that it can be used as an ALPN selection callback. + """ + + def __init__(self, callback): + _CallbackExceptionHelper.__init__(self) + + @wraps(callback) + def wrapper(ssl, out, outlen, in_, inlen, arg): + try: + conn = Connection._reverse_mapping[ssl] + + # The string passed to us is made up of multiple + # length-prefixed bytestrings. We need to split that into a + # list. + instr = _ffi.buffer(in_, inlen)[:] + protolist = [] + while instr: + encoded_len = indexbytes(instr, 0) + proto = instr[1:encoded_len + 1] + protolist.append(proto) + instr = instr[encoded_len + 1:] + + # Call the callback + outstr = callback(conn, protolist) + + if not isinstance(outstr, _binary_type): + raise TypeError("ALPN callback must return a bytestring.") + + # Save our callback arguments on the connection object to make + # sure that they don't get freed before OpenSSL can use them. + # Then, return them in the appropriate output parameters. + conn._alpn_select_callback_args = [ + _ffi.new("unsigned char *", len(outstr)), + _ffi.new("unsigned char[]", outstr), + ] + outlen[0] = conn._alpn_select_callback_args[0][0] + out[0] = conn._alpn_select_callback_args[1] + return 0 + except Exception as e: + self._problems.append(e) + return 2 # SSL_TLSEXT_ERR_ALERT_FATAL + + self.callback = _ffi.callback( + ("int (*)(SSL *, unsigned char **, unsigned char *, " + "const unsigned char *, unsigned int, void *)"), + wrapper + ) + + +class _OCSPServerCallbackHelper(_CallbackExceptionHelper): + """ + Wrap a callback such that it can be used as an OCSP callback for the server + side. + + Annoyingly, OpenSSL defines one OCSP callback but uses it in two different + ways. For servers, that callback is expected to retrieve some OCSP data and + hand it to OpenSSL, and may return only SSL_TLSEXT_ERR_OK, + SSL_TLSEXT_ERR_FATAL, and SSL_TLSEXT_ERR_NOACK. For clients, that callback + is expected to check the OCSP data, and returns a negative value on error, + 0 if the response is not acceptable, or positive if it is. These are + mutually exclusive return code behaviours, and they mean that we need two + helpers so that we always return an appropriate error code if the user's + code throws an exception. + + Given that we have to have two helpers anyway, these helpers are a bit more + helpery than most: specifically, they hide a few more of the OpenSSL + functions so that the user has an easier time writing these callbacks. + + This helper implements the server side. + """ + + def __init__(self, callback): + _CallbackExceptionHelper.__init__(self) + + @wraps(callback) + def wrapper(ssl, cdata): + try: + conn = Connection._reverse_mapping[ssl] + + # Extract the data if any was provided. + if cdata != _ffi.NULL: + data = _ffi.from_handle(cdata) + else: + data = None + + # Call the callback. + ocsp_data = callback(conn, data) + + if not isinstance(ocsp_data, _binary_type): + raise TypeError("OCSP callback must return a bytestring.") + + # If the OCSP data was provided, we will pass it to OpenSSL. + # However, we have an early exit here: if no OCSP data was + # provided we will just exit out and tell OpenSSL that there + # is nothing to do. + if not ocsp_data: + return 3 # SSL_TLSEXT_ERR_NOACK + + # Pass the data to OpenSSL. Insanely, OpenSSL doesn't make a + # private copy of this data, so we need to keep it alive, but + # it *does* want to free it itself if it gets replaced. This + # somewhat bonkers behaviour means we need to use + # OPENSSL_malloc directly, which is a pain in the butt to work + # with. It's ok for us to "leak" the memory here because + # OpenSSL now owns it and will free it. + ocsp_data_length = len(ocsp_data) + data_ptr = _lib.OPENSSL_malloc(ocsp_data_length) + _ffi.buffer(data_ptr, ocsp_data_length)[:] = ocsp_data + + _lib.SSL_set_tlsext_status_ocsp_resp( + ssl, data_ptr, ocsp_data_length + ) + + return 0 + except Exception as e: + self._problems.append(e) + return 2 # SSL_TLSEXT_ERR_ALERT_FATAL + + self.callback = _ffi.callback("int (*)(SSL *, void *)", wrapper) + + +class _OCSPClientCallbackHelper(_CallbackExceptionHelper): + """ + Wrap a callback such that it can be used as an OCSP callback for the client + side. + + Annoyingly, OpenSSL defines one OCSP callback but uses it in two different + ways. For servers, that callback is expected to retrieve some OCSP data and + hand it to OpenSSL, and may return only SSL_TLSEXT_ERR_OK, + SSL_TLSEXT_ERR_FATAL, and SSL_TLSEXT_ERR_NOACK. For clients, that callback + is expected to check the OCSP data, and returns a negative value on error, + 0 if the response is not acceptable, or positive if it is. These are + mutually exclusive return code behaviours, and they mean that we need two + helpers so that we always return an appropriate error code if the user's + code throws an exception. + + Given that we have to have two helpers anyway, these helpers are a bit more + helpery than most: specifically, they hide a few more of the OpenSSL + functions so that the user has an easier time writing these callbacks. + + This helper implements the client side. + """ + + def __init__(self, callback): + _CallbackExceptionHelper.__init__(self) + + @wraps(callback) + def wrapper(ssl, cdata): + try: + conn = Connection._reverse_mapping[ssl] + + # Extract the data if any was provided. + if cdata != _ffi.NULL: + data = _ffi.from_handle(cdata) + else: + data = None + + # Get the OCSP data. + ocsp_ptr = _ffi.new("unsigned char **") + ocsp_len = _lib.SSL_get_tlsext_status_ocsp_resp(ssl, ocsp_ptr) + if ocsp_len < 0: + # No OCSP data. + ocsp_data = b'' + else: + # Copy the OCSP data, then pass it to the callback. + ocsp_data = _ffi.buffer(ocsp_ptr[0], ocsp_len)[:] + + valid = callback(conn, ocsp_data, data) + + # Return 1 on success or 0 on error. + return int(bool(valid)) + + except Exception as e: + self._problems.append(e) + # Return negative value if an exception is hit. + return -1 + + self.callback = _ffi.callback("int (*)(SSL *, void *)", wrapper) + + +def _asFileDescriptor(obj): + fd = None + if not isinstance(obj, integer_types): + meth = getattr(obj, "fileno", None) + if meth is not None: + obj = meth() + + if isinstance(obj, integer_types): + fd = obj + + if not isinstance(fd, integer_types): + raise TypeError("argument must be an int, or have a fileno() method.") + elif fd < 0: + raise ValueError( + "file descriptor cannot be a negative integer (%i)" % (fd,)) + + return fd + + +def SSLeay_version(type): + """ + Return a string describing the version of OpenSSL in use. + + :param type: One of the SSLEAY_ constants defined in this module. + """ + return _ffi.string(_lib.SSLeay_version(type)) + + +def _make_requires(flag, error): + """ + Builds a decorator that ensures that functions that rely on OpenSSL + functions that are not present in this build raise NotImplementedError, + rather than AttributeError coming out of cryptography. + + :param flag: A cryptography flag that guards the functions, e.g. + ``Cryptography_HAS_NEXTPROTONEG``. + :param error: The string to be used in the exception if the flag is false. + """ + def _requires_decorator(func): + if not flag: + @wraps(func) + def explode(*args, **kwargs): + raise NotImplementedError(error) + return explode + else: + return func + + return _requires_decorator + + +_requires_npn = _make_requires( + _lib.Cryptography_HAS_NEXTPROTONEG, "NPN not available" +) + + +_requires_alpn = _make_requires( + _lib.Cryptography_HAS_ALPN, "ALPN not available" +) + + +_requires_sni = _make_requires( + _lib.Cryptography_HAS_TLSEXT_HOSTNAME, "SNI not available" +) + + +class Session(object): + pass + + +class Context(object): + """ + :class:`OpenSSL.SSL.Context` instances define the parameters for setting + up new SSL connections. + """ + _methods = { + SSLv2_METHOD: "SSLv2_method", + SSLv3_METHOD: "SSLv3_method", + SSLv23_METHOD: "SSLv23_method", + TLSv1_METHOD: "TLSv1_method", + TLSv1_1_METHOD: "TLSv1_1_method", + TLSv1_2_METHOD: "TLSv1_2_method", + } + _methods = dict( + (identifier, getattr(_lib, name)) + for (identifier, name) in _methods.items() + if getattr(_lib, name, None) is not None) + + def __init__(self, method): + """ + :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or + TLSv1_METHOD. + """ + if not isinstance(method, integer_types): + raise TypeError("method must be an integer") + + try: + method_func = self._methods[method] + except KeyError: + raise ValueError("No such protocol") + + method_obj = method_func() + _openssl_assert(method_obj != _ffi.NULL) + + context = _lib.SSL_CTX_new(method_obj) + _openssl_assert(context != _ffi.NULL) + context = _ffi.gc(context, _lib.SSL_CTX_free) + + # If SSL_CTX_set_ecdh_auto is available then set it so the ECDH curve + # will be auto-selected. This function was added in 1.0.2 and made a + # noop in 1.1.0+ (where it is set automatically). + try: + res = _lib.SSL_CTX_set_ecdh_auto(context, 1) + _openssl_assert(res == 1) + except AttributeError: + pass + + self._context = context + self._passphrase_helper = None + self._passphrase_callback = None + self._passphrase_userdata = None + self._verify_helper = None + self._verify_callback = None + self._info_callback = None + self._tlsext_servername_callback = None + self._app_data = None + self._npn_advertise_helper = None + self._npn_advertise_callback = None + self._npn_select_helper = None + self._npn_select_callback = None + self._alpn_select_helper = None + self._alpn_select_callback = None + self._ocsp_helper = None + self._ocsp_callback = None + self._ocsp_data = None + + self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE) + + def load_verify_locations(self, cafile, capath=None): + """ + Let SSL know where we can find trusted certificates for the certificate + chain + + :param cafile: In which file we can find the certificates (``bytes`` or + ``unicode``). + :param capath: In which directory we can find the certificates + (``bytes`` or ``unicode``). + + :return: None + """ + if cafile is None: + cafile = _ffi.NULL + else: + cafile = _path_string(cafile) + + if capath is None: + capath = _ffi.NULL + else: + capath = _path_string(capath) + + load_result = _lib.SSL_CTX_load_verify_locations( + self._context, cafile, capath + ) + if not load_result: + _raise_current_error() + + def _wrap_callback(self, callback): + @wraps(callback) + def wrapper(size, verify, userdata): + return callback(size, verify, self._passphrase_userdata) + return _PassphraseHelper( + FILETYPE_PEM, wrapper, more_args=True, truncate=True) + + def set_passwd_cb(self, callback, userdata=None): + """ + Set the passphrase callback + + :param callback: The Python callback to use + :param userdata: (optional) A Python object which will be given as + argument to the callback + :return: None + """ + if not callable(callback): + raise TypeError("callback must be callable") + + self._passphrase_helper = self._wrap_callback(callback) + self._passphrase_callback = self._passphrase_helper.callback + _lib.SSL_CTX_set_default_passwd_cb( + self._context, self._passphrase_callback) + self._passphrase_userdata = userdata + + def set_default_verify_paths(self): + """ + Use the platform-specific CA certificate locations + + :return: None + """ + # SSL_CTX_set_default_verify_paths will attempt to load certs from + # both a cafile and capath that are set at compile time. However, + # it will first check environment variables and, if present, load + # those paths instead + set_result = _lib.SSL_CTX_set_default_verify_paths(self._context) + _openssl_assert(set_result == 1) + # After attempting to set default_verify_paths we need to know whether + # to go down the fallback path. + # First we'll check to see if any env vars have been set. If so, + # we won't try to do anything else because the user has set the path + # themselves. + dir_env_var = _ffi.string( + _lib.X509_get_default_cert_dir_env() + ).decode("ascii") + file_env_var = _ffi.string( + _lib.X509_get_default_cert_file_env() + ).decode("ascii") + if not self._check_env_vars_set(dir_env_var, file_env_var): + default_dir = _ffi.string(_lib.X509_get_default_cert_dir()) + default_file = _ffi.string(_lib.X509_get_default_cert_file()) + # Now we check to see if the default_dir and default_file are set + # to the exact values we use in our manylinux1 builds. If they are + # then we know to load the fallbacks + if ( + default_dir == _CRYPTOGRAPHY_MANYLINUX1_CA_DIR and + default_file == _CRYPTOGRAPHY_MANYLINUX1_CA_FILE + ): + # This is manylinux1, let's load our fallback paths + self._fallback_default_verify_paths( + _CERTIFICATE_FILE_LOCATIONS, + _CERTIFICATE_PATH_LOCATIONS + ) + + def _check_env_vars_set(self, dir_env_var, file_env_var): + """ + Check to see if the default cert dir/file environment vars are present. + + :return: bool + """ + return ( + os.environ.get(file_env_var) is not None or + os.environ.get(dir_env_var) is not None + ) + + def _fallback_default_verify_paths(self, file_path, dir_path): + """ + Default verify paths are based on the compiled version of OpenSSL. + However, when pyca/cryptography is compiled as a manylinux1 wheel + that compiled location can potentially be wrong. So, like Go, we + will try a predefined set of paths and attempt to load roots + from there. + + :return: None + """ + for cafile in file_path: + if os.path.isfile(cafile): + self.load_verify_locations(cafile) + break + + for capath in dir_path: + if os.path.isdir(capath): + self.load_verify_locations(None, capath) + break + + def use_certificate_chain_file(self, certfile): + """ + Load a certificate chain from a file + + :param certfile: The name of the certificate chain file (``bytes`` or + ``unicode``). + + :return: None + """ + certfile = _path_string(certfile) + + result = _lib.SSL_CTX_use_certificate_chain_file( + self._context, certfile + ) + if not result: + _raise_current_error() + + def use_certificate_file(self, certfile, filetype=FILETYPE_PEM): + """ + Load a certificate from a file + + :param certfile: The name of the certificate file (``bytes`` or + ``unicode``). + :param filetype: (optional) The encoding of the file, default is PEM + + :return: None + """ + certfile = _path_string(certfile) + if not isinstance(filetype, integer_types): + raise TypeError("filetype must be an integer") + + use_result = _lib.SSL_CTX_use_certificate_file( + self._context, certfile, filetype + ) + if not use_result: + _raise_current_error() + + def use_certificate(self, cert): + """ + Load a certificate from a X509 object + + :param cert: The X509 object + :return: None + """ + if not isinstance(cert, X509): + raise TypeError("cert must be an X509 instance") + + use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509) + if not use_result: + _raise_current_error() + + def add_extra_chain_cert(self, certobj): + """ + Add certificate to chain + + :param certobj: The X509 certificate object to add to the chain + :return: None + """ + if not isinstance(certobj, X509): + raise TypeError("certobj must be an X509 instance") + + copy = _lib.X509_dup(certobj._x509) + add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy) + if not add_result: + # TODO: This is untested. + _lib.X509_free(copy) + _raise_current_error() + + def _raise_passphrase_exception(self): + if self._passphrase_helper is not None: + self._passphrase_helper.raise_if_problem(Error) + + _raise_current_error() + + def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED): + """ + Load a private key from a file + + :param keyfile: The name of the key file (``bytes`` or ``unicode``) + :param filetype: (optional) The encoding of the file, default is PEM + + :return: None + """ + keyfile = _path_string(keyfile) + + if filetype is _UNSPECIFIED: + filetype = FILETYPE_PEM + elif not isinstance(filetype, integer_types): + raise TypeError("filetype must be an integer") + + use_result = _lib.SSL_CTX_use_PrivateKey_file( + self._context, keyfile, filetype) + if not use_result: + self._raise_passphrase_exception() + + def use_privatekey(self, pkey): + """ + Load a private key from a PKey object + + :param pkey: The PKey object + :return: None + """ + if not isinstance(pkey, PKey): + raise TypeError("pkey must be a PKey instance") + + use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey) + if not use_result: + self._raise_passphrase_exception() + + def check_privatekey(self): + """ + Check that the private key and certificate match up + + :return: None (raises an exception if something's wrong) + """ + if not _lib.SSL_CTX_check_private_key(self._context): + _raise_current_error() + + def load_client_ca(self, cafile): + """ + Load the trusted certificates that will be sent to the client. Does + not actually imply any of the certificates are trusted; that must be + configured separately. + + :param bytes cafile: The path to a certificates file in PEM format. + :return: None + """ + ca_list = _lib.SSL_load_client_CA_file( + _text_to_bytes_and_warn("cafile", cafile) + ) + _openssl_assert(ca_list != _ffi.NULL) + _lib.SSL_CTX_set_client_CA_list(self._context, ca_list) + + def set_session_id(self, buf): + """ + Set the session id to *buf* within which a session can be reused for + this Context object. This is needed when doing session resumption, + because there is no way for a stored session to know which Context + object it is associated with. + + :param bytes buf: The session id. + + :returns: None + """ + buf = _text_to_bytes_and_warn("buf", buf) + _openssl_assert( + _lib.SSL_CTX_set_session_id_context( + self._context, + buf, + len(buf), + ) == 1 + ) + + def set_session_cache_mode(self, mode): + """ + Enable/disable session caching and specify the mode used. + + :param mode: One or more of the SESS_CACHE_* flags (combine using + bitwise or) + :returns: The previously set caching mode. + """ + if not isinstance(mode, integer_types): + raise TypeError("mode must be an integer") + + return _lib.SSL_CTX_set_session_cache_mode(self._context, mode) + + def get_session_cache_mode(self): + """ + :returns: The currently used cache mode. + """ + return _lib.SSL_CTX_get_session_cache_mode(self._context) + + def set_verify(self, mode, callback): + """ + Set the verify mode and verify callback + + :param mode: The verify mode, this is either VERIFY_NONE or + VERIFY_PEER combined with possible other flags + :param callback: The Python callback to use + :return: None + + See SSL_CTX_set_verify(3SSL) for further details. + """ + if not isinstance(mode, integer_types): + raise TypeError("mode must be an integer") + + if not callable(callback): + raise TypeError("callback must be callable") + + self._verify_helper = _VerifyHelper(callback) + self._verify_callback = self._verify_helper.callback + _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback) + + def set_verify_depth(self, depth): + """ + Set the verify depth + + :param depth: An integer specifying the verify depth + :return: None + """ + if not isinstance(depth, integer_types): + raise TypeError("depth must be an integer") + + _lib.SSL_CTX_set_verify_depth(self._context, depth) + + def get_verify_mode(self): + """ + Get the verify mode + + :return: The verify mode + """ + return _lib.SSL_CTX_get_verify_mode(self._context) + + def get_verify_depth(self): + """ + Get the verify depth + + :return: The verify depth + """ + return _lib.SSL_CTX_get_verify_depth(self._context) + + def load_tmp_dh(self, dhfile): + """ + Load parameters for Ephemeral Diffie-Hellman + + :param dhfile: The file to load EDH parameters from (``bytes`` or + ``unicode``). + + :return: None + """ + dhfile = _path_string(dhfile) + + bio = _lib.BIO_new_file(dhfile, b"r") + if bio == _ffi.NULL: + _raise_current_error() + bio = _ffi.gc(bio, _lib.BIO_free) + + dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL) + dh = _ffi.gc(dh, _lib.DH_free) + _lib.SSL_CTX_set_tmp_dh(self._context, dh) + + def set_tmp_ecdh(self, curve): + """ + Select a curve to use for ECDHE key exchange. + + :param curve: A curve object to use as returned by either + :py:meth:`OpenSSL.crypto.get_elliptic_curve` or + :py:meth:`OpenSSL.crypto.get_elliptic_curves`. + + :return: None + """ + _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY()) + + def set_cipher_list(self, cipher_list): + """ + Set the list of ciphers to be used in this context. + + See the OpenSSL manual for more information (e.g. + :manpage:`ciphers(1)`). + + :param bytes cipher_list: An OpenSSL cipher string. + :return: None + """ + cipher_list = _text_to_bytes_and_warn("cipher_list", cipher_list) + + if not isinstance(cipher_list, bytes): + raise TypeError("cipher_list must be a byte string.") + + _openssl_assert( + _lib.SSL_CTX_set_cipher_list(self._context, cipher_list) == 1 + ) + + def set_client_ca_list(self, certificate_authorities): + """ + Set the list of preferred client certificate signers for this server + context. + + This list of certificate authorities will be sent to the client when + the server requests a client certificate. + + :param certificate_authorities: a sequence of X509Names. + :return: None + """ + name_stack = _lib.sk_X509_NAME_new_null() + _openssl_assert(name_stack != _ffi.NULL) + + try: + for ca_name in certificate_authorities: + if not isinstance(ca_name, X509Name): + raise TypeError( + "client CAs must be X509Name objects, not %s " + "objects" % ( + type(ca_name).__name__, + ) + ) + copy = _lib.X509_NAME_dup(ca_name._name) + _openssl_assert(copy != _ffi.NULL) + push_result = _lib.sk_X509_NAME_push(name_stack, copy) + if not push_result: + _lib.X509_NAME_free(copy) + _raise_current_error() + except: + _lib.sk_X509_NAME_free(name_stack) + raise + + _lib.SSL_CTX_set_client_CA_list(self._context, name_stack) + + def add_client_ca(self, certificate_authority): + """ + Add the CA certificate to the list of preferred signers for this + context. + + The list of certificate authorities will be sent to the client when the + server requests a client certificate. + + :param certificate_authority: certificate authority's X509 certificate. + :return: None + """ + if not isinstance(certificate_authority, X509): + raise TypeError("certificate_authority must be an X509 instance") + + add_result = _lib.SSL_CTX_add_client_CA( + self._context, certificate_authority._x509) + _openssl_assert(add_result == 1) + + def set_timeout(self, timeout): + """ + Set session timeout + + :param timeout: The timeout in seconds + :return: The previous session timeout + """ + if not isinstance(timeout, integer_types): + raise TypeError("timeout must be an integer") + + return _lib.SSL_CTX_set_timeout(self._context, timeout) + + def get_timeout(self): + """ + Get the session timeout + + :return: The session timeout + """ + return _lib.SSL_CTX_get_timeout(self._context) + + def set_info_callback(self, callback): + """ + Set the info callback + + :param callback: The Python callback to use + :return: None + """ + @wraps(callback) + def wrapper(ssl, where, return_code): + callback(Connection._reverse_mapping[ssl], where, return_code) + self._info_callback = _ffi.callback( + "void (*)(const SSL *, int, int)", wrapper) + _lib.SSL_CTX_set_info_callback(self._context, self._info_callback) + + def get_app_data(self): + """ + Get the application data (supplied via set_app_data()) + + :return: The application data + """ + return self._app_data + + def set_app_data(self, data): + """ + Set the application data (will be returned from get_app_data()) + + :param data: Any Python object + :return: None + """ + self._app_data = data + + def get_cert_store(self): + """ + Get the certificate store for the context. + + :return: A X509Store object or None if it does not have one. + """ + store = _lib.SSL_CTX_get_cert_store(self._context) + if store == _ffi.NULL: + # TODO: This is untested. + return None + + pystore = X509Store.__new__(X509Store) + pystore._store = store + return pystore + + def set_options(self, options): + """ + Add options. Options set before are not cleared! + + :param options: The options to add. + :return: The new option bitmask. + """ + if not isinstance(options, integer_types): + raise TypeError("options must be an integer") + + return _lib.SSL_CTX_set_options(self._context, options) + + def set_mode(self, mode): + """ + Add modes via bitmask. Modes set before are not cleared! + + :param mode: The mode to add. + :return: The new mode bitmask. + """ + if not isinstance(mode, integer_types): + raise TypeError("mode must be an integer") + + return _lib.SSL_CTX_set_mode(self._context, mode) + + @_requires_sni + def set_tlsext_servername_callback(self, callback): + """ + Specify a callback function to be called when clients specify a server + name. + + :param callback: The callback function. It will be invoked with one + argument, the Connection instance. + """ + @wraps(callback) + def wrapper(ssl, alert, arg): + callback(Connection._reverse_mapping[ssl]) + return 0 + + self._tlsext_servername_callback = _ffi.callback( + "int (*)(const SSL *, int *, void *)", wrapper) + _lib.SSL_CTX_set_tlsext_servername_callback( + self._context, self._tlsext_servername_callback) + + @_requires_npn + def set_npn_advertise_callback(self, callback): + """ + Specify a callback function that will be called when offering `Next + Protocol Negotiation + `_ as a server. + + :param callback: The callback function. It will be invoked with one + argument, the Connection instance. It should return a list of + bytestrings representing the advertised protocols, like + ``[b'http/1.1', b'spdy/2']``. + """ + self._npn_advertise_helper = _NpnAdvertiseHelper(callback) + self._npn_advertise_callback = self._npn_advertise_helper.callback + _lib.SSL_CTX_set_next_protos_advertised_cb( + self._context, self._npn_advertise_callback, _ffi.NULL) + + @_requires_npn + def set_npn_select_callback(self, callback): + """ + Specify a callback function that will be called when a server offers + Next Protocol Negotiation options. + + :param callback: The callback function. It will be invoked with two + arguments: the Connection, and a list of offered protocols as + bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return + one of those bytestrings, the chosen protocol. + """ + self._npn_select_helper = _NpnSelectHelper(callback) + self._npn_select_callback = self._npn_select_helper.callback + _lib.SSL_CTX_set_next_proto_select_cb( + self._context, self._npn_select_callback, _ffi.NULL) + + @_requires_alpn + def set_alpn_protos(self, protos): + """ + Specify the clients ALPN protocol list. + + These protocols are offered to the server during protocol negotiation. + + :param protos: A list of the protocols to be offered to the server. + This list should be a Python list of bytestrings representing the + protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``. + """ + # Take the list of protocols and join them together, prefixing them + # with their lengths. + protostr = b''.join( + chain.from_iterable((int2byte(len(p)), p) for p in protos) + ) + + # Build a C string from the list. We don't need to save this off + # because OpenSSL immediately copies the data out. + input_str = _ffi.new("unsigned char[]", protostr) + _lib.SSL_CTX_set_alpn_protos(self._context, input_str, len(protostr)) + + @_requires_alpn + def set_alpn_select_callback(self, callback): + """ + Set the callback to handle ALPN protocol choice. + + :param callback: The callback function. It will be invoked with two + arguments: the Connection, and a list of offered protocols as + bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return + one of those bytestrings, the chosen protocol. + """ + self._alpn_select_helper = _ALPNSelectHelper(callback) + self._alpn_select_callback = self._alpn_select_helper.callback + _lib.SSL_CTX_set_alpn_select_cb( + self._context, self._alpn_select_callback, _ffi.NULL) + + def _set_ocsp_callback(self, helper, data): + """ + This internal helper does the common work for + ``set_ocsp_server_callback`` and ``set_ocsp_client_callback``, which is + almost all of it. + """ + self._ocsp_helper = helper + self._ocsp_callback = helper.callback + if data is None: + self._ocsp_data = _ffi.NULL + else: + self._ocsp_data = _ffi.new_handle(data) + + rc = _lib.SSL_CTX_set_tlsext_status_cb( + self._context, self._ocsp_callback + ) + _openssl_assert(rc == 1) + rc = _lib.SSL_CTX_set_tlsext_status_arg(self._context, self._ocsp_data) + _openssl_assert(rc == 1) + + def set_ocsp_server_callback(self, callback, data=None): + """ + Set a callback to provide OCSP data to be stapled to the TLS handshake + on the server side. + + :param callback: The callback function. It will be invoked with two + arguments: the Connection, and the optional arbitrary data you have + provided. The callback must return a bytestring that contains the + OCSP data to staple to the handshake. If no OCSP data is available + for this connection, return the empty bytestring. + :param data: Some opaque data that will be passed into the callback + function when called. This can be used to avoid needing to do + complex data lookups or to keep track of what context is being + used. This parameter is optional. + """ + helper = _OCSPServerCallbackHelper(callback) + self._set_ocsp_callback(helper, data) + + def set_ocsp_client_callback(self, callback, data=None): + """ + Set a callback to validate OCSP data stapled to the TLS handshake on + the client side. + + :param callback: The callback function. It will be invoked with three + arguments: the Connection, a bytestring containing the stapled OCSP + assertion, and the optional arbitrary data you have provided. The + callback must return a boolean that indicates the result of + validating the OCSP data: ``True`` if the OCSP data is valid and + the certificate can be trusted, or ``False`` if either the OCSP + data is invalid or the certificate has been revoked. + :param data: Some opaque data that will be passed into the callback + function when called. This can be used to avoid needing to do + complex data lookups or to keep track of what context is being + used. This parameter is optional. + """ + helper = _OCSPClientCallbackHelper(callback) + self._set_ocsp_callback(helper, data) + + +ContextType = deprecated( + Context, __name__, + "ContextType has been deprecated, use Context instead", DeprecationWarning +) + + +class Connection(object): + """ + """ + _reverse_mapping = WeakValueDictionary() + + def __init__(self, context, socket=None): + """ + Create a new Connection object, using the given OpenSSL.SSL.Context + instance and socket. + + :param context: An SSL Context to use for this connection + :param socket: The socket to use for transport layer + """ + if not isinstance(context, Context): + raise TypeError("context must be a Context instance") + + ssl = _lib.SSL_new(context._context) + self._ssl = _ffi.gc(ssl, _lib.SSL_free) + self._context = context + self._app_data = None + + # References to strings used for Next Protocol Negotiation. OpenSSL's + # header files suggest that these might get copied at some point, but + # doesn't specify when, so we store them here to make sure they don't + # get freed before OpenSSL uses them. + self._npn_advertise_callback_args = None + self._npn_select_callback_args = None + + # References to strings used for Application Layer Protocol + # Negotiation. These strings get copied at some point but it's well + # after the callback returns, so we have to hang them somewhere to + # avoid them getting freed. + self._alpn_select_callback_args = None + + self._reverse_mapping[self._ssl] = self + + if socket is None: + self._socket = None + # Don't set up any gc for these, SSL_free will take care of them. + self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem()) + _openssl_assert(self._into_ssl != _ffi.NULL) + + self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem()) + _openssl_assert(self._from_ssl != _ffi.NULL) + + _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl) + else: + self._into_ssl = None + self._from_ssl = None + self._socket = socket + set_result = _lib.SSL_set_fd( + self._ssl, _asFileDescriptor(self._socket)) + _openssl_assert(set_result == 1) + + def __getattr__(self, name): + """ + Look up attributes on the wrapped socket object if they are not found + on the Connection object. + """ + if self._socket is None: + raise AttributeError("'%s' object has no attribute '%s'" % ( + self.__class__.__name__, name + )) + else: + return getattr(self._socket, name) + + def _raise_ssl_error(self, ssl, result): + if self._context._verify_helper is not None: + self._context._verify_helper.raise_if_problem() + if self._context._npn_advertise_helper is not None: + self._context._npn_advertise_helper.raise_if_problem() + if self._context._npn_select_helper is not None: + self._context._npn_select_helper.raise_if_problem() + if self._context._alpn_select_helper is not None: + self._context._alpn_select_helper.raise_if_problem() + if self._context._ocsp_helper is not None: + self._context._ocsp_helper.raise_if_problem() + + error = _lib.SSL_get_error(ssl, result) + if error == _lib.SSL_ERROR_WANT_READ: + raise WantReadError() + elif error == _lib.SSL_ERROR_WANT_WRITE: + raise WantWriteError() + elif error == _lib.SSL_ERROR_ZERO_RETURN: + raise ZeroReturnError() + elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP: + # TODO: This is untested. + raise WantX509LookupError() + elif error == _lib.SSL_ERROR_SYSCALL: + if _lib.ERR_peek_error() == 0: + if result < 0: + if platform == "win32": + errno = _ffi.getwinerror()[0] + else: + errno = _ffi.errno + + if errno != 0: + raise SysCallError(errno, errorcode.get(errno)) + raise SysCallError(-1, "Unexpected EOF") + else: + # TODO: This is untested. + _raise_current_error() + elif error == _lib.SSL_ERROR_NONE: + pass + else: + _raise_current_error() + + def get_context(self): + """ + Get session context + """ + return self._context + + def set_context(self, context): + """ + Switch this connection to a new session context + + :param context: A :py:class:`Context` instance giving the new session + context to use. + """ + if not isinstance(context, Context): + raise TypeError("context must be a Context instance") + + _lib.SSL_set_SSL_CTX(self._ssl, context._context) + self._context = context + + @_requires_sni + def get_servername(self): + """ + Retrieve the servername extension value if provided in the client hello + message, or None if there wasn't one. + + :return: A byte string giving the server name or :py:data:`None`. + """ + name = _lib.SSL_get_servername( + self._ssl, _lib.TLSEXT_NAMETYPE_host_name + ) + if name == _ffi.NULL: + return None + + return _ffi.string(name) + + @_requires_sni + def set_tlsext_host_name(self, name): + """ + Set the value of the servername extension to send in the client hello. + + :param name: A byte string giving the name. + """ + if not isinstance(name, bytes): + raise TypeError("name must be a byte string") + elif b"\0" in name: + raise TypeError("name must not contain NUL byte") + + # XXX I guess this can fail sometimes? + _lib.SSL_set_tlsext_host_name(self._ssl, name) + + def pending(self): + """ + Get the number of bytes that can be safely read from the connection + + :return: The number of bytes available in the receive buffer. + """ + return _lib.SSL_pending(self._ssl) + + def send(self, buf, flags=0): + """ + Send data on the connection. NOTE: If you get one of the WantRead, + WantWrite or WantX509Lookup exceptions on this, you have to call the + method again with the SAME buffer. + + :param buf: The string, buffer or memoryview to send + :param flags: (optional) Included for compatibility with the socket + API, the value is ignored + :return: The number of bytes written + """ + # Backward compatibility + buf = _text_to_bytes_and_warn("buf", buf) + + if isinstance(buf, _memoryview): + buf = buf.tobytes() + if isinstance(buf, _buffer): + buf = str(buf) + if not isinstance(buf, bytes): + raise TypeError("data must be a memoryview, buffer or byte string") + if len(buf) > 2147483647: + raise ValueError("Cannot send more than 2**31-1 bytes at once.") + + result = _lib.SSL_write(self._ssl, buf, len(buf)) + self._raise_ssl_error(self._ssl, result) + return result + write = send + + def sendall(self, buf, flags=0): + """ + Send "all" data on the connection. This calls send() repeatedly until + all data is sent. If an error occurs, it's impossible to tell how much + data has been sent. + + :param buf: The string, buffer or memoryview to send + :param flags: (optional) Included for compatibility with the socket + API, the value is ignored + :return: The number of bytes written + """ + buf = _text_to_bytes_and_warn("buf", buf) + + if isinstance(buf, _memoryview): + buf = buf.tobytes() + if isinstance(buf, _buffer): + buf = str(buf) + if not isinstance(buf, bytes): + raise TypeError("buf must be a memoryview, buffer or byte string") + + left_to_send = len(buf) + total_sent = 0 + data = _ffi.new("char[]", buf) + + while left_to_send: + # SSL_write's num arg is an int, + # so we cannot send more than 2**31-1 bytes at once. + result = _lib.SSL_write( + self._ssl, + data + total_sent, + min(left_to_send, 2147483647) + ) + self._raise_ssl_error(self._ssl, result) + total_sent += result + left_to_send -= result + + def recv(self, bufsiz, flags=None): + """ + Receive data on the connection. + + :param bufsiz: The maximum number of bytes to read + :param flags: (optional) The only supported flag is ``MSG_PEEK``, + all other flags are ignored. + :return: The string read from the Connection + """ + buf = _no_zero_allocator("char[]", bufsiz) + if flags is not None and flags & socket.MSG_PEEK: + result = _lib.SSL_peek(self._ssl, buf, bufsiz) + else: + result = _lib.SSL_read(self._ssl, buf, bufsiz) + self._raise_ssl_error(self._ssl, result) + return _ffi.buffer(buf, result)[:] + read = recv + + def recv_into(self, buffer, nbytes=None, flags=None): + """ + Receive data on the connection and store the data into a buffer rather + than creating a new string. + + :param buffer: The buffer to copy into. + :param nbytes: (optional) The maximum number of bytes to read into the + buffer. If not present, defaults to the size of the buffer. If + larger than the size of the buffer, is reduced to the size of the + buffer. + :param flags: (optional) The only supported flag is ``MSG_PEEK``, + all other flags are ignored. + :return: The number of bytes read into the buffer. + """ + if nbytes is None: + nbytes = len(buffer) + else: + nbytes = min(nbytes, len(buffer)) + + # We need to create a temporary buffer. This is annoying, it would be + # better if we could pass memoryviews straight into the SSL_read call, + # but right now we can't. Revisit this if CFFI gets that ability. + buf = _no_zero_allocator("char[]", nbytes) + if flags is not None and flags & socket.MSG_PEEK: + result = _lib.SSL_peek(self._ssl, buf, nbytes) + else: + result = _lib.SSL_read(self._ssl, buf, nbytes) + self._raise_ssl_error(self._ssl, result) + + # This strange line is all to avoid a memory copy. The buffer protocol + # should allow us to assign a CFFI buffer to the LHS of this line, but + # on CPython 3.3+ that segfaults. As a workaround, we can temporarily + # wrap it in a memoryview, except on Python 2.6 which doesn't have a + # memoryview type. + try: + buffer[:result] = memoryview(_ffi.buffer(buf, result)) + except NameError: + buffer[:result] = _ffi.buffer(buf, result) + + return result + + def _handle_bio_errors(self, bio, result): + if _lib.BIO_should_retry(bio): + if _lib.BIO_should_read(bio): + raise WantReadError() + elif _lib.BIO_should_write(bio): + # TODO: This is untested. + raise WantWriteError() + elif _lib.BIO_should_io_special(bio): + # TODO: This is untested. I think io_special means the socket + # BIO has a not-yet connected socket. + raise ValueError("BIO_should_io_special") + else: + # TODO: This is untested. + raise ValueError("unknown bio failure") + else: + # TODO: This is untested. + _raise_current_error() + + def bio_read(self, bufsiz): + """ + When using non-socket connections this function reads the "dirty" data + that would have traveled away on the network. + + :param bufsiz: The maximum number of bytes to read + :return: The string read. + """ + if self._from_ssl is None: + raise TypeError("Connection sock was not None") + + if not isinstance(bufsiz, integer_types): + raise TypeError("bufsiz must be an integer") + + buf = _no_zero_allocator("char[]", bufsiz) + result = _lib.BIO_read(self._from_ssl, buf, bufsiz) + if result <= 0: + self._handle_bio_errors(self._from_ssl, result) + + return _ffi.buffer(buf, result)[:] + + def bio_write(self, buf): + """ + When using non-socket connections this function sends "dirty" data that + would have traveled in on the network. + + :param buf: The string to put into the memory BIO. + :return: The number of bytes written + """ + buf = _text_to_bytes_and_warn("buf", buf) + + if self._into_ssl is None: + raise TypeError("Connection sock was not None") + + result = _lib.BIO_write(self._into_ssl, buf, len(buf)) + if result <= 0: + self._handle_bio_errors(self._into_ssl, result) + return result + + def renegotiate(self): + """ + Renegotiate the session. + + :return: True if the renegotiation can be started, False otherwise + :rtype: bool + """ + if not self.renegotiate_pending(): + _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1) + return True + return False + + def do_handshake(self): + """ + Perform an SSL handshake (usually called after renegotiate() or one of + set_*_state()). This can raise the same exceptions as send and recv. + + :return: None. + """ + result = _lib.SSL_do_handshake(self._ssl) + self._raise_ssl_error(self._ssl, result) + + def renegotiate_pending(self): + """ + Check if there's a renegotiation in progress, it will return False once + a renegotiation is finished. + + :return: Whether there's a renegotiation in progress + :rtype: bool + """ + return _lib.SSL_renegotiate_pending(self._ssl) == 1 + + def total_renegotiations(self): + """ + Find out the total number of renegotiations. + + :return: The number of renegotiations. + :rtype: int + """ + return _lib.SSL_total_renegotiations(self._ssl) + + def connect(self, addr): + """ + Connect to remote host and set up client-side SSL + + :param addr: A remote address + :return: What the socket's connect method returns + """ + _lib.SSL_set_connect_state(self._ssl) + return self._socket.connect(addr) + + def connect_ex(self, addr): + """ + Connect to remote host and set up client-side SSL. Note that if the + socket's connect_ex method doesn't return 0, SSL won't be initialized. + + :param addr: A remove address + :return: What the socket's connect_ex method returns + """ + connect_ex = self._socket.connect_ex + self.set_connect_state() + return connect_ex(addr) + + def accept(self): + """ + Accept incoming connection and set up SSL on it + + :return: A (conn,addr) pair where conn is a Connection and addr is an + address + """ + client, addr = self._socket.accept() + conn = Connection(self._context, client) + conn.set_accept_state() + return (conn, addr) + + def bio_shutdown(self): + """ + When using non-socket connections this function signals end of + data on the input for this connection. + + :return: None + """ + if self._from_ssl is None: + raise TypeError("Connection sock was not None") + + _lib.BIO_set_mem_eof_return(self._into_ssl, 0) + + def shutdown(self): + """ + Send closure alert + + :return: True if the shutdown completed successfully (i.e. both sides + have sent closure alerts), false otherwise (i.e. you have to + wait for a ZeroReturnError on a recv() method call + """ + result = _lib.SSL_shutdown(self._ssl) + if result < 0: + self._raise_ssl_error(self._ssl, result) + elif result > 0: + return True + else: + return False + + def get_cipher_list(self): + """ + Retrieve the list of ciphers used by the Connection object. + + :return: A list of native cipher strings. + """ + ciphers = [] + for i in count(): + result = _lib.SSL_get_cipher_list(self._ssl, i) + if result == _ffi.NULL: + break + ciphers.append(_native(_ffi.string(result))) + return ciphers + + def get_client_ca_list(self): + """ + Get CAs whose certificates are suggested for client authentication. + + :return: If this is a server connection, a list of X509Names + representing the acceptable CAs as set by + :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or + :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client + connection, the list of such X509Names sent by the server, or an + empty list if that has not yet happened. + """ + ca_names = _lib.SSL_get_client_CA_list(self._ssl) + if ca_names == _ffi.NULL: + # TODO: This is untested. + return [] + + result = [] + for i in range(_lib.sk_X509_NAME_num(ca_names)): + name = _lib.sk_X509_NAME_value(ca_names, i) + copy = _lib.X509_NAME_dup(name) + _openssl_assert(copy != _ffi.NULL) + + pyname = X509Name.__new__(X509Name) + pyname._name = _ffi.gc(copy, _lib.X509_NAME_free) + result.append(pyname) + return result + + def makefile(self): + """ + The makefile() method is not implemented, since there is no dup + semantics for SSL connections + + :raise: NotImplementedError + """ + raise NotImplementedError( + "Cannot make file object of OpenSSL.SSL.Connection") + + def get_app_data(self): + """ + Get application data + + :return: The application data + """ + return self._app_data + + def set_app_data(self, data): + """ + Set application data + + :param data - The application data + :return: None + """ + self._app_data = data + + def get_shutdown(self): + """ + Get shutdown state + + :return: The shutdown state, a bitvector of SENT_SHUTDOWN, + RECEIVED_SHUTDOWN. + """ + return _lib.SSL_get_shutdown(self._ssl) + + def set_shutdown(self, state): + """ + Set shutdown state + + :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN. + :return: None + """ + if not isinstance(state, integer_types): + raise TypeError("state must be an integer") + + _lib.SSL_set_shutdown(self._ssl, state) + + def get_state_string(self): + """ + Retrieve a verbose string detailing the state of the Connection. + + :return: A string representing the state + :rtype: bytes + """ + return _ffi.string(_lib.SSL_state_string_long(self._ssl)) + + def server_random(self): + """ + Get a copy of the server hello nonce. + + :return: A string representing the state + """ + session = _lib.SSL_get_session(self._ssl) + if session == _ffi.NULL: + return None + length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0) + assert length > 0 + outp = _no_zero_allocator("unsigned char[]", length) + _lib.SSL_get_server_random(self._ssl, outp, length) + return _ffi.buffer(outp, length)[:] + + def client_random(self): + """ + Get a copy of the client hello nonce. + + :return: A string representing the state + """ + session = _lib.SSL_get_session(self._ssl) + if session == _ffi.NULL: + return None + + length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0) + assert length > 0 + outp = _no_zero_allocator("unsigned char[]", length) + _lib.SSL_get_client_random(self._ssl, outp, length) + return _ffi.buffer(outp, length)[:] + + def master_key(self): + """ + Get a copy of the master key. + + :return: A string representing the state + """ + session = _lib.SSL_get_session(self._ssl) + if session == _ffi.NULL: + return None + + length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0) + assert length > 0 + outp = _no_zero_allocator("unsigned char[]", length) + _lib.SSL_SESSION_get_master_key(session, outp, length) + return _ffi.buffer(outp, length)[:] + + def sock_shutdown(self, *args, **kwargs): + """ + See shutdown(2) + + :return: What the socket's shutdown() method returns + """ + return self._socket.shutdown(*args, **kwargs) + + def get_peer_certificate(self): + """ + Retrieve the other side's certificate (if any) + + :return: The peer's certificate + """ + cert = _lib.SSL_get_peer_certificate(self._ssl) + if cert != _ffi.NULL: + pycert = X509.__new__(X509) + pycert._x509 = _ffi.gc(cert, _lib.X509_free) + return pycert + return None + + def get_peer_cert_chain(self): + """ + Retrieve the other side's certificate (if any) + + :return: A list of X509 instances giving the peer's certificate chain, + or None if it does not have one. + """ + cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl) + if cert_stack == _ffi.NULL: + return None + + result = [] + for i in range(_lib.sk_X509_num(cert_stack)): + # TODO could incref instead of dup here + cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i)) + pycert = X509.__new__(X509) + pycert._x509 = _ffi.gc(cert, _lib.X509_free) + result.append(pycert) + return result + + def want_read(self): + """ + Checks if more data has to be read from the transport layer to complete + an operation. + + :return: True iff more data has to be read + """ + return _lib.SSL_want_read(self._ssl) + + def want_write(self): + """ + Checks if there is data to write to the transport layer to complete an + operation. + + :return: True iff there is data to write + """ + return _lib.SSL_want_write(self._ssl) + + def set_accept_state(self): + """ + Set the connection to work in server mode. The handshake will be + handled automatically by read/write. + + :return: None + """ + _lib.SSL_set_accept_state(self._ssl) + + def set_connect_state(self): + """ + Set the connection to work in client mode. The handshake will be + handled automatically by read/write. + + :return: None + """ + _lib.SSL_set_connect_state(self._ssl) + + def get_session(self): + """ + Returns the Session currently used. + + @return: An instance of :py:class:`OpenSSL.SSL.Session` or + :py:obj:`None` if no session exists. + """ + session = _lib.SSL_get1_session(self._ssl) + if session == _ffi.NULL: + return None + + pysession = Session.__new__(Session) + pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free) + return pysession + + def set_session(self, session): + """ + Set the session to be used when the TLS/SSL connection is established. + + :param session: A Session instance representing the session to use. + :returns: None + """ + if not isinstance(session, Session): + raise TypeError("session must be a Session instance") + + result = _lib.SSL_set_session(self._ssl, session._session) + if not result: + _raise_current_error() + + def _get_finished_message(self, function): + """ + Helper to implement :py:meth:`get_finished` and + :py:meth:`get_peer_finished`. + + :param function: Either :py:data:`SSL_get_finished`: or + :py:data:`SSL_get_peer_finished`. + + :return: :py:data:`None` if the desired message has not yet been + received, otherwise the contents of the message. + :rtype: :py:class:`bytes` or :py:class:`NoneType` + """ + # The OpenSSL documentation says nothing about what might happen if the + # count argument given is zero. Specifically, it doesn't say whether + # the output buffer may be NULL in that case or not. Inspection of the + # implementation reveals that it calls memcpy() unconditionally. + # Section 7.1.4, paragraph 1 of the C standard suggests that + # memcpy(NULL, source, 0) is not guaranteed to produce defined (let + # alone desirable) behavior (though it probably does on just about + # every implementation...) + # + # Allocate a tiny buffer to pass in (instead of just passing NULL as + # one might expect) for the initial call so as to be safe against this + # potentially undefined behavior. + empty = _ffi.new("char[]", 0) + size = function(self._ssl, empty, 0) + if size == 0: + # No Finished message so far. + return None + + buf = _no_zero_allocator("char[]", size) + function(self._ssl, buf, size) + return _ffi.buffer(buf, size)[:] + + def get_finished(self): + """ + Obtain the latest `handshake finished` message sent to the peer. + + :return: The contents of the message or :py:obj:`None` if the TLS + handshake has not yet completed. + :rtype: :py:class:`bytes` or :py:class:`NoneType` + """ + return self._get_finished_message(_lib.SSL_get_finished) + + def get_peer_finished(self): + """ + Obtain the latest `handshake finished` message received from the peer. + + :return: The contents of the message or :py:obj:`None` if the TLS + handshake has not yet completed. + :rtype: :py:class:`bytes` or :py:class:`NoneType` + """ + return self._get_finished_message(_lib.SSL_get_peer_finished) + + def get_cipher_name(self): + """ + Obtain the name of the currently used cipher. + + :returns: The name of the currently used cipher or :py:obj:`None` + if no connection has been established. + :rtype: :py:class:`unicode` or :py:class:`NoneType` + """ + cipher = _lib.SSL_get_current_cipher(self._ssl) + if cipher == _ffi.NULL: + return None + else: + name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher)) + return name.decode("utf-8") + + def get_cipher_bits(self): + """ + Obtain the number of secret bits of the currently used cipher. + + :returns: The number of secret bits of the currently used cipher + or :py:obj:`None` if no connection has been established. + :rtype: :py:class:`int` or :py:class:`NoneType` + """ + cipher = _lib.SSL_get_current_cipher(self._ssl) + if cipher == _ffi.NULL: + return None + else: + return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL) + + def get_cipher_version(self): + """ + Obtain the protocol version of the currently used cipher. + + :returns: The protocol name of the currently used cipher + or :py:obj:`None` if no connection has been established. + :rtype: :py:class:`unicode` or :py:class:`NoneType` + """ + cipher = _lib.SSL_get_current_cipher(self._ssl) + if cipher == _ffi.NULL: + return None + else: + version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher)) + return version.decode("utf-8") + + def get_protocol_version_name(self): + """ + Obtain the protocol version of the current connection. + + :returns: The TLS version of the current connection, for example + the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown`` + for connections that were not successfully established. + :rtype: :py:class:`unicode` + """ + version = _ffi.string(_lib.SSL_get_version(self._ssl)) + return version.decode("utf-8") + + def get_protocol_version(self): + """ + Obtain the protocol version of the current connection. + + :returns: The TLS version of the current connection, for example + the value for TLS 1 would be 0x769. + :rtype: :py:class:`int` + """ + version = _lib.SSL_version(self._ssl) + return version + + @_requires_npn + def get_next_proto_negotiated(self): + """ + Get the protocol that was negotiated by NPN. + """ + data = _ffi.new("unsigned char **") + data_len = _ffi.new("unsigned int *") + + _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len) + + return _ffi.buffer(data[0], data_len[0])[:] + + @_requires_alpn + def set_alpn_protos(self, protos): + """ + Specify the client's ALPN protocol list. + + These protocols are offered to the server during protocol negotiation. + + :param protos: A list of the protocols to be offered to the server. + This list should be a Python list of bytestrings representing the + protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``. + """ + # Take the list of protocols and join them together, prefixing them + # with their lengths. + protostr = b''.join( + chain.from_iterable((int2byte(len(p)), p) for p in protos) + ) + + # Build a C string from the list. We don't need to save this off + # because OpenSSL immediately copies the data out. + input_str = _ffi.new("unsigned char[]", protostr) + _lib.SSL_set_alpn_protos(self._ssl, input_str, len(protostr)) + + @_requires_alpn + def get_alpn_proto_negotiated(self): + """ + Get the protocol that was negotiated by ALPN. + """ + data = _ffi.new("unsigned char **") + data_len = _ffi.new("unsigned int *") + + _lib.SSL_get0_alpn_selected(self._ssl, data, data_len) + + if not data_len: + return b'' + + return _ffi.buffer(data[0], data_len[0])[:] + + def request_ocsp(self): + """ + Called to request that the server sends stapled OCSP data, if + available. If this is not called on the client side then the server + will not send OCSP data. Should be used in conjunction with + :meth:`Context.set_ocsp_client_callback`. + """ + rc = _lib.SSL_set_tlsext_status_type( + self._ssl, _lib.TLSEXT_STATUSTYPE_ocsp + ) + _openssl_assert(rc == 1) + + +ConnectionType = deprecated( + Connection, __name__, + "ConnectionType has been deprecated, use Connection instead", + DeprecationWarning +) + +# This is similar to the initialization calls at the end of OpenSSL/crypto.py +# but is exercised mostly by the Context initializer. +_lib.SSL_library_init() diff --git a/venv/lib/python2.7/site-packages/OpenSSL/SSL.pyc b/venv/lib/python2.7/site-packages/OpenSSL/SSL.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e015d2d2ea465414a43b1c99b13ddadef443fa4a GIT binary patch literal 86019 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 DlP7`;Z=#59ULSz((*~bObqunt)B9 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/OpenSSL/crypto.py b/venv/lib/python2.7/site-packages/OpenSSL/crypto.py new file mode 100644 index 0000000..72c04b0 --- /dev/null +++ b/venv/lib/python2.7/site-packages/OpenSSL/crypto.py @@ -0,0 +1,3042 @@ +import datetime + +from base64 import b16encode +from functools import partial +from operator import __eq__, __ne__, __lt__, __le__, __gt__, __ge__ + +from six import ( + integer_types as _integer_types, + text_type as _text_type, + PY3 as _PY3) + +from cryptography import x509 +from cryptography.hazmat.primitives.asymmetric import dsa, rsa +from cryptography.utils import deprecated + +from OpenSSL._util import ( + ffi as _ffi, + lib as _lib, + exception_from_error_queue as _exception_from_error_queue, + byte_string as _byte_string, + native as _native, + UNSPECIFIED as _UNSPECIFIED, + text_to_bytes_and_warn as _text_to_bytes_and_warn, + make_assert as _make_assert, +) + +FILETYPE_PEM = _lib.SSL_FILETYPE_PEM +FILETYPE_ASN1 = _lib.SSL_FILETYPE_ASN1 + +# TODO This was an API mistake. OpenSSL has no such constant. +FILETYPE_TEXT = 2 ** 16 - 1 + +TYPE_RSA = _lib.EVP_PKEY_RSA +TYPE_DSA = _lib.EVP_PKEY_DSA + + +class Error(Exception): + """ + An error occurred in an `OpenSSL.crypto` API. + """ + + +_raise_current_error = partial(_exception_from_error_queue, Error) +_openssl_assert = _make_assert(Error) + + +def _get_backend(): + """ + Importing the backend from cryptography has the side effect of activating + the osrandom engine. This mutates the global state of OpenSSL in the + process and causes issues for various programs that use subinterpreters or + embed Python. By putting the import in this function we can avoid + triggering this side effect unless _get_backend is called. + """ + from cryptography.hazmat.backends.openssl.backend import backend + return backend + + +def _untested_error(where): + """ + An OpenSSL API failed somehow. Additionally, the failure which was + encountered isn't one that's exercised by the test suite so future behavior + of pyOpenSSL is now somewhat less predictable. + """ + raise RuntimeError("Unknown %s failure" % (where,)) + + +def _new_mem_buf(buffer=None): + """ + Allocate a new OpenSSL memory BIO. + + Arrange for the garbage collector to clean it up automatically. + + :param buffer: None or some bytes to use to put into the BIO so that they + can be read out. + """ + if buffer is None: + bio = _lib.BIO_new(_lib.BIO_s_mem()) + free = _lib.BIO_free + else: + data = _ffi.new("char[]", buffer) + bio = _lib.BIO_new_mem_buf(data, len(buffer)) + + # Keep the memory alive as long as the bio is alive! + def free(bio, ref=data): + return _lib.BIO_free(bio) + + _openssl_assert(bio != _ffi.NULL) + + bio = _ffi.gc(bio, free) + return bio + + +def _bio_to_string(bio): + """ + Copy the contents of an OpenSSL BIO object into a Python byte string. + """ + result_buffer = _ffi.new('char**') + buffer_length = _lib.BIO_get_mem_data(bio, result_buffer) + return _ffi.buffer(result_buffer[0], buffer_length)[:] + + +def _set_asn1_time(boundary, when): + """ + The the time value of an ASN1 time object. + + @param boundary: An ASN1_TIME pointer (or an object safely + castable to that type) which will have its value set. + @param when: A string representation of the desired time value. + + @raise TypeError: If C{when} is not a L{bytes} string. + @raise ValueError: If C{when} does not represent a time in the required + format. + @raise RuntimeError: If the time value cannot be set for some other + (unspecified) reason. + """ + if not isinstance(when, bytes): + raise TypeError("when must be a byte string") + + set_result = _lib.ASN1_TIME_set_string(boundary, when) + if set_result == 0: + raise ValueError("Invalid string") + + +def _get_asn1_time(timestamp): + """ + Retrieve the time value of an ASN1 time object. + + @param timestamp: An ASN1_GENERALIZEDTIME* (or an object safely castable to + that type) from which the time value will be retrieved. + + @return: The time value from C{timestamp} as a L{bytes} string in a certain + format. Or C{None} if the object contains no time value. + """ + string_timestamp = _ffi.cast('ASN1_STRING*', timestamp) + if _lib.ASN1_STRING_length(string_timestamp) == 0: + return None + elif ( + _lib.ASN1_STRING_type(string_timestamp) == _lib.V_ASN1_GENERALIZEDTIME + ): + return _ffi.string(_lib.ASN1_STRING_data(string_timestamp)) + else: + generalized_timestamp = _ffi.new("ASN1_GENERALIZEDTIME**") + _lib.ASN1_TIME_to_generalizedtime(timestamp, generalized_timestamp) + if generalized_timestamp[0] == _ffi.NULL: + # This may happen: + # - if timestamp was not an ASN1_TIME + # - if allocating memory for the ASN1_GENERALIZEDTIME failed + # - if a copy of the time data from timestamp cannot be made for + # the newly allocated ASN1_GENERALIZEDTIME + # + # These are difficult to test. cffi enforces the ASN1_TIME type. + # Memory allocation failures are a pain to trigger + # deterministically. + _untested_error("ASN1_TIME_to_generalizedtime") + else: + string_timestamp = _ffi.cast( + "ASN1_STRING*", generalized_timestamp[0]) + string_data = _lib.ASN1_STRING_data(string_timestamp) + string_result = _ffi.string(string_data) + _lib.ASN1_GENERALIZEDTIME_free(generalized_timestamp[0]) + return string_result + + +class PKey(object): + """ + A class representing an DSA or RSA public key or key pair. + """ + _only_public = False + _initialized = True + + def __init__(self): + pkey = _lib.EVP_PKEY_new() + self._pkey = _ffi.gc(pkey, _lib.EVP_PKEY_free) + self._initialized = False + + def to_cryptography_key(self): + """ + Export as a ``cryptography`` key. + + :rtype: One of ``cryptography``'s `key interfaces`_. + + .. _key interfaces: https://cryptography.io/en/latest/hazmat/\ + primitives/asymmetric/rsa/#key-interfaces + + .. versionadded:: 16.1.0 + """ + backend = _get_backend() + if self._only_public: + return backend._evp_pkey_to_public_key(self._pkey) + else: + return backend._evp_pkey_to_private_key(self._pkey) + + @classmethod + def from_cryptography_key(cls, crypto_key): + """ + Construct based on a ``cryptography`` *crypto_key*. + + :param crypto_key: A ``cryptography`` key. + :type crypto_key: One of ``cryptography``'s `key interfaces`_. + + :rtype: PKey + + .. versionadded:: 16.1.0 + """ + pkey = cls() + if not isinstance(crypto_key, (rsa.RSAPublicKey, rsa.RSAPrivateKey, + dsa.DSAPublicKey, dsa.DSAPrivateKey)): + raise TypeError("Unsupported key type") + + pkey._pkey = crypto_key._evp_pkey + if isinstance(crypto_key, (rsa.RSAPublicKey, dsa.DSAPublicKey)): + pkey._only_public = True + pkey._initialized = True + return pkey + + def generate_key(self, type, bits): + """ + Generate a key pair of the given type, with the given number of bits. + + This generates a key "into" the this object. + + :param type: The key type. + :type type: :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` + :param bits: The number of bits. + :type bits: :py:data:`int` ``>= 0`` + :raises TypeError: If :py:data:`type` or :py:data:`bits` isn't + of the appropriate type. + :raises ValueError: If the number of bits isn't an integer of + the appropriate size. + :return: ``None`` + """ + if not isinstance(type, int): + raise TypeError("type must be an integer") + + if not isinstance(bits, int): + raise TypeError("bits must be an integer") + + # TODO Check error return + exponent = _lib.BN_new() + exponent = _ffi.gc(exponent, _lib.BN_free) + _lib.BN_set_word(exponent, _lib.RSA_F4) + + if type == TYPE_RSA: + if bits <= 0: + raise ValueError("Invalid number of bits") + + rsa = _lib.RSA_new() + + result = _lib.RSA_generate_key_ex(rsa, bits, exponent, _ffi.NULL) + _openssl_assert(result == 1) + + result = _lib.EVP_PKEY_assign_RSA(self._pkey, rsa) + _openssl_assert(result == 1) + + elif type == TYPE_DSA: + dsa = _lib.DSA_new() + _openssl_assert(dsa != _ffi.NULL) + + dsa = _ffi.gc(dsa, _lib.DSA_free) + res = _lib.DSA_generate_parameters_ex( + dsa, bits, _ffi.NULL, 0, _ffi.NULL, _ffi.NULL, _ffi.NULL + ) + _openssl_assert(res == 1) + + _openssl_assert(_lib.DSA_generate_key(dsa) == 1) + _openssl_assert(_lib.EVP_PKEY_set1_DSA(self._pkey, dsa) == 1) + else: + raise Error("No such key type") + + self._initialized = True + + def check(self): + """ + Check the consistency of an RSA private key. + + This is the Python equivalent of OpenSSL's ``RSA_check_key``. + + :return: ``True`` if key is consistent. + + :raise OpenSSL.crypto.Error: if the key is inconsistent. + + :raise TypeError: if the key is of a type which cannot be checked. + Only RSA keys can currently be checked. + """ + if self._only_public: + raise TypeError("public key only") + + if _lib.EVP_PKEY_type(self.type()) != _lib.EVP_PKEY_RSA: + raise TypeError("key type unsupported") + + rsa = _lib.EVP_PKEY_get1_RSA(self._pkey) + rsa = _ffi.gc(rsa, _lib.RSA_free) + result = _lib.RSA_check_key(rsa) + if result: + return True + _raise_current_error() + + def type(self): + """ + Returns the type of the key + + :return: The type of the key. + """ + return _lib.EVP_PKEY_id(self._pkey) + + def bits(self): + """ + Returns the number of bits of the key + + :return: The number of bits of the key. + """ + return _lib.EVP_PKEY_bits(self._pkey) + + +PKeyType = deprecated( + PKey, __name__, + "PKeyType has been deprecated, use PKey instead", + DeprecationWarning +) + + +class _EllipticCurve(object): + """ + A representation of a supported elliptic curve. + + @cvar _curves: :py:obj:`None` until an attempt is made to load the curves. + Thereafter, a :py:type:`set` containing :py:type:`_EllipticCurve` + instances each of which represents one curve supported by the system. + @type _curves: :py:type:`NoneType` or :py:type:`set` + """ + _curves = None + + if _PY3: + # This only necessary on Python 3. Morever, it is broken on Python 2. + def __ne__(self, other): + """ + Implement cooperation with the right-hand side argument of ``!=``. + + Python 3 seems to have dropped this cooperation in this very narrow + circumstance. + """ + if isinstance(other, _EllipticCurve): + return super(_EllipticCurve, self).__ne__(other) + return NotImplemented + + @classmethod + def _load_elliptic_curves(cls, lib): + """ + Get the curves supported by OpenSSL. + + :param lib: The OpenSSL library binding object. + + :return: A :py:type:`set` of ``cls`` instances giving the names of the + elliptic curves the underlying library supports. + """ + num_curves = lib.EC_get_builtin_curves(_ffi.NULL, 0) + builtin_curves = _ffi.new('EC_builtin_curve[]', num_curves) + # The return value on this call should be num_curves again. We + # could check it to make sure but if it *isn't* then.. what could + # we do? Abort the whole process, I suppose...? -exarkun + lib.EC_get_builtin_curves(builtin_curves, num_curves) + return set( + cls.from_nid(lib, c.nid) + for c in builtin_curves) + + @classmethod + def _get_elliptic_curves(cls, lib): + """ + Get, cache, and return the curves supported by OpenSSL. + + :param lib: The OpenSSL library binding object. + + :return: A :py:type:`set` of ``cls`` instances giving the names of the + elliptic curves the underlying library supports. + """ + if cls._curves is None: + cls._curves = cls._load_elliptic_curves(lib) + return cls._curves + + @classmethod + def from_nid(cls, lib, nid): + """ + Instantiate a new :py:class:`_EllipticCurve` associated with the given + OpenSSL NID. + + :param lib: The OpenSSL library binding object. + + :param nid: The OpenSSL NID the resulting curve object will represent. + This must be a curve NID (and not, for example, a hash NID) or + subsequent operations will fail in unpredictable ways. + :type nid: :py:class:`int` + + :return: The curve object. + """ + return cls(lib, nid, _ffi.string(lib.OBJ_nid2sn(nid)).decode("ascii")) + + def __init__(self, lib, nid, name): + """ + :param _lib: The :py:mod:`cryptography` binding instance used to + interface with OpenSSL. + + :param _nid: The OpenSSL NID identifying the curve this object + represents. + :type _nid: :py:class:`int` + + :param name: The OpenSSL short name identifying the curve this object + represents. + :type name: :py:class:`unicode` + """ + self._lib = lib + self._nid = nid + self.name = name + + def __repr__(self): + return "" % (self.name,) + + def _to_EC_KEY(self): + """ + Create a new OpenSSL EC_KEY structure initialized to use this curve. + + The structure is automatically garbage collected when the Python object + is garbage collected. + """ + key = self._lib.EC_KEY_new_by_curve_name(self._nid) + return _ffi.gc(key, _lib.EC_KEY_free) + + +def get_elliptic_curves(): + """ + Return a set of objects representing the elliptic curves supported in the + OpenSSL build in use. + + The curve objects have a :py:class:`unicode` ``name`` attribute by which + they identify themselves. + + The curve objects are useful as values for the argument accepted by + :py:meth:`Context.set_tmp_ecdh` to specify which elliptical curve should be + used for ECDHE key exchange. + """ + return _EllipticCurve._get_elliptic_curves(_lib) + + +def get_elliptic_curve(name): + """ + Return a single curve object selected by name. + + See :py:func:`get_elliptic_curves` for information about curve objects. + + :param name: The OpenSSL short name identifying the curve object to + retrieve. + :type name: :py:class:`unicode` + + If the named curve is not supported then :py:class:`ValueError` is raised. + """ + for curve in get_elliptic_curves(): + if curve.name == name: + return curve + raise ValueError("unknown curve name", name) + + +class X509Name(object): + """ + An X.509 Distinguished Name. + + :ivar countryName: The country of the entity. + :ivar C: Alias for :py:attr:`countryName`. + + :ivar stateOrProvinceName: The state or province of the entity. + :ivar ST: Alias for :py:attr:`stateOrProvinceName`. + + :ivar localityName: The locality of the entity. + :ivar L: Alias for :py:attr:`localityName`. + + :ivar organizationName: The organization name of the entity. + :ivar O: Alias for :py:attr:`organizationName`. + + :ivar organizationalUnitName: The organizational unit of the entity. + :ivar OU: Alias for :py:attr:`organizationalUnitName` + + :ivar commonName: The common name of the entity. + :ivar CN: Alias for :py:attr:`commonName`. + + :ivar emailAddress: The e-mail address of the entity. + """ + + def __init__(self, name): + """ + Create a new X509Name, copying the given X509Name instance. + + :param name: The name to copy. + :type name: :py:class:`X509Name` + """ + name = _lib.X509_NAME_dup(name._name) + self._name = _ffi.gc(name, _lib.X509_NAME_free) + + def __setattr__(self, name, value): + if name.startswith('_'): + return super(X509Name, self).__setattr__(name, value) + + # Note: we really do not want str subclasses here, so we do not use + # isinstance. + if type(name) is not str: + raise TypeError("attribute name must be string, not '%.200s'" % ( + type(value).__name__,)) + + nid = _lib.OBJ_txt2nid(_byte_string(name)) + if nid == _lib.NID_undef: + try: + _raise_current_error() + except Error: + pass + raise AttributeError("No such attribute") + + # If there's an old entry for this NID, remove it + for i in range(_lib.X509_NAME_entry_count(self._name)): + ent = _lib.X509_NAME_get_entry(self._name, i) + ent_obj = _lib.X509_NAME_ENTRY_get_object(ent) + ent_nid = _lib.OBJ_obj2nid(ent_obj) + if nid == ent_nid: + ent = _lib.X509_NAME_delete_entry(self._name, i) + _lib.X509_NAME_ENTRY_free(ent) + break + + if isinstance(value, _text_type): + value = value.encode('utf-8') + + add_result = _lib.X509_NAME_add_entry_by_NID( + self._name, nid, _lib.MBSTRING_UTF8, value, -1, -1, 0) + if not add_result: + _raise_current_error() + + def __getattr__(self, name): + """ + Find attribute. An X509Name object has the following attributes: + countryName (alias C), stateOrProvince (alias ST), locality (alias L), + organization (alias O), organizationalUnit (alias OU), commonName + (alias CN) and more... + """ + nid = _lib.OBJ_txt2nid(_byte_string(name)) + if nid == _lib.NID_undef: + # This is a bit weird. OBJ_txt2nid indicated failure, but it seems + # a lower level function, a2d_ASN1_OBJECT, also feels the need to + # push something onto the error queue. If we don't clean that up + # now, someone else will bump into it later and be quite confused. + # See lp#314814. + try: + _raise_current_error() + except Error: + pass + return super(X509Name, self).__getattr__(name) + + entry_index = _lib.X509_NAME_get_index_by_NID(self._name, nid, -1) + if entry_index == -1: + return None + + entry = _lib.X509_NAME_get_entry(self._name, entry_index) + data = _lib.X509_NAME_ENTRY_get_data(entry) + + result_buffer = _ffi.new("unsigned char**") + data_length = _lib.ASN1_STRING_to_UTF8(result_buffer, data) + _openssl_assert(data_length >= 0) + + try: + result = _ffi.buffer( + result_buffer[0], data_length + )[:].decode('utf-8') + finally: + # XXX untested + _lib.OPENSSL_free(result_buffer[0]) + return result + + def _cmp(op): + def f(self, other): + if not isinstance(other, X509Name): + return NotImplemented + result = _lib.X509_NAME_cmp(self._name, other._name) + return op(result, 0) + return f + + __eq__ = _cmp(__eq__) + __ne__ = _cmp(__ne__) + + __lt__ = _cmp(__lt__) + __le__ = _cmp(__le__) + + __gt__ = _cmp(__gt__) + __ge__ = _cmp(__ge__) + + def __repr__(self): + """ + String representation of an X509Name + """ + result_buffer = _ffi.new("char[]", 512) + format_result = _lib.X509_NAME_oneline( + self._name, result_buffer, len(result_buffer)) + _openssl_assert(format_result != _ffi.NULL) + + return "" % ( + _native(_ffi.string(result_buffer)),) + + def hash(self): + """ + Return an integer representation of the first four bytes of the + MD5 digest of the DER representation of the name. + + This is the Python equivalent of OpenSSL's ``X509_NAME_hash``. + + :return: The (integer) hash of this name. + :rtype: :py:class:`int` + """ + return _lib.X509_NAME_hash(self._name) + + def der(self): + """ + Return the DER encoding of this name. + + :return: The DER encoded form of this name. + :rtype: :py:class:`bytes` + """ + result_buffer = _ffi.new('unsigned char**') + encode_result = _lib.i2d_X509_NAME(self._name, result_buffer) + _openssl_assert(encode_result >= 0) + + string_result = _ffi.buffer(result_buffer[0], encode_result)[:] + _lib.OPENSSL_free(result_buffer[0]) + return string_result + + def get_components(self): + """ + Returns the components of this name, as a sequence of 2-tuples. + + :return: The components of this name. + :rtype: :py:class:`list` of ``name, value`` tuples. + """ + result = [] + for i in range(_lib.X509_NAME_entry_count(self._name)): + ent = _lib.X509_NAME_get_entry(self._name, i) + + fname = _lib.X509_NAME_ENTRY_get_object(ent) + fval = _lib.X509_NAME_ENTRY_get_data(ent) + + nid = _lib.OBJ_obj2nid(fname) + name = _lib.OBJ_nid2sn(nid) + + result.append(( + _ffi.string(name), + _ffi.string( + _lib.ASN1_STRING_data(fval), + _lib.ASN1_STRING_length(fval)))) + + return result + + +X509NameType = deprecated( + X509Name, __name__, + "X509NameType has been deprecated, use X509Name instead", + DeprecationWarning +) + + +class X509Extension(object): + """ + An X.509 v3 certificate extension. + """ + + def __init__(self, type_name, critical, value, subject=None, issuer=None): + """ + Initializes an X509 extension. + + :param type_name: The name of the type of extension_ to create. + :type type_name: :py:data:`bytes` + + :param bool critical: A flag indicating whether this is a critical + extension. + + :param value: The value of the extension. + :type value: :py:data:`bytes` + + :param subject: Optional X509 certificate to use as subject. + :type subject: :py:class:`X509` + + :param issuer: Optional X509 certificate to use as issuer. + :type issuer: :py:class:`X509` + + .. _extension: https://www.openssl.org/docs/manmaster/man5/ + x509v3_config.html#STANDARD-EXTENSIONS + """ + ctx = _ffi.new("X509V3_CTX*") + + # A context is necessary for any extension which uses the r2i + # conversion method. That is, X509V3_EXT_nconf may segfault if passed + # a NULL ctx. Start off by initializing most of the fields to NULL. + _lib.X509V3_set_ctx(ctx, _ffi.NULL, _ffi.NULL, _ffi.NULL, _ffi.NULL, 0) + + # We have no configuration database - but perhaps we should (some + # extensions may require it). + _lib.X509V3_set_ctx_nodb(ctx) + + # Initialize the subject and issuer, if appropriate. ctx is a local, + # and as far as I can tell none of the X509V3_* APIs invoked here steal + # any references, so no need to mess with reference counts or + # duplicates. + if issuer is not None: + if not isinstance(issuer, X509): + raise TypeError("issuer must be an X509 instance") + ctx.issuer_cert = issuer._x509 + if subject is not None: + if not isinstance(subject, X509): + raise TypeError("subject must be an X509 instance") + ctx.subject_cert = subject._x509 + + if critical: + # There are other OpenSSL APIs which would let us pass in critical + # separately, but they're harder to use, and since value is already + # a pile of crappy junk smuggling a ton of utterly important + # structured data, what's the point of trying to avoid nasty stuff + # with strings? (However, X509V3_EXT_i2d in particular seems like + # it would be a better API to invoke. I do not know where to get + # the ext_struc it desires for its last parameter, though.) + value = b"critical," + value + + extension = _lib.X509V3_EXT_nconf(_ffi.NULL, ctx, type_name, value) + if extension == _ffi.NULL: + _raise_current_error() + self._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free) + + @property + def _nid(self): + return _lib.OBJ_obj2nid( + _lib.X509_EXTENSION_get_object(self._extension) + ) + + _prefixes = { + _lib.GEN_EMAIL: "email", + _lib.GEN_DNS: "DNS", + _lib.GEN_URI: "URI", + } + + def _subjectAltNameString(self): + names = _ffi.cast( + "GENERAL_NAMES*", _lib.X509V3_EXT_d2i(self._extension) + ) + + names = _ffi.gc(names, _lib.GENERAL_NAMES_free) + parts = [] + for i in range(_lib.sk_GENERAL_NAME_num(names)): + name = _lib.sk_GENERAL_NAME_value(names, i) + try: + label = self._prefixes[name.type] + except KeyError: + bio = _new_mem_buf() + _lib.GENERAL_NAME_print(bio, name) + parts.append(_native(_bio_to_string(bio))) + else: + value = _native( + _ffi.buffer(name.d.ia5.data, name.d.ia5.length)[:]) + parts.append(label + ":" + value) + return ", ".join(parts) + + def __str__(self): + """ + :return: a nice text representation of the extension + """ + if _lib.NID_subject_alt_name == self._nid: + return self._subjectAltNameString() + + bio = _new_mem_buf() + print_result = _lib.X509V3_EXT_print(bio, self._extension, 0, 0) + _openssl_assert(print_result != 0) + + return _native(_bio_to_string(bio)) + + def get_critical(self): + """ + Returns the critical field of this X.509 extension. + + :return: The critical field. + """ + return _lib.X509_EXTENSION_get_critical(self._extension) + + def get_short_name(self): + """ + Returns the short type name of this X.509 extension. + + The result is a byte string such as :py:const:`b"basicConstraints"`. + + :return: The short type name. + :rtype: :py:data:`bytes` + + .. versionadded:: 0.12 + """ + obj = _lib.X509_EXTENSION_get_object(self._extension) + nid = _lib.OBJ_obj2nid(obj) + return _ffi.string(_lib.OBJ_nid2sn(nid)) + + def get_data(self): + """ + Returns the data of the X509 extension, encoded as ASN.1. + + :return: The ASN.1 encoded data of this X509 extension. + :rtype: :py:data:`bytes` + + .. versionadded:: 0.12 + """ + octet_result = _lib.X509_EXTENSION_get_data(self._extension) + string_result = _ffi.cast('ASN1_STRING*', octet_result) + char_result = _lib.ASN1_STRING_data(string_result) + result_length = _lib.ASN1_STRING_length(string_result) + return _ffi.buffer(char_result, result_length)[:] + + +X509ExtensionType = deprecated( + X509Extension, __name__, + "X509ExtensionType has been deprecated, use X509Extension instead", + DeprecationWarning +) + + +class X509Req(object): + """ + An X.509 certificate signing requests. + """ + + def __init__(self): + req = _lib.X509_REQ_new() + self._req = _ffi.gc(req, _lib.X509_REQ_free) + # Default to version 0. + self.set_version(0) + + def to_cryptography(self): + """ + Export as a ``cryptography`` certificate signing request. + + :rtype: ``cryptography.x509.CertificateSigningRequest`` + + .. versionadded:: 17.1.0 + """ + from cryptography.hazmat.backends.openssl.x509 import ( + _CertificateSigningRequest + ) + backend = _get_backend() + return _CertificateSigningRequest(backend, self._req) + + @classmethod + def from_cryptography(cls, crypto_req): + """ + Construct based on a ``cryptography`` *crypto_req*. + + :param crypto_req: A ``cryptography`` X.509 certificate signing request + :type crypto_req: ``cryptography.x509.CertificateSigningRequest`` + + :rtype: PKey + + .. versionadded:: 17.1.0 + """ + if not isinstance(crypto_req, x509.CertificateSigningRequest): + raise TypeError("Must be a certificate signing request") + + req = cls() + req._req = crypto_req._x509_req + return req + + def set_pubkey(self, pkey): + """ + Set the public key of the certificate signing request. + + :param pkey: The public key to use. + :type pkey: :py:class:`PKey` + + :return: ``None`` + """ + set_result = _lib.X509_REQ_set_pubkey(self._req, pkey._pkey) + _openssl_assert(set_result == 1) + + def get_pubkey(self): + """ + Get the public key of the certificate signing request. + + :return: The public key. + :rtype: :py:class:`PKey` + """ + pkey = PKey.__new__(PKey) + pkey._pkey = _lib.X509_REQ_get_pubkey(self._req) + _openssl_assert(pkey._pkey != _ffi.NULL) + pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free) + pkey._only_public = True + return pkey + + def set_version(self, version): + """ + Set the version subfield (RFC 2459, section 4.1.2.1) of the certificate + request. + + :param int version: The version number. + :return: ``None`` + """ + set_result = _lib.X509_REQ_set_version(self._req, version) + _openssl_assert(set_result == 1) + + def get_version(self): + """ + Get the version subfield (RFC 2459, section 4.1.2.1) of the certificate + request. + + :return: The value of the version subfield. + :rtype: :py:class:`int` + """ + return _lib.X509_REQ_get_version(self._req) + + def get_subject(self): + """ + Return the subject of this certificate signing request. + + This creates a new :class:`X509Name` that wraps the underlying subject + name field on the certificate signing request. Modifying it will modify + the underlying signing request, and will have the effect of modifying + any other :class:`X509Name` that refers to this subject. + + :return: The subject of this certificate signing request. + :rtype: :class:`X509Name` + """ + name = X509Name.__new__(X509Name) + name._name = _lib.X509_REQ_get_subject_name(self._req) + _openssl_assert(name._name != _ffi.NULL) + + # The name is owned by the X509Req structure. As long as the X509Name + # Python object is alive, keep the X509Req Python object alive. + name._owner = self + + return name + + def add_extensions(self, extensions): + """ + Add extensions to the certificate signing request. + + :param extensions: The X.509 extensions to add. + :type extensions: iterable of :py:class:`X509Extension` + :return: ``None`` + """ + stack = _lib.sk_X509_EXTENSION_new_null() + _openssl_assert(stack != _ffi.NULL) + + stack = _ffi.gc(stack, _lib.sk_X509_EXTENSION_free) + + for ext in extensions: + if not isinstance(ext, X509Extension): + raise ValueError("One of the elements is not an X509Extension") + + # TODO push can fail (here and elsewhere) + _lib.sk_X509_EXTENSION_push(stack, ext._extension) + + add_result = _lib.X509_REQ_add_extensions(self._req, stack) + _openssl_assert(add_result == 1) + + def get_extensions(self): + """ + Get X.509 extensions in the certificate signing request. + + :return: The X.509 extensions in this request. + :rtype: :py:class:`list` of :py:class:`X509Extension` objects. + + .. versionadded:: 0.15 + """ + exts = [] + native_exts_obj = _lib.X509_REQ_get_extensions(self._req) + for i in range(_lib.sk_X509_EXTENSION_num(native_exts_obj)): + ext = X509Extension.__new__(X509Extension) + ext._extension = _lib.sk_X509_EXTENSION_value(native_exts_obj, i) + exts.append(ext) + return exts + + def sign(self, pkey, digest): + """ + Sign the certificate signing request with this key and digest type. + + :param pkey: The key pair to sign with. + :type pkey: :py:class:`PKey` + :param digest: The name of the message digest to use for the signature, + e.g. :py:data:`b"sha256"`. + :type digest: :py:class:`bytes` + :return: ``None`` + """ + if pkey._only_public: + raise ValueError("Key has only public part") + + if not pkey._initialized: + raise ValueError("Key is uninitialized") + + digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest)) + if digest_obj == _ffi.NULL: + raise ValueError("No such digest method") + + sign_result = _lib.X509_REQ_sign(self._req, pkey._pkey, digest_obj) + _openssl_assert(sign_result > 0) + + def verify(self, pkey): + """ + Verifies the signature on this certificate signing request. + + :param PKey key: A public key. + + :return: ``True`` if the signature is correct. + :rtype: bool + + :raises OpenSSL.crypto.Error: If the signature is invalid or there is a + problem verifying the signature. + """ + if not isinstance(pkey, PKey): + raise TypeError("pkey must be a PKey instance") + + result = _lib.X509_REQ_verify(self._req, pkey._pkey) + if result <= 0: + _raise_current_error() + + return result + + +X509ReqType = deprecated( + X509Req, __name__, + "X509ReqType has been deprecated, use X509Req instead", + DeprecationWarning +) + + +class X509(object): + """ + An X.509 certificate. + """ + def __init__(self): + x509 = _lib.X509_new() + _openssl_assert(x509 != _ffi.NULL) + self._x509 = _ffi.gc(x509, _lib.X509_free) + + def to_cryptography(self): + """ + Export as a ``cryptography`` certificate. + + :rtype: ``cryptography.x509.Certificate`` + + .. versionadded:: 17.1.0 + """ + from cryptography.hazmat.backends.openssl.x509 import _Certificate + backend = _get_backend() + return _Certificate(backend, self._x509) + + @classmethod + def from_cryptography(cls, crypto_cert): + """ + Construct based on a ``cryptography`` *crypto_cert*. + + :param crypto_key: A ``cryptography`` X.509 certificate. + :type crypto_key: ``cryptography.x509.Certificate`` + + :rtype: PKey + + .. versionadded:: 17.1.0 + """ + if not isinstance(crypto_cert, x509.Certificate): + raise TypeError("Must be a certificate") + + cert = cls() + cert._x509 = crypto_cert._x509 + return cert + + def set_version(self, version): + """ + Set the version number of the certificate. + + :param version: The version number of the certificate. + :type version: :py:class:`int` + + :return: ``None`` + """ + if not isinstance(version, int): + raise TypeError("version must be an integer") + + _lib.X509_set_version(self._x509, version) + + def get_version(self): + """ + Return the version number of the certificate. + + :return: The version number of the certificate. + :rtype: :py:class:`int` + """ + return _lib.X509_get_version(self._x509) + + def get_pubkey(self): + """ + Get the public key of the certificate. + + :return: The public key. + :rtype: :py:class:`PKey` + """ + pkey = PKey.__new__(PKey) + pkey._pkey = _lib.X509_get_pubkey(self._x509) + if pkey._pkey == _ffi.NULL: + _raise_current_error() + pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free) + pkey._only_public = True + return pkey + + def set_pubkey(self, pkey): + """ + Set the public key of the certificate. + + :param pkey: The public key. + :type pkey: :py:class:`PKey` + + :return: :py:data:`None` + """ + if not isinstance(pkey, PKey): + raise TypeError("pkey must be a PKey instance") + + set_result = _lib.X509_set_pubkey(self._x509, pkey._pkey) + _openssl_assert(set_result == 1) + + def sign(self, pkey, digest): + """ + Sign the certificate with this key and digest type. + + :param pkey: The key to sign with. + :type pkey: :py:class:`PKey` + + :param digest: The name of the message digest to use. + :type digest: :py:class:`bytes` + + :return: :py:data:`None` + """ + if not isinstance(pkey, PKey): + raise TypeError("pkey must be a PKey instance") + + if pkey._only_public: + raise ValueError("Key only has public part") + + if not pkey._initialized: + raise ValueError("Key is uninitialized") + + evp_md = _lib.EVP_get_digestbyname(_byte_string(digest)) + if evp_md == _ffi.NULL: + raise ValueError("No such digest method") + + sign_result = _lib.X509_sign(self._x509, pkey._pkey, evp_md) + _openssl_assert(sign_result > 0) + + def get_signature_algorithm(self): + """ + Return the signature algorithm used in the certificate. + + :return: The name of the algorithm. + :rtype: :py:class:`bytes` + + :raises ValueError: If the signature algorithm is undefined. + + .. versionadded:: 0.13 + """ + algor = _lib.X509_get0_tbs_sigalg(self._x509) + nid = _lib.OBJ_obj2nid(algor.algorithm) + if nid == _lib.NID_undef: + raise ValueError("Undefined signature algorithm") + return _ffi.string(_lib.OBJ_nid2ln(nid)) + + def digest(self, digest_name): + """ + Return the digest of the X509 object. + + :param digest_name: The name of the digest algorithm to use. + :type digest_name: :py:class:`bytes` + + :return: The digest of the object, formatted as + :py:const:`b":"`-delimited hex pairs. + :rtype: :py:class:`bytes` + """ + digest = _lib.EVP_get_digestbyname(_byte_string(digest_name)) + if digest == _ffi.NULL: + raise ValueError("No such digest method") + + result_buffer = _ffi.new("unsigned char[]", _lib.EVP_MAX_MD_SIZE) + result_length = _ffi.new("unsigned int[]", 1) + result_length[0] = len(result_buffer) + + digest_result = _lib.X509_digest( + self._x509, digest, result_buffer, result_length) + _openssl_assert(digest_result == 1) + + return b":".join([ + b16encode(ch).upper() for ch + in _ffi.buffer(result_buffer, result_length[0])]) + + def subject_name_hash(self): + """ + Return the hash of the X509 subject. + + :return: The hash of the subject. + :rtype: :py:class:`bytes` + """ + return _lib.X509_subject_name_hash(self._x509) + + def set_serial_number(self, serial): + """ + Set the serial number of the certificate. + + :param serial: The new serial number. + :type serial: :py:class:`int` + + :return: :py:data`None` + """ + if not isinstance(serial, _integer_types): + raise TypeError("serial must be an integer") + + hex_serial = hex(serial)[2:] + if not isinstance(hex_serial, bytes): + hex_serial = hex_serial.encode('ascii') + + bignum_serial = _ffi.new("BIGNUM**") + + # BN_hex2bn stores the result in &bignum. Unless it doesn't feel like + # it. If bignum is still NULL after this call, then the return value + # is actually the result. I hope. -exarkun + small_serial = _lib.BN_hex2bn(bignum_serial, hex_serial) + + if bignum_serial[0] == _ffi.NULL: + set_result = _lib.ASN1_INTEGER_set( + _lib.X509_get_serialNumber(self._x509), small_serial) + if set_result: + # TODO Not tested + _raise_current_error() + else: + asn1_serial = _lib.BN_to_ASN1_INTEGER(bignum_serial[0], _ffi.NULL) + _lib.BN_free(bignum_serial[0]) + if asn1_serial == _ffi.NULL: + # TODO Not tested + _raise_current_error() + asn1_serial = _ffi.gc(asn1_serial, _lib.ASN1_INTEGER_free) + set_result = _lib.X509_set_serialNumber(self._x509, asn1_serial) + _openssl_assert(set_result == 1) + + def get_serial_number(self): + """ + Return the serial number of this certificate. + + :return: The serial number. + :rtype: int + """ + asn1_serial = _lib.X509_get_serialNumber(self._x509) + bignum_serial = _lib.ASN1_INTEGER_to_BN(asn1_serial, _ffi.NULL) + try: + hex_serial = _lib.BN_bn2hex(bignum_serial) + try: + hexstring_serial = _ffi.string(hex_serial) + serial = int(hexstring_serial, 16) + return serial + finally: + _lib.OPENSSL_free(hex_serial) + finally: + _lib.BN_free(bignum_serial) + + def gmtime_adj_notAfter(self, amount): + """ + Adjust the time stamp on which the certificate stops being valid. + + :param int amount: The number of seconds by which to adjust the + timestamp. + :return: ``None`` + """ + if not isinstance(amount, int): + raise TypeError("amount must be an integer") + + notAfter = _lib.X509_get_notAfter(self._x509) + _lib.X509_gmtime_adj(notAfter, amount) + + def gmtime_adj_notBefore(self, amount): + """ + Adjust the timestamp on which the certificate starts being valid. + + :param amount: The number of seconds by which to adjust the timestamp. + :return: ``None`` + """ + if not isinstance(amount, int): + raise TypeError("amount must be an integer") + + notBefore = _lib.X509_get_notBefore(self._x509) + _lib.X509_gmtime_adj(notBefore, amount) + + def has_expired(self): + """ + Check whether the certificate has expired. + + :return: ``True`` if the certificate has expired, ``False`` otherwise. + :rtype: bool + """ + time_string = _native(self.get_notAfter()) + not_after = datetime.datetime.strptime(time_string, "%Y%m%d%H%M%SZ") + + return not_after < datetime.datetime.utcnow() + + def _get_boundary_time(self, which): + return _get_asn1_time(which(self._x509)) + + def get_notBefore(self): + """ + Get the timestamp at which the certificate starts being valid. + + The timestamp is formatted as an ASN.1 TIME:: + + YYYYMMDDhhmmssZ + + :return: A timestamp string, or ``None`` if there is none. + :rtype: bytes or NoneType + """ + return self._get_boundary_time(_lib.X509_get_notBefore) + + def _set_boundary_time(self, which, when): + return _set_asn1_time(which(self._x509), when) + + def set_notBefore(self, when): + """ + Set the timestamp at which the certificate starts being valid. + + The timestamp is formatted as an ASN.1 TIME:: + + YYYYMMDDhhmmssZ + + :param bytes when: A timestamp string. + :return: ``None`` + """ + return self._set_boundary_time(_lib.X509_get_notBefore, when) + + def get_notAfter(self): + """ + Get the timestamp at which the certificate stops being valid. + + The timestamp is formatted as an ASN.1 TIME:: + + YYYYMMDDhhmmssZ + + :return: A timestamp string, or ``None`` if there is none. + :rtype: bytes or NoneType + """ + return self._get_boundary_time(_lib.X509_get_notAfter) + + def set_notAfter(self, when): + """ + Set the timestamp at which the certificate stops being valid. + + The timestamp is formatted as an ASN.1 TIME:: + + YYYYMMDDhhmmssZ + + :param bytes when: A timestamp string. + :return: ``None`` + """ + return self._set_boundary_time(_lib.X509_get_notAfter, when) + + def _get_name(self, which): + name = X509Name.__new__(X509Name) + name._name = which(self._x509) + _openssl_assert(name._name != _ffi.NULL) + + # The name is owned by the X509 structure. As long as the X509Name + # Python object is alive, keep the X509 Python object alive. + name._owner = self + + return name + + def _set_name(self, which, name): + if not isinstance(name, X509Name): + raise TypeError("name must be an X509Name") + set_result = which(self._x509, name._name) + _openssl_assert(set_result == 1) + + def get_issuer(self): + """ + Return the issuer of this certificate. + + This creates a new :class:`X509Name` that wraps the underlying issuer + name field on the certificate. Modifying it will modify the underlying + certificate, and will have the effect of modifying any other + :class:`X509Name` that refers to this issuer. + + :return: The issuer of this certificate. + :rtype: :class:`X509Name` + """ + return self._get_name(_lib.X509_get_issuer_name) + + def set_issuer(self, issuer): + """ + Set the issuer of this certificate. + + :param issuer: The issuer. + :type issuer: :py:class:`X509Name` + + :return: ``None`` + """ + return self._set_name(_lib.X509_set_issuer_name, issuer) + + def get_subject(self): + """ + Return the subject of this certificate. + + This creates a new :class:`X509Name` that wraps the underlying subject + name field on the certificate. Modifying it will modify the underlying + certificate, and will have the effect of modifying any other + :class:`X509Name` that refers to this subject. + + :return: The subject of this certificate. + :rtype: :class:`X509Name` + """ + return self._get_name(_lib.X509_get_subject_name) + + def set_subject(self, subject): + """ + Set the subject of this certificate. + + :param subject: The subject. + :type subject: :py:class:`X509Name` + + :return: ``None`` + """ + return self._set_name(_lib.X509_set_subject_name, subject) + + def get_extension_count(self): + """ + Get the number of extensions on this certificate. + + :return: The number of extensions. + :rtype: :py:class:`int` + + .. versionadded:: 0.12 + """ + return _lib.X509_get_ext_count(self._x509) + + def add_extensions(self, extensions): + """ + Add extensions to the certificate. + + :param extensions: The extensions to add. + :type extensions: An iterable of :py:class:`X509Extension` objects. + :return: ``None`` + """ + for ext in extensions: + if not isinstance(ext, X509Extension): + raise ValueError("One of the elements is not an X509Extension") + + add_result = _lib.X509_add_ext(self._x509, ext._extension, -1) + if not add_result: + _raise_current_error() + + def get_extension(self, index): + """ + Get a specific extension of the certificate by index. + + Extensions on a certificate are kept in order. The index + parameter selects which extension will be returned. + + :param int index: The index of the extension to retrieve. + :return: The extension at the specified index. + :rtype: :py:class:`X509Extension` + :raises IndexError: If the extension index was out of bounds. + + .. versionadded:: 0.12 + """ + ext = X509Extension.__new__(X509Extension) + ext._extension = _lib.X509_get_ext(self._x509, index) + if ext._extension == _ffi.NULL: + raise IndexError("extension index out of bounds") + + extension = _lib.X509_EXTENSION_dup(ext._extension) + ext._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free) + return ext + + +X509Type = deprecated( + X509, __name__, + "X509Type has been deprecated, use X509 instead", + DeprecationWarning +) + + +class X509StoreFlags(object): + """ + Flags for X509 verification, used to change the behavior of + :class:`X509Store`. + + See `OpenSSL Verification Flags`_ for details. + + .. _OpenSSL Verification Flags: + https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html + """ + CRL_CHECK = _lib.X509_V_FLAG_CRL_CHECK + CRL_CHECK_ALL = _lib.X509_V_FLAG_CRL_CHECK_ALL + IGNORE_CRITICAL = _lib.X509_V_FLAG_IGNORE_CRITICAL + X509_STRICT = _lib.X509_V_FLAG_X509_STRICT + ALLOW_PROXY_CERTS = _lib.X509_V_FLAG_ALLOW_PROXY_CERTS + POLICY_CHECK = _lib.X509_V_FLAG_POLICY_CHECK + EXPLICIT_POLICY = _lib.X509_V_FLAG_EXPLICIT_POLICY + INHIBIT_MAP = _lib.X509_V_FLAG_INHIBIT_MAP + NOTIFY_POLICY = _lib.X509_V_FLAG_NOTIFY_POLICY + CHECK_SS_SIGNATURE = _lib.X509_V_FLAG_CHECK_SS_SIGNATURE + CB_ISSUER_CHECK = _lib.X509_V_FLAG_CB_ISSUER_CHECK + + +class X509Store(object): + """ + An X.509 store. + + An X.509 store is used to describe a context in which to verify a + certificate. A description of a context may include a set of certificates + to trust, a set of certificate revocation lists, verification flags and + more. + + An X.509 store, being only a description, cannot be used by itself to + verify a certificate. To carry out the actual verification process, see + :class:`X509StoreContext`. + """ + + def __init__(self): + store = _lib.X509_STORE_new() + self._store = _ffi.gc(store, _lib.X509_STORE_free) + + def add_cert(self, cert): + """ + Adds a trusted certificate to this store. + + Adding a certificate with this method adds this certificate as a + *trusted* certificate. + + :param X509 cert: The certificate to add to this store. + + :raises TypeError: If the certificate is not an :class:`X509`. + + :raises OpenSSL.crypto.Error: If OpenSSL was unhappy with your + certificate. + + :return: ``None`` if the certificate was added successfully. + """ + if not isinstance(cert, X509): + raise TypeError() + + _openssl_assert(_lib.X509_STORE_add_cert(self._store, cert._x509) != 0) + + def add_crl(self, crl): + """ + Add a certificate revocation list to this store. + + The certificate revocation lists added to a store will only be used if + the associated flags are configured to check certificate revocation + lists. + + .. versionadded:: 16.1.0 + + :param CRL crl: The certificate revocation list to add to this store. + :return: ``None`` if the certificate revocation list was added + successfully. + """ + _openssl_assert(_lib.X509_STORE_add_crl(self._store, crl._crl) != 0) + + def set_flags(self, flags): + """ + Set verification flags to this store. + + Verification flags can be combined by oring them together. + + .. note:: + + Setting a verification flag sometimes requires clients to add + additional information to the store, otherwise a suitable error will + be raised. + + For example, in setting flags to enable CRL checking a + suitable CRL must be added to the store otherwise an error will be + raised. + + .. versionadded:: 16.1.0 + + :param int flags: The verification flags to set on this store. + See :class:`X509StoreFlags` for available constants. + :return: ``None`` if the verification flags were successfully set. + """ + _openssl_assert(_lib.X509_STORE_set_flags(self._store, flags) != 0) + + def set_time(self, vfy_time): + """ + Set the time against which the certificates are verified. + + Normally the current time is used. + + .. note:: + + For example, you can determine if a certificate was valid at a given + time. + + .. versionadded:: 17.0.0 + + :param datetime vfy_time: The verification time to set on this store. + :return: ``None`` if the verification time was successfully set. + """ + param = _lib.X509_VERIFY_PARAM_new() + param = _ffi.gc(param, _lib.X509_VERIFY_PARAM_free) + + _lib.X509_VERIFY_PARAM_set_time(param, int(vfy_time.strftime('%s'))) + _openssl_assert(_lib.X509_STORE_set1_param(self._store, param) != 0) + + +X509StoreType = deprecated( + X509Store, __name__, + "X509StoreType has been deprecated, use X509Store instead", + DeprecationWarning +) + + +class X509StoreContextError(Exception): + """ + An exception raised when an error occurred while verifying a certificate + using `OpenSSL.X509StoreContext.verify_certificate`. + + :ivar certificate: The certificate which caused verificate failure. + :type certificate: :class:`X509` + """ + + def __init__(self, message, certificate): + super(X509StoreContextError, self).__init__(message) + self.certificate = certificate + + +class X509StoreContext(object): + """ + An X.509 store context. + + An X.509 store context is used to carry out the actual verification process + of a certificate in a described context. For describing such a context, see + :class:`X509Store`. + + :ivar _store_ctx: The underlying X509_STORE_CTX structure used by this + instance. It is dynamically allocated and automatically garbage + collected. + :ivar _store: See the ``store`` ``__init__`` parameter. + :ivar _cert: See the ``certificate`` ``__init__`` parameter. + :param X509Store store: The certificates which will be trusted for the + purposes of any verifications. + :param X509 certificate: The certificate to be verified. + """ + + def __init__(self, store, certificate): + store_ctx = _lib.X509_STORE_CTX_new() + self._store_ctx = _ffi.gc(store_ctx, _lib.X509_STORE_CTX_free) + self._store = store + self._cert = certificate + # Make the store context available for use after instantiating this + # class by initializing it now. Per testing, subsequent calls to + # :meth:`_init` have no adverse affect. + self._init() + + def _init(self): + """ + Set up the store context for a subsequent verification operation. + + Calling this method more than once without first calling + :meth:`_cleanup` will leak memory. + """ + ret = _lib.X509_STORE_CTX_init( + self._store_ctx, self._store._store, self._cert._x509, _ffi.NULL + ) + if ret <= 0: + _raise_current_error() + + def _cleanup(self): + """ + Internally cleans up the store context. + + The store context can then be reused with a new call to :meth:`_init`. + """ + _lib.X509_STORE_CTX_cleanup(self._store_ctx) + + def _exception_from_context(self): + """ + Convert an OpenSSL native context error failure into a Python + exception. + + When a call to native OpenSSL X509_verify_cert fails, additional + information about the failure can be obtained from the store context. + """ + errors = [ + _lib.X509_STORE_CTX_get_error(self._store_ctx), + _lib.X509_STORE_CTX_get_error_depth(self._store_ctx), + _native(_ffi.string(_lib.X509_verify_cert_error_string( + _lib.X509_STORE_CTX_get_error(self._store_ctx)))), + ] + # A context error should always be associated with a certificate, so we + # expect this call to never return :class:`None`. + _x509 = _lib.X509_STORE_CTX_get_current_cert(self._store_ctx) + _cert = _lib.X509_dup(_x509) + pycert = X509.__new__(X509) + pycert._x509 = _ffi.gc(_cert, _lib.X509_free) + return X509StoreContextError(errors, pycert) + + def set_store(self, store): + """ + Set the context's X.509 store. + + .. versionadded:: 0.15 + + :param X509Store store: The store description which will be used for + the purposes of any *future* verifications. + """ + self._store = store + + def verify_certificate(self): + """ + Verify a certificate in a context. + + .. versionadded:: 0.15 + + :raises X509StoreContextError: If an error occurred when validating a + certificate in the context. Sets ``certificate`` attribute to + indicate which certificate caused the error. + """ + # Always re-initialize the store context in case + # :meth:`verify_certificate` is called multiple times. + # + # :meth:`_init` is called in :meth:`__init__` so _cleanup is called + # before _init to ensure memory is not leaked. + self._cleanup() + self._init() + ret = _lib.X509_verify_cert(self._store_ctx) + self._cleanup() + if ret <= 0: + raise self._exception_from_context() + + +def load_certificate(type, buffer): + """ + Load a certificate from a buffer + + :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1) + + :param bytes buffer: The buffer the certificate is stored in + + :return: The X509 object + """ + if isinstance(buffer, _text_type): + buffer = buffer.encode("ascii") + + bio = _new_mem_buf(buffer) + + if type == FILETYPE_PEM: + x509 = _lib.PEM_read_bio_X509(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL) + elif type == FILETYPE_ASN1: + x509 = _lib.d2i_X509_bio(bio, _ffi.NULL) + else: + raise ValueError( + "type argument must be FILETYPE_PEM or FILETYPE_ASN1") + + if x509 == _ffi.NULL: + _raise_current_error() + + cert = X509.__new__(X509) + cert._x509 = _ffi.gc(x509, _lib.X509_free) + return cert + + +def dump_certificate(type, cert): + """ + Dump a certificate to a buffer + + :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1, or + FILETYPE_TEXT) + :param cert: The certificate to dump + :return: The buffer with the dumped certificate in + """ + bio = _new_mem_buf() + + if type == FILETYPE_PEM: + result_code = _lib.PEM_write_bio_X509(bio, cert._x509) + elif type == FILETYPE_ASN1: + result_code = _lib.i2d_X509_bio(bio, cert._x509) + elif type == FILETYPE_TEXT: + result_code = _lib.X509_print_ex(bio, cert._x509, 0, 0) + else: + raise ValueError( + "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or " + "FILETYPE_TEXT") + + assert result_code == 1 + return _bio_to_string(bio) + + +def dump_publickey(type, pkey): + """ + Dump a public key to a buffer. + + :param type: The file type (one of :data:`FILETYPE_PEM` or + :data:`FILETYPE_ASN1`). + :param PKey pkey: The public key to dump + :return: The buffer with the dumped key in it. + :rtype: bytes + """ + bio = _new_mem_buf() + if type == FILETYPE_PEM: + write_bio = _lib.PEM_write_bio_PUBKEY + elif type == FILETYPE_ASN1: + write_bio = _lib.i2d_PUBKEY_bio + else: + raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1") + + result_code = write_bio(bio, pkey._pkey) + if result_code != 1: # pragma: no cover + _raise_current_error() + + return _bio_to_string(bio) + + +def dump_privatekey(type, pkey, cipher=None, passphrase=None): + """ + Dump the private key *pkey* into a buffer string encoded with the type + *type*. Optionally (if *type* is :const:`FILETYPE_PEM`) encrypting it + using *cipher* and *passphrase*. + + :param type: The file type (one of :const:`FILETYPE_PEM`, + :const:`FILETYPE_ASN1`, or :const:`FILETYPE_TEXT`) + :param PKey pkey: The PKey to dump + :param cipher: (optional) if encrypted PEM format, the cipher to use + :param passphrase: (optional) if encrypted PEM format, this can be either + the passphrase to use, or a callback for providing the passphrase. + + :return: The buffer with the dumped key in + :rtype: bytes + """ + bio = _new_mem_buf() + + if not isinstance(pkey, PKey): + raise TypeError("pkey must be a PKey") + + if cipher is not None: + if passphrase is None: + raise TypeError( + "if a value is given for cipher " + "one must also be given for passphrase") + cipher_obj = _lib.EVP_get_cipherbyname(_byte_string(cipher)) + if cipher_obj == _ffi.NULL: + raise ValueError("Invalid cipher name") + else: + cipher_obj = _ffi.NULL + + helper = _PassphraseHelper(type, passphrase) + if type == FILETYPE_PEM: + result_code = _lib.PEM_write_bio_PrivateKey( + bio, pkey._pkey, cipher_obj, _ffi.NULL, 0, + helper.callback, helper.callback_args) + helper.raise_if_problem() + elif type == FILETYPE_ASN1: + result_code = _lib.i2d_PrivateKey_bio(bio, pkey._pkey) + elif type == FILETYPE_TEXT: + if _lib.EVP_PKEY_id(pkey._pkey) != _lib.EVP_PKEY_RSA: + raise TypeError("Only RSA keys are supported for FILETYPE_TEXT") + + rsa = _ffi.gc( + _lib.EVP_PKEY_get1_RSA(pkey._pkey), + _lib.RSA_free + ) + result_code = _lib.RSA_print(bio, rsa, 0) + else: + raise ValueError( + "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or " + "FILETYPE_TEXT") + + _openssl_assert(result_code != 0) + + return _bio_to_string(bio) + + +class Revoked(object): + """ + A certificate revocation. + """ + # http://www.openssl.org/docs/apps/x509v3_config.html#CRL_distribution_points_ + # which differs from crl_reasons of crypto/x509v3/v3_enum.c that matches + # OCSP_crl_reason_str. We use the latter, just like the command line + # program. + _crl_reasons = [ + b"unspecified", + b"keyCompromise", + b"CACompromise", + b"affiliationChanged", + b"superseded", + b"cessationOfOperation", + b"certificateHold", + # b"removeFromCRL", + ] + + def __init__(self): + revoked = _lib.X509_REVOKED_new() + self._revoked = _ffi.gc(revoked, _lib.X509_REVOKED_free) + + def set_serial(self, hex_str): + """ + Set the serial number. + + The serial number is formatted as a hexadecimal number encoded in + ASCII. + + :param bytes hex_str: The new serial number. + + :return: ``None`` + """ + bignum_serial = _ffi.gc(_lib.BN_new(), _lib.BN_free) + bignum_ptr = _ffi.new("BIGNUM**") + bignum_ptr[0] = bignum_serial + bn_result = _lib.BN_hex2bn(bignum_ptr, hex_str) + if not bn_result: + raise ValueError("bad hex string") + + asn1_serial = _ffi.gc( + _lib.BN_to_ASN1_INTEGER(bignum_serial, _ffi.NULL), + _lib.ASN1_INTEGER_free) + _lib.X509_REVOKED_set_serialNumber(self._revoked, asn1_serial) + + def get_serial(self): + """ + Get the serial number. + + The serial number is formatted as a hexadecimal number encoded in + ASCII. + + :return: The serial number. + :rtype: bytes + """ + bio = _new_mem_buf() + + asn1_int = _lib.X509_REVOKED_get0_serialNumber(self._revoked) + _openssl_assert(asn1_int != _ffi.NULL) + result = _lib.i2a_ASN1_INTEGER(bio, asn1_int) + _openssl_assert(result >= 0) + return _bio_to_string(bio) + + def _delete_reason(self): + for i in range(_lib.X509_REVOKED_get_ext_count(self._revoked)): + ext = _lib.X509_REVOKED_get_ext(self._revoked, i) + obj = _lib.X509_EXTENSION_get_object(ext) + if _lib.OBJ_obj2nid(obj) == _lib.NID_crl_reason: + _lib.X509_EXTENSION_free(ext) + _lib.X509_REVOKED_delete_ext(self._revoked, i) + break + + def set_reason(self, reason): + """ + Set the reason of this revocation. + + If :data:`reason` is ``None``, delete the reason instead. + + :param reason: The reason string. + :type reason: :class:`bytes` or :class:`NoneType` + + :return: ``None`` + + .. seealso:: + + :meth:`all_reasons`, which gives you a list of all supported + reasons which you might pass to this method. + """ + if reason is None: + self._delete_reason() + elif not isinstance(reason, bytes): + raise TypeError("reason must be None or a byte string") + else: + reason = reason.lower().replace(b' ', b'') + reason_code = [r.lower() for r in self._crl_reasons].index(reason) + + new_reason_ext = _lib.ASN1_ENUMERATED_new() + _openssl_assert(new_reason_ext != _ffi.NULL) + new_reason_ext = _ffi.gc(new_reason_ext, _lib.ASN1_ENUMERATED_free) + + set_result = _lib.ASN1_ENUMERATED_set(new_reason_ext, reason_code) + _openssl_assert(set_result != _ffi.NULL) + + self._delete_reason() + add_result = _lib.X509_REVOKED_add1_ext_i2d( + self._revoked, _lib.NID_crl_reason, new_reason_ext, 0, 0) + _openssl_assert(add_result == 1) + + def get_reason(self): + """ + Get the reason of this revocation. + + :return: The reason, or ``None`` if there is none. + :rtype: bytes or NoneType + + .. seealso:: + + :meth:`all_reasons`, which gives you a list of all supported + reasons this method might return. + """ + for i in range(_lib.X509_REVOKED_get_ext_count(self._revoked)): + ext = _lib.X509_REVOKED_get_ext(self._revoked, i) + obj = _lib.X509_EXTENSION_get_object(ext) + if _lib.OBJ_obj2nid(obj) == _lib.NID_crl_reason: + bio = _new_mem_buf() + + print_result = _lib.X509V3_EXT_print(bio, ext, 0, 0) + if not print_result: + print_result = _lib.M_ASN1_OCTET_STRING_print( + bio, _lib.X509_EXTENSION_get_data(ext) + ) + _openssl_assert(print_result != 0) + + return _bio_to_string(bio) + + def all_reasons(self): + """ + Return a list of all the supported reason strings. + + This list is a copy; modifying it does not change the supported reason + strings. + + :return: A list of reason strings. + :rtype: :class:`list` of :class:`bytes` + """ + return self._crl_reasons[:] + + def set_rev_date(self, when): + """ + Set the revocation timestamp. + + :param bytes when: The timestamp of the revocation, + as ASN.1 TIME. + :return: ``None`` + """ + dt = _lib.X509_REVOKED_get0_revocationDate(self._revoked) + return _set_asn1_time(dt, when) + + def get_rev_date(self): + """ + Get the revocation timestamp. + + :return: The timestamp of the revocation, as ASN.1 TIME. + :rtype: bytes + """ + dt = _lib.X509_REVOKED_get0_revocationDate(self._revoked) + return _get_asn1_time(dt) + + +class CRL(object): + """ + A certificate revocation list. + """ + + def __init__(self): + crl = _lib.X509_CRL_new() + self._crl = _ffi.gc(crl, _lib.X509_CRL_free) + + def to_cryptography(self): + """ + Export as a ``cryptography`` CRL. + + :rtype: ``cryptography.x509.CertificateRevocationList`` + + .. versionadded:: 17.1.0 + """ + from cryptography.hazmat.backends.openssl.x509 import ( + _CertificateRevocationList + ) + backend = _get_backend() + return _CertificateRevocationList(backend, self._crl) + + @classmethod + def from_cryptography(cls, crypto_crl): + """ + Construct based on a ``cryptography`` *crypto_crl*. + + :param crypto_crl: A ``cryptography`` certificate revocation list + :type crypto_crl: ``cryptography.x509.CertificateRevocationList`` + + :rtype: CRL + + .. versionadded:: 17.1.0 + """ + if not isinstance(crypto_crl, x509.CertificateRevocationList): + raise TypeError("Must be a certificate revocation list") + + crl = cls() + crl._crl = crypto_crl._x509_crl + return crl + + def get_revoked(self): + """ + Return the revocations in this certificate revocation list. + + These revocations will be provided by value, not by reference. + That means it's okay to mutate them: it won't affect this CRL. + + :return: The revocations in this CRL. + :rtype: :class:`tuple` of :class:`Revocation` + """ + results = [] + revoked_stack = _lib.X509_CRL_get_REVOKED(self._crl) + for i in range(_lib.sk_X509_REVOKED_num(revoked_stack)): + revoked = _lib.sk_X509_REVOKED_value(revoked_stack, i) + revoked_copy = _lib.Cryptography_X509_REVOKED_dup(revoked) + pyrev = Revoked.__new__(Revoked) + pyrev._revoked = _ffi.gc(revoked_copy, _lib.X509_REVOKED_free) + results.append(pyrev) + if results: + return tuple(results) + + def add_revoked(self, revoked): + """ + Add a revoked (by value not reference) to the CRL structure + + This revocation will be added by value, not by reference. That + means it's okay to mutate it after adding: it won't affect + this CRL. + + :param Revoked revoked: The new revocation. + :return: ``None`` + """ + copy = _lib.Cryptography_X509_REVOKED_dup(revoked._revoked) + _openssl_assert(copy != _ffi.NULL) + + add_result = _lib.X509_CRL_add0_revoked(self._crl, copy) + _openssl_assert(add_result != 0) + + def get_issuer(self): + """ + Get the CRL's issuer. + + .. versionadded:: 16.1.0 + + :rtype: X509Name + """ + _issuer = _lib.X509_NAME_dup(_lib.X509_CRL_get_issuer(self._crl)) + _openssl_assert(_issuer != _ffi.NULL) + _issuer = _ffi.gc(_issuer, _lib.X509_NAME_free) + issuer = X509Name.__new__(X509Name) + issuer._name = _issuer + return issuer + + def set_version(self, version): + """ + Set the CRL version. + + .. versionadded:: 16.1.0 + + :param int version: The version of the CRL. + :return: ``None`` + """ + _openssl_assert(_lib.X509_CRL_set_version(self._crl, version) != 0) + + def _set_boundary_time(self, which, when): + return _set_asn1_time(which(self._crl), when) + + def set_lastUpdate(self, when): + """ + Set when the CRL was last updated. + + The timestamp is formatted as an ASN.1 TIME:: + + YYYYMMDDhhmmssZ + + .. versionadded:: 16.1.0 + + :param bytes when: A timestamp string. + :return: ``None`` + """ + return self._set_boundary_time(_lib.X509_CRL_get_lastUpdate, when) + + def set_nextUpdate(self, when): + """ + Set when the CRL will next be udpated. + + The timestamp is formatted as an ASN.1 TIME:: + + YYYYMMDDhhmmssZ + + .. versionadded:: 16.1.0 + + :param bytes when: A timestamp string. + :return: ``None`` + """ + return self._set_boundary_time(_lib.X509_CRL_get_nextUpdate, when) + + def sign(self, issuer_cert, issuer_key, digest): + """ + Sign the CRL. + + Signing a CRL enables clients to associate the CRL itself with an + issuer. Before a CRL is meaningful to other OpenSSL functions, it must + be signed by an issuer. + + This method implicitly sets the issuer's name based on the issuer + certificate and private key used to sign the CRL. + + .. versionadded:: 16.1.0 + + :param X509 issuer_cert: The issuer's certificate. + :param PKey issuer_key: The issuer's private key. + :param bytes digest: The digest method to sign the CRL with. + """ + digest_obj = _lib.EVP_get_digestbyname(digest) + _openssl_assert(digest_obj != _ffi.NULL) + _lib.X509_CRL_set_issuer_name( + self._crl, _lib.X509_get_subject_name(issuer_cert._x509)) + _lib.X509_CRL_sort(self._crl) + result = _lib.X509_CRL_sign(self._crl, issuer_key._pkey, digest_obj) + _openssl_assert(result != 0) + + def export(self, cert, key, type=FILETYPE_PEM, days=100, + digest=_UNSPECIFIED): + """ + Export the CRL as a string. + + :param X509 cert: The certificate used to sign the CRL. + :param PKey key: The key used to sign the CRL. + :param int type: The export format, either :data:`FILETYPE_PEM`, + :data:`FILETYPE_ASN1`, or :data:`FILETYPE_TEXT`. + :param int days: The number of days until the next update of this CRL. + :param bytes digest: The name of the message digest to use (eg + ``b"sha2566"``). + :rtype: bytes + """ + + if not isinstance(cert, X509): + raise TypeError("cert must be an X509 instance") + if not isinstance(key, PKey): + raise TypeError("key must be a PKey instance") + if not isinstance(type, int): + raise TypeError("type must be an integer") + + if digest is _UNSPECIFIED: + raise TypeError("digest must be provided") + + digest_obj = _lib.EVP_get_digestbyname(digest) + if digest_obj == _ffi.NULL: + raise ValueError("No such digest method") + + bio = _lib.BIO_new(_lib.BIO_s_mem()) + _openssl_assert(bio != _ffi.NULL) + + # A scratch time object to give different values to different CRL + # fields + sometime = _lib.ASN1_TIME_new() + _openssl_assert(sometime != _ffi.NULL) + + _lib.X509_gmtime_adj(sometime, 0) + _lib.X509_CRL_set_lastUpdate(self._crl, sometime) + + _lib.X509_gmtime_adj(sometime, days * 24 * 60 * 60) + _lib.X509_CRL_set_nextUpdate(self._crl, sometime) + + _lib.X509_CRL_set_issuer_name( + self._crl, _lib.X509_get_subject_name(cert._x509) + ) + + sign_result = _lib.X509_CRL_sign(self._crl, key._pkey, digest_obj) + if not sign_result: + _raise_current_error() + + return dump_crl(type, self) + + +CRLType = deprecated( + CRL, __name__, + "CRLType has been deprecated, use CRL instead", + DeprecationWarning +) + + +class PKCS7(object): + def type_is_signed(self): + """ + Check if this NID_pkcs7_signed object + + :return: True if the PKCS7 is of type signed + """ + return bool(_lib.PKCS7_type_is_signed(self._pkcs7)) + + def type_is_enveloped(self): + """ + Check if this NID_pkcs7_enveloped object + + :returns: True if the PKCS7 is of type enveloped + """ + return bool(_lib.PKCS7_type_is_enveloped(self._pkcs7)) + + def type_is_signedAndEnveloped(self): + """ + Check if this NID_pkcs7_signedAndEnveloped object + + :returns: True if the PKCS7 is of type signedAndEnveloped + """ + return bool(_lib.PKCS7_type_is_signedAndEnveloped(self._pkcs7)) + + def type_is_data(self): + """ + Check if this NID_pkcs7_data object + + :return: True if the PKCS7 is of type data + """ + return bool(_lib.PKCS7_type_is_data(self._pkcs7)) + + def get_type_name(self): + """ + Returns the type name of the PKCS7 structure + + :return: A string with the typename + """ + nid = _lib.OBJ_obj2nid(self._pkcs7.type) + string_type = _lib.OBJ_nid2sn(nid) + return _ffi.string(string_type) + + +PKCS7Type = deprecated( + PKCS7, __name__, + "PKCS7Type has been deprecated, use PKCS7 instead", + DeprecationWarning +) + + +class PKCS12(object): + """ + A PKCS #12 archive. + """ + + def __init__(self): + self._pkey = None + self._cert = None + self._cacerts = None + self._friendlyname = None + + def get_certificate(self): + """ + Get the certificate in the PKCS #12 structure. + + :return: The certificate, or :py:const:`None` if there is none. + :rtype: :py:class:`X509` or :py:const:`None` + """ + return self._cert + + def set_certificate(self, cert): + """ + Set the certificate in the PKCS #12 structure. + + :param cert: The new certificate, or :py:const:`None` to unset it. + :type cert: :py:class:`X509` or :py:const:`None` + + :return: ``None`` + """ + if not isinstance(cert, X509): + raise TypeError("cert must be an X509 instance") + self._cert = cert + + def get_privatekey(self): + """ + Get the private key in the PKCS #12 structure. + + :return: The private key, or :py:const:`None` if there is none. + :rtype: :py:class:`PKey` + """ + return self._pkey + + def set_privatekey(self, pkey): + """ + Set the certificate portion of the PKCS #12 structure. + + :param pkey: The new private key, or :py:const:`None` to unset it. + :type pkey: :py:class:`PKey` or :py:const:`None` + + :return: ``None`` + """ + if not isinstance(pkey, PKey): + raise TypeError("pkey must be a PKey instance") + self._pkey = pkey + + def get_ca_certificates(self): + """ + Get the CA certificates in the PKCS #12 structure. + + :return: A tuple with the CA certificates in the chain, or + :py:const:`None` if there are none. + :rtype: :py:class:`tuple` of :py:class:`X509` or :py:const:`None` + """ + if self._cacerts is not None: + return tuple(self._cacerts) + + def set_ca_certificates(self, cacerts): + """ + Replace or set the CA certificates within the PKCS12 object. + + :param cacerts: The new CA certificates, or :py:const:`None` to unset + them. + :type cacerts: An iterable of :py:class:`X509` or :py:const:`None` + + :return: ``None`` + """ + if cacerts is None: + self._cacerts = None + else: + cacerts = list(cacerts) + for cert in cacerts: + if not isinstance(cert, X509): + raise TypeError( + "iterable must only contain X509 instances" + ) + self._cacerts = cacerts + + def set_friendlyname(self, name): + """ + Set the friendly name in the PKCS #12 structure. + + :param name: The new friendly name, or :py:const:`None` to unset. + :type name: :py:class:`bytes` or :py:const:`None` + + :return: ``None`` + """ + if name is None: + self._friendlyname = None + elif not isinstance(name, bytes): + raise TypeError( + "name must be a byte string or None (not %r)" % (name,) + ) + self._friendlyname = name + + def get_friendlyname(self): + """ + Get the friendly name in the PKCS# 12 structure. + + :returns: The friendly name, or :py:const:`None` if there is none. + :rtype: :py:class:`bytes` or :py:const:`None` + """ + return self._friendlyname + + def export(self, passphrase=None, iter=2048, maciter=1): + """ + Dump a PKCS12 object as a string. + + For more information, see the :c:func:`PKCS12_create` man page. + + :param passphrase: The passphrase used to encrypt the structure. Unlike + some other passphrase arguments, this *must* be a string, not a + callback. + :type passphrase: :py:data:`bytes` + + :param iter: Number of times to repeat the encryption step. + :type iter: :py:data:`int` + + :param maciter: Number of times to repeat the MAC step. + :type maciter: :py:data:`int` + + :return: The string representation of the PKCS #12 structure. + :rtype: + """ + passphrase = _text_to_bytes_and_warn("passphrase", passphrase) + + if self._cacerts is None: + cacerts = _ffi.NULL + else: + cacerts = _lib.sk_X509_new_null() + cacerts = _ffi.gc(cacerts, _lib.sk_X509_free) + for cert in self._cacerts: + _lib.sk_X509_push(cacerts, cert._x509) + + if passphrase is None: + passphrase = _ffi.NULL + + friendlyname = self._friendlyname + if friendlyname is None: + friendlyname = _ffi.NULL + + if self._pkey is None: + pkey = _ffi.NULL + else: + pkey = self._pkey._pkey + + if self._cert is None: + cert = _ffi.NULL + else: + cert = self._cert._x509 + + pkcs12 = _lib.PKCS12_create( + passphrase, friendlyname, pkey, cert, cacerts, + _lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + _lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + iter, maciter, 0) + if pkcs12 == _ffi.NULL: + _raise_current_error() + pkcs12 = _ffi.gc(pkcs12, _lib.PKCS12_free) + + bio = _new_mem_buf() + _lib.i2d_PKCS12_bio(bio, pkcs12) + return _bio_to_string(bio) + + +PKCS12Type = deprecated( + PKCS12, __name__, + "PKCS12Type has been deprecated, use PKCS12 instead", + DeprecationWarning +) + + +class NetscapeSPKI(object): + """ + A Netscape SPKI object. + """ + + def __init__(self): + spki = _lib.NETSCAPE_SPKI_new() + self._spki = _ffi.gc(spki, _lib.NETSCAPE_SPKI_free) + + def sign(self, pkey, digest): + """ + Sign the certificate request with this key and digest type. + + :param pkey: The private key to sign with. + :type pkey: :py:class:`PKey` + + :param digest: The message digest to use. + :type digest: :py:class:`bytes` + + :return: ``None`` + """ + if pkey._only_public: + raise ValueError("Key has only public part") + + if not pkey._initialized: + raise ValueError("Key is uninitialized") + + digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest)) + if digest_obj == _ffi.NULL: + raise ValueError("No such digest method") + + sign_result = _lib.NETSCAPE_SPKI_sign( + self._spki, pkey._pkey, digest_obj + ) + _openssl_assert(sign_result > 0) + + def verify(self, key): + """ + Verifies a signature on a certificate request. + + :param PKey key: The public key that signature is supposedly from. + + :return: ``True`` if the signature is correct. + :rtype: bool + + :raises OpenSSL.crypto.Error: If the signature is invalid, or there was + a problem verifying the signature. + """ + answer = _lib.NETSCAPE_SPKI_verify(self._spki, key._pkey) + if answer <= 0: + _raise_current_error() + return True + + def b64_encode(self): + """ + Generate a base64 encoded representation of this SPKI object. + + :return: The base64 encoded string. + :rtype: :py:class:`bytes` + """ + encoded = _lib.NETSCAPE_SPKI_b64_encode(self._spki) + result = _ffi.string(encoded) + _lib.OPENSSL_free(encoded) + return result + + def get_pubkey(self): + """ + Get the public key of this certificate. + + :return: The public key. + :rtype: :py:class:`PKey` + """ + pkey = PKey.__new__(PKey) + pkey._pkey = _lib.NETSCAPE_SPKI_get_pubkey(self._spki) + _openssl_assert(pkey._pkey != _ffi.NULL) + pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free) + pkey._only_public = True + return pkey + + def set_pubkey(self, pkey): + """ + Set the public key of the certificate + + :param pkey: The public key + :return: ``None`` + """ + set_result = _lib.NETSCAPE_SPKI_set_pubkey(self._spki, pkey._pkey) + _openssl_assert(set_result == 1) + + +NetscapeSPKIType = deprecated( + NetscapeSPKI, __name__, + "NetscapeSPKIType has been deprecated, use NetscapeSPKI instead", + DeprecationWarning +) + + +class _PassphraseHelper(object): + def __init__(self, type, passphrase, more_args=False, truncate=False): + if type != FILETYPE_PEM and passphrase is not None: + raise ValueError( + "only FILETYPE_PEM key format supports encryption" + ) + self._passphrase = passphrase + self._more_args = more_args + self._truncate = truncate + self._problems = [] + + @property + def callback(self): + if self._passphrase is None: + return _ffi.NULL + elif isinstance(self._passphrase, bytes): + return _ffi.NULL + elif callable(self._passphrase): + return _ffi.callback("pem_password_cb", self._read_passphrase) + else: + raise TypeError( + "Last argument must be a byte string or a callable." + ) + + @property + def callback_args(self): + if self._passphrase is None: + return _ffi.NULL + elif isinstance(self._passphrase, bytes): + return self._passphrase + elif callable(self._passphrase): + return _ffi.NULL + else: + raise TypeError( + "Last argument must be a byte string or a callable." + ) + + def raise_if_problem(self, exceptionType=Error): + if self._problems: + + # Flush the OpenSSL error queue + try: + _exception_from_error_queue(exceptionType) + except exceptionType: + pass + + raise self._problems.pop(0) + + def _read_passphrase(self, buf, size, rwflag, userdata): + try: + if self._more_args: + result = self._passphrase(size, rwflag, userdata) + else: + result = self._passphrase(rwflag) + if not isinstance(result, bytes): + raise ValueError("String expected") + if len(result) > size: + if self._truncate: + result = result[:size] + else: + raise ValueError( + "passphrase returned by callback is too long" + ) + for i in range(len(result)): + buf[i] = result[i:i + 1] + return len(result) + except Exception as e: + self._problems.append(e) + return 0 + + +def load_publickey(type, buffer): + """ + Load a public key from a buffer. + + :param type: The file type (one of :data:`FILETYPE_PEM`, + :data:`FILETYPE_ASN1`). + :param buffer: The buffer the key is stored in. + :type buffer: A Python string object, either unicode or bytestring. + :return: The PKey object. + :rtype: :class:`PKey` + """ + if isinstance(buffer, _text_type): + buffer = buffer.encode("ascii") + + bio = _new_mem_buf(buffer) + + if type == FILETYPE_PEM: + evp_pkey = _lib.PEM_read_bio_PUBKEY( + bio, _ffi.NULL, _ffi.NULL, _ffi.NULL) + elif type == FILETYPE_ASN1: + evp_pkey = _lib.d2i_PUBKEY_bio(bio, _ffi.NULL) + else: + raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1") + + if evp_pkey == _ffi.NULL: + _raise_current_error() + + pkey = PKey.__new__(PKey) + pkey._pkey = _ffi.gc(evp_pkey, _lib.EVP_PKEY_free) + pkey._only_public = True + return pkey + + +def load_privatekey(type, buffer, passphrase=None): + """ + Load a private key from a buffer + + :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1) + :param buffer: The buffer the key is stored in + :param passphrase: (optional) if encrypted PEM format, this can be + either the passphrase to use, or a callback for + providing the passphrase. + + :return: The PKey object + """ + if isinstance(buffer, _text_type): + buffer = buffer.encode("ascii") + + bio = _new_mem_buf(buffer) + + helper = _PassphraseHelper(type, passphrase) + if type == FILETYPE_PEM: + evp_pkey = _lib.PEM_read_bio_PrivateKey( + bio, _ffi.NULL, helper.callback, helper.callback_args) + helper.raise_if_problem() + elif type == FILETYPE_ASN1: + evp_pkey = _lib.d2i_PrivateKey_bio(bio, _ffi.NULL) + else: + raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1") + + if evp_pkey == _ffi.NULL: + _raise_current_error() + + pkey = PKey.__new__(PKey) + pkey._pkey = _ffi.gc(evp_pkey, _lib.EVP_PKEY_free) + return pkey + + +def dump_certificate_request(type, req): + """ + Dump a certificate request to a buffer + + :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1) + :param req: The certificate request to dump + :return: The buffer with the dumped certificate request in + """ + bio = _new_mem_buf() + + if type == FILETYPE_PEM: + result_code = _lib.PEM_write_bio_X509_REQ(bio, req._req) + elif type == FILETYPE_ASN1: + result_code = _lib.i2d_X509_REQ_bio(bio, req._req) + elif type == FILETYPE_TEXT: + result_code = _lib.X509_REQ_print_ex(bio, req._req, 0, 0) + else: + raise ValueError( + "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or " + "FILETYPE_TEXT" + ) + + _openssl_assert(result_code != 0) + + return _bio_to_string(bio) + + +def load_certificate_request(type, buffer): + """ + Load a certificate request from a buffer + + :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1) + :param buffer: The buffer the certificate request is stored in + :return: The X509Req object + """ + if isinstance(buffer, _text_type): + buffer = buffer.encode("ascii") + + bio = _new_mem_buf(buffer) + + if type == FILETYPE_PEM: + req = _lib.PEM_read_bio_X509_REQ(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL) + elif type == FILETYPE_ASN1: + req = _lib.d2i_X509_REQ_bio(bio, _ffi.NULL) + else: + raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1") + + _openssl_assert(req != _ffi.NULL) + + x509req = X509Req.__new__(X509Req) + x509req._req = _ffi.gc(req, _lib.X509_REQ_free) + return x509req + + +def sign(pkey, data, digest): + """ + Sign data with a digest + + :param pkey: Pkey to sign with + :param data: data to be signed + :param digest: message digest to use + :return: signature + """ + data = _text_to_bytes_and_warn("data", data) + + digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest)) + if digest_obj == _ffi.NULL: + raise ValueError("No such digest method") + + md_ctx = _lib.Cryptography_EVP_MD_CTX_new() + md_ctx = _ffi.gc(md_ctx, _lib.Cryptography_EVP_MD_CTX_free) + + _lib.EVP_SignInit(md_ctx, digest_obj) + _lib.EVP_SignUpdate(md_ctx, data, len(data)) + + length = _lib.EVP_PKEY_size(pkey._pkey) + _openssl_assert(length > 0) + signature_buffer = _ffi.new("unsigned char[]", length) + signature_length = _ffi.new("unsigned int *") + final_result = _lib.EVP_SignFinal( + md_ctx, signature_buffer, signature_length, pkey._pkey) + _openssl_assert(final_result == 1) + + return _ffi.buffer(signature_buffer, signature_length[0])[:] + + +def verify(cert, signature, data, digest): + """ + Verify a signature. + + :param cert: signing certificate (X509 object) + :param signature: signature returned by sign function + :param data: data to be verified + :param digest: message digest to use + :return: ``None`` if the signature is correct, raise exception otherwise. + """ + data = _text_to_bytes_and_warn("data", data) + + digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest)) + if digest_obj == _ffi.NULL: + raise ValueError("No such digest method") + + pkey = _lib.X509_get_pubkey(cert._x509) + _openssl_assert(pkey != _ffi.NULL) + pkey = _ffi.gc(pkey, _lib.EVP_PKEY_free) + + md_ctx = _lib.Cryptography_EVP_MD_CTX_new() + md_ctx = _ffi.gc(md_ctx, _lib.Cryptography_EVP_MD_CTX_free) + + _lib.EVP_VerifyInit(md_ctx, digest_obj) + _lib.EVP_VerifyUpdate(md_ctx, data, len(data)) + verify_result = _lib.EVP_VerifyFinal( + md_ctx, signature, len(signature), pkey + ) + + if verify_result != 1: + _raise_current_error() + + +def dump_crl(type, crl): + """ + Dump a certificate revocation list to a buffer. + + :param type: The file type (one of ``FILETYPE_PEM``, ``FILETYPE_ASN1``, or + ``FILETYPE_TEXT``). + :param CRL crl: The CRL to dump. + + :return: The buffer with the CRL. + :rtype: bytes + """ + bio = _new_mem_buf() + + if type == FILETYPE_PEM: + ret = _lib.PEM_write_bio_X509_CRL(bio, crl._crl) + elif type == FILETYPE_ASN1: + ret = _lib.i2d_X509_CRL_bio(bio, crl._crl) + elif type == FILETYPE_TEXT: + ret = _lib.X509_CRL_print(bio, crl._crl) + else: + raise ValueError( + "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or " + "FILETYPE_TEXT") + + assert ret == 1 + return _bio_to_string(bio) + + +def load_crl(type, buffer): + """ + Load a certificate revocation list from a buffer + + :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1) + :param buffer: The buffer the CRL is stored in + + :return: The PKey object + """ + if isinstance(buffer, _text_type): + buffer = buffer.encode("ascii") + + bio = _new_mem_buf(buffer) + + if type == FILETYPE_PEM: + crl = _lib.PEM_read_bio_X509_CRL(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL) + elif type == FILETYPE_ASN1: + crl = _lib.d2i_X509_CRL_bio(bio, _ffi.NULL) + else: + raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1") + + if crl == _ffi.NULL: + _raise_current_error() + + result = CRL.__new__(CRL) + result._crl = _ffi.gc(crl, _lib.X509_CRL_free) + return result + + +def load_pkcs7_data(type, buffer): + """ + Load pkcs7 data from a buffer + + :param type: The file type (one of FILETYPE_PEM or FILETYPE_ASN1) + :param buffer: The buffer with the pkcs7 data. + :return: The PKCS7 object + """ + if isinstance(buffer, _text_type): + buffer = buffer.encode("ascii") + + bio = _new_mem_buf(buffer) + + if type == FILETYPE_PEM: + pkcs7 = _lib.PEM_read_bio_PKCS7(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL) + elif type == FILETYPE_ASN1: + pkcs7 = _lib.d2i_PKCS7_bio(bio, _ffi.NULL) + else: + raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1") + + if pkcs7 == _ffi.NULL: + _raise_current_error() + + pypkcs7 = PKCS7.__new__(PKCS7) + pypkcs7._pkcs7 = _ffi.gc(pkcs7, _lib.PKCS7_free) + return pypkcs7 + + +def load_pkcs12(buffer, passphrase=None): + """ + Load a PKCS12 object from a buffer + + :param buffer: The buffer the certificate is stored in + :param passphrase: (Optional) The password to decrypt the PKCS12 lump + :returns: The PKCS12 object + """ + passphrase = _text_to_bytes_and_warn("passphrase", passphrase) + + if isinstance(buffer, _text_type): + buffer = buffer.encode("ascii") + + bio = _new_mem_buf(buffer) + + # Use null passphrase if passphrase is None or empty string. With PKCS#12 + # password based encryption no password and a zero length password are two + # different things, but OpenSSL implementation will try both to figure out + # which one works. + if not passphrase: + passphrase = _ffi.NULL + + p12 = _lib.d2i_PKCS12_bio(bio, _ffi.NULL) + if p12 == _ffi.NULL: + _raise_current_error() + p12 = _ffi.gc(p12, _lib.PKCS12_free) + + pkey = _ffi.new("EVP_PKEY**") + cert = _ffi.new("X509**") + cacerts = _ffi.new("Cryptography_STACK_OF_X509**") + + parse_result = _lib.PKCS12_parse(p12, passphrase, pkey, cert, cacerts) + if not parse_result: + _raise_current_error() + + cacerts = _ffi.gc(cacerts[0], _lib.sk_X509_free) + + # openssl 1.0.0 sometimes leaves an X509_check_private_key error in the + # queue for no particular reason. This error isn't interesting to anyone + # outside this function. It's not even interesting to us. Get rid of it. + try: + _raise_current_error() + except Error: + pass + + if pkey[0] == _ffi.NULL: + pykey = None + else: + pykey = PKey.__new__(PKey) + pykey._pkey = _ffi.gc(pkey[0], _lib.EVP_PKEY_free) + + if cert[0] == _ffi.NULL: + pycert = None + friendlyname = None + else: + pycert = X509.__new__(X509) + pycert._x509 = _ffi.gc(cert[0], _lib.X509_free) + + friendlyname_length = _ffi.new("int*") + friendlyname_buffer = _lib.X509_alias_get0( + cert[0], friendlyname_length + ) + friendlyname = _ffi.buffer( + friendlyname_buffer, friendlyname_length[0] + )[:] + if friendlyname_buffer == _ffi.NULL: + friendlyname = None + + pycacerts = [] + for i in range(_lib.sk_X509_num(cacerts)): + pycacert = X509.__new__(X509) + pycacert._x509 = _lib.sk_X509_value(cacerts, i) + pycacerts.append(pycacert) + if not pycacerts: + pycacerts = None + + pkcs12 = PKCS12.__new__(PKCS12) + pkcs12._pkey = pykey + pkcs12._cert = pycert + pkcs12._cacerts = pycacerts + pkcs12._friendlyname = friendlyname + return pkcs12 + + +# There are no direct unit tests for this initialization. It is tested +# indirectly since it is necessary for functions like dump_privatekey when +# using encryption. +# +# Thus OpenSSL.test.test_crypto.FunctionTests.test_dump_privatekey_passphrase +# and some other similar tests may fail without this (though they may not if +# the Python runtime has already done some initialization of the underlying +# OpenSSL library (and is linked against the same one that cryptography is +# using)). +_lib.OpenSSL_add_all_algorithms() + +# This is similar but exercised mainly by exception_from_error_queue. It calls +# both ERR_load_crypto_strings() and ERR_load_SSL_strings(). +_lib.SSL_load_error_strings() + + +# Set the default string mask to match OpenSSL upstream (since 2005) and +# RFC5280 recommendations. +_lib.ASN1_STRING_set_default_mask_asc(b'utf8only') diff --git a/venv/lib/python2.7/site-packages/OpenSSL/crypto.pyc b/venv/lib/python2.7/site-packages/OpenSSL/crypto.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5958eeeb8eb0236b8df43235787c71d136314ae GIT binary patch literal 110498 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 M<0m$)+qC|F0W%L#r2qf` literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/OpenSSL/debug.py b/venv/lib/python2.7/site-packages/OpenSSL/debug.py new file mode 100644 index 0000000..0d37bf5 --- /dev/null +++ b/venv/lib/python2.7/site-packages/OpenSSL/debug.py @@ -0,0 +1,42 @@ +from __future__ import print_function + +import ssl +import sys + +import OpenSSL.SSL +import cffi +import cryptography + +from . import version + + +_env_info = u"""\ +pyOpenSSL: {pyopenssl} +cryptography: {cryptography} +cffi: {cffi} +cryptography's compiled against OpenSSL: {crypto_openssl_compile} +cryptography's linked OpenSSL: {crypto_openssl_link} +Pythons's OpenSSL: {python_openssl} +Python executable: {python} +Python version: {python_version} +Platform: {platform} +sys.path: {sys_path}""".format( + pyopenssl=version.__version__, + crypto_openssl_compile=OpenSSL._util.ffi.string( + OpenSSL._util.lib.OPENSSL_VERSION_TEXT, + ).decode("ascii"), + crypto_openssl_link=OpenSSL.SSL.SSLeay_version( + OpenSSL.SSL.SSLEAY_VERSION + ).decode("ascii"), + python_openssl=getattr(ssl, "OPENSSL_VERSION", "n/a"), + cryptography=cryptography.__version__, + cffi=cffi.__version__, + python=sys.executable, + python_version=sys.version, + platform=sys.platform, + sys_path=sys.path, +) + + +if __name__ == "__main__": + print(_env_info) diff --git a/venv/lib/python2.7/site-packages/OpenSSL/debug.pyc b/venv/lib/python2.7/site-packages/OpenSSL/debug.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e16a68ba7636fe9c10210387f86772cf341b8e6 GIT binary patch literal 1418 zcmZ`(-EY${5WlotyJRixK4Al)zR{O88%&cx2mw+bCZTm|Cj@!1(%Na0rAd@r3K=Rd z`;++t;Or*d#=vUq-+lPb_dC1gUk#)Gvu2GUAG@@^2Mv8r-cmpZ zzNx@t;9Ckjfg3QaeGmu0x8bS;@qs3ug4mb2v_R1??CcO%?r$0$;tKE)O;PLy$ec77 zqZut}$618oB(|ezMwYuG86C%! zN?PuFzDU~Ra2C0~;B9+iyFr5O+wjXEEYHDm&j%5FH@Kqx|J^6;3*#cgX&5Aw@zya? zx*|d0(-z;wI7NHp3ss}sx3c9_tPCtykb`fd6UH-X%HhIDvZNc?I3*=PCgB2gNq9jW z?veEGN^y-$b~1Kd+ zhAy2GbvJ|S`hpz>r>ckU)bf8#Oe0ygGl4M1!?6zt)6TzIh zffMF*1@?@nQAbw~uR}ZFc1q~~3QV%hZ4~C*j!h@@IlV#CIWeclr}4@0+&j5?b$UD< z1+Pz!CeGCRc0^+mn3rbcMu(%+_4(lxug|VunyVLU<`kP;jM7P$+AV2*I}3U0i+7Uf gq)St)RM+bAqq)`4HJ#8F&AQg4Z;7Nt`bu5<1Cgt9q5uE@ literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/OpenSSL/tsafe.py b/venv/lib/python2.7/site-packages/OpenSSL/tsafe.py new file mode 100644 index 0000000..f1c6f67 --- /dev/null +++ b/venv/lib/python2.7/site-packages/OpenSSL/tsafe.py @@ -0,0 +1,31 @@ +import warnings +from threading import RLock as _RLock + +from OpenSSL import SSL as _ssl + + +warnings.warn( + "OpenSSL.tsafe is deprecated and will be removed", + DeprecationWarning, stacklevel=3 +) + + +class Connection: + def __init__(self, *args): + self._ssl_conn = _ssl.Connection(*args) + self._lock = _RLock() + + for f in ('get_context', 'pending', 'send', 'write', 'recv', 'read', + 'renegotiate', 'bind', 'listen', 'connect', 'accept', + 'setblocking', 'fileno', 'shutdown', 'close', 'get_cipher_list', + 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', + 'makefile', 'get_app_data', 'set_app_data', 'state_string', + 'sock_shutdown', 'get_peer_certificate', 'get_peer_cert_chain', + 'want_read', 'want_write', 'set_connect_state', + 'set_accept_state', 'connect_ex', 'sendall'): + exec("""def %s(self, *args): + self._lock.acquire() + try: + return self._ssl_conn.%s(*args) + finally: + self._lock.release()\n""" % (f, f)) diff --git a/venv/lib/python2.7/site-packages/OpenSSL/tsafe.pyc b/venv/lib/python2.7/site-packages/OpenSSL/tsafe.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72c7a13babdb7d33f129af25cceb61c04e8729fa GIT binary patch literal 2045 zcmc&#ZEqVz5T3Ig=Y6cC>+e1D5S{~U?JZvqv- zq+R!*N?_50Ngop0>q9kw#THD4kZ6GOZBPTyJD|2e4dG2MNfe59LG8eA0B-=EPmoFA zY_x~g&0qMOjuKo3a+^P?i;I@+BYSrC#Ao<^+GvaGaqzO#sqv}Ojnjn;TBXvebZx3C zo$A!-MZMB0kZB)eaZ%}&t_+!C+4r@zx(KGWZP>NAs!u^5oI1oS&~B;WM+@Pg!G{hts90 z)Wdmr_2aA0v*t3kA?x1Uj&XAtcF>U!#+o3+ySVn03naIa@D9FbI#3otzYJj;d2FUK zb{0doic?xU6Euskv8%X{iVZkz^{fsC)8LJ%K_x0lWqi<Y}h3Hk_G5iYzlBg3m+WCypJkmTD*<+gJ^^T5`}ibl!hiDy#LP) zQOu>WfsnM8HVCJ&o)jN*ZNYCMOA*BKp<6O_5T$J)qmVSaW7taSq{mLms`7u}TIn*q z??;5i2kB>o#KW)l(rXXxj2XFOS-e;pr$>hy2ZFoY)F5T2!_wKbRmSPyNXO`?b+KWf zG!~=z7bDkPJ6&n%$@S@oW{4Q$rjo0~B7$XHNR@Nl2<3!De}zT16syGI zwuGL&Tw#&7S}b~kNY`EV$ym%kB5@p_4tyQofzNM(k6G+y#3Ebnz?Y|JFXxQuYRc~t zxkrTVuly4tpAw;~BR@pK)~*`PnZ<^WDDyb=Gz3C0u7p_BYFQzhQ(%EE#ggo`_YtrD zvrCDuQ63+fm|?Oz=qGUPvo~xb<4AY#$XYs!Bj&c>ieqz literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/OpenSSL/version.py b/venv/lib/python2.7/site-packages/OpenSSL/version.py new file mode 100644 index 0000000..274d24c --- /dev/null +++ b/venv/lib/python2.7/site-packages/OpenSSL/version.py @@ -0,0 +1,22 @@ +# Copyright (C) AB Strakt +# Copyright (C) Jean-Paul Calderone +# See LICENSE for details. + +""" +pyOpenSSL - A simple wrapper around the OpenSSL library +""" + +__all__ = [ + "__author__", "__copyright__", "__email__", "__license__", "__summary__", + "__title__", "__uri__", "__version__", +] + +__version__ = "17.3.0" + +__title__ = "pyOpenSSL" +__uri__ = "https://pyopenssl.org/" +__summary__ = "Python wrapper module around the OpenSSL library" +__author__ = "The pyOpenSSL developers" +__email__ = "cryptography-dev@python.org" +__license__ = "Apache License, Version 2.0" +__copyright__ = "Copyright 2001-2017 {0}".format(__author__) diff --git a/venv/lib/python2.7/site-packages/OpenSSL/version.pyc b/venv/lib/python2.7/site-packages/OpenSSL/version.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e925f27779c8816c96be839b2942d6fd8c4e4f3 GIT binary patch literal 786 zcmZ`%&u`N(6n<^Dw9P05gaC<)k3G;P>8egc2yNnoG%?gp9CC@$*iGE!hh;mNG6Wa? zWc~r3(>8D+kw548`<|cQ7x#XT?AxDxKZ3(E!1)S?3K1xPkJtg)1=<680`wH91+))z z0Pz5Pq=w)lYlDx1Gw@OK1bmc@z(?g%@KHPle*p9u?1sQB_|*a52KpSDbHY+R(d5Y0l6Qw+2xngas$}Gd(TD9gnHEh38my);2ib=(bJP4G9oOdxhpSewm zwgL4Di9~Cm-aC${3v5fNbXLgNQ7%$nYdmV+_Ldd2#8&^`qI!c#ci4JcflyYl6gQSi zy+tyTwa`V3W+n9$xhv6>FeMxQT7(hi-|U-yN51WQAoH24USs~Jqg!O|y54l|dKcuo z`{T>Rn04@g7E$X*n4*&_SfN^4VVgLuMx(0d(+7R19W}#kn@NS2MK3-0Kf}t3R59tCt8?Z`>L8tghAh`~Cq?pT{)- literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/DESCRIPTION.rst b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..4824ff3 --- /dev/null +++ b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/DESCRIPTION.rst @@ -0,0 +1,76 @@ +PyJWT +===== + +.. image:: https://secure.travis-ci.org/jpadilla/pyjwt.svg?branch=master + :target: http://travis-ci.org/jpadilla/pyjwt?branch=master + +.. image:: https://ci.appveyor.com/api/projects/status/h8nt70aqtwhht39t?svg=true + :target: https://ci.appveyor.com/project/jpadilla/pyjwt + +.. image:: https://img.shields.io/pypi/v/pyjwt.svg + :target: https://pypi.python.org/pypi/pyjwt + +.. image:: https://coveralls.io/repos/jpadilla/pyjwt/badge.svg?branch=master + :target: https://coveralls.io/r/jpadilla/pyjwt?branch=master + +.. image:: https://readthedocs.org/projects/pyjwt/badge/?version=latest + :target: https://pyjwt.readthedocs.io + +A Python implementation of `RFC +7519 `_. Original implementation +was written by `@progrium `_. + +Installing +---------- + +Install with **pip**: + +.. code-block:: sh + + $ pip install PyJWT + + +Usage +----- + +.. code:: python + + >>> import jwt + >>> encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256') + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg' + + >>> jwt.decode(encoded, 'secret', algorithms=['HS256']) + {'some': 'payload'} + + +Command line +------------ + +Usage:: + + pyjwt [options] INPUT + +Decoding examples:: + + pyjwt --key=secret TOKEN + pyjwt --no-verify TOKEN + +See more options executing ``pyjwt --help``. + + +Documentation +------------- + +View the full docs online at https://pyjwt.readthedocs.io/en/latest/ + + +Tests +----- + +You can run tests from the project root after cloning with: + +.. code-block:: sh + + $ python setup.py test + + diff --git a/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/INSTALLER b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/METADATA b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/METADATA new file mode 100644 index 0000000..c119adc --- /dev/null +++ b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/METADATA @@ -0,0 +1,110 @@ +Metadata-Version: 2.0 +Name: PyJWT +Version: 1.5.3 +Summary: JSON Web Token implementation in Python +Home-page: http://github.com/jpadilla/pyjwt +Author: Jose Padilla +Author-email: hello@jpadilla.com +License: MIT +Description-Content-Type: UNKNOWN +Keywords: jwt json web token security signing +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Utilities +Provides-Extra: crypto +Requires-Dist: cryptography (>=1.4); extra == 'crypto' +Provides-Extra: flake8 +Requires-Dist: flake8; extra == 'flake8' +Requires-Dist: flake8-import-order; extra == 'flake8' +Requires-Dist: pep8-naming; extra == 'flake8' +Provides-Extra: test +Requires-Dist: pytest (<4,>3); extra == 'test' +Requires-Dist: pytest-cov; extra == 'test' +Requires-Dist: pytest-runner; extra == 'test' + +PyJWT +===== + +.. image:: https://secure.travis-ci.org/jpadilla/pyjwt.svg?branch=master + :target: http://travis-ci.org/jpadilla/pyjwt?branch=master + +.. image:: https://ci.appveyor.com/api/projects/status/h8nt70aqtwhht39t?svg=true + :target: https://ci.appveyor.com/project/jpadilla/pyjwt + +.. image:: https://img.shields.io/pypi/v/pyjwt.svg + :target: https://pypi.python.org/pypi/pyjwt + +.. image:: https://coveralls.io/repos/jpadilla/pyjwt/badge.svg?branch=master + :target: https://coveralls.io/r/jpadilla/pyjwt?branch=master + +.. image:: https://readthedocs.org/projects/pyjwt/badge/?version=latest + :target: https://pyjwt.readthedocs.io + +A Python implementation of `RFC +7519 `_. Original implementation +was written by `@progrium `_. + +Installing +---------- + +Install with **pip**: + +.. code-block:: sh + + $ pip install PyJWT + + +Usage +----- + +.. code:: python + + >>> import jwt + >>> encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256') + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg' + + >>> jwt.decode(encoded, 'secret', algorithms=['HS256']) + {'some': 'payload'} + + +Command line +------------ + +Usage:: + + pyjwt [options] INPUT + +Decoding examples:: + + pyjwt --key=secret TOKEN + pyjwt --no-verify TOKEN + +See more options executing ``pyjwt --help``. + + +Documentation +------------- + +View the full docs online at https://pyjwt.readthedocs.io/en/latest/ + + +Tests +----- + +You can run tests from the project root after cloning with: + +.. code-block:: sh + + $ python setup.py test + + diff --git a/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/RECORD b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/RECORD new file mode 100644 index 0000000..b8c2211 --- /dev/null +++ b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/RECORD @@ -0,0 +1,33 @@ +PyJWT-1.5.3.dist-info/DESCRIPTION.rst,sha256=NTi807oEiMl9QPTbA_NX8OLmLAtL4WCN9lj6zmw04bA,1639 +PyJWT-1.5.3.dist-info/METADATA,sha256=YQMYS9ks5luILyBhUJWEzRxiaowncPD0NfrJDhNgpwE,2911 +PyJWT-1.5.3.dist-info/RECORD,, +PyJWT-1.5.3.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 +PyJWT-1.5.3.dist-info/entry_points.txt,sha256=Xl_tLkGbTgywYa7PwaEY2xSiCtVtM2PdHTL4CW_n9dM,45 +PyJWT-1.5.3.dist-info/metadata.json,sha256=qfgrSQx6qIBvcFkAaFz34q76NkBadsJioyH2k63e9NU,1501 +PyJWT-1.5.3.dist-info/top_level.txt,sha256=RP5DHNyJbMq2ka0FmfTgoSaQzh7e3r5XuCWCO8a00k8,4 +jwt/__init__.py,sha256=Au0HJMdNUk9rn1oKHq3qlX4etWu_7UZoGpZJgsb738c,761 +jwt/__main__.py,sha256=E2cfCobbAPoNorrICDSD4LJTemWTtKT04wsHHp8g2Kk,4151 +jwt/algorithms.py,sha256=kL1ARjxNL8JeuxEpWS8On14qJWomMX_A_ncIrnZhBrA,13336 +jwt/api_jws.py,sha256=YYGC3eKhyxeeKZaIZkQdyOVZxz0DwZBK0Ee4iIqBE1M,7555 +jwt/api_jwt.py,sha256=xWMYu2xSCOAhIpPhO_t-HJ7IDBPFW7LkqJVKOl7cCsw,7068 +jwt/compat.py,sha256=5cYHQWJuAxcpUQo0e0Fm8-Hn7acYdZQde6M8bnZ6rBg,1784 +jwt/exceptions.py,sha256=63QgVtqVgRHdVAi0NqRO0s13opKdKZmwUGzW_CyPw4c,841 +jwt/utils.py,sha256=RraFiloy_xsB8NA1CrlHxS9lR73If8amInQ3P1mKXeM,2629 +jwt/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jwt/contrib/algorithms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jwt/contrib/algorithms/py_ecdsa.py,sha256=tSTUrwx-u14DJcqAChRzJG-wf7bEY2Gv2hI5xSZZNjk,1771 +jwt/contrib/algorithms/pycrypto.py,sha256=M3nH1Rrk6yb6aPGo6zT4EI_MvPUM4vhO1EwC-uX9JAo,1250 +../../../bin/pyjwt,sha256=c8EOhQZRKjTeuSCNcQgCoufTL6rWKumjJdGJD2ZjG_U,262 +PyJWT-1.5.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jwt/algorithms.pyc,, +jwt/api_jws.pyc,, +jwt/utils.pyc,, +jwt/__main__.pyc,, +jwt/contrib/algorithms/pycrypto.pyc,, +jwt/__init__.pyc,, +jwt/compat.pyc,, +jwt/contrib/algorithms/py_ecdsa.pyc,, +jwt/api_jwt.pyc,, +jwt/contrib/algorithms/__init__.pyc,, +jwt/exceptions.pyc,, +jwt/contrib/__init__.pyc,, diff --git a/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/WHEEL b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/WHEEL new file mode 100644 index 0000000..8b6dd1b --- /dev/null +++ b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.29.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/entry_points.txt b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/entry_points.txt new file mode 100644 index 0000000..78717b2 --- /dev/null +++ b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +pyjwt = jwt.__main__:main + diff --git a/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/metadata.json b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/metadata.json new file mode 100644 index 0000000..6742116 --- /dev/null +++ b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Natural Language :: English", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Utilities"], "description_content_type": "UNKNOWN", "extensions": {"python.commands": {"wrap_console": {"pyjwt": "jwt.__main__:main"}}, "python.details": {"contacts": [{"email": "hello@jpadilla.com", "name": "Jose Padilla", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "http://github.com/jpadilla/pyjwt"}}, "python.exports": {"console_scripts": {"pyjwt": "jwt.__main__:main"}}}, "extras": ["crypto", "flake8", "test"], "generator": "bdist_wheel (0.29.0)", "keywords": ["jwt", "json", "web", "token", "security", "signing"], "license": "MIT", "metadata_version": "2.0", "name": "PyJWT", "run_requires": [{"extra": "crypto", "requires": ["cryptography (>=1.4)"]}, {"extra": "flake8", "requires": ["flake8-import-order", "flake8", "pep8-naming"]}, {"extra": "test", "requires": ["pytest (<4,>3)", "pytest-cov", "pytest-runner"]}], "summary": "JSON Web Token implementation in Python", "test_requires": [{"requires": ["pytest (<4,>3)", "pytest-cov", "pytest-runner"]}], "version": "1.5.3"} \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/top_level.txt b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/top_level.txt new file mode 100644 index 0000000..27ccc9b --- /dev/null +++ b/venv/lib/python2.7/site-packages/PyJWT-1.5.3.dist-info/top_level.txt @@ -0,0 +1 @@ +jwt diff --git a/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/DESCRIPTION.rst b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..3e3abb7 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/DESCRIPTION.rst @@ -0,0 +1,54 @@ +Werkzeug +======== + +Werkzeug started as simple collection of various utilities for WSGI +applications and has become one of the most advanced WSGI utility +modules. It includes a powerful debugger, full featured request and +response objects, HTTP utilities to handle entity tags, cache control +headers, HTTP dates, cookie handling, file uploads, a powerful URL +routing system and a bunch of community contributed addon modules. + +Werkzeug is unicode aware and doesn't enforce a specific template +engine, database adapter or anything else. It doesn't even enforce +a specific way of handling requests and leaves all that up to the +developer. It's most useful for end user applications which should work +on as many server environments as possible (such as blogs, wikis, +bulletin boards, etc.). + +Details and example applications are available on the +`Werkzeug website `_. + + +Features +-------- + +- unicode awareness + +- request and response objects + +- various utility functions for dealing with HTTP headers such as + `Accept` and `Cache-Control` headers. + +- thread local objects with proper cleanup at request end + +- an interactive debugger + +- A simple WSGI server with support for threading and forking + with an automatic reloader. + +- a flexible URL routing system with REST support. + +- fully WSGI compatible + + +Development Version +------------------- + +The Werkzeug development version can be installed by cloning the git +repository from `github`_:: + + git clone git@github.com:pallets/werkzeug.git + +.. _github: http://github.com/pallets/werkzeug + + diff --git a/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/INSTALLER b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/LICENSE.txt b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..1c2e0b7 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/LICENSE.txt @@ -0,0 +1,29 @@ +Copyright (c) 2014 by the Werkzeug Team, see AUTHORS for more details. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/METADATA b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/METADATA new file mode 100644 index 0000000..52e12a4 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/METADATA @@ -0,0 +1,83 @@ +Metadata-Version: 2.0 +Name: Werkzeug +Version: 0.12.2 +Summary: The Swiss Army knife of Python web development +Home-page: http://werkzeug.pocoo.org/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Provides-Extra: termcolor +Requires-Dist: termcolor; extra == 'termcolor' +Provides-Extra: watchdog +Requires-Dist: watchdog; extra == 'watchdog' + +Werkzeug +======== + +Werkzeug started as simple collection of various utilities for WSGI +applications and has become one of the most advanced WSGI utility +modules. It includes a powerful debugger, full featured request and +response objects, HTTP utilities to handle entity tags, cache control +headers, HTTP dates, cookie handling, file uploads, a powerful URL +routing system and a bunch of community contributed addon modules. + +Werkzeug is unicode aware and doesn't enforce a specific template +engine, database adapter or anything else. It doesn't even enforce +a specific way of handling requests and leaves all that up to the +developer. It's most useful for end user applications which should work +on as many server environments as possible (such as blogs, wikis, +bulletin boards, etc.). + +Details and example applications are available on the +`Werkzeug website `_. + + +Features +-------- + +- unicode awareness + +- request and response objects + +- various utility functions for dealing with HTTP headers such as + `Accept` and `Cache-Control` headers. + +- thread local objects with proper cleanup at request end + +- an interactive debugger + +- A simple WSGI server with support for threading and forking + with an automatic reloader. + +- a flexible URL routing system with REST support. + +- fully WSGI compatible + + +Development Version +------------------- + +The Werkzeug development version can be installed by cloning the git +repository from `github`_:: + + git clone git@github.com:pallets/werkzeug.git + +.. _github: http://github.com/pallets/werkzeug + + diff --git a/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/RECORD b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/RECORD new file mode 100644 index 0000000..691eaf1 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/RECORD @@ -0,0 +1,95 @@ +werkzeug/posixemulation.py,sha256=xEF2Bxc-vUCPkiu4IbfWVd3LW7DROYAT-ExW6THqyzw,3519 +werkzeug/security.py,sha256=Z0v0ojdo7T4FNyfIjx86BFQKwasy3ZR9euikIJDQYP8,9191 +werkzeug/__init__.py,sha256=NDY8HsYsT3dguTLu4MhuH-GpQE5XS9aKhrdfwHnzOEk,6864 +werkzeug/testapp.py,sha256=3HQRW1sHZKXuAjCvFMet4KXtQG3loYTFnvn6LWt-4zI,9396 +werkzeug/http.py,sha256=nrk-ASJzcKOuoBEz274TWA8jKt0CQSOBZuP_A0UASTA,36658 +werkzeug/routing.py,sha256=g25wg0GNfff8WcfRlc1ZxTGvz1KbVj09w2S7wxopseQ,66746 +werkzeug/utils.py,sha256=lkybtv_mq35zV1qhelvEcILTzrMUwZ9yon6E8XwapJE,22972 +werkzeug/exceptions.py,sha256=3wp95Hqj9FqV8MdikV99JRcHse_fSMn27V8tgP5Hw2c,20505 +werkzeug/_reloader.py,sha256=NkIXQCTa6b22wWLpXob_jIVUxux8LtAsfWehLkKt0iM,8816 +werkzeug/formparser.py,sha256=DxN53eOCb6i7PxqtldrF2Kv9Mx00BqW297N4t-RxkWE,21241 +werkzeug/_compat.py,sha256=8c4U9o6A_TR9nKCcTbpZNxpqCXcXDVIbFawwKM2s92c,6311 +werkzeug/datastructures.py,sha256=rq0zICISMUetS3xvUVvrhIvyue9oUzrs_NU3b83zwuQ,89066 +werkzeug/wrappers.py,sha256=wceh1RhvhIZVzKuok3XMQ5jqjYYCEYv5JqKY3Nc_oRY,82986 +werkzeug/test.py,sha256=xnabNSpty66ftZiXHcoZaYFP1E4WUNxydw5Oe8Mjhoo,34795 +werkzeug/urls.py,sha256=fSbI4Gb29_p02Zk21VAZQRN1QdOVY9CNTgpb2rbajNQ,36710 +werkzeug/script.py,sha256=Jh9OAktqjLNc_IBBUatVM7uP5LDcbxaYA8n2ObnS4bo,11666 +werkzeug/useragents.py,sha256=Ck3G977Y0Rzdk9wFcLpL0PyOrONtdK1_d2Zexb78cX4,5640 +werkzeug/local.py,sha256=QdQhWV5L8p1Y1CJ1CDStwxaUs24SuN5aebHwjVD08C8,14553 +werkzeug/serving.py,sha256=aAS3EgiD-VjemsYfSf1yqdjaGEfpB4I3M4PKlLotJLo,29069 +werkzeug/filesystem.py,sha256=hHWeWo_gqLMzTRfYt8-7n2wWcWUNTnDyudQDLOBEICE,2175 +werkzeug/wsgi.py,sha256=TjPo5ups3NI1RVVGdMvd3XaceqFtqlMX5X169gWWFrQ,42838 +werkzeug/_internal.py,sha256=sE2JbLnMzN9mRI1iipTYWrFAGEWaZVECqtHAiNEhqUE,13841 +werkzeug/contrib/fixers.py,sha256=gR06T-w71ur-tHQ_31kP_4jpOncPJ4Wc1dOqTvYusr8,10179 +werkzeug/contrib/limiter.py,sha256=iS8-ahPZ-JLRnmfIBzxpm7O_s3lPsiDMVWv7llAIDCI,1334 +werkzeug/contrib/__init__.py,sha256=f7PfttZhbrImqpr5Ezre8CXgwvcGUJK7zWNpO34WWrw,623 +werkzeug/contrib/testtools.py,sha256=G9xN-qeihJlhExrIZMCahvQOIDxdL9NiX874jiiHFMs,2453 +werkzeug/contrib/iterio.py,sha256=RlqDvGhz0RneTpzE8dVc-yWCUv4nkPl1jEc_EDp2fH0,10814 +werkzeug/contrib/cache.py,sha256=nyUUxsS0MTHiFmu-481y9PHd8NvWH5pzCoEX1yA0mHY,30341 +werkzeug/contrib/securecookie.py,sha256=bDsAJmslkwmXjycnPjEjWtfLBvhz0ud4z3k7tdezUVs,12174 +werkzeug/contrib/lint.py,sha256=qZlmqiWJ5tQJOEzLnPmHWA8eUEpcBIWkAb_V2RKJg4o,12558 +werkzeug/contrib/profiler.py,sha256=ISwCWvwVyGpDLRBRpLjo_qUWma6GXYBrTAco4PEQSHY,5151 +werkzeug/contrib/wrappers.py,sha256=v7OYlz7wQtDlS9fey75UiRZ1IkUWqCpzbhsLy4k14Hw,10398 +werkzeug/contrib/atom.py,sha256=qqfJcfIn2RYY-3hO3Oz0aLq9YuNubcPQ_KZcNsDwVJo,15575 +werkzeug/contrib/jsrouting.py,sha256=QTmgeDoKXvNK02KzXgx9lr3cAH6fAzpwF5bBdPNvJPs,8564 +werkzeug/contrib/sessions.py,sha256=39LVNvLbm5JWpbxM79WC2l87MJFbqeISARjwYbkJatw,12577 +werkzeug/debug/console.py,sha256=n3-dsKk1TsjnN-u4ZgmuWCU_HO0qw5IA7ttjhyyMM6I,5607 +werkzeug/debug/repr.py,sha256=bKqstDYGfECpeLerd48s_hxuqK4b6UWnjMu3d_DHO8I,9340 +werkzeug/debug/__init__.py,sha256=GTsOsjE3PqUAlsUVm2Mgc_KWA2kjjSsUz0JsM7Qu41w,17266 +werkzeug/debug/tbtools.py,sha256=rBudXCmkVdAKIcdhxANxgf09g6kQjJWW9_5bjSpr4OY,18451 +werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191 +werkzeug/debug/shared/source.png,sha256=RoGcBTE4CyCB85GBuDGTFlAnUqxwTBiIfDqW15EpnUQ,818 +werkzeug/debug/shared/debugger.js,sha256=PKPVYuyO4SX1hkqLOwCLvmIEO5154WatFYaXE-zIfKI,6264 +werkzeug/debug/shared/style.css,sha256=IEO0PC2pWmh2aEyGCaN--txuWsRCliuhlbEhPDFwh0A,6270 +werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507 +werkzeug/debug/shared/FONT_LICENSE,sha256=LwAVEI1oYnvXiNMT9SnCH_TaLCxCpeHziDrMg0gPkAI,4673 +werkzeug/debug/shared/jquery.js,sha256=7LkWEzqTdpEfELxcZZlS6wAx5Ff13zZ83lYO2_ujj7g,95957 +werkzeug/debug/shared/ubuntu.ttf,sha256=1eaHFyepmy4FyDvjLVzpITrGEBu_CZYY94jE0nED1c0,70220 +werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200 +Werkzeug-0.12.2.dist-info/DESCRIPTION.rst,sha256=z9r9xqJ0fYSAn1Tz7KRBdFGDerL2y4pHWSW_72pUgTc,1591 +Werkzeug-0.12.2.dist-info/metadata.json,sha256=6taKobd3cQ5zOY5MVKlvuCJGaX7VPLaHYuRwzwwkORI,1276 +Werkzeug-0.12.2.dist-info/RECORD,, +Werkzeug-0.12.2.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9 +Werkzeug-0.12.2.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110 +Werkzeug-0.12.2.dist-info/LICENSE.txt,sha256=F84h8-PZAuC-Hq-_252D3yhH6mqIc-WUbXUPbfOtjXM,1532 +Werkzeug-0.12.2.dist-info/METADATA,sha256=SphYykCCskmOJK7mV1-M2T1PTOrx5K3DJ8n3E5jA298,2738 +Werkzeug-0.12.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +werkzeug/_reloader.pyc,, +werkzeug/filesystem.pyc,, +werkzeug/contrib/testtools.pyc,, +werkzeug/formparser.pyc,, +werkzeug/_compat.pyc,, +werkzeug/posixemulation.pyc,, +werkzeug/serving.pyc,, +werkzeug/contrib/__init__.pyc,, +werkzeug/contrib/iterio.pyc,, +werkzeug/datastructures.pyc,, +werkzeug/__init__.pyc,, +werkzeug/contrib/limiter.pyc,, +werkzeug/debug/tbtools.pyc,, +werkzeug/contrib/sessions.pyc,, +werkzeug/local.pyc,, +werkzeug/utils.pyc,, +werkzeug/contrib/lint.pyc,, +werkzeug/security.pyc,, +werkzeug/contrib/cache.pyc,, +werkzeug/contrib/securecookie.pyc,, +werkzeug/script.pyc,, +werkzeug/routing.pyc,, +werkzeug/wrappers.pyc,, +werkzeug/contrib/jsrouting.pyc,, +werkzeug/contrib/fixers.pyc,, +werkzeug/contrib/profiler.pyc,, +werkzeug/debug/console.pyc,, +werkzeug/debug/__init__.pyc,, +werkzeug/wsgi.pyc,, +werkzeug/test.pyc,, +werkzeug/http.pyc,, +werkzeug/urls.pyc,, +werkzeug/useragents.pyc,, +werkzeug/_internal.pyc,, +werkzeug/contrib/wrappers.pyc,, +werkzeug/exceptions.pyc,, +werkzeug/contrib/atom.pyc,, +werkzeug/testapp.pyc,, +werkzeug/debug/repr.pyc,, diff --git a/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/WHEEL b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/WHEEL new file mode 100644 index 0000000..9dff69d --- /dev/null +++ b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.24.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/metadata.json b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/metadata.json new file mode 100644 index 0000000..d77fbb8 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/metadata.json @@ -0,0 +1 @@ +{"license": "BSD", "name": "Werkzeug", "metadata_version": "2.0", "generator": "bdist_wheel (0.24.0)", "summary": "The Swiss Army knife of Python web development", "platform": "any", "run_requires": [{"requires": ["watchdog"], "extra": "watchdog"}, {"requires": ["termcolor"], "extra": "termcolor"}], "version": "0.12.2", "extensions": {"python.details": {"project_urls": {"Home": "http://werkzeug.pocoo.org/"}, "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "contacts": [{"role": "author", "email": "armin.ronacher@active-4.com", "name": "Armin Ronacher"}]}}, "classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules"], "extras": ["termcolor", "watchdog"]} \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/top_level.txt b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/top_level.txt new file mode 100644 index 0000000..6fe8da8 --- /dev/null +++ b/venv/lib/python2.7/site-packages/Werkzeug-0.12.2.dist-info/top_level.txt @@ -0,0 +1 @@ +werkzeug diff --git a/venv/lib/python2.7/site-packages/_cffi_backend.so b/venv/lib/python2.7/site-packages/_cffi_backend.so new file mode 100755 index 0000000000000000000000000000000000000000..4c2e36637604ff2419ebfa418ab4b7f7dbe39a2b GIT binary patch literal 365472 zcmeFadwf*Y+4wt?j4;5!4w5P=mZ+$p6cg_evK-T62pBGE=6s*E_ap(e{hfc#`JD3s zo$S5WUYBP*>silwZfot$-7mi4^Z8Qv_2-xB^QG}*-Nt>$pG-@6g0$WI@rC#u{&yGy zhcR#%1BWqi7z2kfa2NxJF>n|IhcR#%1BWqi7z2kf@c%Ikynf(c-Jas_3j(_+_^kn- zuZAo7zi%slX3xGXeEDTO^!@jQyyYKPDSrgNe)7z}*|Q@z%#XPD?(@Or+YFztZHnI~ zSDNbm7w}akA7;;kHHD+0onYzWMg+XWx8#`5k0Bw2t+U`+bv1muug0 zee09jm+@!z>`A$o<@R|aV_C$rTyv5}A9qY8*X-H1GY;->%!$nX&hi^2Bjx+HEo1O2 zN$20}*|%N$@9Nk{*$9Q@+P4m&tv7THQpcfVad1B-{FmRC!63-BZyjE7eVIM``fDTC z_NE+)i>rU<_f0s<=acLA*KysvdA(J93m*@^=lA_>n46(*9bmWTpWL6%Z}#jiK1r^J#9z|N3 zue|)`an~>4hBv~G&gPfQ??3BpdV6sG84Kn`ZusfAiOE8zkYC!I01h6Y`Z3<~)-J!V zj{C#^4rAaj1`cE3Fa{1|;4lUbW8g3b4rAc|uNWw?{yC#`rr9ypkse-Un`d6;_gR5a z&Nr9%eKqxw)70cZS8i!Aa)Mc(ZmSFA?WLmvWl{MMs?W?GF(x`y_(rr?9g4CY&CDltgvdc9n zSLZe0vYKnUB8}!tf7*=n9yOdhsmn6u35cJv&E>z~nLgC&KFojEHm5)0rbOM8CAN9g zFWr=%=oF)FP9l-8&G)?2LNE17o%-0LZr<~})JZz^x?j1eCwQsjbm}ROxv7J^)Zsey zQ!n+)iv>obE=8yQ31wX1{J=}?=uRY-norS>>UyL49`qmEocn~%L;tlF=S-WdYpAX# zFBl8j=0k!pUR!66a_$EcQvYvwYn#84H`G7Ot-pF%PnjqCl$q_7xm}l8)B8qnF4~uK zo|ofNoumFca{R!{ahlF?@e0~)@nGtyX}Ifi7@Q5(A-8PXBzD;xfr&n>F$Viu<)!^4LR4 z+I>p?PuMNl^;II#tf}4~3xP*vz9>itJIZ{PsbGaWK~MF|jIJu|RJo&9XV_*Kvz~o_ zE`N+=P^-YTo>1qr_jwFwHPli7_fE<*R9EF`$VF#_tB(Y06tOn;t z7q}pt2nd#0&H&MyWGA8{Z1w6)hWu_gqSc#jRPR1Ox09XI-EzCwr*qGFHE$&A|4W@K z%62;!280&{t#o*Vhx07bEb}_uVd=INZtvx$1<;5$j04E0!tDtei^Ysi}uu z-Y2Ea#Y{(`3`Jh0GL0jo%Lx57x_nEfoUd{{qm1f6r)K&(r)DG`E2#H!#`ZD1E=4)l=$>op-$t?vln@=It%Z6KcIqf+ zwR{J1Y7$1>qi$t-atxEoT1c&4(o+|e&^678JutGRIxuZS2dIJoJV2wl6EqjOb!jf# zq8pXEE;ytv&9l9_{+0WEbp_nIG{62?PhFqwP4>}+OLKRxu3vv|UF#_Y!YUbb=Zv1Z zesf4&dL8iUD*4{JZgcArT68{=TpC|952;J97+zfizPGLnN;PX1?T^id=zC-kAx(^^ zKIe29kp?7|`Bu+d@Fqe_uGlkuExBT%^$B%;N<$2NbMD!sX5Mwj&DY!JKVg3@xfz6Mfj6BhO~mfx(HNQIOUi>ITzOE1LoMM> z$zje9`XbqCa%jA|YYDdaaY{9FH9JCfNv9ok?3c9TrgewR#!pX9cGwG^;U@l_T6*=#NC38cXmJiQX;SMW5$lFq9iCe(R55<4v_<2z3 zM1Z&Nzn8j;N~b5XoS*#I?~4y2cOu&1w7T_Vby=O}h7npuHAYqfrr^iy2x?d_H#-7$ z;n#L$1)^SYQ6d_0F7VoK$f~c|6bY)ruN{>I?luI=n#zrllXQ6zx6^bDv+eL6d&Nh~ zfn?PyNYO>b)1{U@Il32Fn*=$(q)`>!qw;0lt9_eX_Ns0CWoZCd>x)}boQE-h(`(5e zx#PRnhN-gZ=><03L%fLJ+B(-I##Xt z#1!fZCbEj0ri4ysB!CtQajWb483wa$n|AfR?N!67aZ-TXV zTwKW1GOD)-aa6Q}CfmGCld`jd4p23uFhVCUbd%@1$uH#O$Qm9!f}1p-Rp>B6rOr>? zmsUk5)5)Ii*99Aw`F%{~8V~nPH9I2LwB)%M$#XH1=VByJV}zP!IC(C%Tk>2a;1md?O=R_+zF%c;n*wgWXcs43qD%h z7PEE;KJF8Igr!q-q{w;DgB=o_qdQgmtn&L{K5N`U!rvp;wiLLXDsVeh;C8AY*{M?J z_6ZuLEd_3;3S5!0V00z8Y$4^7E4sWPq?t(hN|(P@bu0r? zmy5K7pVS;YyxP6A@4kU?QD@nx{3~nOO-z&6z=we_NTa8`HWPh8f`otHIoqvwD&d-e?uJ zG6HJyXlrxTKZHWE5>*G}+7f6|P<{ZN0<~Kpu53+vSqAEo+k%1?;U>b4&Pn7jNt3A~58H?85cMcH#5XU(1g`elOb*#Q^ zA0MuZ3^Xg&Bli$SAYH4PJlf~W@tGA*`_>C!M!3~^1ct8#hq}k9)hc^gm9%y>2CeKsr7}}I z^qv55!W~uF7U|tv^h1^G6p?yk!@iLX&hdV(spM6K8xqkqwx|*=7ePtJ_lfh93pjf>>c8Hwo2MTxtD&ag8M#`1Mw2P~_*hSP(Z5?T<1d)Rg- zUJ3}=7^{SeJaolxrI+?)O$ku8xAlar{(V{7=%>|ffzv0(G+W^B{f6$54WAwF=bAd^ zbtrhu8<1{SL%^7H09xo7`=U~K`2)^EjFx=||21g&TZ3Pp{hCqu+QjT##5#6?6IevU?HRw8Co`zwr~uSEvJXJ3|; zu=ZM=(w7${*_hO*N}fat%2m;h?8e9tm(-u+Rpr#vQnEK!{76-_saoAcGs|qqe)Smy z03@zb8oKvvX(%H$fM%@llkpS_;$2O3$Ed=N>;sYEZgoOKl~YbjvEGUIvnp2e&dSZO z7L2m4NUOYd%&Wq-*AJ`m`x5=%BeZ`$n_s!JrLbLR9SP*sFD-Od1XCjM-^j7922N~>s_S|U9IAgY(a zYD~A+meWG)RDt8W-kU8Nj~lNoQh>fbaCvwPeOt zet$PkqN4auRK-rSB^@jZ9Y)*i$F2t!tIV+`6t#0SB zGX>hr_-Kubm%fFoFpX#=I1!x_MhIbcwB%?ZCM%H`6dkPc0yI8D6n_N#eN`JoRPj`x zoI~W(%Ui-7yoKFKSQ0icG{Fvg{fUbiq=zq5HDXadZ}E}jOzQrvJ8%Mjyrq;(xap?Zo@3tY|qfKLJ00U zLPgF|ZdO+$LkXjT05hxI4sR@S{&=ZIGWFD5=DlKgI-JupHN=uW!A+kbv(XvWn=V$* z#2^+gSaa-j{!p)~=!7CW&`I}rU2d}W)$EWRq&}niC@B$)8dihK6&fpcX^iQd7y#Y% zP2+7M+UjigU`H#_0z5Emb#{AIi}3!_|0ulw*@f8Z70_FYoE)#-*=dZnnw()x%TSX? zS<^ z%FkEH)>Zzx!*1aEEZwn|s{!84H zLa|%=TV*?E+~RY#oFN2~VKtdwB_cmED|QZ_duqdHfvkD~Zm9rQzS0_$W4&u%H9Wg> z;U2Teu{6x_0e!)*{#w9KwH8YW8Ir~Sfbkbu?>J54GzDsN*lbo+tnR2^`9W(|sKqsE zShLb8G1E~$@@N(RS$fSTL5MFBW;)xoyY6AuqSY49aQ^Am2hS{2wXe*R)`IqmD;bUW zOi#U6wE~5eYCSI3tVH}e-I+g0X07+z_Z>z4A~Csjo~|2>pUNc5&P$J!Ac(7~WWCnC z-_4el@R~>rfm!4W1DW~#421da8SbpT@m&YeFF?EGs|rK*${WyWvWo+eAF8^N zI~no;cICgO(*w`cxRA!P>f=M5rjx{QGJm(YBw92?V$<{Vd9%Z%-z#PQ%?a2`KV~{) zzaF{RUV5T?mt!w|WT8$w*IqgcLgwvQd+CwV`s+sZVoiZ50)Wq6x=jG^EX-e>rU96z zCI{6Oqq~|iqWSiVy3%grf$(noK3&<{#siIAP4$tJ2bS!PWbAE{5ZK57m6NWDg6hiA zl91zz^jCAx2NsM}cV@(oRd$R450S^ zEq=Zaf=(x6>?(L;k9`gMijdFcpjQ^1L6Z+Ar|*lUh*@6NQ>ESG-oij20`Oc$)| z67+Z7;SyA394=A>efTsCX`ufIl^aX|PeAy_ck(}veFm{4SuyK#}nE+VMq0ei)h6xCC}Fe)~$Q%f^?@|mV#ZmqdPH$mbIbLrA2?FYIoi4 zqG-iU)DbuOB%DKnOqMO9-8prJnvW>qBsJd-r^!Vob2mManu?`we#p8!*n$<1fB&cb z(PR4XT|l9RS?-Ea;%JfYOfBsF8APFK6csy}Zg1Qb#;E=UjmT1p?3|N{Z;;7bqLPFmudi@=Pz9>E!Di!O|J3tkv<4(a2JR#us)*gZ2%3w3zEO zlAN?xB-hsonx?Ok`CXWXvjT!o*d>m2*{IS+$F2+dTKQhjGqv{icK3{YcV<=8GvFBJ79jd}% z^%K7ylN+t8Lo54g>ge*CP4my)+aP6(8m5!a+HC#ZnY_(UQ#ol#S7YL2y3$ay$*8`NcL{$ihl{Yo)eGH{ zMsNrt=7AKW z<`0tbV90IWb>(A4s_2LeQ;SAvwD7Q?9~=*oR}(YLeg5bf$W|i3N)5ue+^{07H#{~w znamWcVaz@{G^shZf1?4Rjvb@=2p+QP%gqS| zU}_&ZbFw!s?2LWJoib0<-AC62v$$8k=+pUbgyyVG@v|hj;rU$v+vwz?P~Zm)p+saRAaGC9Srbp;|_ygL0Y+S z$NkSDp_Ln-Z|44&jrzX)wQ^(bnZ{<&U8$~_^tTyTBOZ*G9Ifo&4#? zTe|f<-T5D~ZZMm3%*M{>uesk?Zp>+z%1r||8~^F1EZU4;2%~An=@p%@LHq2wf<8p! zZ#0_&)69hb-cMDuok4nxNmJ1Q%jzMeQb<+Q%f)CMl@&w))Xe8jCRa`Vg|_Bq z$#tl2UQShmM%?B;h)csW0Os&6YSc|mG3x{Ie&trstWPmp0#nUy|GjIOU9l5H$1ycg zx*;G+6Q##6HlF~o7Ir2E7&Q$NO_b|Jf5e{SsYm`gh(F_LrYpUS`Br!qO1j|?VvNWQVh6~KOx75hf1@gfOB>b4K`(g0S(*cpxhfY%6CkdH zM3{w9eKbs6SkL8}tEP`~9y?KHWb7%aQ!Tzx=3P>ZGMfbiPtI(Ib;hbCm$_7O5k=V{ zuRSDuDX(wfHB(c>vr>>^;SM#bi!`(jA|1n6C(K(G6&C;8(dEB40<6*z^gBltkFqaL z)Vzr_9u3y)H>$b zf>II#i8`4Wu+k;!B#8$Zi77!$Z|+iZqOdCuDQhSmE23b}IzmM`Jk#l{ZNhq<2O?Mx z>wvY(+G{MX5(qoZwtdK5))%m!~+|*e>2@ZEbL1JO6;~JRyT!B2#i8zload z9C>;#+c{C+f6qMK@@kUp#AZ=Xk|Mf6A{6m34Jz|>(39}R#24er&*uJtM(qUj|Yvl{o|>|Iz1M7()s0*Q9s@#kN5Jp+equb+qkkm9@xd*E@LR; z_OBlzE#5%J@J`#*lYzu%lY<$#1Nun#RpCx+GSZD>O-_o1@$+eMg5Ri~0aLH8j}B7i zHUN%Y%%cdGLc1(b4_^m`c>bLlQC=g*A4D3s9gSt;jD{> z;i#*TQeGu#HEaHMt}jp^u{vl}{{;5%!T`F)NU}cgWOfJE3vOc$`7|eH;zkz1h7T~H z_N4Wi6T1U-$1mMM(wz7v;l$VcpK;>JGVD_Of8xaT|A`Z$>W#DZo{j_uaDlo4G=?7k zO4g>T^WBxa!M_;>=`!WMjQDj1PdKzh3SD2lDSC}qFN6n|bQ&XlYM{r7&+#~MVO4|X z#P3)K@nY-1zvIS@E;oLbH2|kTizv^Ytl@DZckI4*bLsSe2?k#w)gvhYrA*9hifVz4CZ${zhZuU@r^v+Cq6~h{_at_#B9h1 z%i2zIy1Fai{0TY9%5;9mMP)iqaB&?n!g@Ee0$>%Am=_7<5;{x1 z`b*Loz28dlKXM=cEt9>Pf;!%#FFaw9(4DJj!fH0V6VbuWN5^unP2|y$&Qa1prc-+} zvfe=MU8q!T|7(Sfcu;+(e%up3K|oFi+NZs0E{xq?cWM}2+Y889$dF=>(nj&yRGHJ2 zcUnd?L)Bh)4e8<=K@~oo{4+$+JPWwQfSIS&I&D0xU5s2=^()0>|>}1UjTK9%p z+~^8sK*DDgh|#IkIm*Q(Vj*TW*U~8K`JwiMN2nDG!Fl$Yw{O#TKeE?My;a|xWUo2W zO*=-_t(^@-DDjnl$aU=p^~ZqfQK~rDHE~Q@^b{|L_*MdT<-?OuRmIA13%TeB)TYe~ z>dp`YIL5rlw`h=Er(2v#^e+J0l>-D>PM!<4%1=-D;+s|7pOWpiQDuCIpucy1A53pj z3n5>aCRXjfNzlJKuNVE_XpFk(KMRScEBCZYLH|dr9@_O3uvdLd69kE6I?oSx(LYd? z>~U)EWO->8ENZemq9(& z#1eG+<`;;OI5%KFo-YV*jm)rDEtWyp8ku6RI&ibT`!Qi`P!(zCNKZ@FVC4J*umM+1 z{etl^=9o{_-Xi@G!{I<07E&5cUt(x8K2PL=b?Ao>5eX&ds#ZIrA7inq#4koy-#b3oRc&b0=CXk zdR zcOPX87kbXNN`WY8fAH*E+KuLjpKaX*LO_q-B2!MxT6XPCLQCEl{y~#RhHGhfje1nn zQDvRu*L{37hQU&m7i1NYwriI#U`5U^$e*=|agtfWUmRbI#{2wBsD z-aNKu54Y|nz>Ha3L@%Y_{&+c#3VVfANFWANJXl=hbh~fieq(80<&EHOc#9h`hA(I^ z+l#2BC{ZllMzun~OZXY2+TU=espL+&B~-HO2f7_1f6#I z4x7WR(zkhXTgk1ejq7UTchMG!@!Rd%lbDzBa=SK9uCoA2t}|&%u2b#W`{kN%*FGoL zi|pFBDXut90i^L3SVRxDu7j zmjiIu@Vk{C>WZ(5-!guy`2B{TbW}Lc%ltO*6Lf6nhbrr9=hwkcOhjMv3s7H(AMN;9 z`@Ub^n5AdC#KWqGj4PnGSB}Wh(^vbkzM;IhgIs_3z2Y#-EwUfVqkC3SuxiR>eqRR4 zUFT|lWQe?3K11G!a9o^#~J5{xeojF>U{R?yk$Blp(H%vB>%KNN-*WxxJ3KrGgeZ+x$RP!p}(? z#YFl;)pXd~^x^~oh4*W` z1a6Y;fZC0QExyfZ8s=h4^Q-B+BB+{OeJn&W=9~0eRvn}ITxl}wIF}A}4H{ZOtk_PJ zhV_owG8Q8MhC1rzCC&+@dErgaYmQAMTBKfRZYD5Wardh4>x5X(f#PHb~O(D|f4YO!FYCVz^D;cAl;ah8Nkv;2W!qn#Gn=1+$XR&kGY_rE=M~&i~D^V`yrx}N`+oq zT`XB26F-Y5WK6TQhxSWnI?w4B)Z~MC+>*elakQI4aKuci6F-5l3H@~%#57_@}0Qh_x0EdL)PoA z&|p7&^-Ll5PJ8|Th$f&>d~tGgBBRyM(#)o`nnd)UFj`f4_6(heI5Ov27v!w^Sci;u zUTC#Hdg1C|^e0){x;98Cj2oLNLeb=exxc?r`-niks+B5Ogs*|pWf4}ZwvZ5eU*09N z-aUunYSl(JXHHMfmnEkxOMnSDcI8B*R0#VKx+Zj6AGsmJ`{=Ai;f11=mT=9YEtK7?P96x!# z*n3Y;4|Dnowr>=0mgzBWj>Ed5X%B8nMjDq{h zF^YWN=D@;%+)Du4(1QflL~6XCCoh3V)X}q_@Jxyj<}keHy{xA5=#BNW5s5+Zkq1?j zwZpal4Ct}{$X17>Y+ebR2ldaJaWdEPQNmI0oFeB7Zvs5OA7^f|Ni5?lt0id$|d?)^Kgp?Q}f4Kd1LK7F$E;P8jcQs^0-&M6&7lHtZUq;2P zW1*M{R^pRX{;0hT!0(S7Ywk-#f1v%N=AtxT^apJ7I)e#Lj+**K{aFHP8X_mC6-916 z_NqTniOXi4ej2yBte6$Q%YHKg{*atMWo*+Tymc;XxXey*VY-~*FF*oyi-iqVFB-cF zrkt#gAu7L0lOh8g_h!n&mc`@xvgnXygQn6`D;usPkbTx2_H83ih-_^z9 znSoWKt7G$n5g2Nk*#CQy;2Y;k(E~^LeRHt@ugHHKD=Z=z|svT(4yzX z`IOwE>AGwqsc&40fJJY7S1A>c;(n$|R##WS>3Ac~L|%qjsseodJMFuLmCSU0?-Ho> zuJw^wKU4%JH)@1HLc3}K#Cc19BqhtuRZ}lSQ|3ep8BbNlR`n{$(T^NACUZn4%UGLr z^5O_yOznBWW<{sG#W#xi8eofvEI1GLXYP!(3(jLsvSlRA1Ll3|jt{pB&W)$q1=z%b zMc83xI$w}mh`M5{2K_Vd5x*S*=bRBWU5jpzh==g@tQ~gXhgM6&=OeA~7Jti|iCbGn zsKV_k0AIvX)du6T2x@kob!$MjL!56zu&SIe(B~=#$evU7+68`Na%=YPg==1w2}X#% z0M_4X){ioE%q;p@)NuA4MOq zDz+1?!+w}8=J_o0j`fAHoXViYwuZKVze(KW?RKpgSgi2#c5S@``iJZ7+7t0W!IP}Q z^}YO(1-gYeAO1}k8W}QS81Wxc)r=ruSkYEwPBpY)pMXOYFLIGUA{O^jctLi4ATmuY z3fTpjs&p*e(!TWQtma8akJGzzHy{rt)^skB^A}Qe7hp`yllqSvP2BsC=r?gj8X>s(O@u$&9k{>6&m)r_-;8LDv~Cqjj{$Xk3GN3mZqB-ZN<-9q`GlQs}2-ka%6fS|MzYBeS6-9fuX^>zx_RYk=p zqr;ymjV@xgT{O;TFMbvk0;>RY3yW$`JX^_z5JwJTh8QHvXhPeoFA|WVPV6-4 z8vWVaZ~$4a-8lw4#^R8eh7DR!=M#n2@Nqz0ni)``6K8ayK0y0>Z3;!2);yi zq8{keM15o(yjU<+wox|KO*$sDH0ZTo?S+4zlJhD^*5Xqyf6m%gxqmFd#{PGVwZR$4KQ@Y{iltfq$eNPp9t?8|0-QYG~&AZ9moN5XO2ikurNZY&jR=q ztx3Otv31y&rTFs*YaP$V%dZ4a%Z>z3&es@{b@)-uB4(G15;cKk9uLdw9%``!{lK#X zRsMLCQFAmomlpUZj54Z2+y=Hz7-%d`;jREgVJKQkx!6FdE>8}RSe%Dd!@lpw{Phlx zco%W`s$F`zOWWUfc*G^&d3eN(Ll2M83CY7FewNYqq$GAh(-XVoWqo)=@C%p2w0vtn zO>zb#z?@M%l(_*qUjRa@QDR1SAliGzy4Z6v;@;xqgMYextkQk_`5}G0+ij4Tp#R7E zII7d_W20>1IZ5DlVYS{7BjW*PN^CHxNv;tN+LQfgK(GmWk{QrTnBGsTu3i(!ul&l0 zb~Stzv|3N@mf6uzxhbV`KXEdfcmlCAoqHi4>XfPQcgaz)rKStXaM1)pG!V4{=aWlV zPYLurfWwGnrs`1Mck~3@qK%fOzHhZIT^}mQ-n+2b{K!?mTiKOp9k|6m!}*K_jA$M` z&l3Zn@I#hal!C$D0MShWh&AM53GL_z&cJ^1{#Q`sKjF%Pl`~0Cj$kEC%fh$xR9X0n zy%pmPf(xmH$(9%pIhy8T-5g!xJ_hCSb9wB$Z%h*3BeA?CKak;T>375J(VtT9EeWQ> z7c@?7f{E~UyE2285Zn^c4Ks*1cuK#_;3y?FCmy=ZOQDy3d*50Qu^QDk(xl8e#I375 zacjTT@@)Z)!9efMCU>I0%ku)F7_}3OJE4jY@7NEeLwCxW%31`k>seD(*>-O|LM(7s zqd)JH!RVk%?vi@w9y$iude@J= z>!;rJZU#->FY~T1c~?o3Uzll`yqBx^Dw6Wnh@>?Hq4gZI`z&LL7Am{H@j}46yN&8b z$`Ax&)V#%wGSe2ozSO%|7PJY}HrtSv&|`ZJRC;eel<&H2=lwg&p)6OAfV}1c&Tc92 z4pW+k3e|JMhkJHQfp>OGXV2L!ov@>eJ77oE&*jWV<116ko*OX<+2*&g-o(jCP=AJy z5)UPxM)Q=^c~99Zu1jUUe4%K@V#l-9r+wbP-6iqmNuBt+>;Ypv{dksI-af(8kIe&# z$SI;2_gAw+w{9DuE*%z7fjSAS`z07eh~->`j@WRKyI$GO=wa1fWW5IA+Do3u*J`fw z5O{&2Tzf*C0sD7|WGdnRr!SP~!Cmrn6ggnV(?&c*=TEsb+~Ofsw{N}67IKRP3K_v_ zwMV4cm!`48Bf%h=wy8;JLCon_S}e2Ur75e)Y4X7P(5ydNmcj;Wv$e%uel2Dmd&w32 zwaT`3HTgN+gcUM+!_sN~%Kf7vWt9zEEB6naTcQ_6>#Z5i9n=$_rAmb_TJJJ#ukY{n zTWhsg##w?LMM%WzG^1uOkAx8ApxeSgjT-Gl1E>l|2OxsKBB}E@4O<9aGsCHIk)ly6 z<`rxLU2c-F=w=~o#3sTHcDbqO`YZrFBZ2RX*olGOyZ116CPY!|FsiR&NK|xd!^i#1 zk8=nD|4)`rguiFlY9Rx3(3w0{ulsVq`@BPsH+nD?`mH>i z7wuMFI##0(;v-v@NN409$1c1Z>*NO7;}nDx1UM=x+i6c47D%8PLK@cFqOBikO<0V# zD$87WR;W9Ansed5*g;V*BV`Fc(?q2CyDHg&{LTvkUsuT+5V(S?z5H_+n*Gq1{AHqs z-&9K$%6#S|vY@^8Yf_7+OL$(U)3{4;njs51ilo&LIg>i#Q*{&Hs>NRNEJYJ%5#hFW zE1hzxDIFhp5T}>oM&CY@kW`ZQB^3+jFO2)a@od_jeYN$rXP+~#KVOu+r$GrS^MZg? z_=FXG5_OHKWrrUwN?dkc09xRX4OQ|eLGqCk36PJRig-Oft6l`1d$V6ZX6rmcw}R7) zo#zG4n{2Zjc09c}eu6}``YNrhW@}<0vo}=iTr4^A1wCd&XDYfS=N6w1%t{4TP{h5h z7VxeparSw|iRX&ufdKOhO_FRT9PGAqk;W%*J+1B8(V)5EYH$D7Zq)JK_)O1!?|Elt zt9A3vV}SZeZzqnn8mc}N@l!1H#xI&0VgrKjR_=%6{+>iJ@MIV@k8z9bn~reV;9j=N zMM5Xvvi92q{oq9}Y_)&>Lv#y#;ShGx(KErK4(O_TRO*g8^aCHW zU3o^XNHXLh3|fbG)eY3u>IunFXQb1}XrRU*#Fn)%wL(VL0SP300?w{WMNbzC0q*e1L7doQisM)hjSJDW(sW@zQ7V+xWzB4XqFZx6tH8kd}lq$Mh#`dlWc3sm(@q^e8O ztlSWCRbHAkACucw?Hyh;HfvMg^;1n+9+CryBB|IE*bhB}Lj{+n=aN0UVc|dUQqv3L z!3OISj(D&~)Er0u%#YZ)H0FJa{p&leqf|-A4i$6chcz{@cZW4;WDu+@f1G^woCHw^ zE#@bwATV-F)+RYm5%-$9DotIj(ygnPhH|sti2lp$PMtf~PM0lB*eqJvUSeOid^kES z#|?(t#9Ps4zHz3Cx`$&rTKylWh3mk~PHW+sJtXPp;XLe1K8)bu>*Pa*HDL|Nv=?Sc z077=l!nJ0-d$182ZF`YZ{gI~xAO*&!b#2J8Yd>L~vR7>3FWwkcJ5q*9yMeR=D38r; zU^{*S(($pL*d8DBEqfx>c`*Z++Ir#zoI4n+xVqCvy zq^fH^iz&ud>^*F|OKy?*;$J8aqsgXi|3sa%3FeO`ArbD#su!bNS!euq3=0VfBPi=M zmWdTfZ0cg+2nNlz0qT+d7rf~^J}lfSQX69XJ;$iwQ#p~2qIjuUlWTS?x(zZ>`R60fWO2A=B}F;rX}s0k z@R_#fH^13^>+2(ANP#aTbD6Gk*{FMr*?_$?txO8ntlz3iHn?W}V}aA2>ZkWp-Zv)i z&;DTH@7)fwUguBm_3rhrW{X_yp^1%N>u| zo(-lYyi)+ip<{Dw+#Svi?4 z?2ARt4N0tGa^J{GND7Vod^|&{>Vh*Fai48XmJ#<{LkY%Dg!K=Jwu>L(Y~j%j|8#pr z$my;m{9_Sx1l-GIamMwPo5orP2PjFiugp|)(WN>$#jcOT{6ZS1;nX_=)}4WPz@L@X zRr%x5=-+H!3FF;R6USCAOgZDU$PhG?vzq&5s5=AsWEFU%EV4~k54BI}VlE6M(2@Rr}n_Itn}{eaG#rl!dDWK`NtD}SuIB7mG_ZA%}Dr%b%rxI8(&;w{pC!xjV~O3XVrG(|3xMx8`|rVD~zf5h*Wk=|46@ z7X11Yi#>A?dAL2Eiaz6Ay;~_D2KVm!*zJi`oI<+D`ZktndMSIIkx;H z1$@Ia)qc_Ve2T`8am%0FoRcz+I>wFD{Y#~P)OuvIZ;Urc@qq%DKNa+WuQYWzEwssW zGNB}^Wy}W!jKfIY*pr55_Vs$6%6lB4{`moYGK>Fw(Za^+ImDKYNqzNKj?NN}pe_$G zS~Us#Y!Q>0-@nS>!o-gp<=+Qjkzp3+>=qo@&X_m#;Z( zQZO&%bVA85fH^VA!9=YXh124#eY!q(v zzbWCFoR7`;ExHy1Xi}bGO;DGu4|Pq{OW<^ApAtTt)z`_T$(cvvFq}(NJ_}nU!y2(3 z;xrrj>&LH8wg7I(ep zWsLRY$JyYdW}96bz_4XMK9s+lp(uyl8XTXSpB~!>*D3#fnm;l~)t*m4P3#jAB(BeD ztonxtUh?8sILi$%5)}t!i(!irNzp~tsVU% zSdKtn9>-vMrybPgNlp2q5rlp(U$HZ4eg|&3^}jvHucO@0Y#l2V`;~p|R7h+LqM9E$k6xU-_JR zpIyKv(v9pC&B@wkwxx1_39A_3hL-Ma&DyrxxOdXe*+6)2;OAyzFem!CS+Q~W+zVMY z$81d{mZEUGo&IxPPh2T~o{&Fl3^i@r(W?3TzWoKu?0 zaXwL}9z9+ml0ZH*t7#jCo)wcp^kN z!wMSfrj9DNCI`w}a{3LH5cc>uGbO}nKfR;`z1#p{*sHE#7S1T<%sr;qyC2D%$mqj) z`_OlCy-)7nAk&v0r1ul4^xhCT53kz_xVl?QO{q#(B zHyU{INg1*FM$H4%Dw|s0lPd>(5jyo(C~r0E^))bx)%A$IM)hyFB?Q3(du!x}9>`lG zoGhZj-5MEa->*U48Xb_mh%%L;6yg&*aEouIGjS+0>>hwpQ-i9QkfuhkQ3Jd3bv2@d z?%>8Y|3H7>Au-S`JpVI1RcN4%C$tjcz)^DK5vGW|_jcm$j2X_jknWT!$e3*IBY^dK znb**Hb=B*1*S|5*X1o$^jonJ}i_|Dp{){3_SgT~?30rlg!+6|~c zKM~#NY#G$I1?o0xH%KGZRiAk+WYrsMqph*GNM+5~{vnrL8u{>vniUXrY>ISx3P;fz z)z{GkohQ_EK;zy& z@^J<*MVS}2ItvPr1Mo_Vi(&_0CNT4W56P7QQ<}~;GGI#67+argr3Y*y1E%zVZNx2- z&v62$G3HOu5$c@j6o07O`+M1Xb`*rymmA~Efk;r%AKo*9jRoP2jtB(uYGY4#<)b#> zl3L1vjA1eNA!0)b=RiGj5<$%bZg#Q#dp9+-!ZC10zi&VEvXJrG+gbm*Hl!KhU2wD$ z8oL_P_^L@kNFwprc%Q3pA}1;HAx-_9o+jj81rT7R2ZZARK}4z?SZmNizKRVZ#a6cp zhCq*VtXm)^&bq96y*`aE+!PjklZ9}q`V(VPY{>wAnIPxM{CGO(m5e=!yUh7t*jEqI?$eGnY$0jRNEhj@!SxsURGe^Ad!2Bu$1XNOQu0GPM(?O-73z~e#FT|) zx65StgANiqnoLagKQVi;cra|$Y(ZcJ4_fE*c0XP$-mVeu(qgP@xlr$L*Qe%?rCjIv zU-Aeu2)E*WTk>}SDCBf;?djfg$ynhh6?N|K%;$7ule)4&wZ-2jI7W%KOk1Wr*`Y6$Uc!v0r1GeM2K{ag@hy4_0 zzrJXS@bs$bCu)MWtut``F_oG8Q!xQRD6z@3jD1Dn;%^K@@3q%OPs26tgjeXpn+^T#E&AYLco5y73-aU47PbrVm0);_NjuN}Y^-o=r+?e3W1{ zsM|($sXxoe&#LDHqBmnrJgRva910LUN+fEg{CY`(TdcVppyKJ03bX%5GWB<)nqfz# zgS~iWChLAfB->tmAHliYonbE?i1xtU$@b#c-Miz|;<Y-TTR1Silsd<_GfLJDDXM%CPRV557)Ei*b_iqivjij8=*}f|I#rRTrXlol zY9Oca&A&1Gi$y=t^Hv5!MMI)`-1k#@z!}Q1TcHtKT_RP=Iy8$%;lxE8k-#}G9Y#%t zo`W3{YrM&7G?o+T0cM0(6ElUV9KA7XM@+;Kkokr2V7-5%*hqtmjzX2H+ey>&lRfgWJXvdnTJF&p;uP!9S3n1?On=X%l@a7H)}>M9 z*Bsst1bi((PEv~g&{$WL;wEzx(E-^?X*^Ib#||AB(}=n)H)bLwQa0vYL|1#^c?9bgREG)w1Sn!(7csg zpWylg*EL+%aINQB&vh%;tz6rYE{Ud36Ta9&R-&1a#Wj3W0G1e9DDz}Dl*;8)KNa5PWHNbTr*M3|Na7E83{+jDRuH9Ti#=4+O&RR{oT@?{dlU+IfZldI1kEg5fKgQOBUM$OMuN^X+|sd4X$c_cDP znMI_^F-^zf>rB3#`i{@{D)gUtN&duxYEjVos^P1V;NU$%#4r**MGjUv*D5R0*Xqelhnom4TH-$M%+Icnx|RnsQR zp2Zuvh5BeG@unBsUDKsOF{&3xwtSG6Gqe2nmHx zzTLM+i6KT!rdyFTf_>*ip8D#a=x1;~?|fhw7^i&ozxz1#{F=)IvCWB(>q@?=8yY{e z+$v!ZhsMX)m7nhcf!H16peB9{jErQqDiHC_K8HQB{CCO%?VcL^1F9LpPga?8ysO;H zZvwxhei*`@?d~ABl7OV%5x&bEVWZ|jGONoo#Z&eNZpSZPM6jn(jiBsPOXc1hQ^Dt3 z&UwH_gkM>wC>^3oQK`Ljx;r|H?4`@y5sTPM`<<#s>=t|JX7}zI#_mRSuS*EhTs_4Z zKufP%i?5?8IrH@eu%JD{SSC-xLX57n3*1|~U{&vm#rUrOB}1K*-4PubzfzKJCJDo6 zK`&kGh~#ok(}n61=pk~hRPzp`u>Vy?32UMzg-D(%f()k5L_>rQa`}eSE{;QNO47ni zwfJ@qrt@WFJX`#{?R^PB2)c)if3EW%X!t*teu!1zt&#!lwk4;G^{lrpQ7*5?KQJb)^`K#H7Dvc&eonA zWHVJDGDLs5DySxgjJ3Y_iE3r@F|wF*=8J`6m&Lp&ai$Z&=!0bAEyns>*@Nu6#PDJW zmHj6#Ra0EYgExnt5EUJLAq_JOpBBT9E#c}mU$KGrmON2Zd`pq+!TK5F!b(qGTcx{H zfOc3UaBA&v<0yTHcDPJ>u@Trk8FdIUY6@ZJ`EW4~J5VZ98Xr(u@q{mOgdKi@O}RNC z>C64+(qs`1^FJUU(UEd`q6|65bda&GzQ>ilmoZ>^_Qt;^=SQFZJxPfDxB54S{;8=U z@z)QQ1MMan>-@35fe^T>Rr092jC%|FDaN`fDe{FNz1-=AogG8rM;qD(+SNf>?)0$` z8dIxL!uw#V82FNyI@`q$n3|)pB6_rQQW8^7Yn(-oN@8j-m@u9 zZ?q_gTKs13h`X5T_4sdv8hYqa`zNvLiWwdP5c@06U=G-SlR0_yYp_h_q_O-Z5w0qN zz1+pu&!~Qc5_UmIGno|RU$oC))(%3NWMSV=3HzROToOO7L5L!n=OePq@br#PS3x>^ z$<)2WiOt%rrQL(yi*AVZ?=9_NM{LGi?C5wTrem6(--vYKHlt30^30au`B^*0N1cUs zY$4AYtPHFsG%NlXTOA?8@!aYBH70$5w-xBRXsZ@vK6%0?&pV~Z z#_fbsXW)osgspe%`yYWc(U4}!clBa>$*Zc)lebiFb$rGB zy1TvjaKCWX&R4E>vd?+BTf+U=*Hh99`CLT1SkkX`UokTJlX)JV8VMAT4++pInI#^A z7W_Uw$5~1N?>TxMqoJyF7u+p=Ru_HLn^Z1w>y7^y7OvI(U@7tEozAJ-bd4hMOF1O| ziJHK-f=l^yOeYe*q046IR(f~F;wn*{mBC zhHFZ^+&qvLIn_K6jOHdSJe@{qJ@*Y_?b(M8WcgKCoKEo{iC!zqX5qe`1ypW$8k!sA zl$1)JII3B7qnJR=4IGejDE+_V`GYyr96whFgp3xQ5$VUg^UXInmH`6d%)L(iWfw4_ zrV!xWL1Yy5HoT%2oK5rFbgs!PQDQK4f$Kgbi<5f$n`G6R;y&Se@ zbw|p_Y_%^f4p`lKJrm)$hcQbPM~j&3X<<8(T3FMV_j{8)u6`7p{yXxS4S1Bhqrc0S z=mJ-c?aRNC_@3ZNUzei_q~3!C0&&jKzO4DPVXd$&k%k}L!U#7b@_Dx61B?V@jQ0vc zc8phZj>KOb&C?DZKKi!9YA}BL)mxve&M?9scwq`g_<-4xFyA7SUQkX{r}pxT)PjWc zKc8S*xh#cInVitIU@q)JBl_)E`suAtx*DV|BiwE6-}^2hST9H&$8g7Yc%)Wq|A2Rm zN$*>4zW``3$^F@TafOt09P_5Jtd^AV(N^otnezl$yJdUkq zQ^I@)oz7W0IZeMce!J_fk9E^Md5rMe23BeQ&(X$qaagmL2erNy9xMj&n=k>1$(?vY zV=eY7yfM;bY?8cYjxw2tYkZ23*}@x%EMYgVSWJ00^)(4U)02QusxYh1AIT$c{=pmJ zn`cuImT`Tg0JuAzWH$~NF;~Z7yx?U-JoL$i;Wkw%r@KhxAGfgd{PgWPsq%D*Vc(0~eQ`14HwiIiXFXzkY7%d^Ll@y}{k?CW&@5Y+I`|A-*g2tfK<9vW1WFD^7J<6a8NM5BoiFVrqicG=f<0m0bwLy^ zU(!i@RGOM98>;cB6c4v{k&O3xsNN#!Zm4dSbXx&qJqtX*RGtwkVtIsZTyybSGkv;gbOD9|H=7@|J~Z`azswwCy;SdK_1g3;naEW;P-z;*dL#UvxMkCb zO9ToztX{~Ch?PME>M>uxFzOzcN?wcOpz%hhMTf4~YVW7K@YJ+No0%q>Hr=QduV)vt zHt%#k--qz3kud-7g1d>B9Wyu=`I-G_i>21SU+mpaayDPJXJZ?C9gOPdkwKI>QB#Ah zHj5VQHS`l2ia!W_-;bK(8Ux~WSv%Nqvbaadi^+!p85sa45RwXG*HhnjuFoSpX=4^% z97Sjw0!5@kqO0uXO^|7_)qld**y6EC3?QpzoTmlsB~PLwVZgoCey9y4Ap6Zosr}I9 z$XDDI+7FFz)AH1kdUjYKkx$Y5$X@=pKK0&!YQqk*YVs0d7Sq0>rVMidM$ua(Sn3j`t)5#{BR45ERUd~VKFI*sn}CN7pEFf=)m|d-CkZWGMwb{o*Jc5S(?>nDxM!;hP9C77 zU63JXHSUkq3T$4llLu%o|FTc7@7N%{j+}yDZI)WHTBFBaep0L#-xY3-068Y~a2y`a z$lB!X^%9ooez|}-Cm#vtEG7=tbdO6!i7wN<>y2VMM80?VQB{X-;BEZ*5*&^ow1{P7wJw(wt0z7dLW+h{& z_a1dM_2)CHY`YXb@qY^rJthak5xL6)pb1N1>}z16?k-LZh^~wbMhE8{So|69NK?BJ zUbX>;^8@x7SS=?UV9SqD{S>bNU4 z4>o4Wmq>y*K~|nLbu=;>e00)QL3VzIS)W0Fi=3fAN;mO9N+f);_odFi0MP6H=`_Wm zF`d@kL3G@)(f z=zCyI5}Q$t(UvEd;EZZnn0kn=8n)@P9$W|$v_4?lNOuhHlg}C2pqWI?|Ha(9heuUi zkKY+G!UQ5GXoRR#qN0MJg0)HvYPf_%AP{Z=M8GRwrCv~H1e8F+B!t7^02S}w7OicS zTC1oP@KQ(sNkCh<6}br!qn>e68!rt3Df9cRz0aAMfcAa=c%S$A`55M$efD+jwbx#I z?R9yK1|oxnz!p88TmAuH3StDoJUnih^5)UJcN3%e0d~j~wI-q%JF#ka^s?}8r?S>K zutOK)Ui05_p)eo-;ZrdR{?LZ3E!=YN-~kS*=Cjkz-xw*AOyeH67ODA?Yp0b=R*5(v zh#VwiGAP_NM?6A6m;gnkdUMy_qaGN754eM0%4ZB|3Rr=KvH}e*<)4x?1tI33I5sog z87A|=oGKfJd!^wgBrq+~>Hz^wTbdJPrPc;3JKo8CYr0< z5EC?^=yBV0Y1ujI#Rci<>P1sD6iP&7D5@Z$l*81QI4SGZ@ILvC0PGaae2)JrhA#_6 zgac*ho0MI{fiu+U5yL5EHE3OTp+71E(8l1T++8}2T1I6b9z-%x=E*dk#!|=(m?xqk5jE~^b+>k*k~IE3o_2ul z8#RX!GqzV^#=ao2tb)?V?WJ8BnBUOTS|(fKe5rbyt?7|9Zkb4fhl*`1Vd!5K?F8FA=ib*V(~c0O^gdR~5_mw{<^0tna+)ckry)en*3;0PDf%&Dm!i{!*5^@3PeN-_haV5A zZcMfS`f2_tdfxe+>>wv1r}IHl0e`2;yLkCT{ky+ZvblNrR2YcPvpV95Z2zVEOUrIF zJBHc|%4wAmFguAT&(V-P1zjfSbm`}l5Iu-8Bw4X4ab$5x@@ziuzqc$hGpTRVl};&i z_+~zOgl_U@h<2SfsW?)I{)Ll91wYDPgd4U0+9`7TI~kd6k7>k42@XU$6BO0F#Y`Td zCe+p?dU->ccTx4Jm?0=DYE~K0cA*|E~ z-60|tP}u8)hOMj)nVi@vIP=4dc1KBA0A|h0h}_RFd%B-Ze2dhk^u&yc3Q8&^v2q@W z6Ot-%LLwqNvliUu6WWG=Q?%jjCEp$brm|j*^&O&T+Y1(Oxi5n&06~FX-z~_rI$9mX zXG=G(?mJjx{LP!PjmrPfoOg2hcNMPv?P8v_%7M|O7;a) zT6d;TJzv`KWq+^zD4|eWb+&Zo3`&?AUC7Hh5k~!68r2ku7kk0S?zl(Nlp1%mjnzT?duE3^dgJubWb{$s z4e#4tj%+JoT%yxCQeBIhS?C69^{b2rKk?%foT3|8S*g)8>;-=Z$TAM;^E4&Nm0&G- zQo6Ub`VCzu+rpu`%nj@S6VtAqGVT#<74ju)#*o9gXFY7Ms>^egveij}!AzRq+=Qi7 z@FNKgmUlmZh3;qk^~Lf|D%hO=k0Q;j>zru zG-%%innZs`-8?t4q8p4R(L!S^mUxQ?h=PcmFlPTKIdA*2FqB4Y?$;8f)TM z;ed&{T+lbBo>==Ik-&zFb1_s1gA~CmdCj1MDn_{;)y{uf z?Q-C3OZ>jDmJ&aDKKJw`rcy`ZHoc#^QSycQpA&#Pk)Y&+7MvWNKQbjNF2j?4@g2_gpzWUSmHsC&1%2 zd=CY-+Dr4`#U%ZG`#FDm9`}$X5D9F@_LeY3B@*$sNVgar+pq zyB>?*a>bXCtC$eUy2IS8<(bHlvPlyzPebZwtnxD7g@t1|E+Yw!r%Vlc0n{XUX^T~a3=CRZ{R9H z%I&JfQiSC=i}r-_7~{8mYiy|TM<$W!C+6StKRLB|NKaqrY^&_90V|B z!ihMpV^W-P0N2g`lH||FUK#bY02b0?oEAQc_+e9q+e{W;l$;*r*kb1?>6Y|n)}yja zs*ccGE(Q_7anE*dcc#%rYqscBVH@>Q%k zpK{B)ZiKI<4q@9w<49WgihL0{W1L*U|4IeY*l*kly!c0?O9euwWX1ncDtMTeggux? zUnX#+jxBxaylxiZP~UG8A~>|Dl4hX67#bn*QQOwGW&S}k|M<}*PUGL?yxui>IrrRa z{ViY^*2C3DLgzH0Ksd z!|`v%?$x}$?|xKQ68F<5&tFiW&n;mI8%O$#A>f%XH8!=)&!< zq%-#S1!f_hqw5m>%N4#%bm%|+-=n_h z8?En?hocK7x*BuE>#3ODw-x7e7@E+V34!p&6KXtI?;en9Rxv6BL1I$~orDZjz$(GJ z&3%OH#Bk}Jl;F?BqI$5b`X+1e+Dt2boyV@U|6bh@C}S3`_07R=OoZZpuF@r?b zr}7`k>ru@HV19#+Mn|vYHo4cqN0@3dIKwL(-W;I(W^Qius@n$OfK5O;=3FHZ-AJkZ zy41DOKyilLxoM6RQ!l3r$5M#TnNTD-e>6sJXRRt8x&wCr_Oji(sbsH-i;$u^DW8{t zO$N#(>2tf{2ioG$T>U|A-dT<@!er8Eb1bPv3b4M`s{ne>vKL~>CbmwAid zepxw}ka`M&KrBuHEGW#x_+x<}oJnu3@|%b536Am9TdY2L|4aCXFAx>Otl*uDl5HnV zJj8P?_;5N8tewXc;=#;>&VWt)@b`+^E%{!ja(Y)6QDZp6%0hdGDgelV6$j`JtEY#ox32}{GB|tnD zYww0z*Z2Fia=+iA^cPkt^{MVDv+koJP-DCzQ1d4XcqtBcJTj{G>Q-1*6e3I1x>==ied)!2Yx8QS>Yf>2*uP+~ngf z(1O#=-`v9}(NniZikDC8Eg7`E!-d`E;|Te3JlQi&MwbzaKqsc=y3@1X>{_v%Awr?x8jVbWT(A zsRB=-l0lRRcoEK#xG78D2>asOl9*Eh2hX0NEevj zt4MPuN_|2+f9bhj*o$wLaz24;L`KUvraI-MO7DfN4W+MK^$rSfEgBbPSwjLQuFD?E z5{_vrqbDv)Ra2u{-%HbFQe0GB`y$`EIJW$#@f>9nlX008(#isQy(Q7#g#J7+zd#PZ zbz?C=MEfr@B{)glK|fIg13e1E*?Xu4+8@6XG!{b5g#n*Fpv0-7E%i}MXtXgj&?#|3 zI^7CiPLG9Iw_X*(@jon!G;5R}f7wR#X{!^z?NsFL;8)z;(t`>#1EgxSB)3zq=q7ik zA9y++ALEO3!yFNCFDGa9fa{L6Lj%8CQbP-9NYw3~*IiI~J(9!zvnW5kO@6>wSB*}j z@Y`%TsrdnkAPB#y-ZQLmnIxS#E?os{0D+U^^U*s*2l@PS6T+Se`P=}Yo%u;VxI!(0 z?XB|{pPXA;?;hWqe>}X&uS+D?&v~^Y5V!h-Hye(hC)s&LgWZ*HDZHD2Qo=h~Fkq>j z%w^k9f3?fx-ydtA`88JK$sog5_wwdEb!UgadF9hmyctb|G=6L8m z;Oz1+d1}6}3tnAgytbw0(~PvbQ{l<@F_wF6hX7FWGk?hGl)Y6A$%w=S0RbDE; z6btW()#TcsDroh+i0{1z_)~q8HwylaFCp&7{(Ipij3tjzpTduc;;n24mo#6d?)^G= z!6*2v*!%U~Ez3UHySI9ene|Fa%HAyp>JCN*=6t-jdheFdmv}AP`}KoUKiT^UE-dzz zs~lhN-MUx2t0m#{C;KQ*s+9fjPvPq0w750&w`hBQXeGB+h3h{=&3_N3nBd>}>HJf4)imQ+%`{_P{vJu{DoKOAB*!Z1-K%JU=ElX>wY%9xA$DoT zI^W&cd!@+2_2|!9_>JUuZ@p*OWp}|jn7*~-Cxe$i>HF~ihwpuU>^tj0SHXi_)`=_# z)d<9xO7sg9*wdXA&k2d|k+go2@_)|pQ1bf{`R{9;U(pv%dCER6@LTALay_IEL0F-9 znva@ia+A}OlHrBj2UgM?Clh+}4B-*?q-ljF=u0--(Ny)b)l5a^$z9*4V ze?HVdB5YSXKMwj9UE2V|8T!yJt+SuqfIgqrTeKf5=fGb)s$|soQOFC5`Dc&(Q;j{y zF8v?A-Q?*LQ$Sv^z~;XKek>v z7z?eHczNC2sy0#pVby&#(Kh%4)5ApS{gwVK{aQi}h6wguM~F?i0ob6|x3Rig&1YH0 z>Y2WpFEY{&8mp(asrf9B_8lpyX$Q?K$&Dp5A$P(XupCBKLu|X=Agft00hyCjeI4Wh z>vXfJ#_8s3+K!hZ=a(%yRP)`54xCO0#09aO7xh8;FDn!rFd{G(e?^};y-IilLigO< z4$GH-cv5S$%i2tm`QGNyXSt`r56AE(jO_+w*3{GWQD@a0&Pdx}te)6ey1tVSUD7s& zYqG*E-OO&H2RgEacn%#xGj&OXW!ubx z%Q~0qL73vrQhbx%@oUv@bIfsbP>b`I{{{5b!LE_>{P4EbqQPmbs5Vp4f8sMi)67A~ zhlFb}4Nk`{%2?bVL=h`4U{KJ9A)5t*t^7>_$1%(_qDk&d_Y;?H?#=cXw73x3HM3;~ zv%K+JH!n=LCIxIHu;SdaDSRxI&`J;XGWYe|Y7btRWfgvJ&1y+~Ador}N_LzFl!|U7 zf8XQb>WuJ)rPf*!!x1-8AF=g&P!azl^~kAB9><1r@AGNK{=?IZL))hr(Oo#e8k>{OiEqj8nSXl_>}GwNeBGd^BImP}*ukiebtuDw?SUmo0g~e%ymwOv6Y^U?3a7?{`iM}$lSN2$n%k(5ZFCY<6m7?tJBh^)_%{VYPQ z6c9BG94o}Vr(l;Hfe~bwC$yvF66bHv#3%j%=2h0F$jOv%QYXvB3d~XF&PEIg_97=i z3WHaj;M&BDjyOwrTeM|4T6F^4f%L-eplobBaMlPEdPl^nCJ&$46x<+?se+&1V@xDn@m#IUGpa2l42Vw$r>>oHk^c z>9u(|n?oN6qdqGSlaiUmNS zaEKmxk6ADSbCC0;aHzos zaw?L8y-^`sowN5zsZu*@5c`z{!B$<#ke$X+|3tA5MUKi&0D zw*Kj@e|qSjKJsG@xuteMf1S`z{|weYdFp3~ZlskzXmdoSU3I^xmk-IR9pZ+e#+fsw zF|DK=`Vv#gcH{R?+W*>AYjV19Pw5PtD2FB1pmcl96x`?M%A|lS8Wgs-k8q`CnQVa(meVbR-85w4eskWD-tni)SY z+6Di?2VnZ!n0(;;8m-{xYHWSc#kMOROBf;IU2Bsi8)q35IJ=n0s?)2h7?z ze?>idP!DcV2r*Q3)*m3!Pj%v7l(hjIdnh+sPP3`mvEfuuo0ly;sm<#yB)B%OhakN5 z|3!?UMjB+$Xuvd@HO>nQ={CZ%w@FDcDt2-QhgBE!c{YkN0%e)#Kg&d`KsYlg8B6sY zF=wZn6Fu9V$nB&i&~My&;42Zk@S?<+C8m-Z@MEV8_%wIGlgRx4*MMKIVuTPMcff}c z{#a9qz!SO;Z?w(_9Q|2_?3z~Dv@ZG*XOxT{5D_U-#`%!nc?%3O`^3g);tBSTJfn(` zTp*hQf(WuhnKQUzQD%J8shaQnwt9;_t7j4KHac#(&$kU`^ zOCsTbq`&H>(7mXN==(#XvUB{4n7ak!ZDv4->>3`$2dhyb_iyULOq|AAon&e+Sf=OS zsM!4jPg>JZaKRa}oZgF`Lz`H;SO*0zbcVc3N_vYvy?9%*9?obrmNLpI3epL^!Wqe0 zoi!4j>H#UDtnwn)3Tn5*1ZOg7vONg(b+OY4N%IQokFy*S@O5cV9iIip_wrHb)*Rj= z(`DhDRL^BnkHXzxt9mpsz=G8&RaJ@f_<%s3rfnH-!6al3_f4>F2k=R=)GO?nThG`yO+5E&Oc-z`zwKjAb_ zj$M_|gh-NadFS7*UVlseA^pW*QMwG}u|tks+QbdKZCy+os;74NQM$w_QJqnZqz=zf zkZYjZ(>pk29d%cfOYYlbDAs@2@Vs#}5&t?hX&`x^PHtG*$3=$@KK1G?u1``se62UY zGydxUU7Pv%e!%z={(J1A@9l9dxM8FhSS-i^djgXPx1^wbq3V2#bUxMDc)I$)B&1v8 zzGvz$*ec{mfS9Rd({X%Bn(wJZBDR;FhmN29)Xg+fjC(>F`Hto6HG**z8X{S>d5RN) zb?8rfc$aXd*ea8J<`O7hJSvZIy6NuGi>sZpdFG&wK{7^SQu%1SN1|FGYGY^?PF3y2 z)|>&m;@qh#iw3MUop&iZMZfi>NbB>($@8C2xY{N`T`_$N=30g6xmL+erUbuHFY+t1 zC>ZS6?+$@WC6Y^DknRjMz-;Y^IMh3WE-qm|n(T26_M5*T8xdcMoqy_y6Ivh|h_3B6 z<6W5=Y8$R=Bd0lWEMmVqfg(o!Q8_aRvxCm=g&KnDl1V(#jdu(e4WN7a_RPs$td{9r z3U&cIJOwR;>FCqvd+i2um|%NUZ=~D6(JY4IW#HAmFw>lo6)kq&CZA=sVUYIn;~Rmm z`1^3qrB)o*6g8d_d+d}2M!!m&dv$B#?e{1AH-Ot}u}y%)SPS3p#&kW|AX;CLkvKo9 z*CRL68TOO6a#mKvBOstJ-D9tKhoRXEp4`9$j2|PEBi%98jAtvw(~5f8wuFYEZ79gx z++N|9fc||x>3wri0QJ#{*1C7Lqhpzp2gtkSr5NjKC{pY^s}U&NGH+(OHMr`k^Y=v0 zlJ9i>F3DT$+@f=!a6>49410h?v^G}X=p%;aJ9uxXQ`LN?Gnuso)(UB78RCYRPi;{_ zLj5!u>jw7|K|!(8GtuC=*5L3}Z%ZrZ*G0Rv#@9sq^-K(lYUJx;U3((*BDF0_>3?ac zBc|tzM)xQ?oL&9ZY0&2##_D5b-}Qp3Nod3+)pr2p~gE&}AgwV~Y z*@MU^zE{RLQ*>4~dH-hr&wFxa7QMeXh9%QGMUS+7$W%F&fI`aJKhq}UG+`_3rxsw5 z%Tv1j)IHT;gXl!L8|5HIr%~uiFv8{9Am~900sL zd>7hqoSbs2#JvrHdj#XSot+xbbq6Ucr7;B!Zlz8oVjiHsALzGgTJW#8mL|03 zCm{8VKV=H5$j)!Emvn9ev3l~vU)}9c@eEQMOb+|nb%{+k#hJpU$eIS@dN}Va5cr3F zW-VCpA*pO}OT;uR7HSbGx41=@EwwtVu8NcSH--QDJTJG#*3(Z?UMs^4C`8n2Jy7h1 zjdZsl0ncvgLlRTUsZlnR+dv5rMaJR0E1&WS10>|LpF*hv-nZw}w?_SqaguSDSz1r9 z(#apry|iy^nOv^sLQWdXIt!M>ex$l2lLX++dmu^F@UqAPuzWdh&_!=LN zlrQXO4er}g)~|bTm}r<%(HVkj%56Y!x(J>9eZuuVYjCCGX%_kD7qe?ebvsPM_0;OEbW3SXxXko(TVt{q{{cZBUE=PCv+29XMiW_1c6<<$z3?lB zrf@8HF6Rb#414L-?Aan7sB!-Mu583u>n1bHKiwbr`-@d)gjsg|*9fL2c>E#KGwT7> zvjmTSpfcV$qk?DV9_`S^+;^q6(8alL$}b@p!iTqzQItt4s6p`ly|C&%^1e|FhpoZ+ zYQCiSi3(OZu3JbO%Y|z60ilGBr~|?dm7gJ=!oMVqIT`*5`QQX=Z5K{icG;P7 zr~wbJq%Aay^&dJdl`D~3>;1en|2dT_KPj-d zf-$xD=5>XF)&U(vXScFfYld5#g6t0R}emOk`Z^6s#+(4T-BXC^frx&f; zv&a0$@~?nZfpQ!}I#eyfm9a`n1~xd?eGKK4TFyx=Z6r80irl$V0_Mg!wIcHUgS4wI z5B0{ItY4(?6aUod)+4y^Sj{Ph;1*Nu1>eGc^EA$0Fdfd4r(yPj%XQiSM!-^QM<<=J z&<`x?$9m~>Qu!VIin}M*y3(6tp)#%s_ggT(-mK_>wuTU)= z!he>%S~YOQc)S)BI0T1>g4suE#6S*Jq|uqyP;P8`NJ3spu$?tDvvSMq&a@ltWEJ8; zdv+>G$PS6Tk}YkmqOJJZA=MrmbfZgn0&SPZ^y+BJ-UD3xS^OzM8aBOE5Jn6JE zlG#uP0&z=Xgx-o1y6DTN(hn~_5Bhh6QVZbF=}RBpD73eHqf%CiTqx}eA8uoQV}+cc zVK2zrMrQ~3jSBJagUf}3;V-bJ^K(TQyup4tQzjAD$Q9S{)qc8IW>;Q&sMk7}UG>V{ zFJBk$P_JAT8Wm#s**s`GJ}_3(Dv_2Jz7E%AKW!j(G6sJ@^q^(yUzf+7um)>CRF6N< zxw4#;MeU7>nw%mT+5mu|t_$2FoX+6%av0?u+Cz9E(v2^%3=QKDy?5k$+0c#6aY8e$5Y* zQ5ul7r)1g%s7Kd{J2YxzA0-5?dmB&iC#xU}n~K`}dP=2myN+?o*`UATis#LCHdxStj0j;Vc&S#ELEUDwzoL zyI}XS8@MJH0K0ROzZZ4GozZI~T>;)0{GGM1&t@`|9VDARR&kaePy8iU%F)-^S1M5A zV3uH*-mN3pAWvUsk*Jc}xoddN;D5uFn&aHA>e_&g;vQ8MDG35^qxJbHOC z+K`I`RDTt}6}gD2J$(((P7y!FY~9EOqL{JSWxqy$7oU;0lJm#>F{&bR-=Yo~@tcb2 za}?K?;5;#Uc}aLO|3fQNW;pG$n|v1j6d%F;P0TpF&1Oq1400iV$K> zDfd>(yy@LQy~})UWJBB^bnL1yAnr9(E9uLh-7j)7x2qmc`m)^pQqo4g z{8P9wx82$5i+O@8%(b!-j7l*-b4nhicLgF6l8p9(6;c^+IKTiRW65!{%=K;6Uy+zc z6)s=RA7Ys2uz`AI)yvUFUfc zlKQ$;?59ux_$`IF^@cQr2y!l+$&o>+^W`(DLiS0y`cs#9BdLS~(OK@&VBbZ_x)Ic1 zf#1q}2PC8Pl6rDg-dRIio!DeFaG4AU$D>V=!SurEPDZP0-3H;-B3F`v>%Nc^N#RL3 z@W+99UF00zTGb?g+9gae=D%IUs?7b5RBi*pL#NUr=MtgaimvQtoU@Slj z82KNINW->v{gH}Y!Nyn`iT;dUTjjc-ZLUuGd?%k>y=lFettpDCICn_r+-s(`$9M*~ zUoq!GRf2a|kNTa_^42d_BIINU&*D9@5%^kVUjBC^2Uf0)a4;d0i&cHiluFf5m7)xz z;(3{DWs9LC5VG1nTaNRe`+j7}w)I+HoM^;dv6J~EsC*~Iq>fI!M{fI(IyNxtTJ|B< z7m0c}`^f;$QuPFT3D5gCvPOnVF1cj+_9z`45nr&2mH@-Z)3TPq{qxD?@$(oX$MyHp zLD1G(d8q1%`aa8gO_Qmne*E1DIA~1MKs7>iM zoI&!187y|jGZNWJSs|16SPx|pSag~kp7Z=H!2AYC1i~CU{XFxdntyd8G@kFH?dYeV zc54>xvivmQSC=r35)EeP%0xCMNHwlehq4uAHG3oyN#n*NM&aI^?~tC%`IEF#*dM;W zqJfDfB(uZ>=KNn?@*c0EyjNlAzEJ-`5YOC+0b}vqpn-&)o_C3a%AJ2TV^m@L zgfp-oyY&wu!*NvHru9L$9XSPPSrXBXPjE?ZEU6Qun!L*ze2yr^8>_3${15FJ|E}5G zEqua2=4Vtr%h2rfa{vh87{1^XCE*xEkKmYd@q89f4c}wF2&7F`U(p_`6Np~ZBA8O_ z>>|trBT+*vCuI4r?t_iXLHWJnUr$tmkoSThWz2^*wv9VfsI6QJOIi}_eHVm z_g?(b4vCk5v(p2$*e3+91N#v3Zxi7PH?@CvZlXz4a1>*h24hHETv&1?Y9Wz;s&$Y@ z_=1JM1&-$C$g}cO3p7QteKIg=ABY137eSIU86ZP6KmdhZ(1(>|)(J?4dmvfnf`slV zkgQT5X?Rd(UC#UpDzaB}kr~zfjLZWRART zUpq)AFq9PfOGJ;bu$j8kuyHFNwdc9y%iCK@xHxVOiF zVA8$4$WWI{{{{&h$3%|MoM^wbMw;iKmI~ywL!XAwj=9gCuTZA|)LAC;J~dsAQvi8T zZvolxR8S`s)R`}E0!ZM_8v>%})KeR{zI6kivzyxCc=Znn(Dt6(z*w(=a%q73MjFs) zdCLO|Ex~%}K@YjpUrvpjlNsZ9aD}l%$|XgF4n%`DmRv4Pd@NW$4wtFB!gJ2S3Z%j! zRnW_6(KYHRIV_{)UU+bpt}jEXTO?UGs~gF119)Fj9D7qn8!@DvS=j^%z^Uw#L*S;I zPCw>1=a}|KLkq~=wh>-<(N_?OV)11$O2f)|Vg~)<$dipT(?-fT>9XXc9fS(Lm&nb5 ziQK9!=YPme-pKDngFzvUb#p*EY0qEMB*?G;?39TV5?OJK`cT=8iFYNmYGBS56>Iavf#HY(Or5gkwn zsr%4I_d!I*Y^{XmDcTnE;b<4lR&_I3o0mx$*haCxJR&2}hd&&GAGIcCShLltk$Rn& zOpCi})U#eS!C53)p(ae)-hb2Wvz*0Wmdf;5JlaVdpBj}s2vFh>pRAwJ z+l_|;_u$Y=Ncw2!Y8Sg<5QuaC@L(7O?qnM5LZYo7!0`@@M&JD>?U%OyJc&@%4Y|Ls z*5wzNWaRWoEJGu=4#mzV3MX0R2@ApAmuHQ^4dJRxQ^eCFsAZnWp~-O*lFK; z1o6WK>`qF?^s^PR(+L5(gJz^@Siynu3 zV}C~zfGAbemDqFz{I^KT2$1EzY1{#O__O}C5Wv{7vN=A#Vdwcn z&E}WkY9n0V)U(z+UN+}hzws_3NI}aqpDk`aOwXpchQuDbOnPnRSD%7^5H8!Fr7n{+ zWAg*-mrSWTM2g2d{7G|>;VG%w=$XF~I~QraHh-=B zh@dRPE?POA8{ozgA{kDbrz(|$u25_%w30OgOXH;KHHu#KwWJg~AOBL#xNcqURcnW^ z`1paFkr#DnuJx366@hav3u=dCNfrwP;93cTn;|gH>YPB~znux20rkf++ws)cD zYv#XVouPUNy3xV+=f*qujMS35O<<~IZW+VE zKltVyRv!Mv?7RbKNc+z3wbA)ufSyF(l>85yv$*h%I|5gD_v7Nfuw0==hEM0NBq85V zh+8HIlRC!viwmg@Fh4tjcM7Y8gk)|XMPlOgg{-k_oCm23B!t!C4A3MK=YL(SRB{f^ zIXFFqu-MK$x;Av_PGg6Pc2;3fPEoN*+zup-Ps|Wz@|oP!EYkq z^Nrm_8R}+NFOb&mYyK^0^rz3&-t{=agb@ zAa!o~qIS_VrT??Kz*k__lzn=rtY&@L(Q}OXj{~y)-HnRH@;eo;n*zcb#`#XSl(Lka zUzHv0GV`?XVP9yIq;4xanr2iTClBjdG&;BuWZCnOvS_4lt^Ag4$u2uOD};)EIwUh? zt^5;h@7k-d&hw1b!`sEotz{dwl^tvU;6LT*xw2zzAN)*p>9mLUD?f|WFG5}F?^~Ui zAG1a@k?@1JdaU7FxV!9&LuH%Smz_B0!7s{=bq{`8c5G_!fT}p{;a$eMF5wNo4Ik@b zR7vDO>+$8UK&*WGVu!=kKZu9VDhY0DRfN+|BY97(p6Rl~!5|l@rxCpA{kvQwC&&c( z=nq<1DUsjvOdP|C2rvCFH!45mw``t|rw!_<4Nn3G@}I_!h7a6|R*DU`oMu#PB3;_A zoIqXWH{5>Ltq&TNO4ocyhTI-S@<D3j9UY)~7S`jiF>8MJi z8kMKOmAiD#OvzctGmaEcfJ&fsrYIJ<4c(?k|uQqy^PmNMw!BUyo{lCbP)p#n0p}bgbYKz5BI(^|GJ`1Qc*9jq5)D- zfQ%O=GIrD%&y@cxp2+x~&PY6hl*lSC zx^RX7^(6yc9o22)HpAZak|ckhCxbX3eOkw&>mQNf6w#2mA~WsiF%rs zJ~HXKJn7l{?)^#t0D1m|-z-*~2?asDW0p}865 zF`2&L*X1#RRqzYW40!u*j%Kvxx98zpqsgw4XlR1aRWR)YKbpU+BP3;8tR5DBVG8{T z|Io&;b9oqqg(|n1gJ~qXVcIgjSGFNpr(RC#yReb5=u0lWtZWWFtiPSXH|-wJO5*qV zUZTH$%Q0%5l#M8tHce?bJ}R$0CjH`2Sap;^SQYQAbo+(%16UwCh1C{;Z!cp0aB14s zUi2IGgUC04?I&}TN{)}np?YdpNeuaL%Na&hPhh^z*G{;gdY~X+NH;VXs0`;%Bk3Xv zhu2B7M6;lZ>x9G`m49GnR6mr5y$=!lk4P7}Ut!nEEpu;`JCgieSaory>+frBtch|Q z+veN2{fA%fgwxw)j(f%OXMo7?iUiN&{3*8=zu-O)58&R7 z!X~10zf>NR1*V1*x-4AU7zkZLZOB#ZvJOwEwI(t7-nvaysbDM;=&z*H`3-o=R$v^r zr&lqjqz}ze>0<8GWShz=t1u(-r?me9&0zw~^8c3OLdh}pzvZ|^a$HA_%Kh&$83Y9Q z89y+S&L>Cs9oK}Z)W$Z1gDVdI07KGXR83^6*8BL!s(7}=MTzyk)2L=S$OtcLRPKYk za*0*BgI_&;%XDSyeM~BHn!8m_UEgq3p8%xd*@k$1ZK-b%xpd&FQ2|cja$Zs)Z8+*m z2=Td-tUS2=Jsf^H-uPFrTenExV3 zDLmmgr)*BfiK#@>O-_gfIbP}nV_hEM;ywzu3^J-7kfe(834+3eF{848QF$|oLNd$$ zB8brzp-`jq>s#Co85M7EX)34_YO)u+o5=A9Ig~Vao$pFuVo1$DwE!QX7)lF~5SiA= zrW5&^wY1L1@FETB3HY+Ye0@pSNrIl7@BW>3>gc4S)A) z=?Kdw5up1Ur;U7TYn5c>76%^cC@#bLFN3qkHZKx+89ZtGhW`-L~)7q^#IG`$3Cmd{>c)QSzAx0^+E&Ho!WXIi&Am3>wUBlxtebM zWEErFiJzmY0Fff?$iChOnT-60^}OE4={oWqPg-nq9t%_Ku>;}1pXE~Ah>D854{g&E z#*&NKV#{N~0ZG_;?zlp)EE?W7K;*N2b&A%RyMsNGr|1*{*2nFUP&(C4TI4p>{2r?B z#*<3y;59x(eRJ9wl~+?ht&$DY0COa(P2d^ZRyO?rv8$j-KWB&C# zfjI0U?bR-Fxlz?ik_d(gh}>PIBNn1wtz`lsWI(KslB8PCr`E3^?P`42N}diX&z0nH zSA{zzib)xg$dQrAF+l@X?M0&#Ili74UpL)pChRrySpqO0ki}c7XF`;*?E}tjr4EgS zFO$LThogt0`q3$oV__nPn3hw4>POc^j%kU0^ww$(ZH2?7(+H_y1}b=9NAX|pGJN&I z@L3hl>_LP{bzC-h48a{zf(+JOU@C7Gw01DVi#)cg+1`NZRUe; zYqq&plW$EHF?`T&6cG4@OY32zn&xam>||~(alW14fyURA7krgV9kXavZGN@VWyEcU zcouq3Ixbo>_%h+5VMrG0j`rkL*p-j?8j`)&nTg|OtEkQ#fdI5xD>MctX=O%syI@!9 zQ!HivDywL1ucE)en%j$ZELS^>>Y}@~85PApv7y+D-f=gi%gLc`pj5$G@8b$3T-V7Z z*<2j|3eO_ze3@WEm3r#TQ>l9D%F{#YDVwLe)l(0irmCk4cp9gkF6C($Pb`7cjmliv z1O#1dnQD!;kB;|%w$9g!+=kvLSO}+kxu22TdLa}g<-U;IpK7v8-G}5!>i!^6cekY6 z-N^l>&JFo|-OK&4E`Rd;E52RIZ!v7pT>j?31TBO8dD;E_8)@?X zf8*Z|Zr}RAeTX{bE9X0`2^}19qiMaCI=bX|>BnE&!?X8=@UOdG9yM9|!Uj6>r+E z5>7VUk~xz|aSr=p4e*wI5iY!M1malQ6x|t)T^hOx&#^~v7@s>M@K6`1EDnvrTT<~Z zZ>F!Zhxp8btmw~b3-rl*WT4kbCBA6KnFc0&9V8DG7pLCg2WRXjqGeRSgEzV%DxLb)H3nQW>mhyLg5HRrawy&+Rfl*qW;8nvQLM)Qq>buxFEyiD#K_c{~_NGgoJDi zm0Tz1lX*tC<P9lq&M}1r5s(SHDwWX;U1^+PZz z@}SS0sfv6E$skPdfm_ynb|cWqL!? ztuUW$}J2$6r!)S{)H^tlmX0Qg6Gsd0HZBHdS$Q?!S8Ms&gX=Lot-V1pQ)F&3^ODctV@%_m1htm}=-JHkh1 z(3Cm3Uc&CyA<|GPW=q~6r%3xm()6AZZZx6&iDF^j<^(@^jmuAN5`NO$i~c9R!OWuS zBz=zel$_~w-Cgu0U@K9WQX<4)rajCjoaGNj;Ws%a=DZfUPC8q<35KrPSS-;Ysm|4- z2=wO!p$x61leoPzC;tUL(#~I5Or{vl>Hvo|ZlzW93RkH{+IDan0N@R9uMDrw`299t zO{7~|jZQZzMF_;DEECA|_;4z~S{ss;J0S27QQMi8a@JEyo`^uYd(w|{JM`=2P*NI<*MZQUdf+CYK;>{+h5IE4TV1l8nPVN?Dt)HNal8BO^- zwL%oeYAcD>Zi#assL>h%A5C_EAtQz%KvvMNHmZkOmU85OdDo27e1jVn|qDyt~9 zPZ&lT8b(c8v+I5_Pe!Gy5fd!bJWiD_f0(4t)hO;G(_Iq~ejH_og8~%xk!`6rt_JR2 zBm6Jz3lTViYcZp64;B|MfxA}ujxF>Ptzt1xFwLZ)yj37WL0?4_62AkTMaL-0uN)JV z33cQX-s}aRjAj(tw8mLi$a5_a5dA{Fin@NIq=}I>s^4%@qT45;jks-O_LXrN`PEmth z{=(DRNMkBNH2hG*UNAi|mZ7F0C?G`L@0;CDS$$E@_)wVKN5fJ^Fug)uyMa)V{ z_0X-s0X6_-Gh;9Zf;^&mj%|vz#2^60X6K(^EtY7TTlq!6jzuobO3b4gyF2#2>q|;v*Io+yF+XxJmgQHBi~h=W3hpxPB1%Cr3lpniA)w zM|J0w7XZ)HyF#$b^$$jKI1Ep5=Jt?`S<0Dt{JYXm((^^E2~?kmp{t-7Cj3gFbAe1t zKj&P2B(PfN_jx7D6Ot^5c|9Q>oc}O2nmw|@Z51rS{Za^0=%G=xqx0+_B+;x`2ww2z zgrd~RmU$n0ll&*QE!Uc?FYQtCF)^i!kSA(+_BBi=8e;*gINf?63wN%m5BTl$(Rh0I zFTu%siZysiKsmrFbK&9Xo5?8drzX*!rc3bQ*=2K zy{__QC#KSke{stA6`n7j|0@~)ZOP*Y&LFvrKR8uJ`=unvXq#lTpR3PG**AEm2Eusf zl}Z=Yqn9~r$w1Kt%POgIyBL(}!3T^^s6~3&;pAQ_1-PG>uc

    xJwpSV2-_J$1=M7 zT+<`e$&{fFp6=`!nCSEE80I@aPxSerfYVp^nOrwX=+l3-&%+e&RQtRnQ@n&e4DGw? zUq+dUPM<)c^_C|tq~ue^DWBr*dwv3crnnZN&NTp8dzaH^d27Mycl2&Ok4g~{*y|)= z+A^6H@KvDq9A#*@sC8$Qne7g#PAoVJ#X~M+Lh}FZdJ;FEsnbGb5Jl;R&yX%;f zf=m>=VfubW(P(G0j=-s656eF9v1>B2bk93dQu&kS3r8H&j?@skJ#!k4?-ss%zwBM7 zGkHc~O>}f~O-AUF=9=u#r4l*xvgVq+P@jq|v#x4>-)ArU_kEK0BFQ_rCVH`5)`iFD zd3ISh`R#0%6&CT^(JpHb%NT8Im-&TtWSswCoMCY`=h7Dt28fBD5k9U>d@PgcI;p?S z0|=(p-Wre|gELK!cC{A%jYE(^x%+3zdh6?)1AriR0sz`LwS0EyJZqs%DJ#t``*Iq6 zau?F4{n_)Yqi3V+TDb)moAB0GQ5QZ8%Z`#graP_BKQSNFul0e|5>T<7@_MX<{);$< zu<}ObIXuWtGdm+CWH|S5#jdb&DSsw=)VPK1=w{a?TffS2U+v53Zj2T z zs9%g|?ugfaW_VU6CzNt>82ROu{J5Cs@kghOpZ@+8GNi`u_r@QuPxTl6Cc{~wVWR06 zaTFEMf4aZIA59C-?vXN!1}4*hESR@~i3PJNM=h9cK$oQ}j2|eS;#@;Bpxo!OoDH(L zYrTSRr>y6A{r}-GD)rx!RDba)^-B%T#|+J@|FwQUTE8qGILJ;z%}xl%@)8CJ(wE3# z>h;zS^P~0;aeJ({+jV^XDeHy!R*1oZ1dPdx>uY-aHlZ&H0xr`BS-lru?vK9%CONPvEontM(CJ^G~m(M=(j@p{>5?}}0i@;}pIpN-Rh;8< z*FgU8J*xa4$ZB-%Cq*swU|(y2D#M~%vcp~1l3z&g4oe)X8I@o7>GL+v9)Q*)D)|JK zA~Xj(aYm%bo=Do8Kpn0-@F@N$xf-lt8TQl@L_>fR!7(MFjVB+#=eT4ls_VNYXCEFB zjmnSJ`-jwr#5p!2%PCgq042gvUMhL>t5Ft18%g8>#**z|4{}X=LOPb<@p#AeM107` zQ>kya93zSCfeN5`)jPSR7<_HQIixXsuXS$opdJ~a3l$5vZA^)?d9-2xAz-(iv>%X# zv%t17&dzf@NEK*$-%RV~VY4P&V}w6#>WSme_sm_a+2YZTsk=?29J8(4MzJ#=aR_>m zLRXE2Z&SFyn!G8z5tX+FVr1l&?lKnNAT$=kxXIP26S_J%SIdYSfCi$4*s8Xaan|da zU0(}r82>!KlT9KXBhW-WIEIy?c{9dTn0tYcHTf^tuNd6hgi>6ZZUV8m`L~F6D(#Y zcVjj`W@|Q&34Y=^z5^ebf)aDLQ*jl86z@=x<{u<6FrDqv*{1PCBVsv|!iVt*JiXAH zIsA*Mk2urVsf$F$=-jFrGr5}Cr&M!5f0p$xH&OIxytCM?W*7<0o7#lBtjzNo5iH$* zHiGnVd=mgKY=#Wtvtg*bk0U0PAYOs}*v%lK_|=jF=%OnbpN1SD0)_V@uX7GE>g4^P zw_+(K!U{pqtb!gZGlHDxi2>XL7kw+MIWYuBa$(CpR^qzrTYb@W1`K7(Yg(Sm3Zhsci*`>-2|Fsh>oeUH-cV1-}|2*YL)ra7u3| zNHdYQw9hq(Mp3D}3>9#xlOC<&@L-p1(q+tJ5oJJvhqFNhscN#HTET{$vrTEL;*9R8 z+bZL)p=@hVz{>0KN3O=jrQf8?_7J zK76Wy095F%cw?k5yS&LzJ_38IvlN-FvU6t9H6GMqW=0>~B3yH-*k*JVWHZe7gYcJSMam&N>OtVIuf#nFdk^&j4 zPv2OygZGTXt9R%ECnMtz+jbuAyT7?6+sNNw!R^Sm1XB=>f3il z{vif}7gXcVAMgB%H1nvDzjeI;6L(I&y`8?ja9rd0H9hy9{ViQ>-jp5cr0|3@;t(0m zeh7vf82@uQFMsDHhi&jYCR1!qL>pIry}xNZKLJeV%1+APYwoW+%ip{FCGn@p@;7l- zM{McV^aKkMNJ=oroQ!)yAt~3IJ7o(l#>V~G%RDw@DB^~jpeqnXbHfeOE1n(9D1f)7GB%zdFjR4uI+rAL1YlGqD_QUo{LM~Q~BF?zM! zYnN|*NNxVMxrL8%tg&_TN=_W@f!A<5+@PD%b;0e79#uj=@3~y{Q>Y(D?}Ss%|J7Bd z$A0dd79YwX=byc$p$u7WkLZ#NyH2F{H?l+b5tsB$6geo_5PiNHKOcMiu%^#b#Qz_K z7BnjYpnU)k+79Ao4fESiE+~WO5fm^Zc!B-o297{E+k;v5lh?vP^VAWq()!5{CwQ&} zjT(hGWrN{I876ImeyWfKe31d|vDSS>D+Cl|dU2px`3rvG$IVg)#~+g$S;htUm{v{J z1@E?(sP^jc;krb%SBDSRC91tT{4nE`U|a^I+ACmG?2(Cd3mFw#)tfG;qoa9+-SAm^ zQ2mUEN)T*$(jlcQ9$?I)`WEv_zS^_lL%deD;+-hb3U8k#TH$S{dQ)BG?S0-vX$e6= zQ9!N}he49!@~H@$SxjFW$FNFMLJ~Q&rCVdtt%`L!fQ_#yR-dyy@(uOK{xU3nkeYQr z`IZ*|Ug=e2jErmw}e0OS@Jx8N%UlVi7W14HIE1&QOm}y#j+O> z{V^&Qq+ND&x=3$fvRCv}>j&&EfNa=hBS80Jr>>Wq%9^_ZS4Ox{!bt+QI)#}yM3(3l zkf@S$YhL%t7~Xv6W*V=}&h{M>w=y+moeD=BmuG7Eh^#>s?}px|I9aDj{YpT1()n8X zHzx0Fd`s@0!y>FD*w>0PnT!oRO3_NlSDeROQ|#z5%w=30N~Cgi2F(^H~_ zM>eLU_{9P)bh9-&JA5nQXW!9uDF-Duq8i9xSjMI$EYrIOQ8Jnwp z@q`V54S}u1+KAi%6xmBsko~4S%-=8FUwM{4RzmW6Ns{jpG9`e{j5V=`d9eHoUpDGD zC*)t8Z9JfXe6NK{+vBTl6CiJh9kzVYUp8+{4R*2yN=yai-SBM`AEJ|+H~K@j0Di(Q zj84};H!7_Z$jgn{;iCbg;$@zdLHtWR0R1)s{m3i45X72bDC>RE47=>fd=07-mk5g{ zlkmvJf^@Dd^?~g034d@9L1=^H!Y6#J_<^`4NQv&YmOXe6ZJpr}va)WsQ<1RYncbb2 zE~2vL=so){{bVw6wh6W!y+*p2;-|Qk5_($N8B06SC#AkMDbWSwY9mv3aH#Ijee_4B zjvHI@zDI>@*hTj2Ldq%!@CgkDvneu!d09X!0tKP$uz~7Vp1pT(|Mui<`l_Ww zxXI1z3C-vd4DsiNo1tJqzj-8jj+~U}!LzCdt#mSkbb41L$@FMUxUsuSA-&m_Wpa_V ztb$sTKsM&q1jvHj1^&_E_+*B<=!p!T%Or*fbFL>a+FgK381oFcEeT|Vc~vxH8)Z%F5)4OocqHGsR`O`K12wgrD~FHg}=J?-VQLMpABy}Un2&DXPV ziipS;TnzVMAoyF|P6hZC|GQ=Fx?7Q;Sl?pjMb#?Tw4yH113gv=8Qz1dAair5S2LGE z7g|=mWOwhG-@_D1}=&Av>@Sel1iD*H^UqWdVS1dUfy z7-|6k2Z&iUYXv`2Y&c;V1fDaQJU+XE>+_7)N(1~g66Gbo$=8CWoB4njVNmW7+(|uI zUVf8M#{r78GntFtx+^}0$5whB`SS&;CB>K!cOtKQWi>n4fJ}EgQu5yT{y9!*oecHo zE?hue!Shl5xr{wTWE{bt0XAs52o0RNX~Jq}L`7${cPh~8;7q0+cF%o%tJQXR>il~0 z1I)u|=9v;2&>~x$6BQlEEx$k#U>=Ehkq5{A7S(c|hLxL@E?&F-#>|RbrZ03zM3Upj zIA>h1dLcrcv|MZkD}DuA5YcvasC+u+(PBp|D(LCkEJVd$-9{E|-HwYsi##aAzE+cp zm>DS+7sEs?TKa|HS)ItC#x<}TFTFs$vl}mcmeT;@>-P52DMO!MjeuHqO<96k+ z8;xrSU8k2*F%)!cqniWi1RSKh*< zdwik$#CY_^9^p^@!P}ej#s`ebu6)m}x>{zX8=IrGR31J0`!2AjWyZ-2T**8saWN&V zhchGnJc zW7`F3IniL>8ZK=}nLAYkM(P4RPH$HFLXXGF=g%+AUFnP$zTbn4_i z!iynej*SD?z50oeJm<}d>d@Fz{5q-8v{$3?+hzl!iJmXWxj8dB!udxx!9(~P8M0)u z%^Gsx`mjM5krjNV4b<*VagF3W%eNzY&fXHu!yEIO>nWSFEriECzbM1hJC^}vio!Z( zTT7*8bGQA}uc^DZM5Jhgbs4Sv(H7fX~mfejmixpXT zuj`)sex5m}Y0JC2e|*2+&!&BzbIr{4%rnpYyl3W~nMaxBZvqRtm(WPZrgE>7@hgFss!i=e3h77)BA37<=?ZT8rosCSf^MJvrpW&Pi3^yZ`UQ9<)>4)75&krr{@%~7C z+sB%j$Doiu_Dao~(Nlax`RaH>Tp4%0fmQK)`}!(cz}Bkx$L~Snp4(TC7NG;-Mi;ev z_s43k5!AW;x+xeuWbE|yO%5LVtM~d!_(1dM!*9gL`Z~Pxz@8gk>CVcD9J?Mv@w{}} z{GV=HNd?1`@j5xCqn`UK?*8h#;K3!AAz4Q=c%BMCLkG@5G@qft>iZLd)o=;wYUHSu zLSaph$Y=ad{qn`;Y#9vU|B0~ZGmoCtqeigtpGqHy4>UBj~uz8@3f@tapD zqt!D)#YT>&;BfnTw7gN*8>xwbu>2E)%y|$@9ex_mVkV^KzR66k zubDOBb;H?}gibQOw0zt=Rl-{;q|S z_HRN(8}uI~{^RkJ3ht-Qfs3UOo7oOPbe%haLlGZ9w}wYIze!9lLfoY3bz=Gsy3I5l z2h*;T$?vg+)?L5ioFRr<7e;*>D)!%tQvSlSSrxlpgu{l4 zu4(AILZ$zEu-=XiCRWx1@$`;~bBA77cs2sU5kTzZ2&Lu^eGzc(kFo#ZDbpt8|9TO6 z){kxbuHR2?p}$LWU!>^zDr*6Ppf~^Ve_*3_Y3py zd$VwGOl+^rQ{oWKEh6GGFhRL}=;f|EumdRSLwwo#$=98M>i5q)fac4OvuFFt{HME+ zUuBGT>goq^vI$k5b?m+Mt!xE-h1qxGr5abiJUdB*^Du4WrL>=pRsipMP)s*G+V$}M zZRib@=GVBtFhw>2?%wu7?b)@3Q~S1mlgK{E&i>E+E$|P0{sMxjBzU5&mwKX*(p#lD!h57t3?Jl1C<(@@DtIZ}f0-^#t9EXoQZtF2osVxoMojvLr@kAJto_5A z;4wUTJ32d($#ISnx~yF%Oub^lf$8X*OP}VRi|_zK(So>QpQd%{DT`-7ap|?Nd+zm& zKd9hvzem;IgJ6Dk85E(%KlLS6&o~30!B)^thDmfgD3JCJ;8VAAKS`=*EEau}VEmk) zxcmMS(R=C3O+rV0{>$jfLqNU%$FQ3Ja@P#@a&b20udwyV@qM{z9LW0Xsy{u9MN2%Y zYRj}6Ug+UKP*?d2-;1z+<~0%2#URJ#czD${*e(bSC7!wjhganycCD$=j&A?%-U8B@ zvGHR>oi%nkUpP*G;{5lb+Bpv?%KedKcih*Eo{c!u#<>a+z}V_K6`4}H80jlSY{Xp1 zA4VU20pknDARb?FzH?Ecj}*j*DV+WWelt>KPA_s@XTGqvtZVM)xYQfdl-EsX9XIWD zct3vc1oyy#IGJjaAZ$c9P5s7^tMf>@G z?2>1Y*gxF$b0qfKX??lLeOs#j^nFR}6VQS}FJ%{}2+{aXyu zGv9sFouD#*|8W}Q!PYEz{isWMY9bUKFq(oWzOssi3~4p}g@?kH(0sjse3EiZqT96US~iQhHPCp@~CwbL1(4JRYI zagOw~zK_mA6$UMihH2=`%!+3s4xCQMh0`8hh@guESiE9J6-kr&Sjtauo(!^JetO^g zPTT%IsE~1bZSCl_ua(@utSOlrGc~NI*r53BbWL}%e*mxK7h;b7BZQFbuq*7UeY@8` z4ITB-QxJNj&{Yn5sGs3IMV_HD_rk=#1M}oDsJV~g#A`k_a*}^PrZm^1Z-cqje^`g@ zAGjMnls!jrJ`3J?$oY%#1wFS{y7qB5xd*)$XvBr_5gxo}D$Tk+=ww)l-o?&)@Er92?>i3VdH)?S>|WBV{a;(* zHu?mDfUvw~bkkHskx&m@+t;;o_mcZb^?t_ePkHwA(fMH0Hx$Z8PK+O1$a%~SL%W8z zKT@{+;KZ)l`M)e&1iiNxCqj(fz2SZw3~}F71ZL`z`%b`*dTAPymbCA{m{*-Rbvp`mprol#bdU9 zxNpa;H=)KaJBT;GGJ>_u`?sOVpBmcrpd5%Krad$@ncK%{f=-}kewwDmFyZ;_ ze<<5OACQX^sSdLSR}-#IT-$IVeZ%$`OYA|0;*vkZb#(WqKi`OtzNzy=xPSP)m%sym zz^tq)dmW;d{cRlKFm(qvQo|N5&`5$9Qpc&`4|g`PmnD<$9EF>gqOog6(qf|Zdm3#Y z+9GJn`g*jM8a&x)*h#|E*z-L5g$JXqxqTl#8I_23>ThjBSY+(>+SefOP)~7xKav3N zp221WlF{pcr^_aaXgKn|;kYJ($C%<@E<-TSp+ek!({<=*H%MNBClq$R0e>9M6T+Ab zx_?`z>}tf3(GM?^>RFo8IY@PK|ID$aFi?9eP|r>g#@t8884s4iH-+lozPzCPNlAfz zHr9}I<5b?s^A}CI?zIyau?o4W3}?g3`%r@WuJ2j{k2x&3Vzuusd_muY+66O~Y@fIu zkt!L|-c7-z#G_MJ{CWQOr`CUe{=-vOADne?;ENQ3G=fx3(f9&L8f(ataO~ zz4Z?CnlPpC*4?+Bif#hXTXx_2OOMXf4#)2GL!&Qas!g&VGU(1PAXWR8JaXXmeh|K< zuoX)x1{=@k{nOgr7%zdwZY}RA*AA-W;`pFY9@3wv@EXa=` z`gTLb7Zu9Za(wD4HCzQl-%TGxbnxKbPvfJl>;5unXZC&g19UqcS()DLzUkf7ps;U) z+TjbJNRX+7veH)2#N)L{UrAlgv+kIa;6I~k+>H_hX8*D>^P`;Xn*(PMGjf9`Upj2?@? zvoARMAMi>eK0M=AN>80ndYPtprf>W2kdb%&nP+2t?31eyp`YCH7D|0v*12@nN^ z2lQ|j=u05O9{A!R`ZU(Re*a|A7DFH(I+uaG{^cZeZSYP)$IW677rMX4Culu@m4Mrq zCZRh^I9$9v?qkD3){5lRc)LtO_Cl3~tn#oSOU{QF zMdrusXOiF6NTQ8h-!_4a~pg)Ohhp}DCisZ zKaYLvv_FrM4J%2;(QhNBq+tlso9^fhVRUuXORTR~y@b)BJKsqnnwXOH1n^(-hwpF5 zdDj?OqBMiE5_kKBgBP47!#;A5#j?3CU>$Kq;T@RWzz{)2;e2WCFeUynA{oOgef+ih za8S~%aPsKi9D@qc&!ry(^ykm}Ufdz_vd^#Rc}vWegm?S4uTFBix0Lm~K#AHR=FlY` z!c5GR18-*hP}OYGJ@wtE^iBFIEAAiTZOA#JuS_kRh-Pd;GASQ#83F49VSR%*`{0tv zJC{&}eD{)9*g$ie-grDo(xU~XN7ExHUpQ?E0upwY;>l8wDQ_LBg(nSIgLl7AV^t!^ zU`YS^zp&)x=JWR?mxF@iSl{*EMAo2iw(B+&qqQ8|f8QjZIZo`tmz{Tmi?|HLF({|tUDai9On6YakgyQ*+afb(}a-BU18exc49(sczpxPt2h~O?k^5ZlX>N@Vi$?7<3~S_Fr!^7 z=P}YUDDypj?C8Jy?-#Z8XZmisWd%|k1E14&-}*a9r@Oz4QA)HXmm#Jufd?!`C!#ee zim5M-)86^~4*kr@qt`HRUI3L{j0Eq1@A$q^$)lX@dlIz(HZ0)wBTi19+QFgs(U}m& zspB`f4+`zKE<&K7th8bhwiCj^7<>eqpkP7c>E9;pyZ8i|E&nrJ(5tusA!Ri+b;m!^ zhNqGuGq0Wi%wd*9Y2~{h%9G#4FXqRg8i*}1mSf`$=qA+Rd|Vs@2-WpnYbg;F4=Zf{ z-V_{K{{H7+eIk6cjYT-yk4@a_xtb0YRD8g3Kf)+e$vaL${{W(KU#~<4`*etq-@=)l zfIqy94?DhChz|66U$&$ZKg`RiMo_=$8Ypoh?KsYEUDhE0WX}~ zw`J1k-!o=wZ2X|~Bfmgbu7CKYKCfSQjC@_;JN&Y5gLB|JCG`P{{OCvLpv2!dB(-f( z`-Kud^}Z#OTX!vaS!#@zSz|nc&pb?h3lfVSGrOn`tq>~e_(gd2D>EM%D8u~;xev?z zNx45Q_kD67k^3`pAC>!aavziX^Kw5Z_m|}EptkwS%t>;eEcYpLuaNsRxlfn-X>yO` zK11$Ra-S{t8o8e*_Y35Hk=$$LzF6+d<-Stx4RT*6_siw}Ub#2Py+!VAa_^9PR_+D4 zcgua7+xev(wPPyMD_q*jjDEE8ie!tuwko%C__sabd zxj!NIVYxpk_owB)Pwpdfe@5=3a(_yO`K11$Ra-S{t8o8e*_Y35Hk=$$LzF6+d<-Stx4RT*6_siw}Ub#2Py+!VAa_^9P zR_+D4cgua7+xev(wPPyMD_q*jjDEE8ie!tuwko%C_ z_sabdxj!NIVYxpk_owB)Pwpdfe@5=3a(_@C#PnP=>xmU=2 zn%t+${WQ5pa-SjhD!I>=dyU-Blluj@W8YX@ZvXdDfwW=b$nAfCXdV%Fi)};2=JsOZw@C)z{wX`&AjeVeG4=qaKtME^$ALBye#{Tqomle_-Yi8$o5e=$)z z(E_6P6V(v)6TO*;`(*7ujfhKF_Mc4jG!gfoZ{wWr{+Ce$wK>#B`=2LzJ<;!pxRzl5 z2oYU#)xJUoq!MAe-_b9qUl8MB07<%m1q*t z4x$$kw6_06G)8m}(eH>JA=*du8zL?tXgf&64{SRDBE$ag5WR`$UZS@XeV(Y1hOGrV+6pv!DCVx1A0_eLoYv?L49vkQv%m5;0q}wG#b?=mSK|G;Mbf z{gCJ(qP;}FCSu2=?Iof?qSrynkbUUe-a>Rc?G_S!lxPFdPNFWN>xlY@3Pg7iT}AXL zQ4`TGi7q8NNVJk@+VMb(h-!!~AX-br<9^$^h-MJ&Av%?aTQTpiAbN=CSfXDMy@W#7 z#?g)aeWmJ|J&=whN{F)X+LJfc}d zXA>T2mRXi5q*j1k3@G8oxo>5K@<`76IB!4Nc46h4u`j`BFYhMAZjD(Ai9$18$|1f z9wkD@_La7$h-!(RCBh~sue3c+gr3JMZQO8rKRU6mw4F>eo#-s06N$JD_5Mjj%ZPYl zR9iFA7}0e^za#nt(LSQj5&f9xej;wD*Y+^ccZi-Mx|is8L|lp3_5#rW&<~#A-}CQ~ z$aZ6t>+x4p=YQqii+g;b8`)cYA)xvvY}Z@sfBk*wij_-TzL4u`E<}whRyT@yVbF(TJ=Yc5+Vj!oOiNcsI@+4bN6ned+4hcfOVpalMGZZLwoGR< zvzh-~V{>b3d*jAb^VR9j7T4J5pK5G$7d5w}3aN`>)tTCyhDBptD;T z?VH;R?OW1~g`RBMTV-%8NjjHUq;k1bPh#AHW9<@?kBh|I)rrsdMt*EZx{z*EPA1nV zuJV@FuFmE{Ol44breN$()-|W{1>8D17$q*%(Y~oO)9QGN3Vs;a_@_0WF2ImWZB4bb zTKyqyVhK0a}m~f+nnCK zIkP40HZ^BmBRydN@*d(dH|rG2M;W?M!uO3cGEq z+ZPn2OS-VF#O9*c`F0b zh$P3)-18NjI}gB@ES{AELzn*IM_4oqz^|}rAppPUpQldyeKQP8m#_#fu@f%yi7n*@j5ht&UP3Dxmj867N@>KFFI@z1D1x6n~-y?v{scyCM z2o5dnt*x+QIpUB0#??T?j2%_Z%vVNjsITZ8&1|_aDzv4ed{;J$yo5YM>wJ{TrK7pC zqj|HV^JZgDlGSJWJQ!9VRcFs~(b;fXEpA0M$)*(R9r%LUCF)3bZYs37*7jV!0IN;W z<}QGZaE`Lx!>CzmC{J%Mq&G*I)~KuV>dws8P6^Ng3ATIB2KSzs9UWa8oTthsY|V6a zv_vSuIpo5v@U)?)(Y~GanUru+Y918JKETVB#2tuyAd#b8jO54-P{gFOUc76>E;gPgq8@|Me>c- zQj&J?6dobWE=Fo0{R&m z386Pz+d*AWRzHBbN zr9IP?*N^ZqTF4Yq9g^j+G8}EXua)t=2&6AC*S0L+<0v02BNARjF=}qsK2cXT!W(B^ z+oCDt{gW1Ma~f4_kfivyAXO7eYo@Ey3lRZ%V`dXV8k6vOEtRN&S)eq7og=yHOy^@T zlYRS43xkB4LWxGMtIDr#@0{hTRVGuakz->Wxf!IbUOmgDHnvBw*_h6u zwusnB#g&EguSsec)Jy42AWBUmDV6F(woi8>gIVPgRUs(!22MqML?T3jSuXKTniVwh zbEKYlmA*#4F_Iv>IxmqDl|gHUTvhayQoc|XMe;#XTlRDoQr%G{-_eq8jeILuU0oe@ zcXwY{DPO?&N7j#KR?n-cL6wX4mh}{JDRK=&kq9DTb$e%XM^{U_YL*mCN|AiC)Y*L0;VCl~qT%Xnu-T5KeR=5}xpOvI(+eSL3KwKbEwI+bINTL97kc!{X zlI}>e$$)o`^?OuR(~aNmSv0jczOv5b>s*vi^{_h9ctvcaujxXeWx31yujd2Jk}&Q0 z)TUfIokuY8T^)s>35;XWwRdho!D>N05mU6iiCmS7^KL3CAQGe|kb;?avm=Kz#{y>v zY>eO5l*s=G$i}XAq_y-AOc?g{TP|Jb%5_F~VOJWB*ru-1T7fMyQb)yW|4>j5#0__i zTY+|imAketaeXVf^ehDI!n2atK=h$(F=?7Jom)^7v7~QCqK1hr--YRXhk z2F*|bayeQ9tr<2#PLNoP{nGD}$Kw_T3GAB@jq;WZgq5JQj{9^fx;CB5%<*yvs%;1* zNAo6#^1yfB5+ZZQp{Bf#3<|3 z&N*9Bx%N~`dvjFPUY)K^T2I7!dyAAv$y4cEH8XbAthXS;nGO3p`Ak=?nH7om5Yd~u znkmV~9vzaX5*Y$-(;NrMt%~WbHM!JqKF@VamSY~2_i8jF%$w2J;Oi`hpk|fqEj9CO zw60MddZa}$;Jd^fY4Z}%Vedz+kwbY)$^xq?M9LgSN@P)$pB1*3Ro4E_3KQItWM)3( zj+16cDM%Gjw6+UEh|gR9pG!0*nY3$YSSTb)`M1~-7vFTng7ut2W=@g2^LK+IdwJKCA48k_jYy@la|Aa zAMClK_Rd!pkBTga*!32QjD=LqV$b5tZIHg%`?Zhog9v##X`dt+TJY5~vKTTedl+pg zbU`GS^Oej!VP&338QMMO*I8G2V+!BNm=<9uol6xmIrUX!Uy<4=63Pe!vL1(VtT*GV zR|6lVvT^MgENO3MMM@bFu~f;PaCCO1mjuGf(VpeY7ohI!=wMF?@w>6Tr6o;?Nj|By z3uPybBy3AJUkw{6jy}jfSEI0@meu<8LP$(AyJ3m#$~U_qpZB19hIhYZ7{Apho2p+UxOW*v7#FOBr-y)6zN zQrdTrkws;Mg&i4RH)~TKy|=rjhJnEETn9&!#PP};9o(78dE zwGpFo82=JZBMZQSXd_0i>?tX5xikhP$@7Kma5MxDqNk=-)G5Ls3a@rMkm0OkLXJ}p z&E{}kCP9?`KtS{T0|{Q3j!ZXg_E|bBgJBBE1Fbrc!Eq6`FJ1sG$_gc3a0Dpy#*)?7 z8tnb4NK)+MVQK7E9wEdWNBU2^PVzgF-S;UV%c6=xRH(3Ne&Grba15y?kdq(MGB z?~t;KLU|-_MJNj1skP%dz7n$T4-#1Nv05Km;l|b85h}AJ2eUoW;>@HB4F zvwZ6X0XHX=4LV{N=}M!5Ml#ynLX_)5_Zkui5+Nwi9P;5q zl@z_&Ao+2u(jH+f!90i0%?hPdlY4!(4N6{|d?;)vB`Jv7nt6*_r^C~{tb@6yTrQK- zAup>rFz$!K;iu<(%t}S>`)d;8l^j{uYE)CA9)7uXxgOSKEI*Pv*h@qc;73+C+efFm z1?6rj23CQ_(bFkQ6m$<}Y?Slk4dSPv-)iv<@P`zQz(Q zDD0K~!Ag`B2|Z*Elaa#@@_xo2#1_=2nKVM2WJ0r0lIf8sn6u}Ej1+0~NrU$Wp{tab zu#)5}g;e~EH4f~m`|0+oS%E)6q)SiCD2#bVn&m9k%GJe;7AP6W)InSct0F*@P37}Q z0*N;Hz)h*##?&SZo~>x*2!!-xP>XnhQ>!3+KHpIsPSh&CSFKtbDgHPykEw+B)l zDEb0aZ5?&==WQbg&NU50^v!q!23R-uSkMe=U^60~``zwbi*` zQ?si>FEE#;Dg;I!jpI9wNT!sDMmBARc#Wkp2=$EBO%McK`+`JIV)dEr+r%Wg5>ne! zLjt2L@KIG~B$uK%BCa`AHa&SIac~?zCoo|<0Ftq6s1r!Xx zs-}l)>7e|8QLc^*#?hfeBHAfz1VmCBE?@+$?d~lGw}&wUQ7pDkU|t z4=4ch!TCH8hEf?n63+l4|JZ|~U4RKFlU-(07GPIKx{;eYG8-`-E#uu3S~woaX>UKB zLow7-C0|gEg{(yxk7lMAV%yKe!i~+KWEfZKtNCZsZm2OSsBi3n4o{S7#yD4t$|=ks z90>ItICzSY8cZi4qxkMNrMyNNX>Uvw3b_RktU0xpd|c_P5ru3WZ5Sl@Af2(YzGo}+ znA-5|tSeAq;Zt+%oBUus-f2~>yRf`mhSuxi2=z~B5+t#Y+MZRGR8^8ITU@?p^TrGY z|Jf2Svi#gK#t_4&M9By_d>K+^t(UdOiBI^z$U$$yD`NSsSRHK8j6$sdu^2Z_oX^8_ zueD9mo2S%Zkw&@dka%(Lkc^f??m|;;&te+G58~QunID*BNj|ZhBiTfy1mA9}fv*eY z2DZ!opS4lyMbPm3m_vw=H=3aV2t~IR%B0ZHlexKWpHpRg7!@hit(*->xhyiae=nGU)EpSk8`M?E9nW>yr85pXP?Bz#jT|7{WF>tg;ag&!6Q^~mE)S`3p zBGIHa`l(=KZ7b20d7U1&q(ys{&E!RsHNq#0f{BrXP;FqSy!vIF2avJ5+Y6jph9)fX zcZwA*8ZWf>Nh98f5}uJM9w)g=3Wd{tCsa7m8K$ZXRAE+M3rtBTdAN#oEBXv*?<&3a zXLObqBhNw~Uln1k4~?&sH=tI5FQyQzvP5IH$N9=8E6T%-)~|OQB1t;rL2zZ{1R}-i zGa*%2Bdis*3a-8(V7WEzl4e8$b#bI$Djy@V3q&_^*(!#9N#me3dy#S~zgrwpYjmWV z(~a~GLG_(5k%0L54&@wDD0OlXX(`lN&euOw6S7o{oByPdLRz-t!~77YA2oEX(Bz=b zEA(hEY=d#wMyXf5_{4CNHS*}u8mELC&y-eO3Ps*AXOIgS` zq9#MJLmDCq(X7vWKbf)OkbycgDoDy?rZYWmXbwY`p>nZEK>)s*^vcsPvW}ysF<8tg zfU2sKciZxv`8Tl-?f)&HOsXF!gC#ImH+p^KMtp-v#v%fX3@VZuK73B5bq@4E(x#yv zO5v0qN+ob~Yau10onhiLb9g~*L7?n{*-bPX>;cSX)=}w1n$+Ss-s+XAoqkbsn8hx3 z^gEv7bu!jz@}W)z#76e=i|KJ8Lmn^fL+hx5)g;#3BaQ5-b6&lO#8(%G%|i8R1S~wg zdV!zUu*XVbr*0imeQ`S9oWlqLbAWhzv15zryvBQ-uRlaz)V{Tlna$#D!!XVR9hrcG zjLYfRkk4&NE3Ve4m(c;T%E~$vQj41ARN@?{Nx3w1in96k;9=$=KMV`K!Q>&XSb$K- zIzR7Q`Ph_;ku>mTnvLq3J-T$F59suh{U^qrmqz1KQA%Y5Y9ERUs`<9|)`9?bdRseE z_~N2kxVmmJhWxBVLE4PFQ6fE4ttO=tlHoXFGW;<9_==X$eAmW84m}Iakg=D^_>z4b z#`QcEePq!z#UQeu2ZCf@*vfGT%D;uJ8O!aMjq+U~bcanUR4JKZ@|q858c`_}j~k*B z9=u;>7LLMEu{!9IS!WOV4K0Wai$SVOp+2x~PNH0Fu9@s%9i>sq7t-0{pcZ+2F?37$-+B=0E+tq*J^dR0;PdpbAxu3Yi(uYQRPAmtG? zXy0W>nKd@@g4PE3XkP`gYbzuGFKx*Pnjb(+D4aY>+L7_NVeDuwjKvlk(~T>ZByPzu z5#;K0542DbULD8CJ1HGL!7wy~5XMeP(26+mXvks6_PlteLg&Ml(9p(0$18AoiD@dWD88t*CTxI(x$S#V|^CCk^=et=YTXxB*f z$Kp~`UGCPbTe-M#<-#l8?NR;e%RE@Na`mExE7f^*ox%FmiT7=t8j zB3h#{X!IRayw~f~J4T=HlZ%Axyr9PJ5Bd{Wx{C$q?lfJ<8~$=t_Q+J{xSpHWgYPEO zet{u3zFB#q~#AFX1}& zO2i4SQ*q6}RgLQcT#In6#C0jICR|tHD&V>f*G^m?#dSNb&)^!w^-WxRas3e2)3|p5I6;Bt*+t{m4iT&Lrz!Zi=qMYxvYYQS{`t`=OKxVmwD0N2g9ZoxHx>+`to#q}Lr zkKp<-u6?+EhieSii?}8=mAMmfO~-W>uGzTG$5o5#ow(NFx)N6#t{kpyxNgMNkLwe- z?!@&aT=(O82-g$1p29VP>-V^x$MrI<$*D4TGOp8by%|>xt_8Rj=oVPlz_g6s9TB3x(VIuF-XxC*$g z!?hFFM{(Vb>od4`(%m<4?Zx#&Tup5I6;Bw7K6I|19osO#t*F0Po z;aZBT0oN6{T5xsZ>c;f}TsPyo1=kl_%N$D=FYN2#z5+ALA1~V74>Rp~(fmM(`9YYm zCq?Z3ILziBe}5X7>F2XBoB#ZM9%l1j-npsRJQZg1pYCS`?zFE8+-W`sX6%tB*JSv7 zVc^aey;I%!PMWWP+1`)eNgH9d@X`M2Vs}@7*}iWALUwInrv3GSnf~m8+5DsXM*=hL zKLNA7pYC@AX1ad?X8V4+e>E`E{Q;P1Z`Y%NneIP@nZLZqc{VW9?s=HQ_fKd`%yd5q z=J5Sz1ZKKd!))*7?}ETg_hm5imlxgF1!mf9ggJbFCNR_e{V<2`|6pLI`)vWA{{L-Y zru!EHKHcvP%yj=wz^D5oftl|A5SZyc-XHS>%MtTF^E=BB^Et~7^Eb;(88|E}%+Jij z%(u*|%zw;7%s0#{%pc4X%m+++rZ>Nl-^H*pd<+xQooUVVWtuV_nRZMsrV-PHX~Fns zoHL#ow~SB5A>)N{!ScZ}!Ft0ZVT#VoHkk{)sFJQNhi^Nvm}q z^K~zA1CQt~`Rg6Wu7o1S17$3EhyR=O)S-SKo_%ze(6`(kq%R(!T?MyID)}28$F77T z#sdrW8~%#r!~4U{((G@senZQD)3<~n{l>>3)98zu&J11b?XT|lXz4&-*8TK9?|*41 zLZAMCZA_{N~GazkN;AVmwM;;Jlb31-3#2<>%Z|Y z^z9d)OunI_E_CrP%m#LM9w8j1-*BYhKJtY_-*Y7Xcy6H&71+GY@>1{O(8WJlyW~*2 z@%;RYmWQ#WWvE|{{LIaFAK868|4Z#cA8y1qL`oPs%DYSb3C;Em!^=b8Lq>xCyVK!5 ze1p{=(TbzLKM6@OI#QW#_%HZd{FcNNhV&nTZ|Fb5y9P_j!bre<8g2&`p5?~Kc_+#_ zt|nYoS0ryfI;!ACdav@YrU7*fuIweKKd}4cAg1HfF#iFU{6W@w9j-Nt7rD#UEOK?r7rABY7P&R67sc`fd9U4xzNde}HGNaT zf8yuB65qxRd~5uNNAL0BYWu2&uY^|dfVZglUWvnDjAtO+6?=W#+z&q~%SDfQ+2o?H zmAP4PZ-SY!&{tum>{s!)H!r^raxKhbFf%ltxgWAF_zh2Z^KzVXc@h2pfj5uBOj)b< zhu;5luzzSMi|u)!%+-N!vew^x8~tsV2f*k1&-iYcTMhHbus6>cDs%6Kx#=g~{Op5e zZWG;MrYyMcp)wcBa_|2h#x~$S_>Z2y=l{VN1kAPAE0z9#_EC%z!CdoGAHFl5D03f% zxgTbJ-zh&p*bx4Pr@i|OY+D)1rn_LKtXumt@BZ(@=&!(RvTE;-4o$Na*uJv%_4o!{ z_x|Id?s%>It)$WpW{J2Q70PT>@x{n0CqFCSjPZI7Ekk9Na|l>aQa%^U)G<()D9hSJ zgP)R_lgZ7I`IyR!XJNX7(>EBgjr@dz=$3OHr`#s&Xei-#+x-0%S$R>m9olft$yoTu^% z4p@rg7u?vw$ZEHc8)bOiEo|+u&=0_4DieWL2Skc$^~d4YOvJ4YTGHj4(pUl|3Q?R? z;gd(u5|$`HAJ}^jMT_ zE$%tVLY(-IU0GVo$5~uf@`ejBGYQ>l89av)DzPo6D%VM@tz6qC>!_ec;9pbX30C~I zt9pJsRZ(7rm1{nlGtGY4JQiwT`sgop)yNax&ULV2qto#8*&^%t}aJv zL-SVGm@!TyJH)9NmsI2rr2RU?Py9X~=aLV~WA%fmGFz-yhgJT50RZ>GLGH`uGFzZo ziV6psY-uih=3WR;1kdEkx3s6iuwze*XoaXfL95+sX~Zwrk2UoNY%(C~km6VZunZ3&1baHhx?K<3B-_!+qj2yH>lks1>1O$*PdWgDYGYBo!L-n`(<_reVyr zM0MqUt~%cAK=uFVv#)F_{SGpf8kgRL8KQE&0X~@W2`8AKyC)TlrhzEwb1wzHquSMR zMFaw8I$oKL+&lkuSEb5z;fz;*7VSgi&z0O`lZC-I15DQ*#1eD>%*R;2Sk|li0%`Gr zbqp=3TuXUf%+|__T4{`@9$A^hoK4Lu6!Q9vY@3C0W|U?G>boDt@tWxJG)9=}1G zL?E=Le4tS@{JvOBYf*cSun`#)(+llLS9~m%I!2<@gV)RUgI@g~r5|(P)RnwCU0x}T zbhX??haU={S#HK6O*a;0A!&nkcD96;yIjf+!#*g8mQ}i`rhNR_4C&cOa7MlfHQd>Q za*xlX$x0(G)nk6the|4@bT=|dxtEi)YCD`a)I-Z--Gj9KsOGBp(OYG&#B@hKO?icB zih6caF149;=u(tg$~Q>2RxGOXDz#jRfK8S2D8%rpIhV?}1-T93R;f)xGfr-k_L(tX zUA_`cJ2o*xDEM*&@Q~+WrwjY$#0&domqXji3sad~RfhV;^iEgCqiEX3Jgl?QEhyyc z@L?Hi&9NrqS~TIz=q&0HylO|1i=@UFpz~~>O;OK5p;iJ@O7hX_hzVPmeN z2T`^bQH8=US&?a7jzn(gX`mAXsRA@IeS@+LqLZy#j}uIz?CNwni-55$D#zx3o7zw> zXqaOe&9*W|$)YwwkOC^B;p>?3`8{4rqkP5|J1)$=S%vOpx&zA`%k?>t0=$Cj#afaW z_SUE})Fc-HNNNh%fli{b9AU~~8$SFZGFrj3{1 z&;gZA;vc=kLQc^kLs?H+I$!YlVX81vPB-LWJdBEgDv$P2vwRCGnU$g!UhESoq{P84 zmo_<8KJ~gBkS9B-RmT#-cAaGzH!M)YV#lkY9EX}hzBk>CJ`EMS$`APrDEKh)kU4_S z8%G|MJc5=0RZBL7)vo&4Xc%NuN(m^JepI_7PNp+jRK+MZ}4p|^+@kOCM~vog)x;02OCLS-B)yuN0D&k!Hc z-fKYpl3Tn|>PP6+AVRzhS&eE9q4HS`U!cy6Vxn?{G?W0VV?P<_`^fi(f1i@l#@ew53 zN(wl7_t=_Itts|Il3d2y|6qbDxfM}LV|$~*TyuXoar*Izs=d6 zs#(k}2!$-pr}V*e@XaMwYQ^1f--U&fw%aP$_%uXkhad2&yojh+DcgM%`J{rB<}m4T zBU%u5*y^&f6Lm7uG1ak^Tc<));*KZWsmpiC@dfKU*`$8_2Y7C~4wC_7$T+hyG~?fVrgA9j|@XDo=Cnjk(@RbGy5 z5@t0uF*dkv+c)x;%Qq)wMH>y~&i2A=Uy70C%nK@VAL56+Mha4Nd8K%3y%ff%4+V;& z*D+`7ix|~TEO+un+WK8OeM@KR=i2fix$BTy->o8Vsso#LvX+TM#2pMe872hTK8+C{ zhbm?1#Oi@7(7CaD)QSAVYE4TPG8!8R+y30kbtWlz!45SAB?Tz`;uFxg$zrIaU1mVB z8xJ?9l|CE4628hNu7THHArav-F&*`-y%%fC;DFL7B7`pVS1U?Q{6y@)LrJxRWmJkj zf`uBQ+N49GB9@=@ybh~+H*xn_Rocv>tU;&?su;9KTyxgK1`K@$xL^?;GOn+M z59cQ}y`h_lK3rRS7FnU3KE|z;RNFQ(;)gARu9jqO#1uP2e2ezt&<`n>en=PrMPfdl z(bfbg8L03vEJcGY%*J%N#GMRZ$mj(d5^Pz7_by^+j;dqOe#ZhZnQ-*9qNnW$5>{HBrbFtm6sjkZB7ggYFV_1G? zm9sL!r}&hJ$9>TMz$U>MTD8@IQlfR?p!v)3R9!sCOsR64bl&+zQu88iZ9tESFWZq= z#lZbeAPtqT60v#-cVD7EBGfRe=ZcXvdk^7vi$4H}FB5R9$*a5s%mro0$CZ9-E=as_NF?aV91ly53Ooo9`aJf8 z3I(XUDOf=^7b!%ml%svPoI{A z(ut8Wob*(%=G2D8{Rj=qh?EFKD*hJ@3M?q6u;Dv-*k>K35kk0R)LHLYu)#NfI z`Rj#S_SfFgbSImBJ3hJg$;0a&Od0=?BieqT4|*hjNOWXN$>H1n(pTzIq;`)r5{~f>m@N1$lol9yq)DfKM?#%d2_0K^`q9bQWG3ZG8YUrK32UiQO zt8o=@ZO8RNTp!29ziU4RU71t-S_GPR(mXve-vV>f8xk`);UDwB0Q7XJi!i8eyHh@n zcvHL6f%$hXe#g}ABDGtM-`dE#uT{Gy{0^vHyV`B#@0p%=z1oSVCAS~K4JYM_p15Z_ z_Y>H?7IrLSX7_XTqav{Tt=gR&*d2f!PM8%vJ$n|$L;fn}BK~k4?XO|pkvW6sB0k=V z@5lAu^_P7c^!0E>7hnw)@=ML4B)@zPy1xB^x%8cUwqmh=ws%z$rhecNTv0v3iYxpZ zT8;PN8qr_Z;N44GsP~||kJb-c^^$Ut6R+Ry(qo@vo0VE1tzK`Oa^lJT@VJ`~!5Q+$7 zJ>7EXV6ARi`LbxuNj!Q=H%$1uO8ETd)b8SPma${xa8v6#)h6nkUkc2 zh^lcN2HV^v*R=H0x^Afs>3i$m%f)s{cXJ~Ye*NCFGK}te_u`az`74VlUQ5%vCzjkD zs>JSH>7EjsV1(YqkJe`j@Y3&OmToC|V)fcm3k+UjU#+br)@%F;5hb>3d(d~@Tw=+X zD6v|P`TNUKIc`^zgzHicZ3e`p*t5^amjrz&v=a+~c?Gr(l}HxXmE4j#F|LwB?E{O| zqG`~$6!QSC_qOTsjM^=$Yh0Y}aJ@Sw4h$bx86lRY-QP>Amf1#uxXs+;HCqsdwjZik(DfJP7VOp3xPW5r=_sy&oP5Y#JF` zKKd8?DaR!^f|J`Fy51(dz9?^|H)jhtVOn15dhgVryuvI8-a6UGWNiVmW@8->r+_f$ zT^czZvQ||36PqwI6}zp=b(OHMz#*2#IjOc0;=Ak<*{El*_fE!pVoTZ0jqizVsBNs& z&|0Udi>MG|x$kXAqZPK6Ew#cvvZYoR6xnc-+7hp5RpJ$`O1z>~u~%}KcmK(VW=$j% zqx4Elz+At-q|8@OnM?=DKxXqw#H8zY*F2&2vMWFHP{)eS)(l;Si(FRZ z>tfXgx;|Otx&}KQVm5;gPkV=?!mCejUD8dLed?m6ZejjXOg1&3T)}Om*o`3!T%S=_ zjDk>Wq_K`C2J*2{b~^PKrO2qfH}5LW9EIkbKtv0ejpBWNVjb||q$ z#Icg1?cO3=pY3S>NRfRKmro@2Y@2+p9ac-sSv0PIZicTMC3>C=oHQ`rl`nZZa9j%o zti)xXcahd@VV*zaj|8@t@o2&%yw8+6B|#olCutfN<`-wWcwQ;IdoFZf)=!+qywkE3 zD}5Ee1gBH^XnelJ1=*U)b3uDRuMd{6g2Mljck%*DqyOoGO4$#J!(b`pM`Ot z$Ys5ruu4~B+<8RCs#IR8tGkL=K?Qer;1GW8;5hd7%6m)P!eH@p?mvRN`SCyrCkWDz zcS4EvG825(9r4_#B5w-O4*20z+Brlo@G+vY%(7=?sC;58VJJok_r$|J3keE*v zIl)VM^|ZIt_M;9#pzXdxY)#e%aUpjF25F?2#OnUCbn5Cg=~i)mrpQ@jL_9QFWUEpl z?4K*OUx$fkN#Ly25vRaP!AP3o40$_wkO|+R7^_CBi=r!jM;0!CW-Xw ziO{hz)hwsqHd0BQuEWKys__{+KUw5VO{v)F=^`g?a}6;scHO70(pL#&ppg>$xQcxy zbkOQ}G_-5bg7jQyX)!aVmh1{G^W|qDzlERpeBibszZUyXv-=H)gMq^uo`Xfpm%OF+ zqSn`~org@baBba+6-nat9wP-RB^UIqH26bW`5pHj!`@NjMrz8^ ze7`rN%Y&n(V1B@xH={|#DivRjyj32@p?4Nq*<&JcuiD1FC@!z0!z1R9gWj{TpP=Q& zLT0PvreT^m>FP7rlQh~fS@7X$Z;r#X&zt4=EI5yNBi14Eb=w}|X&M&GU3 zsYWg=p!3aY&Zm8SFUHNO?2PsGD=wc`Q*$m!duVGLoo-4ORBK%#?Y7V@*#wo3-5xsO z1>s`@bjufV8p=D(=tFsz8e6*L8}3#klrHG+pc*^%;d|9wfKn#i?-z3q^qM;v%lIqv zr%Qy}BD>d5bR*bjZRCvpX#*2#N6H59uYbaD+0aS7W&Ouy8^$Iz^iRn4mkpQoP8c|0 za7uq!(;y9HLlXxk)C`pkP8=#5KED5$5xDnH94s3v8=E|K^3a6d+1P}EKY4Hhekb%|Y$-cfHgsGT9!(g) z<3sScq9Vd+=QYt#SybVt`YHe$dcCoxW@tjT_e8vZO6?##Z^An#L_?E$kLfKN#_Pt! zrfjfm?3irL*l}YMn}#ZSCypFjJ5V+_VX%DYtig(bV+YD=DhA8&hMJn1-U)+X12!~_ zl=YWIwM}Ca8k!oKnwo0x%vkyGC%wB3`@_w4 zliZU_oom8xwA#5^{JxaJ7Bl$mz; zH%vbFKzvI1#0yV{uA_ zk5Aigk^CWS3}}4AeRl}~K^tcHzz!{l>6%G)b^+S%Te41a&XH!S{R zzskFnZ+lmgKOFE4lh6GuA5gySZAm@@MrVe{u<*~tzNy9s{xR?l^6^J1pB*?RdDbwW z<$goI)n|!~UjyYMV!q2T`P@76pOsJi;yCZ>*Z1;S!+e(eY@T$Ik2hjiN!XeKzG3pY z59jI1w>>%eErS8yF!|i4bB^+f&Hv$mZB_=d^PuEREb$|v3k zyaQbR*|XUoZVmI$Ai$ABuv+^|)mfli#q>xjy9+8^0ESn0&+J_cvodXyp@= z!?^7Y!ef~HiZLpV&f0t)x_i*CV!yQxz{P5*!b3#k#Cs%ifiDv@`;UK3qVZ1Ve%VtkoA;L zOb+9-Hi%Edrg(i@tXjM>v1zo ze$5W(IV+!-9EQIam+=itc)TebCRvMw+aPh>f2O!edzc z2WPhO#{&Lvz&A|((9PINTKUAW{{X}cPgXJcH6Mb^rhH;@7@q?{`7%uY@JF2MQ9iNp z?HlR8Ve*^yICrD+iH+|jB;heE{9By+wDEzB-!wVl8z!Ioe%_^gV&hj#O8AD!AHKu6 zZz-SH_%#5;^|%=(-`(llKPjJ>R*WADGx>&v{~720XnbJfHvtfnZ34U_M_=3J%niI2vw0Owrg6B|DY{5LG$3(h-~UlZ_a0={AL zo4|RO@`=rVi-Bh8RZij-~24~-+kS= z_bH#)_(RTP@(nXQL*U$`d}8At&i@f`_9&m&_!WWwhUxzpIDe~rV&fmq|BCxiB$ZEm zG=2>@-%>vD(fAGEJfeK!qw%xg{G;-TkH+r@=QqkHJ{o@zoPSk5vGFYqnO=q^y})@% z`9lHU(v*C|HiowZ&E(7@p}WlVe+%z zK>1NVvGJpTZ<2&rNy;J$b#;?J9i0Qv!hNlLcTa-_HG(Pw8{;cwejb95uO#cnjf9~6Tukwk> zVf~!NWqiZrbHDC~lu!H*z&pU@pFQi2OP)0>&wkIjU)Zz2F&}`KVI$y=@b_Z;)A+zI zjPtIFW0PkM^I7f*&du^E#}d;|epf9nV!q2T`Ay)wM)}0X9}M`0C2Ws7_eSM&e{tiF z1boBfbI1HNJMn|^{bvXoC8 z^YvZyzgMyN56*!3AMl64A_=d^ne(t|lKC$sF4E3-uOg{H_e?j@g#vcs)H%$H* zI1}FB%MP*e$Aa`SOg`6nzef4Q#?J=+8z!G?z)w{^vGHpHzG3pYE_{aaiH$!N$nb{A z&;HuExymPw`2fWAxQ!_$pKHu7Rz5K~%nwbth{-oh{t!4Tl}~K^+Mo|;n0)sf=E{^$ zZ2VpTV)}2G{N8_d?mFcYlOy4onDCnvlg~BiwPV&fAK*Yl>B;o<%O zPZ?kL3SeHfI3(XN`P@HXRQa}-z>)YoKkP5cCx#bN7KVHYVAW}ZD@f!mF4U^Av$lj`a;-m4oAHp)_6B~ad@ZT`~=l%$nDWBN*{Q=)F z`4!mzpjG+A#*YHNVe)Ih*`j=6Ir)ak=ROW!S3a@vEezxvCZBseJgj_T1z1kH+WOb5l?A`I*@GHHaf(hQ~0!m*>2lp?qTF*9LsU< z&$H-Sl}}6#^N$PKBg4W+L)&9~VB`1W5n}ppn0)S~af9-SjUNSk!{l?{jeZM%$cG!B zrT>v)^0^1cCzVf34#VH19P$m5&pkOluY6+T_Xm8#&}n|Ehdq<2MC-!{l>c z5%)%4UWkof5#$HM@_U$+$OZmjK zXZrRkhkV22^DMLF$|pAdV9<9kOg_&;Yg0b4@rUpZV)}2GeD1fhOZmjcZwmN^$>)A7 zdz4RX{N8|XnEZ;mGWU1NCpNzM$?zB^KMT(N7XE-g;F9ng7XKIH{C4vn*!<51e8c4P zyv1KDpV;_A0pBqBJd5$5@`;T<2tZtqn_=>K7UPuDeSRY*hv{p1n0&+HKh92^p?sd< zX#8G0LrlJ5@_E+ceB~1xzXE`me8c4PT*Y@OpO~B@g@@-LUa5RyPS(fB+g@mtC#HooNt`fr&2^K8V&l}~K^EC4b2hRNriMn6+NF*!`T z3S7oFOg{HLdPe!g#%~DthRNq1N&l>TV&m5ae8c2N^*B#Y`NYQW4fux19{^_(bRuUc zHhu&^3}rvE&ja=!A3 zjXx0Z4U^BaESD>v_-K5ddwH4iiI2wT8JU}uPkb~!&(qwhd}8DG2jMr&@bm1=o0Ly{ zG(OMiyjA(c#;*wcH!SG|&S#ZB67ZvdZ+JFFDjqd_))+&Og_&geGM#_|A~!X5%3L@&ofNVR6eos2Lrxg z@_F9r+mugi{HB0!n0%g%x?1_f#vcgyhQtSJ-e4fkNr+i}L*93gSwcog`!vwS!Y0-vII@;zm4w&Dul zMT(~ZzgzKi;EdwafUj2^0pFr{2JnDlo-zAH#XM*Bn~Hfp><<+4Y}j8a=DDzcRLnDB zC%wssljp&nte9uPzDY69fjw6-&wyR7nCHK4P|UMm+ZFTN*Y_#rnXeyG%=2FVRx!_d z{hDH)^ZI?oJmd8zig~{4?-lcG*OwLZT-ORTG|U4tepu!r#XQfoMlsKFtySFnBjg9g z+kR5!u29T9R5vMZ0`5^f;~&f1&5F+h{(HrXfgezOIq(k@w*fz+xB&c;;$GlsGkrLB z0#_>D16-&0PT+Sdz8APn@d)sBiYGmVeLfX02L6=d7T~Wa<{9)4Ddw5*KT*tc;h$B^ zbKaj<%(K>yf3pu8&zgRNVxBEsshHcPaL}0F?xm_{W$b3aH*S~yUG1s;{t(fap_ABO^l$R89y~&AH z-cPP2Ia@K;iM&HG*MKxA=K7Ay6?5%IlVYyR=upgc7F!i_4aN0}xjv##@c{5A&3>+P zUr@|73-=j5*SQCce*yHs6?5&t(~7wk;914g^M77(wiZJ%v;23}E_Ci>#Y4bvR7}14 z8H%YhKTk3B;g>0~}hMhhplf ze$(uMpHfWy(&rRYcl0>qExwm}q0i(@a&R3u_ub4V} zHz}q*-scQM*Y0bI9rVN=R9pf41I0DKKT}NIwr3Uh1OGuWb<+MrG4;)kuhuYs9eU=9 zsV8=pV(NgMqnP?#7b&i|58tA=2KZ9N4ZzKcv%p!!{lM>6JP7?O zqkt&dd1YwnW31vH*Zx;y_!XesWa1{ znEEgq41W(x0}StVu3K^Rm~%HMrk=^ijq^ClmtyLNd{HrVKfY<4AD~WFOr4FNDyBZh zvx=!-@w{T{PE17oDBlJATE*0PI88D28O~8mU4?fjrXIp7#ndr)xAA}GTv{=81G0)a z@Be<|{}b}0V$Rp^QJnoXbpI4{p8d;;IfwqJV$P5MS~2Io|E!qv+EY=#^IJG)JzX*9 zqbn72uK8TW(Lv|x6myRF62+YV?NH45-0g}vS9`l+&clAi_`r`V=KSf;6?1NMzhcgN zPMGJz#yQOs6?4Aw6vdp2oMm`=nY&Oi=Md`^bAE86V$S{L6?0y1r((|8eL^wk<36vL zb8X*HT!DG3NB<9d?*blGbv1rZAc25{2`ZW@XtYtGDi8!Am1ssXcm`%P2q;!DLP!AR zCYcdbz+jS=<8ds#+qczXYumKeN`0-yOEuw^;1%(PS`{qn8OJJu21I54zqQXkGiL(r z*XR5G|M&Zz?;+2#Gi%@1UVH7e*Is*{y)`@nc)Nxd11B^rds_!IEc;e{&T;UUJ*g8k zEc;DoYq+8qoHe`__+kyq9?&ce%l^(14a?rmDhg6*BX{Rh5S)YTV%iBSPjcwz$tF{x!ANdEH?ZLH7xe| zDH;~r`z#HMU44;;#b*9J4U0Ye7aA5@_v0ECJNDl-EH>&7G%WV#E)9!q`KZwjo?=5D ztYNtye3XX8-aARdV#}@8u-Ivry5ZPVZ`ZKcSMS!a*iQeVVX=#D)Uen*U)HeLGk0iM z?31>J#rF8QhQ+R!(y-VJ{pUJ3i#>3#hQ-!5M8jgo;J%I>;3f@=9iUOeVh8xKhQ$tW zkA}q#aKDDd4)BzQ#SZY2hQ$u>u7<@9ut&pU2k2Sm)GKy?0U8!NK#7LM4lqW;Vh5O{ zVX*^TsbR4LEY`5t0luqYu>;(tVX*`Jw}!;Q&_#SU;U&@SnL4zYgp_6 zPia`}0NXSyc7XRZEOvk|G%R+2zUMi3iXGs14T~LMn1;m;aG{394lq^2Vh5P5VX*^5 zH7s_3CJl=n;Kv#kJHXu<7CXRw8Wuai-!xqE3hz^Bcoc9#!%az za1^*g!(s=Ru3@nQT&Lk51AkA$_X6Lg;fH|#q+ziGtk-bvtJudhTnYTHhGzqJX;|z4 zy~-Wj#13%0hQ$srRKsEi7^`8i14J||c7Pcg7CXRo8Wuai%^DUvzz+pJ%CQ4Hpkc8C z{7u7R2Y61yVh4Cl!(sIbsJGs9~`K4ArpM0mf)p>;ORxiydH&hQ$uB zTEk)okb6UsW;5$9=pFME9 z2Y$^1f9Qd~^1%IiX7D`O1Ap5Chdl7r9(aidZuY=G^}v7dz>j<2r#(Aw9(aNWuJyn-df+u4_-+sUfCqlc18?)dZ+qZ>df+cSaNoQPp2vIOZ+YOL z2cGSLZ}7n1^T5CKz<>3?+dT059(a!j_Vvo(^9>Jtwg(>PfvY_5)gE|(2ev%$Z#?jW z9(aQXe$@jfJ#cRC3~qxx@MsSl^1xSm;A=hbjUM<85Bw_+{AUlm(F4Ejfj{-YDGywb zpTV=(1CRE=6FqR92VUiYf9`=>Jn$nPxYGl_?SVh{zy;`r?pQd*1CRBpk$T9{7hI_)i}A2@m|N1FN>Y;(_1xz#n?x zFFf#3{S?kB?@1nbs0SY7fzS8A6Fl%G9(cM3zQzO3abQTqed!+f77zRb5BzHn{GbQ! z@W8Ko;150UmmauZfoh|wcaR4@+XJ8PfiLmE)gE}E11nlB^}s7UaI*)Fd*GjV;JZBV z?>z9IJ@DT=@HP+pz6bu&1NZEo>Bply@G&0vL=RlzfzS59=X&54Wcwd*f5hE~yC3%e zZXNC~xCe3nje7_ubH&5BM{upUM{$qg9>+a_`y1{_+*7zVTsv+(ZUb&3ZWC@Zt^?PJ z+k$%<_YCe?+;h0+aev3Xje7^T1Gf|R58N)?dpMb!KETG1+&7H$}BIIa|T4sJB=T-;b(8SdM-^Kdc`m*XzLRp5fS3Al@J1}=mP<080=ahKp^ zzMhP`6gLGo6*mo6gPV=3#ns{F;O64y;jYD9hntU+d3_;n5pFT=dfXCRJuZri;cme3 zSMdV$-imt>C%VT=xR-IS;9kYOhTD#N9rp(AP25|!cX3JFC%CV111WDXZYb_-+z8yC z2p`4o7~J`|0PaHEcw8lJB5o4yGTi03>9{L!-@#ppy9zf0Cpt?t?i$=o+$`LmDSITp zN5;;PvGYGYc8Yz6xqDTfrOA4eL;|`!Mv@82dW9qt?7l!CA=&RQ5z_r7lB^*0V3369 zYm+mNl6V5;+GqD>dWk7d0hyLcv6P2@f~a^LB>>9r|LI4)s3LU}V(~Ac)FUIAoF0LtGI-mO z6_8b|r1I7&WJ#y?MjVpMQ(yYc5Hbs_AA}I!VP6T!ipY#(?-On$Ipmp;Oc)&}hnV^-xOxL5=!w@N4ZaNWWv=;6B(~N zJ`tdvw>XGD%p)A>(CpVYJi&5HzdWhO&vil#r;zH*dmEXstcNxvIO~NCZ$Mh0I7zg) zaXjiVjdWtSZBCrqH2KYbOhYnAVCEGKH^g~9!}Yl(cpu2fenf+m-bhEb%;Ql)rE=&f z=LtiSdY{oy-hcU?p~QM$*Erl`djH8&8;7RR&r?W5Mv=^VEK#DAKveH;h|eQ+TruM* z#uJ+nA&-0DS z?|Hm2{Xz#ot)tOY^ALr8lS5u9^gPBP-t1R6vO=8K4OI{?7cN;$qt$y5`f(2ZDu??V zNBSKO0A2I!`Re5j0_4dJ^;)EQYePZlM>ae@{klfxT}l0>WG29QdNSjm&vbl9BKO(J zOfvoGWOl$gBORQgGO8p6uS90280+!t$0jog^iz}B0a-;j&rD_#+`zkvl&IefQ3A&2 zz7nF|1L1iP_gxV6D~k`_2~jVB2vE-xAk_=9-u^i3qaW!&&ubs)FbYXO^Wnblp?;;d z`sfmQ(L;XaDG&KoZ+Hlx9`C5G*ROUQ^0MV{+I0hRbodQ3mkh64G#{R+A3pZl;Y-fp z>6fzEqeqOme$29SO3xiRYw6O(OJ>#Zn8k=Wi-%7gzIfi^vuDXmG-r=ovLrUKY`8oE zGQ4KEuiE<>$gmpU|K=K0ox^!Ga`CVQGiw&rFFU(*#ISSEh7oG#pFMKe7*NQ@VA0_g z%H0#y_-ckPm{(s@9aXQjRxe&uKX2Kvxr9nze~g#`(!p2Z|I zb9VLod9#+xTtauus$N*Tv>L)Lm=~RQ126EAE*2bBVlg>`f&+mlZ%q#&}uN zn5zqJh%jg2qB;TVS@t@R6z+xUU|Yw(WaiSDvu7`|db9e!B;mie! zE}$&$Z`KT7S~GX%lIpp&^B31HacYSzTr4P12^mB-E?gw|czTM4FIcqDNlk4!4H=|8 z)pKVqM6gNzI&_=v-dWD0Zp5a?D;3o!GN=lrJ@t}X`JAd0!Ro=n@v0;a7gR@iLsJN? za)?JN5YIebuX4Duw0cB!?J`lNcmdPlDvFXPc^A#PR`C~Xq~XJ|k+=yOU5u8Xz`33 z?~`R1-A(0$RKsJswIT-&Vfb{RHHR{#Thg5Qi)KLxMz4c$H#V)VlZR3>1UrPe>t<1H ztvq*ET{90-<5vQr+TktNt0L-nj#qO#FBq}hk2*{N;cIDbwHxSAP4SBxRlVRwS5tA` z+H@9dOXX$JYFJwuP&O~9ZBe&`E)AHcgw0YUO><=)5_xMX`E!MVl5xBcP-!luA7?I#fFR91lFo1CRE= z=X&5V9=OZ{mu6Mwt*z8sU8%ReQg4N&-WoaXn?bSETW2ZyT^jjPF9svM7>x8{Fw%>` zNEd_Z`r0`)i((6-iO`4ISSFC!wRKujI=M2OF0syF zRO#l+MDEm&mhWi$5|PDa5&$jK?BW|9t6wsF-ol#svDvl5Rgg@$l0?mHix$@C;*f*F z(V{^}?EHE4j?%&;D*kkfl)!P8@FFa9TzY;M|Drl~xQNfyF$8u76W!x_e4=~NeobZZ zID<GjE_TKq>@OwUbV&a3-O2)8r{$RhW~bX7P>Dxy-uG zR4BbuT_0P#coEY}7Dh+{jq)s%MQMXfdCQ;=atozhPqtc*bN%(T%=Ghh#!L@Wbj_kA zGm%8XIkdal!9o~AT1>y7V=QK&h-jY8qwKl_mnS^=A)~xen(jz#QAzhncfl?cks2Ij zOeOQ^UDdF0dgAxa?gXdFp^}L315m27JMF6w8Gh9)N9Jh>I=|YP)-pjJl_y=MCrk_0 zj9!%KXiusd^-6uUCq(s-@=N=!o3{|%DDBnSYTA#SXLX$RrsqwmRkEvz6ShyMm?@7Z zXS~cKvH5gMI=*)P{CSJ(=Xul2oHZ{iL9OU+-UMRVa>JaNIztaN$8__~l}Cx`BAI@K z6*2iYK;KD@<)w82+1{pR^dRhOw zu(l0kN)olwQ%ah!3TYxxbmuKj7d5lK-kZ99{yY&yx-{trda-s{E!wGwfK0ebNS6@i zsukJ*p$LQOJSXO8%C7#R^(|3jmM&zylF?=yO3U!plyx>RwO6Ok?g<^JIaLbKA>AA3 z1kb6-3?5ZSI{1(hNa|ttOv!}194~>aa=H~MA>DFHA9qWof<$a#(#VKhS&}WB#{^jC zEZm5KTq;SXNCGtmKv^6m!dJ37^8>MNrvp0U3_y1+ko0*vSTTUp>qODx(mGW$usgxK zerJkS1`5%%tLKR>k@3c|z4Me3;)(9&pC`5`Z}x8fd16=c#%KI$s;$AypyYH`s%~Mz z!LT0)gqjPbP0k{^d$Mk!s`WAq(bHp&#+_+rwWDsU0MFdwR;==> z^3ECQE>zSsDT=nP-;Hq!b!;m2b7RrjFfKyAwr(cE&%0a@g&^BvGE5{X!p@mxyTxU^ z&O)y{uEQ48Gqfj62wjNzpmyPG$68Ej%s9@}JANv~SE^;RK)&kn6J#~44d~-5MMUZd zfiH2!{2?Kjn>}F{jj!^0Lo$Ax=m_KELWjwn0EKbwGSL&HkG>}kNz3mpPRorf&WIZ$lRo4lG zP0ixh${2nE@ zTcBer$^?qgbt{2LYNF1BWb~zUqO^vXNtIE6Ghw<9GXcW;=|ZwJ2)Y__CY7Tl zd;HF(V7l-qoW7_o6Yp@C;}4?)JFF?%aJuI%LZO|a^;suc`ZCis!xo5jJUb}E#1i3l znTJWUg53gK8h1;VCiEfUda2I8kW`gL(|;T1;-Zw>G@aa4nkOrABuyg48IA?+ zaACB|;rkj#MWg>`u>eHkC?PYmz8W(uA)Wv>3l@t>R4WweQdJH_5mO*r5IT*T5n0)= zP*CeI$ImcjMs>Qzft}`f=UPvD6qS`s5}Pj)bC?R5y@*HQU3;Ti7b%lZMpV-bhCHSZ zS;nOm|3fT(!!W+NwrOyZ1&0g`vMioCr&ie3V@eXMva~R*vBtZ0 zVx?Q8ZNT_kJx}Qt|H1;V)QWXJ#H8-*^eSHYe_~P>^ZF4Rdi4<-y0(EF zv7uKVv7sw5d&Gt=8w=`ub=pF!Y%yswcb2_3JIxUry1Tz5OPBPHg~t+n#DE%p#0zC3@66<&sV*3IrJc(yQ#nKqGue-(x==NXuZU`0fsdiv$z!T~6TZ0aB{nt2t;WsHa)30+DdD!k>me=5* z$0c3acu6^TIYq1g)zu5<^Qq~AS&KN2uFl(L<0p4T%U_}T&zmRsz3r6pp3`yiQ(ZlO z=D#a%jV{mD%prbndD7k&vdZhucir&g&S&{6)C02t|G(!ub=WjrL-+nz^OjRyXV6I^ z{(oQItoqETJ+yzX`KH5VKR6>@Wmb7^H@UIGCkC#%Ivl!qQm``Q%BU*Mty^_UdBBdp zwHqA2G~Zj+sdUu{i6Y%uE@#Tt3Xb&xKq(Tud@4tq5ma)WdfZoqFd(J$(7R zf5cUk>Mc`#d~(mAIH^bO8}#;*#C!j2E+U@qMMy`U$gk8>|KRs;zh};fw;wD#c)|YG zZ^;v44v+QX!cHy=RdQRWby_NgkuFunW_fNOw9;czXnNSVI*uoWF&aNAGOWBR-pVp8pJ4{K8u9W!^4gl+7$&H> zEjrY&jQp-u_fc7Xbdb^5R$|0QuOY=_Vl*(!4*PLl`yt^($|>UgEyEfMbWlM)(6Ul_Fr|_gHG73 zFB5i;4!he4>*BR6JFdfSbHc9W6)gKk9VXYfQ}5fnXl2*xFu5N6w!9N*LK7_*Ov6YK z=7FQqF8eKm_DRF!PI@RaZ;G_{9m8C2mq0RUp4@&h}aoLlBCIEl(C;S{Aolgz+=Muf0 ze?r;jhn%dV=pXwxy3Vyu*qtfDzOTb>C+xPoSI%*I^-;kxKJeh{l#IzlNz{wOtqKWboAN{yaG@3+-F-}Egld0%2mo-k6K&$-27gYK)i4*onPH>u< z>ts1uvV70Y@(II=ERQ%@j?!6Lb(R;2-JEA0)x(#Qxc=)@Dr}98(A=%s9ACmX-CA?udprWFq zqDp!$V1-Mny4u@RH$Ga3;mBY4v}sfYtf_==?h)<3YKzZT?DGW03cA+kMhAo%mzPxJ z#QG3VLBxm6+D;=L>(t!YVVl^cRMoO6fsiO0*+bf}t*>fB>|_{VJbYo_!}FRUb7R;% z?GY!+-}C}pteY3{SAOlbhQ`^)xDC3GG&HE^|6GGabgBl44bte?oZ?SJ@fsJUA_+J1 z3~Y`xG{g^WeEM117=V34W=Ets;gD4akIKp8A z5pnhzivM;} zG+nI9Xnu(lyLr!5YUx9Yz!M^L;L$f9=ON6Rac9}zC4b1=9HA9WA4rp}@w} zKWy%?A0&6c>y=zXfuDgWwLl7|{M7KR$Xnj3p?b6(eQ86qWL(GBtPOFMJa zOD;b9dESb3h#g(&64oU)zhW-+@jF6(A*p>E7zH+8bd@jAanW@7q|%7zy#QyDrb7Cd z;40sRw58*ssf=dm9L#XK6!5Dw2fx?b8KBM8AeB7I=*WA45cxx{UBhE~GT$>h$Nbq7 z@CG{s(sgyi{3kc5%S1%0gfCe8ZYhWSp0`=OJFXETz~j0ESf#x?M27jceY4Z8O_rqT2yT}O zt=O)LuFXATy&9kIVa9eD){5;$b1EDkJ(Uu|{@_0Q5!IQ(*U{7Ig9*IaX-^}}Q5T|R zVe{rfI?&Fcb%r^SbMwOC(<%|t={*x`!y1qHg;#p29HaLmi41?`?(`Hq zcNFQ+(H0}7u3~!g$X#pF;iRrLMakTLX_@N;#QKTEEi@W$&JwtWIm1Ta+G&AXbdG9j zvIq3A^7cF^)D>>q9qa27amEIF2d^;Ktx2~ZwwWM^Gyds3#XV3VXs5Yn7U^lk7^rEx zLhrotD5Xb_rlNaz@^MtR40HOM>0yJOr-+;{B9;Ug&9W>^JxD!ls`=S6nMdMn*ny@*sYUN)(y=r;(OuY(>WDDbz6 z3Lkl5y#y*$N&iGR(#~k#Q5p8A+P{K1%g@^&CBAPzD#TYxeDo@sTr4U1 z{g=dwU7$!~s7X$fsM5TyiabM9UbNuGj_F~uD{Q`NCn>$sym_kPJw4RYs|yCL8gFX- zqgFqK5aj3Xz}=oE$Uf>6g8Y&SAjo#1#B-GVZ<==%?*~is-Vk)1=2ibE&HE|um6I;3 zd2m2Og`&z~TG;2178c6-NeiV+`_%ew)kiIgyv>V+eEf9;?{$7&7TSg5(_Rk8XWSc( z|5Xx%<9{2Weop%-OD0C*_u6R``fT`ul-P15;Q|UT&|K zmNafG7Q!9N%Y#<%WwX6;OJU0~{$Qus+1Odp)n4fjwwuA14J+7b8CB-ftKJnpT6IAF zM^6yHG(5n1R6+&zH_OXlt9GVRUw@5qXIRZrzhO-;v{UD)9#Oi?T4r}Cl@;ocApOV^ z@eX;$3|ZO|Ht)Yinq{t7ZN$f;DK%H&eNyTOmhNJG*+!~$G_Z6FqO8GWLNX(F2F$LG zU@HkzMo059`Qb ziv8Z^d^FK*Z+*#>=c)O%t{U<8X`1<_joeJL>Yr4i)_4YTd!xyUg)UYO1gyXsD)Izvy zv;X_g5*{{p814HnFxu_%aE^dIE6oG@-U!$137xW8N^aUs$?#N5j=ACqe{(6VxiH@E za{?Lg?+$%B5brm@sM!)OYhPL1wZ3=sD41_&zQ0)>a0}JE5XyP};&_QlUb-!m^I2ky ztV2!~YOd+3s49;3d-9-kaN{z=w=(ZZz*PG`dKxtwLh*2JYTtI_PUDo$K>G(hrL6eW zeyM%0hig6!o$_k9YYQ8YW)a!`vG&{~l_8w`atBHF2xTdH-Ar3z%Q4{`uhBPXBzrFB!Um zFXu2idhi}wJlAR1mQdNoNX-X&bOzUj{TJ_y$@TA7G|rzN}Lh@iA=~wJTB7N{^=N{f1G5L-6j6mD~9z~iBF#3 z&Cg8tC@Q=C>oSxGrlb$x_9CNaWSwD6fdb=;EB#Nk1G3pf^m?f5*^oc-Y$&xURQ8tt_T>kJ z=7HYnK8#o9^bXOBblqy&+LA0bth~>D&rnc0djZx8`-*e1iu{5qlvp=9q+fmEnztv# zD~nQ<=Ii@jM>ZIzvj*+tUE6%2_)w-_6 z_0y5}H?f446~c@5L!+sbg)SVY=Fg;z+i=aad!^7pQfPoePjCu75ssBYE6rDvz0KIY z5*;>|R2Vgz4f8@HY~EDdFl+KtVe9OBs4kQW`V!BpVVT!QS5F2*P_QCUyuHL|+#u+D zhZRk7C5zV|ekt<{@xn~;(Je}uE_e*;FePo|r?f3%wqMG8eOW^EGaB~5?;Ij_FPVip zr6x{u>No#IDyRNxQkJ%b%{9eruxV8{b$&;ja3^(C(GEpH)P2l zwcfr=R)obJL7RlWj^IbI7|6}|D9kD=93Qw$P__mJzzNE{`v?f=#dc(e41N~duZmJ; z4~IcTny}W9wa|73>kez0ZACt^H*&Tty(%icGH|slY4v*4yFV~i*aFLcx>wYRz!kI@W5fs&W?bA#;nP7TWjgeiEhUM@UYK5ePl+lyOK=yKozi2Ssc$JAe4F@E8kZC>enEQkS`;@rQnOL`McTI z2)0hNt^!E)MD8MA8-(tEz~#p#$WNia=^?2cmFZe~57VEj;9&_%9mQHza+&X7^brH* z6k!LY*oQ5uZu*VFJJxB$SD;~jXzvZng2=ymDd89mpn`~;2u&>jOS{H5iI6Mev9<)SpBP(tYPyL`x7wcS5{gu(K;~-Hc(8& ztSyGno$L}-gv>|r$Y9?& zf?;|+Bkja=_$~==knk%)seUD~DIpBa`Se9{0_pbNVHtD`KVs;5MD?$jB`{T3vE8H` zgg#*3QY-AHZ9rm*$hLoo;vn{q!xuWsDU_k(6l&iyuUl#UlPfaoKefIc0oIoap~O?ShjS!quAaJO=aK~s)4J-N1IGr%s^WMYB^!Q zwG6(|M%4EeUk*Oua|&kl(YymDqW+_mzb!W4slf!;Kcg9jnfKLalB(^NLQIn%0gLgz zRsQWU{NKuZpO8KNEApO4=h_qYpS2^D61)5h1c&_(>@Xg^?~l%(EF1Ri44JPzMcKZ` zSnv2A?LjGlR)$b2Sh_{lqh*_5#h4^%RgqGg=T}tlQhY28~kkmrE7jbWrl@vnRkW+#mkpL6Z@s%uJDS^U}$VN zQX~p)51AJghRo_BY`MkcgJ{)5#J2d;VPv(YA)1$<+;v4OVSu6=rDNYgm$LU!8qzxq z9S__sDP_Q{gHMtf1BjLP`@KY&U^4hFpyXsy|4FBIbe3r6UO<|b zbcv0`+XIPptt#E*Np~Z7DXVF;){P@PriUhJmf}B5k&(YpR@sF7=n2$gr0eOLLOu7N zCCJQR80@oGoGMat*>0m||BS?EM96qESXo$;QDXA`3`LEy_0fxgPhj>D_(I@=aIL`S z0^fvK6Zl)eudY)ta}B6a^YeG%S2TM_YCgxU*$Na|i>t6H7ssa3aZe%hjj{s)|Bsp5 z%7>}~5BPt)o&;=xSLUyemh9Us1}$0Xg@%A!p|zw+f+~E`K8AH8U6;D?Ov74MF(WaG zN`MRr%2jbzMUmluU|B^{l2#DDtk;Z0fl8J)PGi{EF3Q|))lY``v_1Vy6eC&wtLe=< zzfFKJ1wT>5=oDfU)C$VL$Sjt83UDv;{65i)h+`yxVR~`;2t9 zeaT8;nCD3bJ2n-Vea+O5Qd zbN+EjeB3A}fx(c7=1*s#r&8>(e<~@QVx~YD5v9!2x)HL8bhI=(Uc22hhuS%0I>g>u zEIT?PncaS6BHBAy`n6#EW2#?E7{Sa(=}tAwS4Cs0rd}aKzaBycrgW>CiI9~wthLw* zRJHVu&NJ7qdRIO=i&clMrA2CAuM?`Fm2byJc;hh`p^BpgVe4i?yt!fP7DjTY!f5;g zJ4%11Ah9H_{xN_o+)<(r*lSdCH;0FIF;}sly)V%~H0HWGgw{xu$b1ZxMFfel2@6*N zpqRIuGVfGdW4afKNMVooOgD-r$R((ymqKiDjq4|Fg{?L+;X)-EW8*FK|Wl8OkoQj#+g;B)b1r zp@zT%fG0U9|NdtVS>vOBG|{DJ2W=C~;u^EW1DIMMz_NhQLQx`4Nu_T>io0cZG_@gI z_T}q%#XMu;XlfAjJ%!rTA z5ks5#cImcNWzs7D&(<3`uVMhmHB#6E_UGL49w`I|p+)_oRqK7eRLXp@J<*qa!0mLh znZN4Y6vn7kPy7BZ-l`rLbaIousTQC|sBtqmJ%gH+bISvXSrq=C6d?$oD+pV8BYx_V zeGr2M9-dMnH1|jIg=+^m*s=gfCC=eAN@oAmyIviFWN}s8p%+tLyr2*BBQwU+_qmeA zU8gF^k_QipWZ5mlz*^C2SeF-eU05~3-*m4EnXy%rJ+F=6Z4qCi)$ zD%aoKTeyZ*m{Y@aIO43t7_)BR&yZ=ZmpE z;pR{MO;r&0G)YXi2EVZ@(D-a$qjAMn-^$B^&ASXU2AWvt8GH*mS-1pJ&nCWBCFi}5 z)RL*)(e}ngT&6wxn+&jTK-yPyg81klk@mL;ho;Wx8R8Y&{ZQx~ArpO@d@FRmw17D^ zUG~GLQYY)=$MiZmu?N{4vVsV|{khS}{O=K6DGcgweuu6TQz(+}Xop70rfwQ0b(QM6 zShyQj6)c4q1OMf)NKVjo7CLn%3Mi%Y&5-}e z^KDa*x2ClzWAyV7F=SnWWX^p(#Mnx0FwUE?b@{7_zk|0LKF>oh+5CeO?ru|qsGTT| z=`}yg$0*WO)RCB)l1M#$q$2#9`5|141 z4EP^D-@ZY7@@Zuyoi&GnZ+#3(Il%yaikRw|@ea5@#SAU@m|2 zi2%tfT5@8uTYC7L8>uPq1O=vA^8HP}eDv*=N*--ES;-@Ra~sJs2cZ&wadP*FUJ-bLA*{;`=rUs$2cDo~e2EbR1fDnw z@DGmWaI%{(5O_kCt`07J+j|dOW-KPv*zhPjV`kW&2RkFxge`HOQt(6vZv?jqek!mNU;8pn5r}OWTqY z?QXU{EG7|-OV(i#BII;qmE&$j~v=$2S{#cPO7VWPz->S>Ck z(V1SLpotVDP5C9kRM#p^nF^eI&}&an?cuz&I^%=3KL%V`#hi^PNoo6XLTX1^+g}Os zC~LkPI$*(aX>shEv^3voDf6oc#4j$Atj-ywk%Ou4d^Fr047e|TPs^rKf=050C5l>` zm{%6L>l2homMm<$y<-o8PMO6Qhp^QV0>M}MU#&8S|AE3-O`gvz`U^@IcqH&G_c|~~ ztqQ*Utpm$Kzxobf)g{+5VC;>91k>adhIJWJ>g2*$F=@`zX&mVu)Qz#{k~TTqu&zd> ze=|D5XgtrivH+1*qN*LA&nc>S`D#+zhV-v&g<;p#Cp@qvSb5vxZslW1mRyz54_w+m z&K?4^|I1oU`)s3K56Xr1WwKE1y71Blg{>S{&P=SWF1C-INDY1j(Qdvfl(SADbt?nODV^>VgAF+#!Z_X{$5MeQ&GOP;W~&7M!+iel2tU_uM9eao=x z$oiV|m+{d*hAy)83`Z3Beg~3tO&E9=j3sad@HM)dMj7$HE<^CaHQVenLAJT=#z5k1 zDc8z-{C1~>@zJ*kbqi@(!qHb;J?Jq(T+~EUor7Qr*FXqCVi5!xu$Vw?H)%%rHt^LN zi($ZTU?~@jP6dl1uwb2sT)20MV=n)>D(P<$A^UnxoibI(LP-U)Q(H`|Q>AK$^pM>f z@)&WI!oL3-3YIq7_XunazDk;v>Y0@95;`pja|5WWX1nL;@j-k zJY`0J8Ljm1s*O89L`jAWe|hW`?9#AAkFl;Fc(LNPf@e@W(LTfXIQ<-PPZ>!ct4*3F zDDG_1_?tuoF`BokLr3S8{|v;UlOt9g=akBS4SnsHB-U#{Sze-xM0+x*8S3gNuN=wb zcw^YCNt+}P0c>F0JXXg1kP~QfZOB@Q4JmK3>adRJu?Ur*6#go)jDWMHcG8T+QWZTm z)G=W!6+z6*ZUglF>NbbIMbK}qz-rjn1S#e@7Jd%3*q}>WLOk-F`pOxD48_y$VzQ9A z5kpiWNcCxZ$&{)PC%UZiKm8H%$r(%<9*QsTont>O9ivDPU5avmaYL4pxm3z&-EP+Z zAnUVBDP^H9B|lwCQ>K*COes$uFQu?*%-a6ppz|`(N%B>jozr(R**OwZ8R)Y23#wrI zUm*cS!cTL|WO5#KEp^I>X2rotme0_Qk6-#tdbVXTkC5KV z8)zyL+qEEA`etI6gvQIiFDbS<@Q(!E=)gY{ShPIS+$XR)m4lsA;I&TpO9KB`U@Px( zr}RX#6SbYF=$Zo@0wN}w@;B;DGm{o?H8|B2EL3@nVg~Fa zT9KYI)g*P;{a(?mDkLc)R9fkaMSv%p8dprE` zcJWxt3d7c1S?7iucjQRi5JKa*o5UFR*be>~{)@LF1FjdD^KGaor||f8!2QlkhWk8h zPOh9=CZ+QI0<)YQBi!9@nnAdI;24b@GY;F4pK&aI`lEfRgtZ^Lt$U5%hRp9uH-tJW zOWLi}Y`y{6@?=>eG_$PYp!lg_p8Cxa#(d0NFJe~gjp6YC$co>YCKk0^Ag-lIXJrsssZ1B_ID ztRD@;>!u<~(j-<=t^GJHlnFL#e)Zb>ib9;Vu=3&xIT|ioDre7GE$tk<02YKKvPk=y za;We0kTs(y)VN6&8S))TUTl?WlKayKurm7CA*bc zcOsRAY9jd|^Wut7O|T#0*O1}F?-1#wfH|S6B`b490p zE4>YOu%&1(1w^EB;C}0c@!S!Lubvd{aQJGo(SA_)>fjm>yafbZo!~ah`}CesAg)(R2J}^cB|05rm_Uq_&6LttEUlP-g7!Uwl!R{ zU&Py;#7~MZA5In$acVYqdLXqqFm!XM=2iPHgOHzZ{RE%Q?=S z_r?n8O|2jgGD+sDh!sO}t*r1Zs}%$E>RW{Z@q$$( z;|SV1MYP9?36xWk`|ah@aEn1>J{$2r@WGQ3qYT$S0FW8{=b?QmmgW8?F^p2PwOr7V znnzP)vWcLzPLQ@c?PY!9+MOOlZ*dk6@q(`i7Ys_fboI86x>bdtjt-e*Wa~XQdbD7l z(^~9na3c9aE!445;*&kui!fuqWL&Nj8-)zZhh)-0Vvm%Quwip03;Lz{ z$ale7_T5^@vQ~fR)?u#|!>Jm|D;4HhL)q}|a?FPJGwXNkUFMg`K1v_PvQ#AdyMK5g zH`>>1U$xU$!KW!B9?geJb$=+#iG^E=V{bs5#+w~_Ioq0#vapnu!5j9k`ar!1o4^J} zUSCeMsPT(b>=-`uDE494Mzl|)GbOrt%gWx&C(WJF5{es?Ra`t>TouKsBlRYmePUo$ z$3_3md{}8lIxEfKvmx_&jzxtKsOHy*Rut~?itocx7r;{PC=z`X;{kHi`989~$cj8$ zXHF`{P|we)tH)zQl+$7>w%WCHxs2F*@@4RLFm$%!l@>P=5->N)kTI-$BgI!V`7sX4 z$S%D)oOsA`de^d1Qq*NqRH}nhR(!N+>Jh?I_`Qn#+u)GAuCzwI%ZvC?`$g<)<*x?JaZ#7O5g?3dhGaOsc8;YLK8B zu@)9is#*S3v3)^r#bK>dhU}QBgTG+j$^jKV1?1z4#<8^ap#Ki$WO|81DeXJ*LOGj| z0|Q&eA36{i)ck{S*Sh!!*)IEF1Za>?9Jr6KEFqy0m+g!kD~Xpb{>Mp2RS zp1qCUE#tgsbW+H=ssyS}nI5jGpE@xfKIe)HH&>o>88w$*{j3_c@zG<7Y1*#59G{9B za>(2V!G#aM?@#=4(KS-Chv^@$!+FqBye)sqO7T3Q_ED zAVH*t4xxD*TVdnsi$JOaO|+Qyw^W`7*T>fQZ|^T8v!=CLm3#Whk&+(mJ9{4ucSeK9dX zWss*$l)Ypa+Dn(+_p~%led4f5b^`d?oGe&te#XKF`dic1UOELL98Y$LP>dW}$C^?# zTXq(eL~?l3D!7b(F)aClR=$MKUewwb^zzsv-TQLpYNhQfur5-$m5>S7?44vCyRU0~ zPV6ir)dSUz`2DI?dgWZmW}{e;vnw&T9_$=`5)d!{Vh>REmTclR8WF6rzaEl zOyM$yO~iapOQz!parMsWQcgV2!U&`WkiY2{GPKknqWFs_o(=Mv4H4@sKK7NtSKFqG zc>x92Er#Wx6jPZg<~~9qR`PCz^T8VIb=vYg%~!VSIEjOiCFVXijDZOmxgM>udq5A z)Y-LxqX>_}nnI-?tE7TGW}<`kK!v%SiH}|h)^~hY8Xsh1*r4r7^*SuhCpkEOA=9;N zDf~JogL8z@u@8>d11OOP%3`_|#m2#$ikS`+zN1Q{X+whyZLbX&t0XK~ck$a%^CFq3y%)0S8=(MoE4?+MhnPn7id=(Y0W-YXy& z7JdeXBHe-{=WYQXvyA6%f&Y_ty8LyIL!9SmPX^H*4x;;Hq2NVy&R&h^YIf&A^l~QR z{~<*CX+#UDnYCxDj25O{XZN1@`@(qTH+vX&%3unlkh@>|V;_au|CwKDez@x0gLIa; zwO@~MoL@MZ0?cPZHD9rWT4Nsrqbbst608mf1=p<%BVL$YMLA$nxiEfgF~X0rdC)#r zjs>Va6MvI)yHMVJjg(L}9vf3{;T9{nZlZbB4s2N)!{^nmS^l>`<9j)e(yuTQ%HE7t zmZ#uk-+q)NUa?NiEgs8V>L>(#oA;v`Wp=z5^qvx)6I0R0_AJ(Q;2|@Mzj*+qXJ(f~ z54@NoGDafl%Ax)a%vCt3nS&eBALX{<3>CwG9G1aCEx2+ za3C|dru0p|+JmKRG#&(-C-)F^`np!N&@bHDT*44g;cdvv>HeeIc}D z*yoRLSbmx;Q3CNx(B^{v&^~|Y8I(Em8Np}ypTpLI)k;0ER;*PBB#&inkn~sbWsxUJ zSjB!)W}fCY!%|I_erDSijgXRB472jZqKWb4XXF^E^@d46*&F`b-$QWP8@^K6{7s?_ z$hk7+eRyWA%>9WGPUn2I9~N|GU+FWk)g02-5soa=-NlizaV7rd$H+0MY|uVF9GASQ zo|DW$`x5s8)7N+LBd2_t%ADfklEf;HuZO|nqu)XTD1kgcFq2b#av*3PX%Z|9(jiR? zoXk~3@R4@JTK*ROma=y;@K_fNR0dRRsYAtv8fdtnL>d%3DRA3GIpa#A$K`Gv*LO)F zD;UL|2kpDbmOQDhV|;G0ucK$}!q|e0l~qRJXB_oaq=}c076f52Os+H5qP1cF-jR&oCwDL(xh2Ss(q2*?ANr2EzJ9k!Z6YyL=|94wqU7)Z1O>$rw=%Byp9S6ed{!bv-Ygn72!dlD+?!Ify zO7|L=cfKTz7P7ZW`v1T_^)m>WeHF~xtgpx^UzVp1xe5mLF}D3Nn3js(vDYQ(L34BR z#8AyUOw*H;9!y2g<|}B}Gh(eQLS<{f()L<@*eYocbZtauyNmWZM!bI{-e*EF ztiks`N$n`XD_C#s#MtvB>YUG>0X5woSR@JmgB}=2i%Dk)y*+f7TW#>F^^xwN388Q> zeJju4GX(<_$!XLRijR8@iP#ym=D*f2(6xze12wsbfyz2ry6XF2<`^4}_Zl1WPC{jp zVZ{&matwcPcf)zeKH0FpZ9G!O-*gY4NE-jGKLe6u<<3dk5fquYo1l<&!*uSnFu%5k zivp-Q@JhIZRdT-;Y&!{m^YzTGUE?QLFehR2tHwvQ!^9TEVKjbPr0!Sgnfkeei4~>~ z2~HqJKJMPi7rpkTE~%a`3a*jd)_5i``8YN)8Ly~=zfzP`+e#Y6o)W?i1`8=kunezE zk9hIRy!nBBgCtP~;8rpIhMuB9Ol-6&rz6y!DyDyPZkFr^?OTNLbnD)d*0sOa3oWH0 z(737MKk4Z+_mOASbG{0S>DJ+gy-?_VvHt#-;`U&xIew~4TO7_=myqM%_6uCOA(MUc zrJ%wnI_3$w5PGwIdkysxvcAfXBI}DGDjv>-AvvD>m2e8{s$_#Xd$9K2{#|Z z1m$q^_rcd~?>$ucpS1BJ>7#CqLyG)ga`Ozqg6X1}8@u?X8TB!`qN}1`VT}F0%6)~L zDPsFYG#PWe(VBWHb?}?xs|vs=#~fe90iz+XLh^V%+OB z!{UO=Q+n%JNX`}wHX4`jDLlyat>=Cux7gg+&xsG4CGG6`T6vGu2`_rgxY>(m`z~7B zO@C7IUY)jFOaV9O0!)tG)x6DTLGbK~H5l30a>>K2xjK-VdJ>W*xLQuDpUh$PXaPFa zm{&6WCBY0q;XnA~d^uF19CUCSU5uTh;A(0=v3u>-jAsP_xsFv3_yqo= zbS1a>tw5pWzQkaa$P{7j8LhD~FssK(p~bkcBkzV9>4LHL^Pf7B>K=00 zf5j6qR}4XyS<7x*5BsNJ7BYjyO4n!lCkq?=HT&&z_5g!L(>%e#iWD1WfE86QRyoCC zb8#_Mt~Hvstt>5VbM+I$3U4UlE5+hyE+3;6b37i4C;7tbhsbxxlA&zt^4Ck-8dp5) z^Z%sHFn1d9aj%>~vy8?MSbjWj3}vVEGh-iZI+ymf#dD`~S&=ybR-al{NOk@@?v&K> zrHT0(N@wE-J)hCF=0snYc z>9NW2T^lPZ3E*t%Z{IHa#Z+gs9eIvV3B1B~i^PJs`x}&?>DV6A0u2TPN(J_mz za?iVa_baEX9TV=g;xix2cfQ60vsa!-?a`U4c2H`=uxKYfL4r?HycnqqA-yP!# zNv$`hz08qbWfqHdCRYT|aGbeABuqRy)9?AN%XPr$mkU*pak*^tw* zEV|ao@d=FE*0h)HDWadiTg^KOvnNx(^1X;pOh*cb#KZWMKup_rSkwHyh>txOz^m;( z!k=dF&Y<JT09f4_W-D4*4lE{qEvr(OKZ5b-U|*0szgUn4bN1;4X}n*9 z!rzodX$cbk0|fnQxb;r^J~edIR>PfaHT3gwsRwJs^y>5zwK`3h&n&;!OBCm$n|1!% zC(%w}(v8zS8+K|L!QB(AS+ipjzx-T%BAsq;S{^$09|X)-)rRX=jvQNu;F9IK% z`s{ztktK^gN$9C`3%*=3v36wA^>xyXU|ULVk)h8z5g?U(sW}z)V{_;X*keYu%O1^G zSna1-FObOo)5kDqp8Yeta*Sy^$a_DTuRL^rcr5#O8zZa$SzxnoZkQaNk_smlN8)p) z8`e$vk(#AbnLSCcHTn(JmOb`og1#Wwb4fmz3gstzg>y!tu?HGf_=ZH!3Ro9SOm-I^>i7I#WjV<|3qopj!<<^$p5-M#A z_nZeg=aK)Ti21SHAm#+;a5Rpujyl5Ut?2aMF2_zAS8Vh}%N6b`)VC)9ID#^Eoxkx#JlwbLBGo*$Xf)wF+&MGo&@R zo{DrFm#%G%)Nsf_vGgDsQ8{$KXw}Z0Z1Jn|bL5o^@#whes>N^E4-2=-?rqNW ze2(BMs7Q^$tXokO{nFzr{XM%Z4lqih=UFQYFOHvu1w*c+>-V*s?vZT+>GkM9Bj@#y z8D>9jz{L2mLqq1&lKf=9P)@&+(l;YHXO)z0kyt)oU0zbG7Px8&vDwBzz+78dQeEu<3I@46u(4U0r;Y}}t85Q7$1hD3Hpaz2)02J*==<9qAM zMSMUh@}JgrPPC$S5oZ+C9DGBu96 zq1MG_)aC}BP2ryBB#-Wc}AbHYf)H+TdmvtspUi0M)X@=|I{1-ksj8 zpE*Bruz4E;pi*p(@xc@2#~<9zD6eYqNBcyqMMDxVFvZAug=oL9b@tD$#9o03z}LJj zdYr2Us+dg@^BZFLoUTHSBur?jh(-CZarI~dS;WkP;9otMU}@AJG+ie+Qz6!;4{a zJwx0&x~}o2Vs4>iMgpM=3+0~2SZ`&HPM)lO>ek4`90u0dA{F_m9I?D3B|31<7icEv zV0_H}{__83Q~fz%rNoa^S$UBwyc9TI5h*VP>#MtohG)eF=^wYfoP?FD(r)^Ilzi=! zmzS0D1+>&~Ja0UN%F6J%9U{Y_7Zs6+y&A!bqdp9?EzCtZootupC*`}b7Pj)xW_33$ zaS9(v;mLbKIlW4^KrxwI{CC_a^k>A#+1Vx1d-2KW6Bx7OA@qSrs~`hWYg-bcMk_+g z@Zc()+$Ajkc3{%@inV~zxbv%MMV;Ya$Ymmn+bSdR%95`t&CTr}_egCv8sG03UBD!@ zj`9DYvG48D)L#EBl?Qh7KlcE7buP4yeUuDKO*RH@V<@b~)ECcf_v}|0Ci~xQtR{beF84Axapr_K2^ zGkUC&k6cew2S44Q8z3tT_^SoVbPru6}qJ z`Q#irI;gkhVz-DG@;Cj|!66@+vRzHwFZ!Egs=!~dh?>gqGY^Tsc)s?(<@oQ!Ot0df zlQPf@!R|AZZ+JUw1&RCn!Pn}%h5UVIKO5k`om6a%wAH@ZE)iS!Wa+3a-7* zfyDy!zG^{dtZ$@j4%f_Gp65s<7m=j{prU-KLZ=j3ldJ0Xt%pQPv+r8ZBK&2r;2XaX zfmUDpsTXvQrf?p6j>GQqIz!y4>}cm%Cb9Mf&XF3mk9g8 zcQyHi+naBL%M%ebaze!nPk$5EUmxu@U+S}A-v*x#A>DjAL0uhO2*^w$jc=#%($`$= zS}59@(g)tQM==0ogDP+D6vY7krnATh3*3v|t@@sgH<^XLfJvDxa(&SYb;r%roh2Rj zoYO(7HTYBwqu2G&w2}`qKHdSBZAC)CS~>pjVs!K+`hm9nPa-m{+C+-PTaw@Z zRIn|{2Mpy8(M9&7kcBU;`x-TbV#DCLPT3}Z^V1Zg7%1^)AU+y^SJibhBPd!fli}2W z1Ig%<+8JG44fl~4Lj8~^6apC(oF4(~C`oJp5Sq8V6>L!^SamZ0G%1Argvp8kN;t$v z{}&W=f|+R}6etqz*!gWWKVO0JAgqWzC_l&foE4s@5mv5>YZ-i+_M);~Xa9i)dYT?BwB}#v)<|eLEoLT-RJ!jX^X(X5; zRaymotE6lBEW1i1{X42_?J`=DIFSS)B?U2Zt^S4bEiIC{a+g!W0D|n(N%}a#$FZIq z`~o(X%RB7;S>f+XxE$DLjrSVaP6D6PaHI9Fz~aus6+uoppZpl^Y5gm(xEF9}@Q2zX zWW7|yxgEpY%X*1hsIbb&4E=)^SbpDn{`HEM$stO1Rt)6GvMG$Cl^4U?TP{|-t(L6u z(c6)avUALqal#(?7GxMhM+dB>a-CgnY%!m|G_n0A@1^*gen7E|Bc#ME^>L?MkmZw$ zdiVflTeN4yIv4Y`Sb^B(faJ6t`!q{nbtdW*wo%P?wbDc}T>T13B0c9+pmi{|%96`p zP6*Z!>+*_F;{mRaSB+rqc$`qMm=2=JV^kng{e36!hXgte$=fCyO=a!T@vIQeS1i-c z;~w$6Q)fHjd@q`JcdY}T3>kVjWY9DIEeA7XNS+h1Zs4mnu18RoUE2?1t4ZR2G57BA zQ5M%9e*y^vBs>8@7+6j7{lQ3SQ#VON9Pf=MLnx=8!2t*zRk zRz+(oZ55~&OaMvn8qq3<0xHV0t_q@ZRq}g(W}dwSX#4x?_xkaAg?*lR=5prDnKNh3 zIdkUiN`tz<ty#~aOT%S<*;tKmxtA4`=D+KS4#RZm+2>mz4cBrGEoy)TS_seH)#nBlh=J#$uDN zr?a%9dF{Wp*k)Sc>-(;e`)gM34?g81E*rbAs(jy|J+n35Ygs#!D4z<28nTaeWQMW3 z8??uHV5RUJyso5vqc8n!z7lI`{^<+>LzwH?pPi-MLLbiEY5;CEfSl+oo!&0AZ|>(N zZJ%HXa>YVpyT;EtM}Bi|TK>YHN<%#euieN*Q4F59gD*zcsZpj1L--btY5>&aOv}Jl zj^gNTb~oDtM-zzOUomL2bC1@%k&%oFjcd)L8seR0q2|8Z{gLUdzP`KIFLgxp*tO1C z+T->qYK@lKvHxL|gE47dT01&-U#o`teuujJ_O8y-i+7leJp91JrTOi6+G(CLc-n2A zI`FjDJZ16plX>dQ(|+^R1zea1^%fG<{Z);-gMW_h)Al4Xe0!*=aa#u7EHV(}V^Dx0 zw-GaK&x@$W>R}=H!f6 z;N)Di(CId8fzxf|Lf#ki-oX1}-Wzyt;e9jjExd2$eY=z6@VedUc9^ebTeYty#$Q82 z@OjM7g9wdvIWSg6@&nQ58Q%l>EB3z7J_rbQI#28rxvx4cI84fd^q|i-xcEyyffRaR z|6?u}5#uS%{c63@-Ex~y=F_~3&>}@4taxr$CW+5RWRq-gB|G7D#ta8@(QoudWsvzh zlHJwts%GNR5dY#Ds$mI~6>$6n`;5IT`=g2WS@CG_KOUBIZ^@|qEP}C04_B=iQdLY- z4p1%tT(bqgUNaio`nz(ww~&z6shwu>4QFhtpCRv*r>iknYPs75PGq6f38D?YcyHEX zD0E9cO!UUc9cOrTP)xRaMb?nQsm*%T`g+aYj(2iQKl5CHG^xu1UwUKfrzQ2l){^>j zIDrxh{xl`T1LD*?8W|UT9+ZTFyG>e1PI1b$;2kPo#~+uswCeo6e&c_r?OAF|66d2v z6C)b;^@B%ox*0{gLnCD4MBO@9yI61yE_UdvQ`=pPI9$|@7x!=gk=V=X5Fevo+HrAe zf1|WW_F6k0PHnAy|A(}zj9V4oPWQ&`CdMkDu{W)~t&ALG2)$-%&73$Qj^g#$HKUJ{ zO1?mEY5Z4!Zx-+MJll0e9x>7LK9Jg^HP|EdVWe@7L2#> zt1kf*sByt}yX{wyP)H-K;0v>yUeYdzp=22AWLm5r9XXeM4;`tVwJ$OZejhj11YO}ONMt@5w`oBdc#RKuy%CLAG z@@o%QqJgpAOcUOQNIUFp7?xQaiUvHq85+nC4GhZ-r^Sfco87+bKcQ_lATU@buZ_!d z;cRoaA0ABco6!u?ZUw4De3`hvM1eUc_itnMW&eitAuWi?Xsi498l!}szgQ9+XJCBc zdLyYf((evV?fv}tBjvff^p25fRzm=1OLA7`pvaS)u!n+`k(=@hWX1~LoEFOxzvBr_ z^*2r}BZ#)8JU>17^#$P`*b$5(#}|47{RJ+`XmMA&L)(GJ(0a3b;Xr<9JKm$sPW_(* zQq60ei)g}$cF;RB7e?G{50hp5;QJ|m=7_Yi9Quo}-7F+a{|&J4+JEs~kpc41+P1hI zNSAiS3xv#l6ZmrK4DomFQFOyY(e%Y8Ord)wx#N4j;4~o8J$9_|9z=iK9*5|=ci5y{ z!T}FB!D{K4Bv`jVNoMcKW{4D!tt+D^>lr+?V_`z4+fJ|C3}xoJ znK|Lhb9I&40Ja3zyNl6P#}``(B(AU)&a5=;4Wz#}F%R6w$Q6}V+gW-hyFPK>{qar8 z)OI$d{|3^??ED5V^d?{5O-6eg%Q8Poft}O$K)|QH!lhF)cuC50&eEwrwW;|iQucc_ zx7wPu`}6hPo&4Yd!II@c#Xix%;N?WEg#%CH{@|msE*~5S!V{R|^quNolWWMYwW2+7 z)5Ftprqs;HORE|pX9h*m%K;Y&ee^&utfS+2roKAtMDfI6KWl3VHTvJ%;%|KuB2naM zhy#Oun|tIZ6Vr*oF$z&zh7!8WYS%`}RXAmzRSx=Mj=yryk2A~colvUtOKxAecVwO( z-b3anZ)RaGiJWg^ez3BN8~#o|@hDvcF6|g)i{PGhDcbl*!tdI@BxaPV`JVGG)P3c$e6ZXEr7U}kwe-Io)bXE~juOSZK zm|Gd1Tq2ujJ?kWjxN;mV8=~#1KTU_^7BvJeC)^T31(xk??uCukvi+);lf4Z$NEB5J zE`FAF0{tLzmifso;(of;0LuPWzDmP6<-jo3i{)YC#1Sdj;00HRv8|m{;=LF!P_g0a zeMx!{#e|rqJmu;r7$?J1c!sX3ZmA5-E?`3fmo^LE4tIjdWr+?ix3pIasmiT`l(ZAY zO&v3X2)G;CeX|&E5t4B04UOmK@Zov9N%C-N8ChH=XBTj#IQ|&2J`87J;O3aYJy)J9 zmd-Yf#eH@zG5K@k`ACFP!k;|%x#?!;MSVp}ZbEQ_i>UU13`Xl9GZ@G|k}F>P${P&1 z>=ZOZ;CGvBGqg@MyPu)awXU62<&q;gH(%mK!_b0N)+PwXo7y&oGw-ntP#r6c7TfhGGI>CJh@DKvXEyfnFa z`h?jR{YE&hX(}wOnU%wU2zAUf_dy!;LOm;JtKy*l&E%Y&OD-g6KtLFl={r*F0EYV+ zNQ!ekb}qDoQy8uYa!UFiVJUr~kps19{#6r={+_aCO%oXZ_9~4OJ%l@n@;pKwG09$D zIG03xOF8}!PGMM~0$;|e2m!>-J@b9E;zoP8LZosGJvN^A>8t4gJnQ1*h*4k|1*Ulg zB1OlN+0C*U10V7k7o`LEoI#pSlk4^m;%W&tBl4vxk`L)GRb|#c9fA4CG)Ot?ojv90 z!t}sY8{y?fqsxk9KXrp=J4U_KDqSz>QZLOgL;eniGK2e(IqcgoC^u4D zm6=zO;uf;IBY@F65@`<9h;(1b#JbJ36|J@?``n&GOq1`*y4}-UAvow=8A*HIXPSIh zM$(>Hrpb4Mx9d(zXXz!fU(?(*nq|>f*s~Cb5CiIPd}=O1^)EMB_!(p9pal}C5YgGG zEg%^hI!nMkBW!z-^JV7~-Edh_W#~@$%7{F`ON(X!Y^r3J6`W%QIj4@TVLYUEKbp6V zJ@yTa5v#$eJB2j2*D8%sqpzufmB2`CwcSY<8vd36$XUS=#-Io|G?V!o{GZH*!NgoH z*lKc0{@>xgvJzA1Dk>TAFM&0v{#?P&~S-4vB0mU}gA8jkxq+(t0(ZBN4B;!M60z%^X- z6Ngvbo-Fg)Bh42#1K*~UCy;DYfk^SH3&=N^d~sS3`%;BZ^WAC)MjH)*Q+pgK(h@jz zex97Aou8(c8Qi0Z?;ZCzN9|cCql$XJ zlZyFX0Bq)+I`qCUjvdr6acr=cq_t^~-Eeb_f+No~QfB13e`iSIMC8!2FYV=(i_)YCf;4IUP zuYe-njY?&S1gq81C0XWP2&cA~L_^mX@Sso!psLQI5>~%~JqxTJtzjg4t3@Eu(<9k$ z_zZG6bQ8%QVG*r>q@x&YL*lht?0$AMI;$09y~GPh1XQd{cY`ZMB+m#8HcQ|j*Eqn) z!9j}*EF${`uLY^~z5qL<%a1}fVEIwl(2=d~#s*`AuG82YAW~v+Hp%R7&5h-9w|H+2 zil-iTb$7>8PKY*_f$U@a5`!|oF+M0?qL~%0ZX?A^7l~wvff>QTAd7em#fa9(bGBPf z-EY-HB4!av&Z#|HIOcYoy5T$sEZr3w-YCqXCb}#(e$@`#S+#z3 z&?BcbsT|~#HiKWSRkcs?5FS=ivm1THeXtEV8P(m(L#gwN4$)unV14iAQUSJpAb5?X z(j8(uZ6?5zd}5)2b0MTpNUpZGsOpg=t!oIS=*%+=IMVZeYQ!9LuP^=G)=zbhN>p-u zGTT2WgnUq+nvE@T*XZ+n;9O7ec6{mTf?$muRxM%{3Y8hYG+mQ-WggJ=5p;iqx;*|@ zca4YO&14m#)f}r(Mw(NHecSe(+4?7{H-1%*@Q}EfB&uZQ(wfuET=H!9H&R!$hQhiW zC3Xz0e)AEdvf~w1H;U9qYYOQ!}B&Fw$X7b7Y#dXa-@)v3J^&^FxsvGFUySysC+J6&QC_Tya*3I+=W+h{{5 zSfj0YSD~OQDA46@@1%6*cYw+eaLw8QAI|0jV*e1XQwt8S2p50VkMre48nqJ{MRPxl z3G}^sBW=~tme@~9#c#eS0i^gPiV>48`i-Uxaq)PS93LraqMSh(wG5gig;V3rJQ{Dt{WltDbKY53SxKOS zKf^oJBSio`#6Uj<3iP=@pQq?T9Mj=Cb@r^GmVV=ZVnT-hnDep|t;KAZ z!35~z$gKLDV)n=ip27Ck6S`}k1#@joO6MAr(seQ=HRu-C25!ixnSnvDheYEYB(SP< zu-dlR?O@ibkb_fV;}14J`wx9Jh4jy1D$(qdhtH+h1L#<=kSUdX0lZ$E$fPyj;` z{!Jt7^J(eC2elBCDeHB5dE)urH~K~zW<<-$V$9n~{ds(S zPS^{}L#yH@Lun0(sgN$TXHN1!v5LaCH;5Au{TzR@r~?O94&4Y<;}?v zt&#~v8T#X9RL9b_ZHaC6^v8OB{~&vo=TGScId!YSLs__hQ}+M33p&~-w3rnja0$U3 zvfLl&Y{=f`WKRP~l)fL~9+~@EV4>i26*Ty?1xM+|s{$(0k&`wqg4*SK_gnQ#HuMm6 z6j6sZdhJCtjHk;d>f#+AF&)7gik)C*_xXR& zIgZQ`C2HJef9QCY#MqJ){|s)!a$CT;y^yONeRoGD@zF^aavA2Bg0I&!M0QxVfUmc! zEWYy0#0k6w3@QphE2l#a)Lm$h9yk0!V zmZ#!}`@-V<=6ZkVeP1Y8ADZ>1arqBloQJV&f#nR9529mb(l6w~4Gh???U#*VH}G=W zkb_Bl(TT%SvpzbtyMWU;`~H>(g%b!2*L>%);SEWChe2kcFC18h+J4B#?sywGFJ1%K z25qQ!LuKoU6~G0jv6*kjF0i$LNOL~6d?Dv4cNd^NX<(s&-vlzKE8p#&T9;0ORkmCZ zD%(SR1md8s%Bmc+ZRQFO9)efSqKlaQulT#+KG-!Z45&2>fQqFss~)cd0v5Y2G7gm3 z1^XWHSssjj&h*52E%QTu=pM=N+2FpXu7#h_KDHwKSGgd9lWMj@K5`k@s9oBk z;=TVC9#^})OqcPHFsH$vz%0P91iBpr+9557Xz9T)O<=p4^`KMxprBSzw)=T7`!OWB zMd-S~^O$AsXliGKQ=y*#7zyZmYKW;UHX4M1_6DReu9DzbjLO)k(}Xk>%DpC&89+xo zgT^HJVOjhG76s>k1@BPS&I9x!Fv{yw*0L1;tWnJTV*)UbYZ-Enjdj!N@;WH>R+lzc z4St}(v+V9O%5Iuw*%c|aWOp?Ti)xUnR_B;@PC2R z;}TU~LY1*Ov~pr1X#$${*i9rkiKI2H-JG7 z<(nC)oUl(8CsbCxDfk0jtsP=UTJR?1eayP6-CS8>44HY{iXqrcgHmWHo|rZ!$$eUM zF0VTq^8)fp@}*TxB)%EPRdxpa5aFr9))h*55e@(VO)kFne+r`UC!GB`11x(a>i9b9(2aU+023C{1 zUt-j`V4YmJk8GDVNkmXccA1rspG|otgl0i6lT4sfC#a)@ap&1~I^>(V8KsilhHega zlihIcDxnq$24CToZWCo;9ug~(`a%4+xJg4>bkY1qca@3#r<+0oPn!%1&VHXiB_7rXX2C^7@_rxhTFsUx%7vx3GIBu5J~v zLAXOA_6IIs(^Dss2r|+dKol;?5g66Rld>6-@#uvw`Qf|J|#@r4OqPVvRovh_8mi+ z@7x6Vk<4a(QrjzWmT;0KC%wsewdqjx`{sV#0^SMXd$QBl*bF0qG^Yg+${e&|+8Dv7GIAliZ3e7iM zG$ZAZWx3l_zNL^xo60w5@x$o1&aUjwK74cOvddoW@Kb!g)a)s^^BCWx?|kip+iM!L zLY13ixvA?r;+*S?T*ksX#tk1)x3<(NYvJ0dcY~!c*7e`6Uy~v~eX@Ri!@BG#G`)V! z$ITm~tqp@#tZ!JqCio>G(bj)Eb^IsmKUvqeX?^A}W%+jf>nfdE{v*nhsIve4six^C zl@GoZ>&!1usIE^w`eeO^q>Vg>li`&1BicR42Qz;Vd0EvfSzA{SNxoOjXZzDvL^AI6 zHAauC`E<8}vz6zCRuD>_^MsA=F*Tbvr?-&5AoP0UXC2Zh6FsWt)9Q3>N(z-P%j7$< zcN*%i^cFSWw*4v2t>ro2JGWL2oZ{?loZ`$WZ&6a7l6>)`%~W=3`B)BGgv$qxP@`yZsU0jqAjmkIk3+(Jm!Hp*Vxc~OOH1sYoqM02`u79Zs_Hbq$UOg__ z`%y{YZN@8+--+ihH6X`}>{!@#J|^UK*2sPCy=Y}wWei`BZ)#?MGjGqrf|s&q!PhPE z0r@t$nL*mMAF5}JN(+ub${mZZ;zWD}Z{zH7RYmxp)$~J1&U9Pof<$(tlx^-x^Rh)R zTiqq*1vy{qbsRnIs+s`H;@fp_M_OnSy zd~P`Kvq?yNZa(m{Nr-+_f*L@Ka%+nteaJ%I(|?>CVM6Y5sJ$f&}|){ z5Hj>D(NVt(yvzm})9}lgf1dN7bE3e#*|C=_lyW1(6{?s!Q&V zd}4B7rp+{;1DCLjqRjaY4l3@QGJl;V=QVES+}Zf_#?Ny)?Q@pQZr8XqtJ5ZD$sO%G z?e|SW2ISlT2UcoU<7ltn706R-f^7B5$Cig)01JSI%3jTlf!uWAY6UUm8)HK&(m(fc zMH2#MPDA%)Gpjp_x;%?EV`0JFPlcVYXesjlrfH zqu}NPKB4m&xt3v}3^od_?&Xhg_&HQ|@@~Jv+nbvN+(#eQI2IodwBk~E(Qz3XG{yKx zbN<-C;J2I~$~ZwXJW9b6b`v%YrC^SK&?nA)eIY__Dp*_@3QjByJyLG~MD>aMTzeTL zK@hzh_Cd3&{Eh&fmIxawVakotXU> zgv)kwKw=c_k0m1i1>6iYI=}HVhI2-5$!#CGa`6k^EPOg=T)4#cP2f z;L&|G?D~9)2v`M9?ewAYa7=S$Kkicaa_5R%E;js9w?;R01j+caY%tUJRlUTzk%~mn z`jY-50%+)sVWF$O%vBY~j^HUzBQPJ8DGX#h^5U1773my=Z^%R4l!DKJ&XUV5=o5Nt zPI1r7x1v|`Y{ z)TG|2=kQp(4L154zsyiiK0qlI@5x*0p*d0G_MsQ3ZD*r0zzEckr4WYP`VqeLbviLM zzwt|c?lRQ4i+96Z_LI`5)2`4!*kS>0Cc71zt)?NzH|UMviptO{)zr=u{*46)6(Z3T zbz!(W3}o_Vs4p-Pc7PdBO9JN1$YOH)Lv?1I4V!(M`BrBZCu+daobQnan@!6eKHG|0 z>h5A~bWi3#st#tlIXsyb;G{LHQa$Akkl!vF&4~5i+4{Re#x<_FVwFjA!@o0?Ikii8 z!$Jxx80%{)_3_4(w^Q))pFxHY;=0I0?kV3Y&)6tI7!iFD!11bw5C{O;3&9X1oMyyMIr} zqe-7M7Tr@iY0;%pgm=^{k30yBbq%wxR45x7d>rRq{~!*f*VX~ni?Da-$Sh-nj!?@+ zRaK@Fz9ujn%RG+7H`C)qo1MBhgy(Q(udKL$uwfPI4>)dSmqgM+lHA*WYnQul=0oO# z=l?j{ESyaDw$|iG(YPi}*y0WVr&Tgi*?_RKOwv1w8tz7>6Hw4%^x4bY+cmaU8~!lU zrNNwdMAa64K=A9hmQHrhYLJd~R;-Be^(#svZu`{Gvm8 z8uz%ed8-&S-AK&-JpbUzJg2r&bs&$)c7#K%^q2*C_8IhMcag@GbUD}7A8($eSuE!O z=fxm$KkFdanospsFj|ISbnR+`EM%k3bRpUVA78ZHsg)3{2wXGAmcF84f&!BC&za_* zF9;8a(Mh>}|7iv5DQIhUYh0{Q-qpl+QBy^G&L~I9(~a42@Qv`3*JiFTLu-_Si}Ij} zsgJ8qMc3&k^**i-=ONCC8Oc$K`?#7|8~;DLk89>Vl4$LXdH=*eN+GEbO#X^W*3E~w z>_9uU*zpp)!d>pQk<#}K$EqaY5)~T5m*O8((UMBTwD%0)a(if}mcRXhL zexrWkeb>C%AOO^NMV6xPZ@|D)`W_xRYG-4^i<-*+%1OfpS@t^D-G)bx+PS)2pv&Af zX=!pJs!Wfptqsjd$%-`k?jL}gZP)psDljs%ZHCJUB=mD@s;~FwIjb!Ro>3jCI zN&kvh-4h($!UJWaXHy5AWD`c~PpXv8nSyfxVyAXacyxg;e2#m}eBnk4bEoz(ii;iY za-RY(o=&=oP<>WbNu-Qt|6- zo*T%6YcyoD0xnbZGC+YdxWtwPg1Sq-Q}?imrB;?NB|!9UiW%(QLn=8j5jb^snHOGe(*RpnBB#owy}oT(rxtB>T5rZ;b!5H7-4hpEESc zDpQV%2$fMpY9k$UIPPdT8VqphNaMEwD{o=niW1N4RzHwk{%mNDMmdhoiDGn2Sd6Kl z_{-PSNpyb_&(0TJT1I~o-%6>?^7I?;H=}+4E4PmIamQREjwbnK!oNgorG@{~bOS#y z+di=IUdN^zP(S41)or;AuoB4bcfdwr`2 zt#3Tat9DZr7?s$BPv5#IP(5yqi}S$3_3((hi) zgUov2;=z|PTa2-+Xr6~$nah?@Qo-4akKsGsZEQ2lY|=3^GXTF+2Ha1NTiZ%iT&-h} zcCX-Vu^J!dL6b`8%MVrEKg!m zyN^K%n#>zC9C!&C`WN%>BN$HId&L;McEJl za+8~3FuYRkTj8SPXsGm6)#2&aap6l3l&T(Q`OMt??r^W|BfYlK&BTsO!C$=n4&?K- zzVUaipbWkg%U}wyTP$z6H*Lr%!R*p|FU=oS{aIeaSJIZOd6wVqT%tRaA*J5Vx3*+-k~d9%PdB*uIsaAFMm;z!XCB*2C2O zR4()b(LB&#h-Nm2jzpq%C1^u5H`6N-jjlyyi*(q z6VOgQwi}QJ@ijELke|dquH45Mo9OOZM&^+>K5r*ck6TE^6!s1^Y<1_~tM^TAccq(7 zb2>~7Sa$8B%IqvtCGP3ufKx<@#r$tyd^4!G*iwGa6daQ*+C=|AS}8%6^_r`4-6`C zcsSs~S-DQ&e1n%`r0Bcls!|r9 zUB*EHBVyPk(J1j>cXO$k0X!ePyEdx)Oq2(fXoCIRefRLfcc!no0dnYWAx?UBW?s>E zuXsz_%gWYfIXhS$iuLEEs*?1Bxch%p>VjQN78)(#-Sbp~l_akl7A_mYO-^X7X1=yeB7A?~DLu$@UY9jfWz{)G#obgul;4@p zyef$Z3Jc%-pxi6DB#J44PJN-g)K4>{+@z2bt+5K_;X!$nLDYIs6qZB!FCHSS3#;s< zyMzp*MhSMelCCd>gSqF@c&dFQMgFoQ`~6O#01+zEbI(gWMzYtVU@)Y&nT0Tg{MNd^ z2P2SIA>_9?Ap{=MJqTtW%e~_#b3JN#JeePsvZ_zNb73(*z4sv&gNf z{9`BtxXM4)CIT>LTQDz)gDD}r4eQ-eXIbyvl*3yU0~!%m1{Zgt*5FBa>Zb9)DjUwc z^+zf;B1$oJy6@L$g2XQLO`7$w+mRQ4sGOIk1()U+GL6?!f zzotQ`>42$kXIfsuv&w8h4(h-BA-Mpk_^MkGM>*4&&5qPZLmqYJvm0ft$nk}UwBp^0 zYTc;V(Qk5d5GImBcb4ag)kvM<^l{5$cn0=9C}eh`9Pi5b*{biQR0x z^hDTdVL&^68D*m3%+6^ya{^2EOF|4Aqjjm{>5Gi~*&iOTQTit|gn!};K~qI&kDGx{ zfXW|P(S9-;ospcMTe;sqcsxCNW9I9z?#NpyvB3xmv_;EwN>cP;fQtK1;6KBCxm`ik zpcR2hJipS#J`*T9^HC`}Ngv7cafjLGp>|Jui`F`}1stflI`V%JFkeBJ%kTs;w+&3Z}hY|IN{FD<^%G`F`@k&+|D%Q~x(y&U*L^%Lk@mbD^~ zFCR*_YdAFHoJd6Juz!@2h!)hz7oJ@}!_)H=YHeI}6;1HuQ&NWcroen$Ys0rid^-fa zn0RR~W&*d1_9;#yne0+xr)Y&jTo|$gVn0S+mCWd-fdbH%r4v9U=qrck1v(o~IkP*H zm!wwnZ`^RT_^3ktRK?XRFVBptR|0QY)k+29;87)-d$cQEgD<2ki%%Z{-jw~(K;s1| zPeP7dz-_g69GSIq?qBE!ho3?))G*GZ@mADVKDEU)7AU$J9_V^UiID$x-j3FTLcZbTTK$)WCcHU4Sa8h#Ku)g zS7_&r%YWS(HmKeIj*#e-H7XqAaeCp)`s#DjO7BG&lSEGZU#n}3WT){tif)D@2!C5d zrRZ(6jC7eJb|Lk-jfVtPZfh?{P|rBEYfS!Y^K(mgHqn2n{QQwi^T+xpT_usX;@B&= zaO~L2M4-1LY(ktB>;@6icFm>}`czs-)2vc-& zP(4g?Qce^$2Am(8aP$QI$Y-AiZz*4>mEBav)jZt$#!A18&WTP6`P|HVi{2GP)a`nt z_Ygc5-D73L+&$XDa=4ugbN8SZ;&~0v)TtL1(uGKBi+!h7vS1>U5|8vbl0&|{=woE7 zWmvM;m@Vs?K=10oG?MuTGB8U2B(;Lm7_qJ>>|Ld9nQOE`SKPb>g$D|faXI9)??Jtf4@4-hdGOSlM>#tx&f zymr6rVH!Gk2VwlZx2s=FY1_*rx)z$E;y4%pvla?17Fy=0~+LX;ak z%1E0c=Qm(GadKX4#yxW&>RLn2fg@~ir_EqFb;HgjmicA_be&so>crWx_;ofO?%_g% z5x|_<52#K0>L9R%a=F=;4IFaB6khGgzz0?0Q=!o-@i`@QI*?It`%uPrUxd$T` zdA}_j(TkQ_W$a)Pf))F&f=uS%8=?90AXQ85{LXZ%=r%8Tu9tkfC^k}bjhFmOFFCWF zNuF;O>rL)xFS#Sh&|dUg=p;qw`*Nabf&^jE1`&;=%xf@vxL0yFB?L|rS))I;Ej}xy zcn4ejZm;ojl62u*QsEDNZGSXWE3|7`2xa2l&1|jA#lQwK7r%>VJzBTQAR8MS(TG8 zR8-{WUJ%OIQ;JmHO1S^mxIgIonXmgN?b0=2TcwHnfOfTUd`$)zX|GMZM4?Xh9e3As z3l<7Mz^W>Ao0Z`4(>E9?yyTtv^<>pX9Ic75o`eUx*BIFCRvV#)zRiXt_PaAF4}8HR z3`r|xw?7TfZMsDW zir;EN8ElEpC+Se~bo{;&d&Wk*#l5>qm@|gZo>G`&Lf!A~({wS3fvdF{84i!Vju=G# zLFHM9R^iOOQLqy~AY845P1pIbUM_vwM3P9$@;l`pGBFhCorP&Ut;BRhrO_7TODSL6 zJ4jD)PEVW}Cj272VM}nLdlNZWQqcPs|Mfhk`c6>dP1A{D3|H|k#xMrHu*$uVw=!*R zi>sA+O)~Q>WuX~a(#N?ysL@a^reQ`P2my%ZU<=5|aR{Qjf8Az^9+j-=|ET>$YS;7( zkSrq6y1unN8j7`-o5crR`@J!7ORiXn5RX_fm_wuLPK&jiog|?}vXa zbLOuEOt#1mjtpPgC&yXxdZhHn#)e)syB%kqrVYy4K1dGlvF;N$cb+eOck5<)(Ev?f zR80^iq+YaL8TrxY)pc;gI`f}q zmpQU#W}hs^IEP)On_+NjdH1hK&?|YK|9+5>>jUUb7*;sw zu>fGcqQI^sR8n{9lRpY_DNH{qH-Ev*DWW`M7Lyunn&{<5(FVif;8>wFQ0s1?LXT@b&O&BAf{L%$OO-7UOMJC`mvs_7L}du!N*DcN7ca}t1FdP% ze`yI#K}Q``#`WBzs1kJSMeAZ6jI?j!TEPE+j(fFPjTB90&tTD!JvE6AEY}%Sms}g8 zJ6QixTRtqMGau+%B(s{9%|+9-5@1lPFC7`FIPZ#KtIN(a1Ce7}j)mhb z|KIItY36Hz**V>7no4MftITV$;(*!}v1r4iUP<{TT}I)kuDwAs37O++`4yNlehQ!R z;2-q14Wr8v^E;}b%a1Meip%&dRrTSj0--m}{S_pEHj2DACYuYzo0GB;9m|&6$o_?K zYbalKVK|V7mZbP0V&=G=O>w&iJ(>ETghf8Q?&RW7W^ZjKuAVoT8sCDb_GfsPLgi4> z5&zV1u8OV&aA4Rff!_x4UHYdKn02Mu1OYJ-ATA0sp^Zc?)(0fr1W7f68K)<#zDY>% zezc(6WQi+J@DxxoP2pWd?YALsRTY{VU6S2dRAm+nOYL`=nk~-|ALf%hDX#p70o~4| zEHfO5nItz9Xv_@mHwJHs!QE&-8DELDJf~3HN?zUCTj}N0ch`$Y_ea2suzl-=&zH{jKQvUQl5=`n! z$+-VS++Hv+H0Dj2SVOGh2oIN=?qVMZjcX_izf{k-Ag|B91FSU=eV+xFoqxDwq847{ z_bCg8MKaDn>0a9SbuW|)rRl3m-~Guy>0@8x=b4mQRuLY+qPr_0B>W7ur3eXKSwJ45 zjnYU(K4L<-ViWvn_SvPat8}|w8OROK+^ChJrHqxLRgBqK^MXgXvnim(x|23KC^l!l zFZsd5UrDto*34>db?!4lB>lO!EH`IJuRz9-!;Ej@qB30CYgVP?kH)G*W5t2942#(Q zu%?@$&cPzw?{5Oehug>}2ad<}jE6t;qmPq);mkg!i_jldoG@-pjoY%&g63!txU-(= z)yF@ni5mo0?Oc%_B(BW)^t2?8H6~9E5ICI8Vzxxri`TPmNb&IqPQ3A@!>EW+nSICS zLBp~FqqL6rBbUQz?-Zv!N1XN?!)c#Xkkd%f+)q|Tugo%$4C?(< z>_zj?V&?W@iem82xX|5mqh_>a-8ea>CD>wuU+W>4PMS|S@dt@Jq-5ml7is~J^RvWa zvoML5iq-nU?fkN+NRDj48=YEw;R|qJsmRYOXL(2aXRbE$h0jd%zyrTBG;8|E&*!E`Kkv4*#f?EJK>vQL9W|pLXEI_SEt*@{XnY=E!TU<%)YVDDv4pp!7 z-4+JQ+9!;@kI!H@D@D1-t5wv=px@>TuLr2`&idtn`Z?@39IoLYgVBPpzPP_L2sEJr zE<_mvTg{h!lu$j_Q5sehAPCTftlt^yjqYU?x|e-3H;M$M7nY3j3#zDVnBM&WlU3ZO z++Ngj(0S5?zHn4LCP3y}A6cB4E#W42q9NMX{BwW)0g}C=3ohL4*#AbKVVJSNmW+&) z^*)?i6u0|ApK_&*zi$(lDOQAjLf_xn&+KNn0^|LWU^)&5ZS4uplEbR^a@BO*M>Su?LwXEWC$*Tm_>Ieopn(6QZCpJUged{cK&V8|x%}+6cn#H-#FjKiyQ__-gf@ zqo+Gmp(*S}FH9U^UV8 z4an!ib9uyCF(SQ7-jFJ%ZmrlTsr;lZ(|^&|_+Mo(NtiNRTFSq~e%HjtC{5P|5P)`- zlOFo0`m;^dD_*VMd-T-Ls`upwKB?X}A+WA`WlQzGPIt7FI?Io&S@CGi-XooPM~Wpx zilXf9e3N?o)|bAc^)pz_KFp38&OC`jaEntj^fhCyFTI(4Wu#~*qN*`%iNrs+Ui9hI z>0)02*#RJ<4ZO(gatV+RIi0I%Ni40Nlg^_&w0LaCV~ZXsf|qv!7XXqLovU_hc4s=Z ziYsqmsZ#*p(z!z?U4Qjdr*5Lx80Mq2=xCFBPbNXs^%N-@jhOi&J4lIm?%5uEr+G!N zK&3_VY?1a(-4RNjJ9P3b!JD1BPF@}?l4;SOv?ns*8h7Z4Yq$`U65ZYefvMXc@J)Td z&_z&oTZDMRui7G4sEE2GNS^hIX#b`n(t<~SYl{HMeM+7?^rl;Hxz4GZT z&u*?n!_`mdpsVAR7Ae|+aFu{*q}RatUSSRorbXogPZ8``qY{Nru!VnJl~TB?S2)uv z++BrtBR<-~$Tr?UY#|Le@3{4bYn{3e^+I2IDEI5UILjMKL&G_rmL%=yKS*Cj2Aqx> ze9MROpubpGPrqeuE@^Fmb}KrzhF-5;(Nev)^VF!BS-qWk0oA%>jn8@f?Wylar+5v@ zXccdS%F?2hd;lSV2U7ZU?i4#n{k=k17t^BoHsfW=7$=f$CSx#5UCAL670p2VllcDK zWLuGoXstY)^-YUz;KjErc+0dKuDfOOwf;dJow{c4`{DZjlKFnetv6jAxZ$SB=KCV= zdry6TNZ%txPyL35I?@HvNWIt4953S$$~e_jG-24SH{W*Co(JP^=_r}&?o_uuDFxBi~WUp!qT7JvR#%5yv|{`-RWP1EEI zW{~z}P3%AV!CS`gr(o2n{OUmYw+gl!>z?Fi(r8{!`SS4WywbU?8ni%+2O%x+83G}8 z-iHwxwWfDu{V@3=^LEg*rp7#^53#EnU;4V%&E>c^)gL1UTJv)|Co)b?tvEgr5tJrk z9LQp~^Nmw?JRg+0jXhWCD?r>Dd&;9vbfr!mh9C3&9esZpNYY~SlHY^ZsO&$@Haxt-`YMXjn&S_5(9PKXQ@OMp zQ!B49-_rkM;MN{yIpu%MweQ#DdX`)-srk~#y!{3n-JN;2!hQf40yCJ)-bl*{W-h3I z-c5n<@VsJG?$q8!CB<542+W}?R) z9Db|~;-K}~A3h8nXz~TQJbG4hR`59Qf~{o}{1;6a?ytb-96$%9JGHl}3JNoMrxKb9O+uuBbk5ha!}3iMb$i=0v=KzfEI?C0Zb4;S-5J5MA{o60X8Bcfi04! z&=2$pt;Bo~Dt|eBr3?tT5~54sL_Pz-Hntx!<2Fw}(CmIP(NF-QcV#od4Cp3zxd30> zim;E-f77T3-kkYojd};??sM5XK~j)WWpnk+to;+5IyBR%Nd&^H>)|Ci%S$q98s4ed zJuis_ZLcn z&NCU^!4PMh><&p!7g7T>m>2B`BorclR5BBfU^}`G&cY*;wDgtq{v>?kF`mn~&N*e8 zuAxb9nl@AV;89|925NMs#^YLFrsCEg%4rVi3T(^CbJP7cy> zBB!Jl$ML_xDB&u$Fy4PMw|LWTadO%Xx}RQ&AJI()n{F1uOgr&LPoX+Zh8upMvq<7v z-hxCP_$F|Zk}n~-GW50S>>Y&)yf^6WX#|%WUQiLr-|mYHmk?YS>%ZJEK~ItooEV4a zVCK5s8w^$c1&lAWGI|@dpDb_)hWzM!;4l4Oxju?`!e;;b(DRh zVZ9xuxBs>jd>yazP4Tvu(;*<0drynY%jse(yuD`Mpl`h`<*jDc%c!$fu)nX~{pv~WUr>iP zONZJbV^jpxGUu747uzDW?*j$1bZDE81HAe&ZGC4^-veHKfM73eDmu9h2}t-LQ4@CUE7 zeZ9dJIh`VV7%26%lT$a^7HL)yCXDUtWUt8Cw#YFQS?v|cc4~(SHcEGK>U!GJzgB68 z!-k^n+ZpoJ>6fOSv#U`-a1 zZDUQ>YwImmFKzR2t@m-R{Wz@6#~19!x_fL3`Lu9^ZQ#L)o^W-?#Z#;eG62KhA6O@eJ>ylwB{80q%&fQq4o!@JPRt$~k)7xUE-t z`nJ+{ThXv1B0R8FT_4hjxZ02qRthbUgyAycYJv71M_eLB3;a?>edc zdhG~&;W`!cg(F6Ne5#EOVm(1Ws!QoaTyy5so<{z7?++;h-3u)k8K^xuy^thTuU1Uj z>@6SNqCZ%{wFiU{wU0;exY0fy%j0|YF^|V)`&hu^EB5h39{*tMcR8s;M?PDk-JqSLHW0OMRe&5fc2qB%g#h!PO(LfZ_~;UuSm8n zavDV*i5KA_Jg`8Qwu>!CincQ%$u70?O1{TO8tYBTNh%pB`nU2Wn8HVw+OGe_=Icwo z!Q^949U{!ov;4iuU&eR#?`xiW^4yUq_4+-Y-?84a-jCo}Y4Ja$#q;TR8xrvKeD4aX zj^*zZ{x*=d7dn2DW}oM81%FaET}ZyUNQ?UW3x7+zXT3M_x0b&}lzo-Ics~7}N;~?~ z^Af&&K|Nz>C(PgTaHN03ySIA38%Wdp{~!OlvZ)tbW!`Tb#@=w=vHZo~?@amr49{-L z`!QZWFZ6!r^7{gRtHAFr{zTfZQI}?geno`({r}^i=2YCj?Lht0^_;`@hva2I@aZ|) zmAwMrON%+)`XFApZYwh(JRvWFOP173J?=chKPls$iuCQRoArH}zK1@JZK&CIN|0kY zT#PrOFnlo^l$L2H_$F1pj|*LvuVxK5eqGL9xyuSH>ugpoDh!psANyk|_a$1@&Iq(W z-0~7CMf=l{MQC8H<&>OPhgG&lZ{t6;=kwq}#*d#YC-7i%tUGhBwDm1z>Fs5y*;nAy zbw(CcVvd&>T354qf3dWS!91n!{!;xLk*7X%JHTEOS|{y7aBQ)5V{^LH>^>#Xvu5{| zft*-*vC+wOES8Qgc#c2J#e?A^xsS5IH)&V+7xaFUQ(xe;8~zB$KQSgA+T~n?_yP1ZmcTb%Bs@2=F4=JLn0V{ zR=u}x5IZ-w3etu0^qsm5lj|SW#F_F|um*7tHC2N5Kg^1ix-w5p(11 z*X-{b=vcGAU+{z2o2{=;=S=ruj8dVGm}kCDulquW+ddVBr_!PCoSHO=`;i`R(VsMb zdkrV&{+rrmtACM;8P&@ROP6W1a44!@N#@pus-Xk`inr$v4-HSCs*jwSYPKX`jYw=6 zAF4WEE6+ghu5N0q#51JPJPJd(c!VUz0cnj$%4n9D7>J ztF*UE)Y?%*;6GKNZ>2`nL>gMHic!0qNltWRfg!g1+10LZ|Km8g*MMIF>^;Lo+!xp2`!Iyb)*9Q4lLV(|0T-BNLX`{ACxKt<6V%2Y*+vcgtW^V7PWl0a82_LP!b1v?sq2xc7ocZY z=za{8sDLF?Q|Xv`BU2x9NcHcZqdxUy*0U%y&f|&Q&$9FHEi06RjtQ;V*Cq;dc0|$=!NsVV38{f%&~F=+XEEx<@zCdGF1sH|79HR-^avr}8aJ<>)=Zfd;LS zDJr9uKQy8+R;XzqVhWs`MDBt7{CXy=$WY4zb$TmAH`Rve_ommT+@(t#!!N-gaZd~SAw|uC^F`IFV%JM52XRXk>6mPu=pm-Cud^$G<%qnIO{H4L2P!5Rr)yuKHR?{9gB&Y5@J%mSO$$z^^&xAI- zh#xlKHw_n)wO-oK@=5CAKafUm7AEj9-+UlkF*q?-tKzl@n-UL#@nGDlT#TtAr>|2t zIVH&#xhe~-x&emBgDL({B*Mnd@r4gJ9^fBv6M}Uzlkd1wn{PnO9I*z_bWSx;QK=Jk zhjyD@kJkhJd49abf;+CvxY3+<8Sd)}Mz$Ud#t$t;_enpixX&mBh{BE|nEZ<`vq9Vr zI%sLUr6rNL@2e6oaLSWB3lZ_2SA=iMVi>o%jkIjL5ts;b#hp)HvX2itq(A=wK2LQU zs`_&v0d!?2ejc{2q?Hq z#?~a{HM3tJ{s(cPXjLl<3&$KSe{y)1m+DkPpPYRLC`KUFb;qYn2OYnnrzVV8(J}T@ zV7TaJ;rXV1xoQ@>e@eXQuzS&t(-m3{&##Z%U-6}sAY^TWFmbYPdPjF2-;!s;?fogh zN6-Mm(fC5s@`zo*h+TTP_6pNj1`dwzH7q6*1&!@F0oH_e>HBvE% z3)RYGziX}-)X3u-#t_KrMew1)nYWXP8&yLJ0(U1~za~b-7l5_KpW!1jAVZ`(S4JAlG!qS?a4KXIMl{K*@F^ChRd?D+T4fW z`3ug-asMp(&{4fN454f?ZerX~z?gXZMZw2;Ud~PwpKupQk!d4tiZCwt~}FJE}fI%95(6g?BqyJIMM zbt#ika^`w*FAiFdQse79Y6z(3O{-F{VS}6q8?Tfa`uT;MM+dyVyKb*!Z@f@(1asM9vfouG2t@$dCVp3EMc(7e4MVVG+i4x?67H1=Mp6 z0`-9^ZxkLpFBP+Pn#cVa4ZXULsWUY*3e$9p+$ML1Uc=J{DyrcCUsHRuo4gnIz}v%Z zPh}*LLeemxNp*|m)vSx=G&~)E?H=MVeCh|fXiDhrUWL<`QQ)>Wts94NJ7>JRBJ6!D zkvpNV;_m7j^F^a@@O;5P^Mn6%zEX!N^Zwgm%H;l7;~AgNoD*yf^nm7bP0!mbzqUSo z%scR-IU3C6fCtBO2F9P{{om?7R4khFqMjPG7OmI|b`=E`X$0PQ+CO-ovOu2JorQi7 zIQjs-#d4SC4%SC|7XAXWJP?17%DFl9pyi=;`Vp~{wHr(E4|OjeA|ebHa2|;BraOc4 zD?_`uldWy|tHeo&lw-Ga&s!hDBj7mPK6lKNx&~ZEdfWm;k>cC#9Ve62?WZv@Zk9%Z2vk+>!cH zYG1Y?hmDI4urD8*mp;6t^4prGvE!oMNu07^=Ljwe>;eIDe=5X0B6p?b$eHgwOQYua z$eJJwuzs*1ww2`13m)&~c`lJ>#ANbZ>*eu<=P3G1Rc3S*DBoeJt?tdLR!sg2QYyo@7ML@# zKk?$jVY?zS8MJfHNF=yyK|GLGQlB&j#{Q*ua_EwC4SPJgV$jXYg2cf>DR^vKdI0a! z$I!QHAdCJxQ^Lme5uKQG41oaBXN%5SyhC+|JZV{Vab@^sK^ce5shecvT5b%@2SHQ* zB0TA=&inw49YZ~w=TNlHe4#iVt+OCSEK{43fIsw@N9=8_{vYlf!TsOy@o^H>j#0I% z2H7!WeDZt*++E%dj72X2nQiC0sUsJ#-gzbt)|o0_OZgb-bMlP(%I$84A&|+~j$5g) zLZYXX_U})W@2c`;@%C%x6o@Rw3OuLW{u=VI@!kn8ty&b(sxnc7JB=FJsfG;}1}I^t zdq0>GE9fBVW!9T@)AE{HI%nmzDK&FOrB$iA{ZGd`^o*+e=fEUFY?p?5^+j22#zlMb z-H=0D{3Pr9TcW<(Ro|qP`T%YR&z|`LQBM+oh_7 zZ2$Fmh8DCo%ShY)==_7nrTnDgHd!h_JY7P(RV+S&`uT=8}X!9j{ z639FR|G3^4YT-N>vW735eWV$VPLjGgT%DAJT6JT&^k7ary zgJQuhU%=l&jF8LdMrDIDUs@&Y7Aqng^XBFp_8y_h^%Ws=Z*rUUjD7CMpt5|SKYcY3 zQ$9g#9k9+fc-(`+yZlt0ipGj?LFvx&Q8~dA!Mx6xE*&L?JN@S96TsP)AIi@y#CA9I zfwrQz9Bp6?40G!5Qr|*bq`IhS5y~Z+0Y(``xjKU=NOmUqex9D=FVmN7@0o_VP?fA zIw=(?v_?8<+|sB3s^Qz{^Hz?>a6pL47rK4;=5A&4J78wmAO;i9&+-SMD(=Q6q=8Pol%S)YIzMj9 zS*G=!d;|y`8{sF1s#79(94m_Ukn@evRTQ7FS4kV)X?zl$y{Tj*-afoX*YJ{3{1XF} zjR^m>E&kaaTYP|5{9UiOOV(&JFNicw-GxB2sKlv#n*?F(2Pnl<&X_b9A6PN$;ko}J z-~Yqj+rU>_7#Z??7(!ukkR08S6oLoO%{Era)5siI%awd=F@B)Y7I3#xmRlX;RCM#hrK)8BsTC?x-u@!$0xS* zPXA8@H)57f3l~XH#8nL*R15w}KVQw~kO4jTG8X~^haj^maF$+h?QX1151t5R;F!CC zCX|6*98LB*Hqc7Z*X~^mpY{`KsG;ImKgfDYPkdHxyyX2z;Br5>i{R!Xz=a$pvp)ia z@SG+Pv-oLQZ%q*xICQye{DJxo6U&OJrZ|kgn|V^w8-v%SzYG53c$WEo4kxWZrLXP1 zc#`-jE`&eY-iyQqMPKqlJLy=-Q$`-IU=QHe?MbWv*B2RkT<95EoC_Z4zXl%xU~%A* zYp_HPxqmHnyV~CMPzT>JV}f_s&AAr1%o4148vJfPcXPh=92K-Ty#pwzKoD=gV5{_2Ji-Z6t*41Le06#m zB9wl=6IeN3G712D;?@cZG9LO;4Y&b6_CD^Wt_ZNrDxh9l@UY4C%EidFd$?R{n|!%)C!V@y)eED8m#GdZ*^3*J?_o7<>epbrjPdu}L-X=$m-dvgHlP#Z6$g8}RoJ8Zyqm zd+;|8>4zgc3V%~IWSoB-4efj;*#CIg(TH7emhFNVVfLo0rvNu7JLj+yLaW<=@1=Vl z=O~$7hbM8w6TTw)_F6P{9lKZ2WGtEe6iBd>CF{9T1Op{H*S7(77r`b&V1D(R$X@0& z|AI&9MJUa@GdhjInV8kaNo_C*#V+5J8>4zqsGxf2Br7>93M^$&cawX17ziSdE<~=)AK7%OL|@ev%K`A@Hm)?%D3lN_>mxP2%P@n2wdW+1aJ1If*tWM^O3h#|YFkx`4t72S^91yZ zbO(rMta!<@fEj$dyJlWm3DZ4JU+p~?;Swl4%kXzDbg`wd6FtXMf|r%xgy4qCn$WWV zC=!od)(c$r{Db{h4#HYF@MrWRV-M}c=9SI4M@Y->psTW@uaee&7KeCmK03S|)S30H z4C}9aU*eQkOY&-F?MR-67aIh4M-r!B=S~;k9m!)5-!8yAl82EX^NhpsT6!N|8pJuP z3Iqw*^UIY3H6_9M8tDagqe9#A&JGwQr%|sxxwocr=*f-meq#Mf+WbHy*&N+8?gq5L z(CY>F=M661y955<_CA)AS_XXO^yS%=pRh0}1lZ%i`s;1z=(BQI{ zN`LdG*9KnMRd8D$JaFXgD7b&e;IH07)`Qg1PdFDDy~GOgV3G@-e5>G*9XTyEaN5o; z@{cVR?puWWK?bg+pnQkTv8CYgzL59ek-SIpo+`Nik%7z5yyzc?BAAcArTDAWka7Mk z#-Cj;Q2z#?Lt$@KL(e1E{5Is`JmB|uO-<^pRnp?fKq2h{5ok)6V)`$9E5xT&uJMGPazMUS6Q?1y&Sk4+W6j>FNMPEAgm6d5U%!2gbRG{ggFQBGPGgCMB z3=Mu&vU*_VU=JY1NYgdd0x1_rvFXws$irx$7)7B@4B?*Bd92>za70=2fSk25z~T(D#>b~8rkl*z9Z*T zHDFl8gow+to5vq1l51yj4&qmT7wAD-fOH$b8vMaHq}%vc?=kUX;8h1M}3a- zQ<(K_wyTVCry5C_`RHHk;ZqKXbngmV7E)IL7M(#a;!F)-hT z{yMX^=hr-+tT*@5g1G3fVg{I#yA`Td64iPweTXUAl)9owwxRqUxyj*kwUkfLe*vvZ zggIA*b8R_R2W;p+!Rza1az21)c-oi$1~8I`;>VZG4VNc!s6Y7z2hD|F=`v7~0!uG9<|2V^G_ltP=PJjv=Gmzzt;42??$O&UtO?u zsGrV!jot1hkPv33YoEM&6>1~uP=?>O!3=PXyvJQ%+i0qJcQ&SH!!36fT;EN|v8nCw z9EF00&fn@4Q8y>@;D&qQooiKKnG~E+;#KGrcFsPSZXZl9IuYFy+s?5g7RM(K)~A=? z0oo%4Lsjlxj9P{S&#ts@(ACJ1fCx-_g3!+Wx|eyq$sBe5(FrUt_fvwYdXK@864{*l^YjNUMCtzhHLxCujD8_y zI5j-~39O#}3tCBOwMod0%|qx#*ueC}s+^zUAXF0>UKr3*sWU>_R?nyWC-eE1J0emVBj6hVuj@InSZlhSMk zp^LymtJ6mxk2G(j=z&b?ytED?7K(FSkM!?_@JjT=hH99gINQSWuAIfam``k;@h9M5 ztWoc#e>efzRneGntU>~yO99fiF!f|}2H=Xy+Jf)BRy+2RBKma3fH{L7tETS;h~0Z* z7o;q`%y?Vd^Sm4ph9MHV!!v;A+StaAhUf_qt7Q+#lgDuM+EDTwNLv>Jz-rVvxdxU0 zUz6Uew(gEZi8@#wYPH~jU5ogn2S6`S$qN7>YuNMN3YyFZZ!41 z_DMd+9&l`m0wzF$dHg<|i#!I}*m-($QwqCz#wvgeEWuM+THU%H94NgoZ(so)c>60X z|Gwb01qYNPh2@?o*ffuW(B|AL*sW&aeww+z@J_v-Xzri8OYe`wJq@-syB7{}7>mXhZ2Ap_0u~4$f}de@^SSUIeE8nVrFp6I zruGdyg=dmUVQMWN78Y#UMyNS+clUxLp#RVKH6rOfAOpwFUM4~eocU>T)gkN=n=t-? z-~-)E>OB{q>TtmM^5wXl`kc{Ux;K1s(irSg8hWH=)>9k)Ja9hJh;1!&dtz>FIg7-} z^OrwBhIQbfZCGB1r3weq$x)J>RmzE@ZJlq}*5PEMbDEUU0XH6`MD?PDl#U=~_WU;tjTk!v`=PNr%~;jg={ zCI>e@{i)!A^FFxdw^Hy`VN5xJk)tv)!zA&mR8bYkbA$E-JxLr z^l`|pcJmi1(zk&Z%pfu84#r+fpF$EtW>g!`Bu$=@%QM`uhK+UpCty2}qugm(y%afc zzeMgbuZSxyKoJifqq2@$N@VHX@Dt@7_5yIF0gl777H~c@*{KATG5wLvUO3+b_>3!% z9eFrh6%R=w*kwM2tf5!Q%_A(Q&)nGkKSt+1FGsY0o}rr=Q(94dm_&ZhEW}Q*s7Pi{ zg~@zOp;CtxTnJwbnChF!(og1~CObhaPL^5LYs_?+Jrx^(w}|B|Kq!G~&y$&=sg~KA=PM7wC-wJy9cC%4S;5SNSVJ|BAHdm8+;7sh@B>dz+Hsa%!-lYxiJYrpHomWE3SUI+dKB3c-?D?sbmu4$4U$c1TI;n}+ z-k}}cqH+G;6SvlK+^F4Z@qr$;SA=(Y-0`(M7#|LZ>W`e#s z9|GH9G4LGS^9>ZE_QhPbI~ur58yNl)llVY#NuYtpqrKU{1wFKXZ^L*yfULKnZd6KpRZT`pe0k!$)+Yt;_Lm@+fl_&vYh#AQ{ z-Smf`w8E=h~Aq{Jdf-Fjzt8^ z$%DtEjfIcqz|7_GG3^s&Qs~^bm$Og-Nf1%X;F4v4!M~7!T?kkR+^qE-oQEp5Ipd-Z zt#{1c$3iJF$AI%rK^idbqInXtHdx7||8;>{L)d-W^TJR+W-)Ls!b!LEA8=uYiI4Fy zaXm7qNI!f8Xg(i6p!xVDny6+7#ufBw?E8hCxdtop+*LmaJ32u+@iAOw2^ta|DDW`` z%arL!c6~(O;auN*wNQaGg`q-U>FV~cXOASgM%+!NMy)NCU?`dIU(2F5<0G2Qn4IJ5 zf%H05VCr*haV&xCO<&3U(0KA$z#Lx%&|27YxEb5AH=n;dU5U436QbRpy?Ojsmr=cY zaxsqj&w)WB;AjZI4`Pnmhw0`BP)(CeFqB3}01tf=Q4_MB4x^~T+&LUdS;%L+*Sh{$(rl+QG z<-m_&E|!M$@R#z^^GL6aSC(k29Vg_&3;~q(wupNum_{3Ed;veoHxt~Wc%Ij{3v(*jr_EG^U)ZG zxs>_Eno$4H?i~Xs4qVPU^+7NGW?#>a0d4`7yPJ4-zP{55LPc@JN<4=AL$ZyV_ z|24J?zQ>SH6JhYfzP{(u-34Y&!m|ai?`{|Dc>RzaT@59yp3Z-f@{;*r+ zQ3@vFg*E&q1#=r7pXGKeNm zs_UU6DEWZLr9bi~s*NbJM1p!RWS7c~V-p2c>hnu7XAYDynro)}@!aw`YsBTErjo;;8OFinSrbbZm)6G5fC zz1?Eo#7AWtuP6+qPPt(oRQmeD>vN{EOjJC*!D1uZZ8jeUqChVkUnp2&6G;Q;I^#3I z6y!J?sj{3u%=aDOz*el9Lu|{$rya^`6*ZD!~TVj;IX3w`ZLV<70D~O{#uiLyc0Sx7~)|7 zW6MwNQ0=T&(34-mc^jbM`!%KS*Ub7=>V(>{{4h+4O3$D?*eosp(yt#%8DsB$g*#B_ zQyzut7o)u{%QqCt{nM39w)U-GmkEWAN2Q&09HeEU+DB{Nnm09C)6GH8d)B8`Ir2bJ16w#HZ6e ztRIAVVfqV*RsD>V<_MJsfhOu6wa&*;A?-|Q5aabLOr?8Xgmn(){24c%iU*s=_ti=D zPhgf<+xsbW6sSV4ac%GW!^{_?U!*ro6QpXd`A9K(Cl9X+Mt?+X1dOIB0{YZ$zRu~!3v(&YK%y28p^HaG=q^^;$QzRAXI;1jUw9;n z8iam)u8`>cPYi=lWB)Z{a<33aak&@QHa9PGlb#z@KT9&vJDwV9+XkrJ8lx4 za-kQ!l|BztnvYK{CZlG9pZ^KKox!8iU&6pHXLt@C`V&wCbYJ^Cp@#4rmHa~ogPCxW z#fA8@x_MW(3!-Vp#D&tfhan&Cy<`_i-_3@`IU!Gg-X%y-7CDxm+qwh z{E{&vA9Q{{hs~0kUcxkQNV#I zt~bi{%W~Z!*RRU;Cb`}$*IVU!n_O>~D?bhzn!Hu6cgpo{xqeHo+vLhG6Ne_>BiHZB zb-P^emFs$a(!H`JLUS6T%VTfGji>h>vM8_Ual|5 zb(dUUlz9H8)<(ii3@8wFq8k+nkx$cqcTXKC{u6yOWPprMCD%{MwMed?mg@w$o*-9Ot`p@t zNv@~JwM4F`%C$_c<#Mf%D?fo9nmk>uXUKJ?TxZMmOu3#V*Gjq0lk0rBE|hDHT+fkf zom`j5wLz{+<+@z1pOfnfxn3yOi{*NWTvy3;wOpI!+9KChxn3&QHo3OTH7?hLT$6HL zC)ZB7ULn^Fa=luv-E#e+TsO(}I=Nmi*Bj(|qg=l%*DZ4Ws$6f9>&(>_ zQ?6U(dZ%3Pmg~3Vx=pU%k?TEj{VuMK)5^=h z*ha=~Vhjd(XW$0Le#%%kV=pkajaK*`l?DvEMTGMaIZ9t#>lUtp%-*F!m^8uQSFS@U0&(#xLAjkH&;*;9HD+hOyfj zt77b{jICtsdd5x2 zSUF=U#wIa#6Jwud>^qDVGWG~#hcNaUV;`W?wSLGLb+Xn8n7j|98T%|_uQGN%W6v|T zma(T8yNAW4jr%a7+cR6{y-PT z(D?Y(Z9e{wmqG(yHZ=Jagj-s#g1u<~C$bK;ewneC8M}+I=NP+(Z_>`&`VeEZ$+SMr z*nNz>#@Kfl`wL@R89SWs-pts^jNQoCRK{?|&roY6V>GF?HZX?ogoavIF@`0Zq1G5< z7c%w`W6&v48exfq1Ja8D`D)A!x1}yv7;H|w`#4E8OvvEI%AkM z4YgJ=wil{w>q^G>VR36GW4~qWCdPI#b{Av(g1Gfw#<>5xbq8ZVW~`sF?Tqba>|2cO zVeEFqgwVKvf8~c_<%gSY|KBg3=I`yZ1<2X+Fp?`xeE2KfCOI9+M5-z2S~p70>R7DJ zX`ILFx=5lU8f$l^m4CK;>gi6hHQM2>jWws*BJTQdhuaie8;5_hX167la2vXkt+94@ zaufeKjZG~r(ZRIIDf&ys`KlXH&)H7mHX=X3##j!)v1=2NWy80g_|4OqN@|(M3>VZS>G5> zMAt@>(RGo=WLG?59>w69Ba+BG2qzNZuFUN^IJ3*#8CqoSQ|+j}xn*VBBFRXj!o(7d zk}9RNq}rR39w2*NX_>l+fmgT}T9*vjUUx$}~|JWZO- z+1z>g`)<8Ay|PTAS7M95KzqZt7|#^v-Pxo}VN9|$lD9HNG0Bz`Pm+ABzKJ2SHr%O? zObiLl(UulGV?Sb`p(h4hGPYYhxue)^g}h?2JGps|n{17^9jSO6yaegR#~p4s5pk!M zxzozr>1FOrr~V|vgMRT*a%!pLo{FS;Nz0NXYvAf}T?Dy6y0~qT_BF{?rzM)`NaE2N zcWnxh)kt>ZCPTMLB$NS1FQf6q>+oiFN`peH#!R@kmn?5Y2&?n>_-lQcBtm znIa?L?07K`d*tc8ix+24ZZ0l!*SAKSTHQ!zQzX*dAzZgU+MH}ew1!>H(p8&Bc(w>`=;JrwMnRrXcSYBT4c6N5oDV7?L{$PD~ za{0813W!{cx0F-hQg97a5f>_9d9=N$E!7+;DV2^%Es`Y*2bk8-w#mwgj1v!Eo{Csb z&dSO3@%EUE*k}sncEA8l&{B9`%XLfE#}b!?6XdwrNNz6%2cxfKWhkgMr{ZnVrf?G7 z6kXNyZOHgoyD)JC!WRlJb5C{f>eai{Nkp1bqBmzmG*HSep*hkP;gEss9LjgMq@ojH zXDRQR9Tr(__3MP&5$>WmQo4c~k;_x)wCr~sruKZHNg5{F5nhvsL^^;*N2)F98v;El zI??uZ=vd8=6CQ|;H?C9Sc)S~SlOTdf0_m6?PMPbV&7D#Q3LEL$5*Ga*h^$UU(bh6U zu*$HJZ;41Um1uWSU@C$^Y)vXC6*w}ZbyU4JFZtwvH*i-twHP-j+;x2MFPHph)6$}l+bon$zQwhm)( z>sm{pX-YLhr^Ca=%4JPXB_a^}6x?B#$_b=qJ0xYeD~4ex3B4Snfl7we&=Z7;US3)+ zdEFaf(7upse_M>#%Q!-76xA*c79OKx{)PIZ!q}lKXNuBO#dE!?xUY&!^M` zX)qeZ+S|G^(vhPkV54Su^Y{RbR*X3wr;d?gP?R#YeagCUA{uUvHn}Cy@<@4R^aRzT z&C(-@AYH45O=CjTved1;kwIGP(loE{r|4f*km%U zVPK(>DE;43OH$0x5iFG@^!aFM5IVlC@e-+1jQ^8O3T4QofHF9VKF)w z*}@j{PHhdYzC5&Nc_b8`{nUTY&ADp>EdUq6OTSaEOoO%n0*g{H5IkPxv z1GI0>er+X;5ut-gIw#4P7L0fXi-B1=!)Og-3L;$2BFQ~|VV==4bh6CasSkU1br|&| zr9~NvB*Mv9LUR?}SG0DjgkpgJ>(Pv3XETnS)gVU^Hck}Al4uhJDRo3pshBfi_tave z3HXJheV2vLhU{!><4g(kT^((1j!8-3Q{7UC0^w8#iB=Ow zkqPKiQOx>KOQX#jD$@3;Dh?($n6fs)DhK+0fw_Z6MCFxXrGLfWd=o=5BR{${6Nt2w(e25V?eeCR235OJ^p z(9Y?eIoIvv1w(nJ@l-4EHJ{Z}v;hr^;&o3IY=NMa0cHeRv43YwP@FTcIgJQE(0k!{ zJQ9YWh_*Mwia}8h>CBfhsx}3Wk--_2*Dt3jmZ>bV&`9~3a;Q|D)YM=)$h^Sm1XQqO zxVZIDD~_Esw~KArsg$j< zq+}kmy)t)MK!#|pqC7I(etj36a@DkM|e2p4b~jm}NMa z}|Z2X`)PWAe%;>joZAj zcRq>*vPitK305?yQYEEk^n!w$5MhIf7%W|p$Xc2zRlTy+1sN#Bv>*grb0aXu-K3jH zVR{V>1dZV9&@}n*rDCdHtKzVok6u zK~tHXpAS8)8C7wRwXe>_(({UyGESx+N)O3iW5|Aw`V8KKI+&eBR^|#MdL^Y2*7isp zV_3&ZWl25EtZM)8&3-H!`#Pa##zBb~|DkC~vD7{>=o&MNuUB*I$aD*KMhvLNXyf<_ z!gC|HIb3yuaK_l8C}ots;SjPaq@fvevhy1@3r!X(VXUSpOA(_j#&F8kK09kE*J6as zjr8)@_cY1*G^^Mf(d=&}n_@^+e^SS6Z)w|KVi~as=X$hSRGyilUi*H?GiG-fow5qs0tsIw%X{L6m7JcVBd6_v46qoNHjV1_3c1X z7imT5V-h7z44VpQD4{TGpS`BZsm9ze5#a_2*d#5CnM$IW!d79ji)o;%r>jBLCso%# zJ#?b8GrK41Pl|4kJJ~@YV*vL}!1jV1bwiEtE;=b_%>^X05^RUxWEd+9@p5;$ZwJoW z=$h6fdIj1(j7*?k!;nGh*q1<4DN4-F9F#DyxH5dS)2=DXF&Yq>kuflXQ6Lmh0qPTu zL94?l=S{Wl^nt3Cy{S1>rqv@mF8mm#M@?(5ouZT(S1tYsZruR7H6 zOk8Z^a(uDtE!?XF#JE+dkuyVyV3oL|12Gs_NgtszBBB-97iG@@M2*#G%BUf5f+Lg5 zHEprguu_W^oT?11gj@_ai#$|L4XE%1wOeRl)cknQ76Y}-`Yh5oI10l!!CY;Ab}OzV&->^E3s0;8BoICZ~9vA;KllgY$vsM}od%Tz8{ zG)TxX(`Qn#71DJqJ0oqu?xt4Mow5P~3sp@-*BBE%%Cw@^nUkL{2KQ=@pymy2f(-RB z22f;)s1mMhb~?J&u8v_zfa3#+WmcSFS@gdpTaUoui_kL5j0QdoJ&^;6gE@xTo@FLz z)p&xz6`Kt}MQ_OBDjybs?T96FeCiUGXwco6wHF(M>(WWbPh(O}zHCLttWiIle861-&>XAnSIWk!sb}c+G}7VpY4Qw#nf~(G z8Pnw%0^9&vcB?TCEz@ka;*D(Ln(4&=XCERn8$}+vT}vLBjcb{xz9f(JEr}}zEKj$B zIkK~kZz4YiGbP1ta5Fb%kC`t)Yp46od+mlpeON;2$a?6!_) zzJ+C6)Jh;I+e5r=n$b9$b){Z3n(%6~Kn&Klpv4_VNzD|<`ACQCZ*_zDW`K%U5-YPQ z)8hd!c4sun1!wG!1%HPra4~pcyw42cjp*SqS@>~;yQEV%Ivd5tPE3)xfd(67>aReY znoj2B63SN0Brx6;n?0fKM59Jd#LQo}$J&`SYAGc^svsA;O;~k_#(0-wgiTzw6gS%0 zzC*)FW}5CpSL`WJDe6yxR$&KW71XM@nt_1**6ulJ0vWhNM`o*18PQ#!x)GM6qCYPg z98|JrZCPc#B@t4iE!-4oWPU)^OwB|CV)Y&Lb7-O5sSBcoA+;PMf4F(bHn}(aX9g*> zWfT=NhD~EjbXu^#gF9idy9UM_SZ5nWt{U};4P{mkGuo8m&6xtMF?hRJYE70a7N}yA zv#4HH-x^NKn&xR)U>w;zL$yN&A}Z08XJ+jztSX z#E40=r5d-Caom3lC~^v-x`C&|+0fD6aWZGt=HG1Uq*_5Sq2Ru}(d<%gL>)vk78O`@ zP|?&-@hP#EDcBtnvHRBjS~#_bpazb~F0^EfGi-b^hf&mK`?kPf%@e~0X8>hn9o0@` zNX=gPEw9r(>t{CkS?nx_d3y`Lj#xmgey9rs-Yw_;+2CF$1CIx1)@p08gM=OK(MI;I z(+*xmV$s>SS*#95!NS}1v(0LUeJwzp>g8zl`H_yM1ndgr0Lk_&ha;wA_Q6*h`60VV zZC#VGGInokoN-JUgb zeJ_)TjBysb2{SM8I|e9)l=&TIl=touUQ7mfdshZ=%^6)JvrEv?Dw`^LnFq`gp=NuwlHd(C56kY=fe(fBeM0ai7VPLYui35Q@l(@`=KX`ESYiw*cxPuF{^Sr zFKSs5C&OjR@q_R)7#O+Ll<*j9D=Q!X>55I5Hfp zpE}Bgp4wt9y`Esn(3UV(1-UHJg}tf3SM3-bj`R-GU@*-9LoX?VS{96F4H*I0zAu@n z-B7pJh%DxAyf}H*SVA#VMFU&()f#B_iO8tNt*)}6O@uV6O|~%mbd7-Jh8;*=nJMiD ztCJp`8R?n<&=5t!2yc9-giY9f+ET1S#mr2$S^r@GM4$_^`V%ukDuXF;=L%dqI}V36 ztW#l&zc=wVb9g&LleE7oOEc-u&Xcxy^C6rW+R(>HW=yEDC$a+{+-15*W|3bR9TpPq z&Vp3rq}X@yU%=&>GS$_QE#l32<9)pl5U0vytJs=G3IMX7xa7C zYMYgj+G5e=gx#d;d*&#^OlLVI6c43Y?@gu|a@bNARX6A=8j6#pHOdRB?rWOd;n1uF zsRGXpR*oWP#G`+m*QP*KhA~6tX2Sr9OgA7#zW9Vo_SP1dvS6i!Q537l-s*|GzBUZA zmutoXBbP9LfeBhM^aOQg70T0Yggtyp+;FP65xHi=MwjUcGpBG93PwQ3#H^J>9!)*N zOVwyr^6AsOWQ}Geqfd(Io|7wdPMKfQ(uMN6@V$=o?n;?tc{XDVla#C8Ts5=ES)vVs z?jK8Zon7ke_hx1iX9TDUF*R;eb&zafqbCQ9R7^)}D%s2ruCNC@6+tXYEoEf9x(5<@wIi<#qEL>#8pNyooKTzraKm)z#0ds?+59Y8zcrKYu~p zg5?V=bX|Sbd>BbuMYYCY&}b&8DA(+=cSt@nCl?LbF^U?eKbTMOfH`LZ{_usq!*99y zW5}ehIeYNQxHI0#-Hnf=w;tn+adCo0#c@u~?&F-?RVO$h*L8BXx=wEVB*%$QbaMMo zaU8b{&&r%J@hQ$&x7^8zpXQ8dnCj$qPjf-HKCNDqqc0v{S!n*(G&X`q? zI!@)|!1HmG|AaHPVyBbqJn4j-r<^g{pK_e-zi@IYo^e7A&!AqvLLSe9ey=+@dtP^P zyMK%H-+?v*$mFPD0+NghCZK z5v02Wd6(dMX~>CBL0&laprRr)cK5VU?v~S$@9Ck?s_CJe{^{2bH^zoU4;FLcFHC)8OODjfHTJRUz%hG*pE?QQt@9ly!;!}qGg3$Ghf zJ^qlz8$WU5A)9l*obwg3sxt|Hg&gA!Zqrm+EX@%ea_u@$c-MA3|)Cn#>_4Q{{tLbAwQdcLw5e87Y~8i`9%Yd13}Ht!Y|sG z!;`Xz$J2mwHySvejUqn_H%xnd0C?v*1AmEvdwBckI|(vqroz>Y0LSv{0Jlovcpi%U zZ218?uwEMgv;BHgex-rV@PXb-{Q( za9^-+Hb1R5>oWl~Y`DSX_sbw$pgvN6!0%D`4}cs4%^@9SqdD7#hR9u2}(8~$Q`Wq>QZ+2pr92+*!a?+!-!SEF09@rQCO;g(mksCRzq^^A!o3)5|8so&54eV}oBSYFv-1nka}rWN zApC6x{zL`$_+Re{Hwm<^QMh}9a0@eXtqyRz6>dead>_4&fa~O;BKZA2n4gdTZU&37r^5Og8u;U4R;&(-zd0O|3&-DtuiV$|Hr@|8m!+i z_*@M5-3ou(0pLmJ8v)<&4<`Tp=&bZ(J?{ftTH!Flo8KsOc?0kdZZr8d9t0ha!a+#s zdkp;QpnMM0lX%YueCPcJzAK22_6y?O2DttQ3|#mCcrf4F0blr#fq&D~G9w>-a{p1l z?NYci(dXqi3O(KieEMONFVBEF5d0*J{nzg>@KDFH;RF4O^;{14yhjZDcMgINH!*)6 z#)IGLgTUuL!0&v_z~6cRIuf5Z06+671OF^|L4KpqheuPDJZs?3M<2<84~+lP{(xWc zf`P9N;_s86ZGh|kwShZFv-SF$-ZMWQd9_pF?hWSWlQ$0mZq;v0emyq7F-=(m9`k#H z`6=8;@`iBZ@}aZ8X!1KPSgubl@pSB4Uovn!3r&6_(3AN#1AgBt27ZNt2kXstx)E>{ zuNt`5f^Y#oW4;doez(H&j57IIJe2Oz{(xJt+vI!c0q`aKQJ7;r$fKk1OC1FKe8A`N zBvt$dgLnk^h507|zw=E4?}9hwXYn3JzT8cGcx)?vXXgaqedF%afGhlW19w;u50w|B z+uMNKr*NTQ{d{zrFb?$ni^-4Yy~%F`JXxuJF4QMhjh;WWQ8JbxQ-o$s1*pE`iNB%YHn*Dj)OSNxiS`TEAC zI>4<`xc&Hdn0DO&_`;7&zLy2*>#slHRty=q^+C8gqkphoJXUQx4@AT7!62T2@tpPg z0PvL|1OIRk-dFx49D=q>;b6EhKg$O`xH`b~jWPKl>ufl^Ww}YfZBsZjh56b1^pi@s`P~P&qOpd~qt)YOz!e?@TnsL6KvCMCn_PrZ$I~DGjQQ)2ioaMjcMuB@9a1UyJqw(nk_~Y5CaQoQ{G=H}5 ze8A0A`i;haZGdwXu6Y#vZUS7Z!nKY9_YmN=E8J-9@dn_wDI7$<`3*zoabTt`3U~A< zaMJ;I{XxK847l!tfZGJPPKBF1O1by=@+%nuj&ksMAAX6Tyc%X4%7G1bSB~jV`^`gr z<3<_aDsm0nbX>c+ym&RFX3~*>@$xw`F{QY@TBW> zz_%V};5TWx9$kI&vWo%NuW-*FME!0AeE0Dt-)lz6_ddX-6>h)w8b(ik1Mm-?VDh~< zn6Hn&$Kit4i5po z?_`s2XE0yiIQ<6TiY6Jjk;Vn`!8i;qg$noB0rWz`p9%Qw#U|fh1lxBQInxIChEfCn z`5?Z&cDM;}*DKtI2aq$w<59rh3J)gyZ4BZu48Ok(_=DMt~p^1?^I=K)tV*TB6F9Y}r_ zZWwyxVDN0MH}G2zFdrkmrvrZG3Ikt!5cF#%{6z--?-d`rz&Z z+=B`?ntt^%;I=B<_F%a_d7T60wd7)h-)Q6a(mLSc~=I5i!1PF_6g}Y}IxcPv~ zyTs)8-5{K=9&LczqHv?t<0imeuW$>4`6-{Xz7GLzyTa84;e7q_4Z!VExR-)(!}PPG zCZPOAQ=hK~;q{*7p9wf;m4O?LZ<+y@*8D1Le#^4VRI+|}BjENZ+*}K{C>xIb?>@lg zX}PO{?HuUe#Pbcn&kP$p&ln+J!i_r~@>$`|vT&9!^qz3j0oSTqHzB= z2A}<%)n0yw)-&fFB87az`uJC z`oy>s(f%<5|J7hUee!oY;C3pU9bPmqGV2>Yz3^_ptx!1nTaw=>eDyrwJL!-Bzt_{8{MIWC{9Qr*^X0nA`ORZl}V{)oMAbvhf9oGj4JwziAe37&=V{+&;~(Z3H-}Kj13AWboT>J#82{ zbR*%fH}E6bH;CtbfSajsqv??^1Fk~hAPUTHnEK?LlF4tsalqHV$^f@j^Xm!b=Yv}g zxV#=yj~hmT+W@$@!i|>S-GJMraHHY(G~g<4Fy&r1O1WrGH;tJOug!7HxHv#TJh5Jen&aeLi&h0hzb%StvPkwm=a779?T7Ac{ zGb`LZ!TfyXP6yoe3b)F_ePRFpbTQ!i6mBFwU_aRexDq-Q!td-cnxUoNFyrcdfS>tg z13%il<7L3P3g=opZN7R>`s9>?J_^Ts`B^xXqxSK~;r}cOJQ_9w#WNc2((tz${z1dN z8alecBwxd$G(17W5)G$mc&3I6HEhuELJgZWY}c?;!!K%hqlPzYxK+dNXn3E7Khtoh zhRz0A`K^MSf=3_8dhp}j)u!MyhOuR4HFt}(C|79w`h2q zhIecDT@4@9@DUB4*6;-lcWd~24d2%ABMtMKO?{5kaDs-XXjq})Yz^mYxJ1Jh8m`u` zO~Z8>c58TphBs;WO%1ncc&~;JY52H?{TjZg;TszMNyB{_j)|ChjMMN_8oC;us^N4E z&(g3)!=)NttYM3WaSgA~aFd2#*6>yh@6_-f4e!^mPs67)d|ty>HB4*xmWCf_cu0$> zPoajN)^L)Bb^aGr*B8h%d0RT^HZVN%1ZHN0NKM>Kp|!xuE%t>N!Ad|ShhG|XG0 z{G;In4NuXqLc_Zi{<|7JsNrl)pReH(4OeKmTEjLC*J;?T;SCzzq~SL;+@|5Z8a|}q z;~MsB_@ahyX!s`$te?XdZMz0cDZeyaC5dcRZeyY>DBy~mRHu)h!K z$`L2u=6Kl}WM5uP8X&k1M$5Os-E74E#=}kxB1{D4}Ja} zeQxnbC@J^qb6Z~pcYd-zJjv!fs?RMg$4DzU&QpQswq2eLJh$}ujXt;KTKLxk&n^7# z^|{60!oL-GZsFh8=eAue{Ma@Vv(GL3IDO7k`^Wko8+dNvi}gA0`DgQ=5qNIl=j-zz z{!0VTEqqv?TRd(4vA}Z+f3-fhxLf!e0?#e{E&81I{Il?P2cBE_d-Zt`|Azz5E&MO^ zc@X~>1J5mdI`G`$^XI^G3;%xLxrNVJYht!s3x9avxrHwZJh$*C2A*4ZkZRPQ?H^X& zS@~n-jg@y+&R98T<%^YXR<2mNX61>MA68yi`C$9E?T5DC*?wmGmF-8i-`IX)`-N=> zOLt2*OD9Vg+h1(|u>HaEzvXw!-(|5|>v{Au~o@}K25%U_nCEdSW{x9x4^p_PAD zu30&D+nuHb`!(FB;b(Q+Du`;jPP~KdJwem=U=4`BVESpAUZDoBV0xuZ$6CU0@7LS% zHQmZ#1MN5~HGK4c1^zM^}Pyd>xSAJ&r^ncLwz7f)YsOkOX!@vJy zO|Lj@`1FT0y?cc8oto~bL5=;}|LfQE$`R6kt?BqiRer(uU)A(JO%Jx;pv`}}c|VxG zPtyx$44)oS{fFPj@;BB5-Zf9tWt#3TH0izjS8y)BVgM=GBmrUwlRW=>>X#SNaW#dzkc_k}W zIU)P~?!bK(@PETib}cdpoTwl01?#otl#$-Zy!&4f`&;{i#c9$0k?#)F4kN!gdP?h?2Unlb zbNSm-N5W#Aw!_Ro5%JoQ-pB^5IOpKtvfmo{?)~8SaIVR}vhHsyXV1U>ZSRka@n4rR z5*B~ZcBl+w*Y`KpJCNN$-v-;EZ}CW&A9R)i_&>cr9Dj$YXKYq&=@q-@dq?HanDH}4gG z-yq=XMv3kEyy6b?d{37NyB8Yxeof!4;g$={^F12&S8Kl4=zABL`@WSX?ALIDeuzEM z`ykuE+pA5#cZBq*y(YgiG~9TNxevZyr|B1HXww^74SYnyrSs=G7c8CURM*UN7A>FW zEUlj>pxL?Fw;iYJMw8N?c_gulp9UWMKe`=UkgacR|Jh$x@bDKIF_UBBx#lQbUlha7{ zvC1Kn{%y@aXy0m()fMbH*YtkP-`0P3$neb%HNEhkP5Cx`&lr>bu%^d~pIQG3mSX{oTLG&c8d)q`z#-e=$3K>o}ACdz=1}Nw@TK3rzZ7 zG`(NbZTq-|Cf(X^x4xYHe#H?ceI)zoR!z6|-L0==zh8Kid4DAP>Q+rRZ;gEY-pz`! z+T#i}to#q!!|Le10p|tNT`}C6(Ag8t*yJ(T#i!upRvt16=Se(G77hpVrse zoTSTgu`{4*0I8JMlg>@$FZLs zNN(%ON6p~?Rs0aN!*>@*<-I|-LO4J<5$@^$&ZqB(v!28ctS8drz{C+zCFX=^&i76S zMb5^Nf#=T2ENGbXK?Q%fo=GL(X(rrekCl~kj)Ac8#iR$7+Y_40^K0ol9jQEk8I|B6 zqbQX@*sYc$>CJKXaMx&@GFs=krf6ZxDtItcmmcM=TV>8=#R=D_fhK@L>g>&{jB-@9 z9O#}PD%B-_s~j+H*%7wJipo;3@k7D95;!VcVtF~jO$|R*(iVr zTB%-~UXp6|Ol9$^u$LA@S~ldi!A%RwryJVSnA ziG1&Xdbc>9?Rf>>;f;&9wPCsdbmNKGI&@43BKSIi|B_}nPj8}6xmY59T{P^+y%Z(Z zien7;Ju~O{dxdLd?E(34PA?9}@-Kt4Q+5=1;3L!FNMUg^kC4smy{^cZDyaJ~!v{Qy zn1o&ic?mx}6q4*T^o=|_BkIU}>QO*Bh_q{VtMkoy=5V|c1r}G}k(^)5yp0$t?uexl zO_5@yrn$o@!uc!#;MPF_4mLsQB5CuK-GE$iLD0H(EpT_ zFUKdVj~aGo@uiidM?jLKjPBebaPX3hd4fp_wq7>Cht?yn&0o49PZxGe;9006x*APr z4r0$&SBu7BmiVgy>(;?PiS!dQT(F(HK(lC*hq338O8lOizG|ri&v(t?M00+%2dx5* zeoRQUF7ahaPN%O9^#3I>xKop%$TBlVBy>~K4z7m5^l&S#)DbVkbYNFfioR^TjpxI| z%VhwN_UFO&(WVsnLF-@UUYdgI_qHemP_^5Nv)|EHu~@t*?xj00fthiup?n!w*a(1I@EcrG;hKphlF? z{em*8VM8N{@=Z6gUL2)2*|Xw_sdv;lj>2w%gCbNgLswxRFfI?jUmKxoLX?IcjuYzP zoy^dIPXCe^!jwOvbQuIF(4Bs^qW=QHKf=!?+oLm2~(@ z9@Uou!Yk4V#>qE2mWn^qm-f$w-b^~+Jx_E7h{6)qe?7!)#ErCdM5ybqc_E9}B*JSc zXBVO;)8zu1um!GJjbkSIvrDysn$p>u65)9 zz`@@Y82HKhlmafYih>D5*&`vCTxJ*-A`lwW8oJhEO2A*Oak@$}!b@(VtqYV}28uy0 z2y>G4^TDAFT@6fv9+rfAA2aqWg63siqkHY9B)cpUi32eXTltAtYE3H`U2*nQJfk{6 zp)p6>dkvvX>a~X|e5fls2J2u{J}P@0>b=fx#$$N%iL}9kZoa-J>Vxr}be8rs)}+NP z_B$yPB}ya-^rfUBY(6kdgi+&8kp$s5{BJe8CCCtCWrW_XsE*LttT>#A!doji*C5vc z&KFr4&bMQZD9WOz7N1&7zJ$B#jAK!My>xh-l8j9;RU~cb`%GNNmRR{;Mt_NLGY60J z-r@W>A)l_jP{YMU42S+VK_hGH0>9bUI40;g33OSmk;o#YA>XO4h3(*u5{i}iOdA`| zFce3b{FoiQ1dD?bWXT@yF$4xO7NOn<@|gyX#>~fHQbCk{1v6Z|2(8W9VXm5zeu{3ZIuZECIJgC+W$4!D z#yN1w#LmvniKfxAC%eTMmCKQc_H1zx3Wrf1KptkhT11tWqikU;Gj0MyTSH(GK6ugqy`87AF-yW(1BQ4m`wFmzc-=-ML-%s zS5S{h zA@^mboW@v-`qu04J&}2T2fjSZ{!zmOOVjst2}O083*Xsz4X!U@agNBo*{YFXMyCW6 zsmNE*oORTv*zB1J8Rebi3K78+eHm&R#z*S$C^69%j?c*ti~k|jRG~{jFs+WTDcD}a z=GzqSDk&uw0gGaziLl+ebU=ffP;cgMX3R*^Ih?9Srfo5gVg(K=3zuGf!gSl5m6NJs z%6T%u2U$S7t}@J9A+^!0;kNZKK~UN1fHY`k|CQkZH8{Urs%TW4wUK0NtQn0a{DCft z>0g`<2AM@$cDcx;sVzmfg!#-%?FH-=#?`YidrX-!g&G(rYSfD67+Vy~tQkWIY{zIF zaHihj zd%o0Xw!3N-^p29^74E6UrK?tvEc703w1X8=`Ai?u@r7&}O_rH%4&Jj_(4E+Rc}Ou7 z9qsOlV#(GDd6L#(fo^I%orwrc+KDned0mD^j&*QWYz9SJ2OT8Q?$u!1&#U$vZtE~& z$irwQ_@$jV0cBe?6l?TaVimRxMzKLZ=Z77&wljiJizAz0fKZMlnQI zW-7(U7zM>8XJ!Z|qO&^A=-E z&_^=UKowhzrrXBODl!0QK~&_MdZ1Dl7;Tg8nQ5y8vzS?v)o|Q3LF zP>S;^mZCF5Olk6EO5-O$)-(a{=x~Er#u#EKEb}||+SQSKp`DmW#6rRWCJL*Y>(1kF z2F^@j@}QoDQM%~slt$YAb}B;-^HC~$o>AsT%AuBEbOjr7tVbzEiHG>|$p(%jON~1? z_=m)NLU}fZi30ok#E#> z?l4)aFHo?omY<(p&OFe~_5qb?I&gTnlkYt{T6M;RW3bE=P1A@lb~_#6kpLOGdYHj{ z+~Tfgp_U$$!I}veLkujYdw9JXK5tpge7;K8>%)2%7Bw0^jL9+!A+szh8TQHdx)MZ& zEggtKTT0Qoh8H0S!k$}ZxG%<2&M>HS;RePM40d9M(urH?9MfOdqaEC8s!C=q+lF`1 zeipM+avhT>C~@I7UC9w8 z6oru}qWkZ+Ame*qMnA~}wwp*I+JxZ;QwA6M8#)~)b3@}62YKcZe7ad%tS;Y3H>V{Z77^)W**Xu`t=O2f zuEBz&Hf2#9xdLVu@6hh~^rtul=~yX}nTaV6xi1Gh89;P5MU3W%c8q|TX`)PvC6i21 zMr)=ARB(6k+HfZ{4QR<8CW3lq8H)W$bt52z`ICJ^B@Ks0bQ0+EqOhpIIZ(ydv%E&k zNNi=p0g~ott2Q#B7X4JYkgS@rHhxGzj)q)r82?Iyax&DcT;I(UIVQ#^SIJ3m!JV@$YCQI6<mG94+5)|u5~=o6N`0M2CCN$|gY5ncZ$Q$>d7Dj2aG!L;>p{rj@B0rDF8KByeXs9dvQvWJ(QNtG?DPZO zRTP>1AqRpBrWXYt{1@M+zhdaV5W=>5MP0511yrkuhFqnBs%`-Z~Xa%}j3 zK7VM0bc?TrxB0z20(?mKQ+-0iadv-|W^j?-Hz?j?ZN?gAhEt43-1pHQ!|oMmVy8iB zGm(1)U_H05{ZRAUq2W^+KC9u28V+c$sDFL{7dcP$AR~vv^rT2R#W#bnKz+I*H6_c~!HU;3muJ`c(+?@fqAL{+~ z0NjrPaF5&jz;|`Ow9l1*ujqY40PbG{aF*T&3a9J$eTOJup@!MDcbr)Y_eo8+<601| zQsHd5?g;tS2H+-+0C%3k9jfV*Mu5}D2MqdW7>svoc)%A91n}7)1rGE=b~^kl%Y!|$ zOjtSlZ_6(`_y4>*_e_IVT*H11t$e9iWYUB3r9i*a+A>1=fiSe?I{JN`EjPY&csh0K z^FEutO!3xmr1G{dH*hxW3*7J4`{4V*8N)>|*auhU9I} zQG>4-raUW@F@karjG0EM!PXej%p$XyQDuw>%Q1@C`I)SN%``SJRrerK%v={+ioFN&syuQzv&ZB_hICr_uu)o? z%6^{`{H`R}jvwEDOo5Ln@G%8GrohJ(_?QA8Q{ZC?d`y9lDey4`{<|q~#7SGmuKGr( zsyjC?UerCUFkZ20*1V;E+rQd)Vcd;hABt}eNo>W^`SHB?R^B`qif@yLORJVuEnR@e zc^0aWZ`^9%SY)Ezp?IZ<;WfMr{NhEp<}F_wU$N?V;JJ($EyN>$mLNC&)iC#i{}*?c zSEQ?ug&VI}T8$jGhL*Ap{bQC^FRNN!wX~W9iRZDfr8O%IaTYFJxU>q-4(_j_JI4iD zHSw9tDz=2qpSN`3@_Eav&#%}%cB$cjvnm@Ky5?bKU&VF##^u;=;GB24vxSeV7pB@V zbB?u}$MS4JXHz4-zDz{1xhW$1iVQ5Dn~&py58Im~oq=cPM!Et|eEXC#`7Mbhk!2gU zreogQ9C)LCS?~e2Y_wo=Rp9Yb?g&^LM0HsgmIl`bKw0^~qw}%V`GRnQAN6GL`W!cO z_y8A1+af*^EyPD)N#A{KyZ^2Z>z2O6#j$35(&BqiFMDem7h*S*(|vup5M7@ws&1Sg zX~WY)wr(rPO5m5R(I)IsXVW;{dtNh6J%&PkW4gy~-CD2}*DZ%^?OWo1YZ*SYsKo-Q z)4gk(g_rbY_{>RB>VEL?>?HYo*N5(MZs_*kgNDA_^UdnF?@1%6Wyn82B46VzXvYG% z5;%()BWvTyE^hf|Vs{>JL-KNL7!NluOTu2$Se?Qa02o9}N+b7^ElVa+O};074$4kj zo=63tFT_4j3v)zeBTQh8+=|fH97|z;w9{RPa=eFNwXl@qJ>i#~3hD>c?YczL1I4b5 zAGd#V4(Iz~BQ5MfKI`gh(&xS5yEEszp<++i)hqCr_8wW|w!X6UylwE=MIRn+tLvBB z2I;i}%KX}SKjbj*-A!M+ZY+$nn!j9=Nm>&UIYUWJa ztg73-2y7d(7+Z7Ab{M%M+V(@}X@kdzXWHAW3C#+&E3=(DQm>BoyP~x-tDRx&WokPc zUEDuu@8-CC@6No}R?LdXJAuu;TM6Ty%;^u zfJ@5m1t~jtY^!JH4fYO(y~YJ=W3k)lD6wrgG*qze$XR{0gT0xvXWR0|%#M?iueB{2 z?V+sFI(tstH;``g>zIK?Fl@> z($4I|t|a$HeqpxUZu)op702UIm>^4y1KrNDBi478Yy<7cOc%Rn>yb>8M&Hp|JveB) z*G?7gO%wRv82e}Sy5+srPmK-Oxo34f*qJ+XUKS;yn)XJXKh{_lVBIyxs(!TvTwNP> zhiW??2+jQ!mHy2eDnq`Z%Xz!bp~c+ES=l`_`<~c-sXb}ycJNH>bJ=+6w>R&X?^9Z= zv-|S5`sww@Wps~d5FK!$=a?f$6bZns=v6t(XnnyF|ae=+??ehZyiJk8GLf><4`)W(rO7RlrL2(fOwchtVE zfLu2Ya=VPVRb*1PjTc2yuj!mu&3E%s-(B=|7b!s>s2$nUCU$q|!RELV+Io2)?Fo(AGBY&dqTzgh z{H#V*kG47uHW;xH}dl7vNao5TBTXNam~7Q+0JVm?DkF= z278x`sCW1frM31X{wOb4?VzF+2aZ4YonFGVfi;Ejv1=@AluGV_YzQPK@9PLOJ#xjEkhw0A3sf&w92ip9$yxxaToDtJ>TB z{!lu^N$OSW7f%l1!U@71w5AtR_<{{Qn)0aGYoH2!Ba8!+6I)${YJu>KpRZp#frF!E ze0K*iOnXlAw9B)-OXzk*+oOHz1%Y=T!s}hc2SY~&`vgI?WN);>xF>J4l-MnsL1aU| zXb8C1F|Pj%W&zfJWCkU;WqYY?g9yH1+7)_PyrHZOzxrg2ncFS&nd=Y-r(F7b zi1rvcvN}T?r+6=U(%wdMo5k^Vd%JTS8#n1H;U&{j8Dj)^>B`<_NuISZY1y2!SXw7d zcefT48w*-p?XKp6nXdLT8ePo;`g$9Si>(EHjjm2tW5LXl&cRrl26fFWoL*39ceNMJ zc1<7DUOZ#6*21<6X5xjjOJ=*;2Xq!rcTF#zUC=tHb=b_oodwnQ!e*BV7Bm<4&2+UE zHWxP*&n|3rHx6npXfA3lY%FMFe6@36b*5|92A3>;i?`brJSNjvP$+cUKl|J6>aJGZ zYEMsNq2={(lP>K+`c=!_!a{q|%%Y}cvT2q+>1NgdeRw2aIi z+&H1}^yvdyT|M2?UEMuBJ%#3imX&e3tI*qPc{E#bWhEnN%t0edJ6>`6>Ti+E*7h{-3m5bn*FoV zS@?pb-`DJFFX}ENO`C`2lw?tIegMR`)Sl-%%6?C==jjm7-S#{ke)rgS ze_>yJSdv(h>GJl7-)B6uuq(OsFMn_q0^w<}W%j4V2Odv2JW25AsQ4`7>(khhBYiQ#Ltns(E%<>xWau>y)jOycBRup)b6BJ= zI?Bqgd8$4_y;yoD4D=x*{T|L!b%*r9yjDoR6{Ls!hYWp(;X5jSq;E(1kfGN+SPxJy zHZNEHZmigXAEX~L^sNGXljJe##pdPoGw`$p4E+qi7BKXU;~gdkbX)j<;g9mS`Cuy; z`jDa5JX_DBUMzjXbXcTsILgx3JX~i|FP6TW56nv+GSb&PT^CRE%-tDAw#cu#okQ47~xSL`pjXGzRyvxKTq?9cTpeCLk4{#2#@qbcKPSLWFJ)i zgL%rJ??n2Lq1U`+w^1)v{$0i`4&^^&r{}z8UzDDFxAFB%8$XJ#Z;>}DzK{{0=0UrU z@rkAHU7Xj4487(_dysnZW4|Xq4If=vzK{`LvFHOF@-%`>7Xy zIV#V$B3Asc!Hxuwn~-pbr`P=}Vn=@<-H*5#H@z@15$~0YhKC%p1<4 zUM#&6S`aYO583H2_xf|CC%?-0dhg}_D!#D&M0_D5zRoMWXpHfRr4Rcj(1#3tbI|K= zpk6F}11q-R2l|kq?;djA$-Ai+BRsZeb&>a%K4j<{*LeR=Q!kc2JU)1^xd!b{x7FqjPOXmFX|7341M*_y?%&#vGl!Iu?0U!KV<0JZ*bnp>!=qa zJksaxO!Xl{-(%OoSl&s!So$_rY{3uG4;gyRBlEY^ixD2_H_c&@K4j<{Z}k3Opf;Jw|f0y&$RFX zOW)_c)AU1zzDfOw)QhE`iS!{uU*!fphkCK}Ev(prALKt|=)2$Mypt=b7bE<9%HMj2 z*Vm~ROWz2#7t#+I=@l@UIrJu!$E%<>xWS9S&oOg1Q@=un&5RG?)41Ldgz5Z{g z7fat*4yxx=9hX2 z^i2e^`YvGkqj{2Ma#nkVa8>c!HB`CV_ukfCpU z(x-m|^8n_=1wStRfT7oXskc%uMlkIEMi3tQkfHCr)dJaa zC-q|K+s-#jKV;~;Z}S0uNWFNz`VRH~ru>to505wGKV+mo^J$;{5zq4VU!3Zr{C5Wo z{VeszQ!k#cKH23XJe7L!eD&SbpH01ZzWM_7=TR?~z7Uib+b?94zexR`QZJsbzK{A> zQ!k#czCry6_2T*JThvccFP7dNIJOPID1XQ(f9rO$+46en$A3!`ZmMAg?jOP z^)uAJn|iVIVSPpZLq__u)bFHTEPa??=tG9S`!l|Pw^A>bK1^?4=@+Q~BK2bF!}Ru* zev$fbQZJsbzK{BQsTa>z-=O{>>c!Ikq4GDW|0VTe>Dzwuru8pmZ2#WR`Tz@$^zD~e z`ahI@ANAeTi>0qd>4%K;JJcUTy?DO*;^%w{WSGe>c#Wbcc{OPda?99(e?`&+b`j~luhcz^VMr!%lA?* zmcD@%TkwPJ7c$b(>u+7$k6wE%j;jN@{^@+V8s^vApapluX#5wpk9pd*!~4`SisO10Jeak*Swln zQ7;}g4(sP@BZeOF7o+RHkP*M;<$OEi7fat4=|hHI^LG9X^gB4rw1AWNQYhKSgsTU(W${(h;uk@?mw?MXhP5CEF?-DkDF!UiK{pt_QX3Krj zlcn!-zL`E`=rwQX!_qou2cG9{6m3d~2Rj>8GRo zhYWr1{XW1ms25A0MAyF|JN*M*f2{Om=^Ih{Aw%C`_!m(xmc9__Lxz5q`ZK5(OCMgZ zuQy}J(CfRM=TI+B^;oe5KTaPo^!l#nCDe-%4E49q92V*O9C?O*_CarWwenAvz8H;P zg$#Yqtk-X)UMzh$-h=#y41N0%uYaq`PnNzB?f;OW*Y`L-M7>!0-k`ilKV<0j-O$fd zFP6R;=|hIT@Jk=yE7Xgn@4<>K_(A$1L*M%==bhX`y%^!K|EkgWeaO(apY-|%s25A$ zu=^@lz(_x2=!=KLCrKWmUJNVJPon2_LUww7uk$JC$N(1-gQ>4yw`p@5i^Wa)E#{TIVJAAN`V0`+3)3y9nnFw!poYyl(v zS?X6%FNQzT?=^=741LJZ7mtTelB}g(4C{RKP3o_tUM&3#BDV#M^k)FJfRVnw+q#K* zG5nE!%N!Ok^euobVCeNd*R9lx;SYVcIV@o4Lxx`8d3^)*V(ELFI@5;?y}tkYF6zb7 z7bAVh&^P&A*bh-Jmc9=ww%`Z(4;gxWFLoF8VuVNei{`LMUv%UddVNRsF6zbe)$9AR zd#D%BS3k|~&i;gYvGlz`eo_9Ak^h9>nf*2O;`!=(sb6}uZ7;-6mOk8GNIztx-(>g# z_2T*JJJk13FP1(m@4m`kI0+$>(07m*DL*I8Q ze3Ik}>cz04{)PQN=tG8nh8?V7>c!HB{V(W4hQ50xLMF*p>c!F*qW(+B(D(2=yKkgk zEPczxo^8L7q1X3%-$lJx`tC>{GW7b+?|W5#=12MhR&2q~dixVH^vRh%z{jW;!;0%CKb$k6NizMrLDEPX4|hYY>G3;Y%8#nSg$9So*$5AF|6ozf=4)>h=9# z>3gI48?wuP5h1M{)ECIo&pO{M{~<%)z1r(frCuz3c)YDQW601K&++>6s25A$^xg@6 zpbr`P&Ke)!DwUrME9!6f{1@~gL*H2I_1mczr~0V;(*Z-T??V4I^bm0S6`+6tJI67Z@SpC{U5SRpWm(ifzl^SALbY34;lI@ z!#}F@BYitcKV;~8E<{Rp*=q02xaXnBuwwtWy?0uFLWX|!MdY@Ck^hjP zFJ1(nBsqh6F|6+V<$N=JBVg#;)L%%wSbCSRX~0N7WT(Fv#w2-_^knJ7{6Zfx^xZDf zB$=RIEPc_%o~0i$^u5$yN4;43o=6`u^bP9YM!onw#@ADeAH^5uAJUK!Ux)F1obidJ zFECCpf`$zJEcLfiFGhIm&oKPH^xc;rWRiT5da?9j`JoRP=@+TLn|iVI(^#746%1@rJ zzUOkE{wC_h^VPSh-$uQ7zWUxPeEK`67tdEeL;a1^i|4DaUg^`{NxfM5?r8gmjP2i` zei!xP`Rbe0@1|ZXeIZIeWTZb${r%L7rLRW%kfASJg^)?|DD`6Ln~^?bmp=7}6#Vf& zO_tuwZUL{iKLwBOc!0jc@W+}5+7Gd&5U#`_nXs1q^-2&^KNQpCqXjyj~0|^u_4@ZphHL zU+wkRQ!kdj+v30iM*1N`-=Y5If=^#8y_wx2eaO(yQh%FyVE>7wM;Wk4FTT5ALqUs@ zUC)n@XUT^g@BKSJ@cupI>V2Nqf|uI%C0|AEJmCEY$XEW8=Q?@j z$DSMHP5&%?IF*fA}2rbd?$IwPd$H&-2F4pKO(n&?s=BnnDxByc|QLw z^0UZo^2y{G@{7sIBVK1g@=@fsk&h<7pIji{PJSWz@5s}S`t&;DUwFQc zocz-Bto(oFx$F79d_9kQK7!o&wda%M|Agl=$TQ@%v=P|_>|`cxi?vW z>Xp2iJk#a*J>=O1oDi#koyks{1CaZ#Pcu7t)-q1wTh1VSUBAC@nSyU ze;T>xY2JSgxkcVc?tZ5CFUy}?7eCAUzmBYVCErM{a-PYX$&WwVhrfkfc#h}Ya*_Nda+UmEa+~~dg+JQIcPF_) zzK7g*toQ$Ca_@1Te@Wg^@Vw+i9)IK`$;t8F{}l332+kuQ{<{0egM`Cfl5_)t54 zkl#YyM826^C4Y?EeS+8DMm~ysKe<4Di2OqGW8@z4l9PP;XOW*pE|OnB?j^4!cP{kl z50m$hw~}Ybe@5O*{wwk<8As)yKQ!I(c#HWTW~}dze1WX*iQGfh_dy;K+jR<-C!{AY zeW8y}-{Uxr+$y->$qF*sc`O%`_5F(hvc6|gC+qtZ|BI~eP5c>I-;a1JS>J#7YqGxQ z@P4ws&+rMdzPE6P!k_N*_YJbXhwy#zD)0Yevc6C7GqS!n@C3P7^x>EMk>5Ug|Nls` z-seA&toQTJQ1~@oUnJ}O`SZzoAO143-fzE#toPHmlJ&m%^<=$2{sFSy_r9I1_qV@B z*8ABHkoA7`BV@fVot*5;tM{LmiZA!&c>!7PBfpfa_lq}>^}g^pS?~W|N7nni?eKrQS?|x@L)QDSKP2n@)`!V@Uv;2G+$a>#%GgwU>Dll4C2ePq4Q_-pB#K7WUw!u<06!;{H+fACDQ-UsYe_?x`` zDss_t6%f>hr7j%MK^&eX$pk_5RmO z$$Fpb3bNkM8YSy}t8HYxKlLth_ia8uA5nPn-DJJ5w1=$skA6%}c6t3QS?>ouNiNWT z$ueKQBKeu*K5~KFAfG~RkF@CA)#d*M&p5B({HW*C-z>h%`@fs4=f!tQ{|)cIi>&9l zzasvo_wSJPy!Cx#Jx~1*S3QTM$$Gx{M6#Y2UPadPzb{kx@B930 z5dXmQ09nu5R>^vP_O;^seE1z?J>U9v@dMt!MedM4LY^gmnylwTzeLvap5IpZ2Yq}$ zCF^<2MJu?!_&9RK1$Z}PoF32d8V(E^?cI3_04#)rS3tozMRk#+z0;4`?t z&-dYweku$h!ZvQsH}jdPTDCPraP1`%RaUb^qvUvhD|M zmY(-}wv$`De{zHL=4YKY>+)vj1g`bgizulQrJ@=VXny-V9!vjkn%H)_ChKvc_A# zO4fMmcgY%W{SjH?t&fp4-n!&$pPt5Bk0fin^(3;!ThAhEymc*EZ8pW~^cWR15r z$Qo~Lk~QA?0kXzhKTFnl>$k}oZ{17Qcvs1 z<+9st@zpnxHQstNS>vrAlm559J-Cys@z(E>HQxFovc_8CWvX&G7LtuG^My!9fo##_r|jkj(UbG-F0$Qp0GNqUaAeweKB*4yRJ z@z$@3Io|pYWR17ZkTu@=C|TpJi(l%?tMS%j$r^7xgRJq^wPcOAzM8D@)+w^aTmO=* z@zxeux;-5Z+!__!W0iw=Vb-A710FOUW8< zJ)Nxa)|Zhr-g+TfYdHQqW()_Ch{$Qp0GnXK{F&yzLY`gO9#TmO-)@z#gQ8gIo> zgjbLBed!~N4S$Dg1uQl^oMUT_a@-s7K*W;~zaiqABK}0gUyk^D5kDO9V#|D(|7S#8 zh`1->V#MfH+5dEV;4~fbP{dmzesjb(Mf|~tZ;klt5r048y%FQKm;F!ki`z^gpBV9~ zh|i1o(ugY&Z;AN&h;NMe6A|AT@%JMB*NC5tcwaGe1F6bNBrxE z4_=%v-;oiY9PxP(4@SHt;x|NmbHuks{OySUCE`aTP7cWD|Jf0r8u3db?v42Bh{qy+ zQ^fC!_)`)8UBusw_$LuBIxt_JV9MSOq6k3{@b z#D^})mk-|o43DofBEB%f_ohAHIjr`vc@y8?H9r1S~ zek|f{yEYE%&+{TaGvc)oUmfve#5Y9z&WLY`_zMw#({s8#_C)+Z#1BXOWW>0ZxALa( z9Ut*25x+R%)e*0YctgamjJO=}HJ&X?ewmE;x`^Kq@dqNlHR7*Dd~d`LNBp~p54URz z%Uqhj<09^fcy+`ZA|8nNTF>eJcumBOh<8NXjQGZgTM>Ua;!j5W>4@)+cqZasMEu)` z7ax|dZ-+*FM8wBNd{V?c5r5Rq=N~ioadV$AH*M}y=Khblzcq*c!ENR~ZElyj+s%E( z+-J>w&fMqC-C^zv=Gx}&H1|bwe`oGX=Duw1E9UMpx7*xT&3(<>-j{r&7mLipt-%~9y0f@=6+)Cr{*3u_j7Zz<{mNkZ{{8|_X~5s zH1{iWkDL3ox!;(3!rYVQerxV`=AJUwW&MB!<`$Y;WNxv!1I!(0Zi%^r%pGj*5OYh- z9cu0{bBCMjHup4hPdE1rbI&w)gt;Tlp+EE-bI&z*w7Fx<9c%75bH|%|p1J3ndx5zV z%$;cNBy%q`_ebVVHuoZP=tnIxx7^$cb1TiAZf=#iv&@}s?j`2Xzxrcye`4-s=8ERd zF}KFt1?JY7yU^Ur&0S>f5_9N-{i(SP<~EwU)ZAs}E;o0Dxhu^LnHx5@$=ry!Ys_sn zH);-jv~hD2=BnndHCHoNH#cc+%G?%nTg`1VcZ+TBPnttt^B>H8$J{;UzH9D#=JuHT zM|0md_XBhHn!C^3{pM!O{j<5BnL}R`{m-M!70jJtuE*SI=FTv8rnwiJTW#)KbLW{` zYwmn=7n@se?kaPyF!xGxuQK;)bLfMX%=MY;H#cCeY;Mq8#oTstwiNdtJNu8F|L$X_ zknCd~KARE~v%6;V(!&r!_Q}fXTCIP3=~7GrYL<95`kW~Z#CbEb ziRlrHMoj&w*^yzk2^WK@=wX>V2Yq0LJe_>r?7^(_DPg*Kf##VPYjRbwn^|6fxi+(P zn@e6`vj@9r=_BSGr>Pb5*&1N>^fj0nS)hsH>6cE=t{LKK_fx|Q{Or0U%UP;Ytm`!k zyuv_{pZ=Xb>Ade`P54f<(z%)5Gvs8snIS7F3dc#^;T_NBE?a&YcUgn^+hN*PE@4vU zk%6hnip6V_lG5tuJwi&i3YI)Q8iAjrUv@%w)DNzS=p)c8($1RoG z(CEb0oN>d{_~gh~K5HAd*C#7uxnQXGIm2c3N)6j+WPDg9ax=E3fx;>4t;h~_^f(A7 zu2%qO%XY-t{8aS_?Q6G8-&BDHBrMI9qaWkiTN1;7w zCUP2(H#cQ^z)=uoHJpClLObN~>DH~%`q_}>nF^z6=i%>7;l%FB#qaTQ6U}GJpuuv2 zupBuZ9(shcyXWkj z);(u)^SNghH<5dWZU*-Nv#HxNW43#^0o`Qnng51hmiB#G-Sq64&&JB=P?Rfc0Y)1e$cf0EhaH{saF>6YKkbYH@vu6UU75Q1&V=qm|p4r`O;~A>zSpyo( z$8P@nn20^K=4W6J%$TOxW=8fisAu+U&h^Zen`|BC+$`&%A#G565H>d++=S|BV3p1L zsc87kPpA$7jM+@;vTSfusEZUsI7xbbB6SNHdiu6yq&zX`x*YUMt3x=Ix+zOIsrWP3 zxs{>*snN;v#!breQz@EZy;Nc#JO5QKvh6%-X;>_OXu9>eVK_xOJhHxIWvn{69n)32 zqiEi$71PmG;wKPFAfp2cM^+3sK*5_C-zj|PFd)LwntKXWbTFtr&F4)|e)*&v1 zQ>;4!x=wb~OqD6i_c=nJOKVfPkgu?5*;9Yc(r(kWSA0*XWRsC|UUoBv6S4#IGqL9^ z!&CjWK`Vj<8nn2oezm3v+Bq}3resg&Vz(8hJUHrRUpE7$T`ys#Z>s}#8o*jQ(Rx6f zVcl6KQQZe8rUp=HAaDljTJ_uZNqN-H$a4Z!Idgp$tUfY6xnfnIgWRX> zr{XAJ$VCA|E(#dJD7H+D*!I-C@g=k|iDrs-bHdvc@tPan{o?w==8AW-!DFRv)4-R; zF#r2LCw@x2exjl z)&|NppLx%4b@`>st0UD@2c||w2TxsDt4&>a_Hs-Gzr4IW$;}DBto&b{f=hF`^}Vah z#`?<>^=+rF=vlVvRNGgT(NkA0JJYg|&%wmLE|KFv<)plPY@}W;O>U}Li(INs)JL{0 z+hkT0Yei|yb+W89<>ls&tE-ZQwK{I5(tw?QOfxz%Q0uSR?ieVISGL*_GBP$YIkKhV z!lhPUxpTIDcWsT>6be->7sPg?wJbT))cDB6cxoxT%Vj$gGUP<9WWDeh2i%|teAC0!5-PjR;1Wc6>hO2u zlX4rZZn^O2g7{icnyl0(v7wy;fCK;|<0F&4R<0=Zlq%cMiRvF^t+J@lAWjTiASN)RJF_sqXz?=%7Mp~X*DHYT3=){0+2s?Uxj-zT? z8nSA#DcfLkD)-QUI}`QSESn>?sf}F&QSx<5=sbo-Mn_rO%M;^vp+D&>g>Co>&e}5i zt>)^Byh>x+)j?TZM?b}1s%@=}*b!${8wIEgS8Aof{>gsZxMA?QS9obklM^M>coQgX zT2`zoVIM`-(^kSNBez8^pIL@{d$5fel4gtBVr*{1&{# z?HRk8@mE9WbGSXtmdUpI&_rnx{dlzTTP8MJEl{hKl>i66PZ>RmEI_^A+Gf|JlqSYU zt=%3T8MP*{K2@{mhH;JQYGxFzHDQwzR^39O&+T~_5<`u+Y`oS#Qpa$nZ3e%we8Z^b zu#9SAhey@6lQxgH*+z1WGMhxn-A-0(mD@JwS0>j?*znZw)WlR>*Rp9t)MJ%Mjnax> zePytITCje4uzp6cZhfybo->2>vxD^&xx~WM>?Nm6z9LL-MVR1_YwU}cyCdvh!cwld7YO68zbuMC$bY;dnyo3J+9MT&;r8mB?q*n!0zS9uc-+`MHD zm1@@aK+`^GT?RXWdYG(Py|Z@Jk=0A9xg%(7%f7#jQ;BKdVMmykWM@tbh9;ANvXih+ zWr!`MS7kLFzW!iz;YM*H_vu^b-golhk*j4e*tT$Imt^@=y|#R0ygWKJSXu5&cEZgW zOIu}jC3YvgiSaU1vE~sK9UTkAJ33PLeHlBqg42S!cF14TqYa^7dfEn04CyEWsq2At ze~j5)6C~)8Wg8#hk2$Pa+4^nJ*@v-?Lk8InLO6dqv2KKIL2I{4J{*$p=ccr1{WynZ zigI=P}o^Kz%`p-Fd23waZ3pu?I)owJM6DsuJieYP-O3 zmD8HXvW8gFeG<3#hz2S6KAH;_bjM0oyVL$ac+xj>x;b1Bw28LjderI-I17%-l3k^Y zuwfl7`LkVS3VK3moPmw)ZPs1Nc61P`?C;nF7Pp5SqkNm~y2)B?!~$d|Hf3x6?OHj- z^mMB5?tE(1J`K@d8xGMLaFiiizNG^c8uMq~oP#3y+u=x{swmsab zC&Eqrb)52@7pj8Rt$?WR){1#Q9wsT*Y!uU-wQAd3mT%^;R^!@5kHhxLC)s@QPO&|j~Iq3fd~Xo~2G{f4XGZ58XZ zq6x_CE}-oav#Gbi;Rtt(SdV&m%6Fi3-exxpy_>DL)01^_{FcVy?eoMg8Ihs$dxA#R zR75~aTtIIgE@uaiOCvSUiNS&f)jf;Z?5goF+Qm;4B`lE=`#1{aOlY=jfFo;iaiunH zxAlgG{Pmo9+2(RVvM9~S9N1c}MxpVA)Sn;BS3BKS{c&b1+_kobeV&?K1@L>_ylju7 zbS`CE*Lh#;&)m4uw^r9K>_^bW$Z#r;Bd%`}ct<>fVWm(W@d!qlLjR228Mtht54fIi z6*J9KWJ4Wh)f?^KJ~3q*-bcwObX}3^{k3%*EV8=N<1kEz?t*-ld@tM;JUF)~VW)NR zowicfFG!sk%K7+>=Z9MAo2DiQt>RiE@5iLWs|cLJd>6$o68h0nqKl9pT3Lp+)qMP! zI`YfVUlGQ+Up7{^gMIDVb?4YPLuGu>k0x7eb`C_KzrDKmr}AO*_0G?~Q;kw!A;d%>XrJ>iUl z-f(2}gG!kZ&9D-&yt`9-W=Xrkp^4q$%#?MBGaL6|WN97de7`wh zf0Hnce9~(A#8Bq%YnbPYtk>$RCi<`Go;%;VxEtBS_1@Th*{)eOhSBr9DXYZr&@Kxq zY0j(&w2h;1>4u(T=hhDFE+e)D0~312))hVngvXi3SqF@+zjKY|9faL2zi8q}o4RLA4FWoG^Ut%+{yE?wcH~m#j*$8N=1Xs%1v- zawk-bxnifMVCT)MJ9XNopL1=r41He?Bo14L-Hp|`!9g1y0%MfkhQQoqkDVF? z1JboaB-}v%pWiC5)6;+beF2MfU$+5pDzv@E>&^e?7R9hSEfvm2id#(Mq0DK9GK*!PdByOH<(qw4?Dqw4nYh5rkXZhVaZ literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/DESCRIPTION.rst b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..e118723 --- /dev/null +++ b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/DESCRIPTION.rst @@ -0,0 +1,3 @@ +UNKNOWN + + diff --git a/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/INSTALLER b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/METADATA b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/METADATA new file mode 100644 index 0000000..d8d7378 --- /dev/null +++ b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/METADATA @@ -0,0 +1,16 @@ +Metadata-Version: 2.0 +Name: api +Version: 0.0.7 +Summary: Consume an API from ReadMe Build +Home-page: https://readme.build +Author: ReadMe +Author-email: support@readme.io +License: MIT +Description-Content-Type: UNKNOWN +Platform: UNKNOWN +Requires-Dist: requests +Requires-Dist: nose + +UNKNOWN + + diff --git a/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/RECORD b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/RECORD new file mode 100644 index 0000000..841b3ef --- /dev/null +++ b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/RECORD @@ -0,0 +1,11 @@ +api/__init__.py,sha256=lNE1-WYTjWaTJG2SQf1JC5fVfMZiTgFER8qCwQwa8CQ,18 +api/api.py,sha256=Uv4ZoExlbL2vKBgy7bmcD3gn4hZLGHWpHKpQvW6ewDY,2572 +api-0.0.7.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 +api-0.0.7.dist-info/METADATA,sha256=2tWv9XRdYvgAjj3suwLYpy-Zrdh94cSC6bfWyYk6zNU,288 +api-0.0.7.dist-info/RECORD,, +api-0.0.7.dist-info/WHEEL,sha256=F38j99qfcoNzHo88G-kisXWtI3MVVEd9JWjaAPcHMTc,93 +api-0.0.7.dist-info/metadata.json,sha256=gW8qLDjlCgdg5g-XxgVqxtNE3svisFD5fRwSmhIo6NQ,536 +api-0.0.7.dist-info/top_level.txt,sha256=0XF5TFwfelCuuPcFarhKT7zW-9WUsZmb3a790D78BZE,4 +api-0.0.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +api/__init__.pyc,, +api/api.pyc,, diff --git a/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/WHEEL b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/WHEEL new file mode 100644 index 0000000..1b49229 --- /dev/null +++ b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0) +Root-Is-Purelib: true +Tag: cp27-none-any + diff --git a/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/metadata.json b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/metadata.json new file mode 100644 index 0000000..2ea6780 --- /dev/null +++ b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/metadata.json @@ -0,0 +1 @@ +{"description_content_type": "UNKNOWN", "extensions": {"python.details": {"contacts": [{"email": "support@readme.io", "name": "ReadMe", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://readme.build"}}}, "extras": [], "generator": "bdist_wheel (0.30.0)", "license": "MIT", "metadata_version": "2.0", "name": "api", "run_requires": [{"requires": ["nose", "requests"]}], "summary": "Consume an API from ReadMe Build", "test_requires": [{"requires": ["nose"]}], "version": "0.0.7"} \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/top_level.txt b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/top_level.txt new file mode 100644 index 0000000..eedd89b --- /dev/null +++ b/venv/lib/python2.7/site-packages/api-0.0.7.dist-info/top_level.txt @@ -0,0 +1 @@ +api diff --git a/venv/lib/python2.7/site-packages/api/__init__.py b/venv/lib/python2.7/site-packages/api/__init__.py new file mode 100644 index 0000000..b69959f --- /dev/null +++ b/venv/lib/python2.7/site-packages/api/__init__.py @@ -0,0 +1 @@ +from api import * diff --git a/venv/lib/python2.7/site-packages/api/__init__.pyc b/venv/lib/python2.7/site-packages/api/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2fc7bd2b0b53bfd8ff09a1235aa78df563031a7b GIT binary patch literal 214 zcmZSn%*!>Yjy)=w0ScIav;zXz z*dVFIf=mq{#eg7+V}V@#f}+f_#FA9~vcw|&wEUcu)S_bjG!y*{L$e|i!?G-sY-2OS zjHEnEGlTTBjI444AV|;C5795kEYM9V&CE&Bjm!x$2u{=oS^&oJ@tJv 299: + result.error = content + content = None + console.error(result.error['error']) + + return content, result + +class Response(): + def __init__(self, error=None, is_deprecated=False): + self.error = error + self.is_deprecated = is_deprecated + diff --git a/venv/lib/python2.7/site-packages/api/api.pyc b/venv/lib/python2.7/site-packages/api/api.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf510973fafc5b9fd65471e5ecd8f80db6fe2956 GIT binary patch literal 4403 zcmcgv-EJF26h5nuG4JRKLs8PtrMQRlD@dPy{Wb9B>qV6O$CP@WAou!~iKN7tl zdfb?zV1g%&G6f|H<|vpvUYn)>%jYO4AA@En0Cb*$nPU)+Q&g`mfa>s1JbP7zp`Anb z$%6-9?)WBbzTdZPI|)cLiA@seW2POzcF@e*=rqVsq=hr44;&X{s^l_Ei{#d;yr;=` zaO24?nps2#LIy-DfkP`Fe*zKKt1Q$#GlBl{liOQeQU}+pyWyww(kn>&WG!#$?OrRMp_J@i1j#5+yZX z_@@qd*%F%+OtCK3GBR!^8EVZ8h$jd7XiWX75^hVl4sO&6_s?ULiCwuY@g|x)%-ar{ zSwok3RY2@R95uw5;8?jQvBBhRmp8HJ4#bl@2|gz|cgt85545Z?qoY;^!X(q*=`zo3 zdR`cZ*7KH`0H&N&lV7X{wmxCv3I@;}M+8John3h-2zkyBV<(Rc5|fNh55uND!5T*@ zSAW~r#%54H+GT%rSvayQ&DPIK>lx!sKZ-nW6*P$1lDed-tOu9*cG)sqb}yHM@t86h zovL2M{4V0skvEkKF2{r>nmqr>AX(VlSf{&ah82BmkWe0U=}9WgEt4@tGq2LtS=y&a z|0>hWS|L?dP3DA+hJ%T4^E-qA%Y-#%>8j(<3x|dU8WgC5^o*&ZVKJW;WIB;gi!v?I zph)Q>&fORcCaC4ma*QJ;XgEnBPAL%_v@^j;eipbUwb~zLe zOUzzyf$TgkE)L6N7x;qVG#z0}nL3LyouRMdH7eTkbTCcnI|>gkF41s?VnvU5a)CM* zDZqbO&Rn4b7{fFn5}@xaQ~HzQOCe3jMeu`5v^oTTE7Z9}!72-AFe?Hp&@$wpzzk!q zQm{q`km+w~Fe7KKaqWb=dFz^-56ER&%{K`a7_V2aK(l*h9ewrQo$8Z~ub+Q&{aWqX zy?hAheT+8+e(he!&JeQ6LQk+1_S*aFrnYVj2Uk=G?IZ@kus=Q8*pX7=b8Y>N&-{45 z@9%5bg7gClE`4WBmu^70pTbLj-^A?lkji8sDDL~#-ZS{Q0u z+cS4+T)u3k+7G&VQ%alK;Z`l}$DkR1$pjsf#1a?VK*Lc2^ttTA9c+3;I5=z_8O~Zc zoge64s+*{?0x64Heq^-lv?+q`Ns>q8nO*E&Hqqg4qnOLkm)Qi25w6Bh^Bt(SF)&XMvu>>VBH^ds5N#a7HUh zyOv{HrYCQ7o|L=2gMBa6Ch4b5T*XO*lSGJfd7NXiD9n+ux;sLNv=6R1z>jiDCcIvP z>;oW402BFqB=TWQSDPM6Y3*{^D;3s5KkDlbxvtErFO&#Y$JS+W3j*#4bj$BYR)`Ia zHV#Vk_bgqSpg@j5VJz8{3E*RecKaHpEvERzCb ze-kfrA04TSYMy_^D^5Wzs>`ZUD5*JTS(WfRugZlo;0tOFu&YiPNnj4`LSY_#Nv$}q z%-HYZ+%ZEkI#sSDKfi`c^Nd||If6COlF zqW#Ns&0E}S=;RwME3U>cz|WwZlyv<7R~@J8J^6k)QBGaQs{0mqTv(l{hFBkUG^ue* z>ZQB0srVzu0GD;?UPdSOiU8wsba&Zm#ozPTvdKX?iz}RnT&_zbi-<*t5xjKMsoJ3g ctGn69;d^XCVm`BK{9ACArpkq-sip0|05@5X2LJ#7 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/DESCRIPTION.rst b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..08533b5 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/DESCRIPTION.rst @@ -0,0 +1,3 @@ +Docs for this project are maintained at https://github.com/wbond/asn1crypto#readme. + + diff --git a/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/INSTALLER b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/METADATA b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/METADATA new file mode 100644 index 0000000..986ad32 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/METADATA @@ -0,0 +1,27 @@ +Metadata-Version: 2.0 +Name: asn1crypto +Version: 0.23.0 +Summary: Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP +Home-page: https://github.com/wbond/asn1crypto +Author: wbond +Author-email: will@wbond.net +License: MIT +Description-Content-Type: UNKNOWN +Keywords: asn1 crypto pki x509 certificate rsa dsa ec dh +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Security :: Cryptography + +Docs for this project are maintained at https://github.com/wbond/asn1crypto#readme. + + diff --git a/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/RECORD b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/RECORD new file mode 100644 index 0000000..4d5b3f0 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/RECORD @@ -0,0 +1,61 @@ +asn1crypto/__init__.py,sha256=d-HnaY-IU0N1aepUI9bYR11J2EGccGAN8kDvKMgGu78,209 +asn1crypto/_elliptic_curve.py,sha256=ZiHhIgy1KArwhXw5lWMB_-UQfgArE2xdlRRn3tFAqzY,9411 +asn1crypto/_errors.py,sha256=YCCXkifzLkCnxo-iIO-oIWY-UuPZNbEai7z94ps8ck4,967 +asn1crypto/_ffi.py,sha256=Y4IhTLrLTxt7Xg5vcQFLAvH_Mq8xg3LTcmkIJn-G8eE,738 +asn1crypto/_inet.py,sha256=_eOoKD9oIEQHSiFm6T77ROFLoFtJ4C-MV0zvuAI7Ets,4831 +asn1crypto/_int.py,sha256=I-INe1rHGsQfV6vndtD53fhyjsEOG5a6WoDY4w6M2B4,4618 +asn1crypto/_iri.py,sha256=5gG6VBG-tYAQT6lWnjvHRH-RvIStaeG_PxhyPLnL-KQ,8628 +asn1crypto/_ordereddict.py,sha256=5VAYLbxxEtfdZGKgjzINxlmNkYg9d_7JmZAFfr0EcAk,4533 +asn1crypto/_teletex_codec.py,sha256=LhDpkTprPaoc7UJ9i9uwnP-5Am00SVbHSQizPpCLpqE,5053 +asn1crypto/_types.py,sha256=OwsX30epv-ETI9eGrLW9GLqv0KeoiSRnJcjN92roqhQ,939 +asn1crypto/algos.py,sha256=PIvYYSxe6wGQtUSnXonZk6x1p1G8W0iZwRbalnmNMoA,33275 +asn1crypto/cms.py,sha256=Vs46hBMccQ_dn9GumwWZ7X6hogRx28DJTUy9cXFQ_fQ,25018 +asn1crypto/core.py,sha256=YI3j9PeZFIlGBnJDlzNGPhd5vWf0EMLNKOqRIdznhqY,156648 +asn1crypto/crl.py,sha256=KJLuEn1IDJO19X4eLYhRyaM-ACnxKkimoGsyAnzGdgA,16104 +asn1crypto/csr.py,sha256=CP0tOGyHPEV3ZpnB7L4L9X-X1epD6TVixal6UAtTvLQ,2142 +asn1crypto/keys.py,sha256=0TuSNrh4RD3CZxu1_MSMdKVzUbmWctEPV6B899CtPa8,34989 +asn1crypto/ocsp.py,sha256=jF_F5-xwcATqxs-2Qpo9V83lhfDNYuZZTd4ODpKnyAM,17792 +asn1crypto/parser.py,sha256=pkyVS-BJk4mDTve0mZMUmrrUV_IHnQk9AvgtkEvfEKM,9149 +asn1crypto/pdf.py,sha256=HNybnna5WG2ftmb8Nx_T5reyLJ0E7hJXoj37DuLbpX0,2250 +asn1crypto/pem.py,sha256=NpcI5XBIfLExi3JD-ZvY1vfHjCBwq0O16Ovcidza4Ts,6127 +asn1crypto/pkcs12.py,sha256=q-KGfvaO72B8AfvolwsqhAQpjuqnkEczPddXYLBFUSE,4566 +asn1crypto/tsp.py,sha256=jpjpFmWBwX4GUVrYu9Gnk6YXRnzb-uVFvfaJSo-m_2Q,7827 +asn1crypto/util.py,sha256=m3dc7XtmQiq__uC0G2jcyHYkaJPsnm7KGAWiCXj-xio,18043 +asn1crypto/version.py,sha256=KdyPUHKd8jwhHwkBvhOxLAgLMI0X29xMYLf2xWkU4pc,154 +asn1crypto/x509.py,sha256=TfCzaCajyWnt6xVFUEwdaan2_-4G7sJVebji7HzIvxQ,83708 +asn1crypto/_perf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +asn1crypto/_perf/_big_num_ctypes.py,sha256=bc1WXhoR08nB-l0mOutKldupcjybswWckOxquiXByx8,2027 +asn1crypto-0.23.0.dist-info/DESCRIPTION.rst,sha256=AKxcPr8A1r7Lgepi1zxda_bylQUpelEwT9VouCPpXFA,86 +asn1crypto-0.23.0.dist-info/METADATA,sha256=GhS8RqkJUnCxa85HU03PWrTZR4iJa6D0y-kPCQJmGp8,1132 +asn1crypto-0.23.0.dist-info/RECORD,, +asn1crypto-0.23.0.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 +asn1crypto-0.23.0.dist-info/metadata.json,sha256=4WvMgz2yiILjw2KFTpDOgkfHUsGQCxYhFu1q5_yfduk,1177 +asn1crypto-0.23.0.dist-info/top_level.txt,sha256=z8-jF_Q-jgzGox7T2XYian3-yeptLS2I7MjoJLBaq1Y,11 +asn1crypto-0.23.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +asn1crypto/keys.pyc,, +asn1crypto/__init__.pyc,, +asn1crypto/pdf.pyc,, +asn1crypto/_int.pyc,, +asn1crypto/_iri.pyc,, +asn1crypto/util.pyc,, +asn1crypto/_ffi.pyc,, +asn1crypto/x509.pyc,, +asn1crypto/crl.pyc,, +asn1crypto/pem.pyc,, +asn1crypto/_types.pyc,, +asn1crypto/parser.pyc,, +asn1crypto/_perf/_big_num_ctypes.pyc,, +asn1crypto/algos.pyc,, +asn1crypto/_elliptic_curve.pyc,, +asn1crypto/core.pyc,, +asn1crypto/tsp.pyc,, +asn1crypto/cms.pyc,, +asn1crypto/_perf/__init__.pyc,, +asn1crypto/pkcs12.pyc,, +asn1crypto/csr.pyc,, +asn1crypto/_ordereddict.pyc,, +asn1crypto/ocsp.pyc,, +asn1crypto/_inet.pyc,, +asn1crypto/version.pyc,, +asn1crypto/_errors.pyc,, +asn1crypto/_teletex_codec.pyc,, diff --git a/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/WHEEL b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/WHEEL new file mode 100644 index 0000000..0de529b --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.26.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/metadata.json b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/metadata.json new file mode 100644 index 0000000..cd985db --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"generator": "bdist_wheel (0.26.0)", "summary": "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP", "classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Security :: Cryptography"], "description_content_type": "UNKNOWN", "extensions": {"python.details": {"project_urls": {"Home": "https://github.com/wbond/asn1crypto"}, "contacts": [{"email": "will@wbond.net", "name": "wbond", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}}}, "keywords": ["asn1", "crypto", "pki", "x509", "certificate", "rsa", "dsa", "ec", "dh"], "license": "MIT", "metadata_version": "2.0", "name": "asn1crypto", "version": "0.23.0"} \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/top_level.txt b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/top_level.txt new file mode 100644 index 0000000..35a704e --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto-0.23.0.dist-info/top_level.txt @@ -0,0 +1 @@ +asn1crypto diff --git a/venv/lib/python2.7/site-packages/asn1crypto/__init__.py b/venv/lib/python2.7/site-packages/asn1crypto/__init__.py new file mode 100644 index 0000000..afdeb43 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/__init__.py @@ -0,0 +1,9 @@ +# coding: utf-8 +from __future__ import unicode_literals, division, absolute_import, print_function + +from .version import __version__, __version_info__ + +__all__ = [ + '__version__', + '__version_info__', +] diff --git a/venv/lib/python2.7/site-packages/asn1crypto/__init__.pyc b/venv/lib/python2.7/site-packages/asn1crypto/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c2646d49cdd6501e5233a8a88af5f98c6ccd0ee GIT binary patch literal 504 zcmZ8d%TB{E5ZpZ4lp-D{K7dm$B@I-SkPzYs7lZ<*T$VIW8n?C+C3aAI;HUWk)>Tna zEo;0pUhnMM`#BrGeFtd{`{mO4^yxwOOaY_qfB=vVqz*_IQWvBLsRz=B)CY&Tz&sEG zkV8m^AOlDPQhi_pSW@~3*bv^sfQoVJ5c&lAlE5gQ*Q`Lnb?+%7szE(w_2Z**0fw{ERD)FrE!O((6+2k2@w0Dwa*cE76;B%StFXGBxCzHPI?Vb zY`yXBsx;cP1!6)B66=;&x5OjRcBs8!V#i7be=1@o1Y$@W4$!TMMl?a6=_2a0HY#hu zsN<-dMO8d+XK}xpt?%Y>wNUr->9VX=UsGC36@5evZzc=F1)EfQ`?9@_vQEW$yJ>X& fKSbn;Ys8yov-{BpSu-PwN85HcB)E33JkR+BrOJ46 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_elliptic_curve.py b/venv/lib/python2.7/site-packages/asn1crypto/_elliptic_curve.py new file mode 100644 index 0000000..0ecab2d --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/_elliptic_curve.py @@ -0,0 +1,314 @@ +# coding: utf-8 + +""" +Classes and objects to represent prime-field elliptic curves and points on them. +Exports the following items: + + - PrimeCurve() + - PrimePoint() + - SECP192R1_CURVE + - SECP192R1_BASE_POINT + - SECP224R1_CURVE + - SECP224R1_BASE_POINT + - SECP256R1_CURVE + - SECP256R1_BASE_POINT + - SECP384R1_CURVE + - SECP384R1_BASE_POINT + - SECP521R1_CURVE + - SECP521R1_BASE_POINT + +The curve constants are all PrimeCurve() objects and the base point constants +are all PrimePoint() objects. + +Some of the following source code is derived from +http://webpages.charter.net/curryfans/peter/downloads.html, but has been heavily +modified to fit into this projects lint settings. The original project license +is listed below: + +Copyright (c) 2014 Peter Pearson + +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 unicode_literals, division, absolute_import, print_function + +from ._int import inverse_mod + + +class PrimeCurve(): + """ + Elliptic curve over a prime field. Characteristic two field curves are not + supported. + """ + + def __init__(self, p, a, b): + """ + The curve of points satisfying y^2 = x^3 + a*x + b (mod p) + + :param p: + The prime number as an integer + + :param a: + The component a as an integer + + :param b: + The component b as an integer + """ + + self.p = p + self.a = a + self.b = b + + def contains(self, point): + """ + :param point: + A Point object + + :return: + Boolean if the point is on this curve + """ + + y2 = point.y * point.y + x3 = point.x * point.x * point.x + return (y2 - (x3 + self.a * point.x + self.b)) % self.p == 0 + + +class PrimePoint(): + """ + A point on a prime-field elliptic curve + """ + + def __init__(self, curve, x, y, order=None): + """ + :param curve: + A PrimeCurve object + + :param x: + The x coordinate of the point as an integer + + :param y: + The y coordinate of the point as an integer + + :param order: + The order of the point, as an integer - optional + """ + + self.curve = curve + self.x = x + self.y = y + self.order = order + + # self.curve is allowed to be None only for INFINITY: + if self.curve: + if not self.curve.contains(self): + raise ValueError('Invalid EC point') + + if self.order: + if self * self.order != INFINITY: + raise ValueError('Invalid EC point') + + def __cmp__(self, other): + """ + :param other: + A PrimePoint object + + :return: + 0 if identical, 1 otherwise + """ + if self.curve == other.curve and self.x == other.x and self.y == other.y: + return 0 + else: + return 1 + + def __add__(self, other): + """ + :param other: + A PrimePoint object + + :return: + A PrimePoint object + """ + + # X9.62 B.3: + + if other == INFINITY: + return self + if self == INFINITY: + return other + assert self.curve == other.curve + if self.x == other.x: + if (self.y + other.y) % self.curve.p == 0: + return INFINITY + else: + return self.double() + + p = self.curve.p + + l = ((other.y - self.y) * inverse_mod(other.x - self.x, p)) % p + + x3 = (l * l - self.x - other.x) % p + y3 = (l * (self.x - x3) - self.y) % p + + return PrimePoint(self.curve, x3, y3) + + def __mul__(self, other): + """ + :param other: + An integer to multiple the Point by + + :return: + A PrimePoint object + """ + + def leftmost_bit(x): + assert x > 0 + result = 1 + while result <= x: + result = 2 * result + return result // 2 + + e = other + if self.order: + e = e % self.order + if e == 0: + return INFINITY + if self == INFINITY: + return INFINITY + assert e > 0 + + # From X9.62 D.3.2: + + e3 = 3 * e + negative_self = PrimePoint(self.curve, self.x, -self.y, self.order) + i = leftmost_bit(e3) // 2 + result = self + # print "Multiplying %s by %d (e3 = %d):" % ( self, other, e3 ) + while i > 1: + result = result.double() + if (e3 & i) != 0 and (e & i) == 0: + result = result + self + if (e3 & i) == 0 and (e & i) != 0: + result = result + negative_self + # print ". . . i = %d, result = %s" % ( i, result ) + i = i // 2 + + return result + + def __rmul__(self, other): + """ + :param other: + An integer to multiple the Point by + + :return: + A PrimePoint object + """ + + return self * other + + def double(self): + """ + :return: + A PrimePoint object that is twice this point + """ + + # X9.62 B.3: + + p = self.curve.p + a = self.curve.a + + l = ((3 * self.x * self.x + a) * inverse_mod(2 * self.y, p)) % p + + x3 = (l * l - 2 * self.x) % p + y3 = (l * (self.x - x3) - self.y) % p + + return PrimePoint(self.curve, x3, y3) + + +# This one point is the Point At Infinity for all purposes: +INFINITY = PrimePoint(None, None, None) + + +# NIST Curve P-192: +SECP192R1_CURVE = PrimeCurve( + 6277101735386680763835789423207666416083908700390324961279, + -3, + 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1 +) +SECP192R1_BASE_POINT = PrimePoint( + SECP192R1_CURVE, + 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012, + 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811, + 6277101735386680763835789423176059013767194773182842284081 +) + + +# NIST Curve P-224: +SECP224R1_CURVE = PrimeCurve( + 26959946667150639794667015087019630673557916260026308143510066298881, + -3, + 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 +) +SECP224R1_BASE_POINT = PrimePoint( + SECP224R1_CURVE, + 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21, + 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34, + 26959946667150639794667015087019625940457807714424391721682722368061 +) + + +# NIST Curve P-256: +SECP256R1_CURVE = PrimeCurve( + 115792089210356248762697446949407573530086143415290314195533631308867097853951, + -3, + 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b +) +SECP256R1_BASE_POINT = PrimePoint( + SECP256R1_CURVE, + 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, + 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5, + 115792089210356248762697446949407573529996955224135760342422259061068512044369 +) + + +# NIST Curve P-384: +SECP384R1_CURVE = PrimeCurve( + 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319, # noqa + -3, + 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef +) +SECP384R1_BASE_POINT = PrimePoint( + SECP384R1_CURVE, + 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7, + 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f, + 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643 +) + + +# NIST Curve P-521: +SECP521R1_CURVE = PrimeCurve( + 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151, # noqa + -3, + 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 # noqa +) +SECP521R1_BASE_POINT = PrimePoint( + SECP521R1_CURVE, + 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66, # noqa + 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650, # noqa + 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449 # noqa +) diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_elliptic_curve.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_elliptic_curve.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d0dc1dec1ee0d21bcb1a85a634d77c8dd80b565 GIT binary patch literal 9525 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 MKsS64ZUh_AA0O;Yc>n+a literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_ffi.py b/venv/lib/python2.7/site-packages/asn1crypto/_ffi.py new file mode 100644 index 0000000..2a4f5bf --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/_ffi.py @@ -0,0 +1,45 @@ +# coding: utf-8 + +""" +FFI helper compatibility functions. Exports the following items: + + - LibraryNotFoundError + - FFIEngineError + - bytes_from_buffer() + - buffer_from_bytes() + - null() +""" + +from __future__ import unicode_literals, division, absolute_import, print_function + +from ctypes import create_string_buffer + + +def buffer_from_bytes(initializer): + return create_string_buffer(initializer) + + +def bytes_from_buffer(buffer, maxlen=None): + return buffer.raw + + +def null(): + return None + + +class LibraryNotFoundError(Exception): + + """ + An exception when trying to find a shared library + """ + + pass + + +class FFIEngineError(Exception): + + """ + An exception when trying to instantiate ctypes or cffi + """ + + pass diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_ffi.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_ffi.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07d44cc1723637aa236498a09a2d8c3db04bab95 GIT binary patch literal 1958 zcmc&#&2G~`5S}<`(zq=YgnHnBR$K^&HVssj_z^0gRH}p`WVqmqaqM-n#oo1c*GW?$ zE>ye;Psj@}V<#ysNN^%6?Ra)}y`FF8n{oZemizWg%a33_>i9hRSO@bBl^DQBS%cVt zv<8_2z5`hu{5oU}@Eee=fxiYdI#GwT30VvL7Oop`fv>JZyaDkVT-3mKA#RpNw6uV4 zLW1wCljSSG2Y(CV_QL8etvBd`cb!dirTC7*Jw85RW1i+*vq)umXvI*Z!p>My$jAyM z%^vHYp(G##9;DR(X^7T_}m zw}$bfy+J8Ga;v&+12rLq6=5pQ5g9I_6lR247af@3m%5WscQJ}F*QT2sbjQ6zebAen z9(;Oy*c%V!lf(T{GCrN|;~2^A`))4s-C-fpcz0~iPtG58LnC{Up5<2kss>3S_VSs% zh2Q!uoVU?v2n^IBde9^cCAJnS2<#ND0JFqf9ZoxR);3X8x0Y%ao~2x_65(|o?Vy7T zgs7HdiI8#>UxP=sfs*_Z#Q)C~`9K`Mi_f|9B`5z>Ps@Hns9q5#iPapN0+u~W2fT`x z#WS?K4982!_*ukrDq}VsbIGipQR!O65+P$2GBXY}k6Bt3aQRk;5?|I-5Xdm&L12mf zL6E7qNNGug34&NfL9oK;d0XhlJ)DNZ*laYNvd*veoPUqn5nl4ws0nFoD6zsVXOW%d z+%ScW6HD(hbROl!qc-GGw_0U{s24oIxs1@Dv-E48)TFS5#-w_93_RkNM+NVdB%rFV zV3uvpqqRqE&Lc*6^cS&h6#WIu%A9!g*%iVrx%<3g>kIO>tdyp6-`TFW8=H-GW2gNS D{(0mC literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_inet.py b/venv/lib/python2.7/site-packages/asn1crypto/_inet.py new file mode 100644 index 0000000..0322bb4 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/_inet.py @@ -0,0 +1,170 @@ +# coding: utf-8 +from __future__ import unicode_literals, division, absolute_import, print_function + +import socket +import struct + +from ._errors import unwrap +from ._types import byte_cls, bytes_to_list, str_cls, type_name + + +def inet_ntop(address_family, packed_ip): + """ + Windows compatibility shim for socket.inet_ntop(). + + :param address_family: + socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6 + + :param packed_ip: + A byte string of the network form of an IP address + + :return: + A unicode string of the IP address + """ + + if address_family not in set([socket.AF_INET, socket.AF_INET6]): + raise ValueError(unwrap( + ''' + address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s), + not %s + ''', + repr(socket.AF_INET), + repr(socket.AF_INET6), + repr(address_family) + )) + + if not isinstance(packed_ip, byte_cls): + raise TypeError(unwrap( + ''' + packed_ip must be a byte string, not %s + ''', + type_name(packed_ip) + )) + + required_len = 4 if address_family == socket.AF_INET else 16 + if len(packed_ip) != required_len: + raise ValueError(unwrap( + ''' + packed_ip must be %d bytes long - is %d + ''', + required_len, + len(packed_ip) + )) + + if address_family == socket.AF_INET: + return '%d.%d.%d.%d' % tuple(bytes_to_list(packed_ip)) + + octets = struct.unpack(b'!HHHHHHHH', packed_ip) + + runs_of_zero = {} + longest_run = 0 + zero_index = None + for i, octet in enumerate(octets + (-1,)): + if octet != 0: + if zero_index is not None: + length = i - zero_index + if length not in runs_of_zero: + runs_of_zero[length] = zero_index + longest_run = max(longest_run, length) + zero_index = None + elif zero_index is None: + zero_index = i + + hexed = [hex(o)[2:] for o in octets] + + if longest_run < 2: + return ':'.join(hexed) + + zero_start = runs_of_zero[longest_run] + zero_end = zero_start + longest_run + + return ':'.join(hexed[:zero_start]) + '::' + ':'.join(hexed[zero_end:]) + + +def inet_pton(address_family, ip_string): + """ + Windows compatibility shim for socket.inet_ntop(). + + :param address_family: + socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6 + + :param ip_string: + A unicode string of an IP address + + :return: + A byte string of the network form of the IP address + """ + + if address_family not in set([socket.AF_INET, socket.AF_INET6]): + raise ValueError(unwrap( + ''' + address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s), + not %s + ''', + repr(socket.AF_INET), + repr(socket.AF_INET6), + repr(address_family) + )) + + if not isinstance(ip_string, str_cls): + raise TypeError(unwrap( + ''' + ip_string must be a unicode string, not %s + ''', + type_name(ip_string) + )) + + if address_family == socket.AF_INET: + octets = ip_string.split('.') + error = len(octets) != 4 + if not error: + ints = [] + for o in octets: + o = int(o) + if o > 255 or o < 0: + error = True + break + ints.append(o) + + if error: + raise ValueError(unwrap( + ''' + ip_string must be a dotted string with four integers in the + range of 0 to 255, got %s + ''', + repr(ip_string) + )) + + return struct.pack(b'!BBBB', *ints) + + error = False + omitted = ip_string.count('::') + if omitted > 1: + error = True + elif omitted == 0: + octets = ip_string.split(':') + error = len(octets) != 8 + else: + begin, end = ip_string.split('::') + begin_octets = begin.split(':') + end_octets = end.split(':') + missing = 8 - len(begin_octets) - len(end_octets) + octets = begin_octets + (['0'] * missing) + end_octets + + if not error: + ints = [] + for o in octets: + o = int(o, 16) + if o > 65535 or o < 0: + error = True + break + ints.append(o) + + return struct.pack(b'!HHHHHHHH', *ints) + + raise ValueError(unwrap( + ''' + ip_string must be a valid ipv6 string, got %s + ''', + repr(ip_string) + )) diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_inet.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_inet.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e99bdc979c0c64d5343739cafea9f789a1c93395 GIT binary patch literal 4356 zcmd5<&u<&o5uRQCrbyGWtw>FgdXrQr1K5_FIszgXP24(01q6bz7HWWKx?OQs~`^>935jurF9J&rBmr`K-Oo8??i6s z_c?Yv6yJwdof*gf$Pj?7BDfwMAsb(&$VZJJf-+1I33X$nWK z&^jD`_{Ayx8n!i>)oEI1TXyJcV~VrXrg4MPZ;UA*tF$p|&=hxBLKv|HWN7YlWUkQ^ z&Nny$i^-0^F^+#SN2*f_8S_*LO59He*rXCXc#CFD(${I)nha1$5vdQOm>Lq4$h<*@Jy z1ku2Xk1Rd(E%suOSQiHJ60!t=S}ce)%Zs(b zOlj*79_2BbueH0WKDcb1tiQE{7scAzR7mF)+Hzb=d3_-)@$Hx zdIG4dNsPeWwgP2sddps|0B_T~Grtw*pLc&*T#_b(Z*c{ji84-ZyBUkSyZe&rq_evQ zjV_^4zLw;d2Tl@O5j;t$^OJ$BLi8(llKG#dX`I@Uh`CAqB$ZBN-biUT>ic$u!P%_? zq{ZBx^Qp`?@gpQVJY>nlw>jZ@^KcVIMM72dl2^ltn$7rQcis2JonQWxsQnV!B^Tz zvq+Z79S+`8OwF+kWHACDP=Flhp>)O41s{Fyd?X?SF5+kikRN$n$Rv##LfQgHonWC` zCvLiR6i+-qRa-~*wuX0i(tCGLM)$@)-MKqFj6UAk9vlrvr`xy&(bmCM5+t_|vtZ)g z9_r_N&p+I9RdlzXo+UcID8hH-kmO9_vPdPoQuR4|a^*)xwOle<_**M=jB2Tb-ya&+ zL}IyP+%T`1RfGTD5xXYZw$Tx}ZN6{f$!r=;v(Lwl1HRzGuiiK={L}zxjaHZuk&&4W zk-~*IQM!PAKwRJj)iOX3ps#12bMM119x$;m<5grB*aqZKp>dhizeKJIQT&%rBp@Dx zmB12U#C(8p{C9fFI?&s;QSg6Fc>WdYM!7RuWiAB3pTIU?H+BkMUndV72d_bXU`TLN znbMJwPZ|ALl<)(L|JV5{g|L=Z*(z2U9SSBQA(-bpT$AwR1HriU3y)2vH4c~z*XaW3C@<_!`jr`Z2bn6F2)uff>N;%@}=KE&=UvECvQ7npasa=4Uy zh5zp46#OkPg&wm%zKqTV#bq;ivDUsfFHKGZJw$Pnr53&-`~ea(1g?CRJY}rZ1!-^z zv~B6w`tYNVZdrp@>kGD2%!Tj%99Kco@=cP{cEB_t;YVQXo1)%Li%Z3n{uu0;03|m6HzPcV74-e7X4o(T~BeU77T4He+uV%dy{K6%X*a z_z( 0: + return ud + else: + return ud + p + + +def fill_width(bytes_, width): + """ + Ensure a byte string representing a positive integer is a specific width + (in bytes) + + :param bytes_: + The integer byte string + + :param width: + The desired width as an integer + + :return: + A byte string of the width specified + """ + + while len(bytes_) < width: + bytes_ = b'\x00' + bytes_ + return bytes_ diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_int.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_int.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc83a4eb8fbc3cadde2baeed5a8cdf4ac4a21442 GIT binary patch literal 4753 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 IY3&F90dbA1NdN!< literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_iri.py b/venv/lib/python2.7/site-packages/asn1crypto/_iri.py new file mode 100644 index 0000000..57ddd40 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/_iri.py @@ -0,0 +1,288 @@ +# coding: utf-8 + +""" +Functions to convert unicode IRIs into ASCII byte string URIs and back. Exports +the following items: + + - iri_to_uri() + - uri_to_iri() +""" + +from __future__ import unicode_literals, division, absolute_import, print_function + +from encodings import idna # noqa +import codecs +import re +import sys + +from ._errors import unwrap +from ._types import byte_cls, str_cls, type_name, bytes_to_list, int_types + +if sys.version_info < (3,): + from urlparse import urlsplit, urlunsplit + from urllib import ( + quote as urlquote, + unquote as unquote_to_bytes, + ) + +else: + from urllib.parse import ( + quote as urlquote, + unquote_to_bytes, + urlsplit, + urlunsplit, + ) + + +def iri_to_uri(value): + """ + Normalizes and encodes a unicode IRI into an ASCII byte string URI + + :param value: + A unicode string of an IRI + + :return: + A byte string of the ASCII-encoded URI + """ + + if not isinstance(value, str_cls): + raise TypeError(unwrap( + ''' + value must be a unicode string, not %s + ''', + type_name(value) + )) + + scheme = None + # Python 2.6 doesn't split properly is the URL doesn't start with http:// or https:// + if sys.version_info < (2, 7) and not value.startswith('http://') and not value.startswith('https://'): + real_prefix = None + prefix_match = re.match('^[^:]*://', value) + if prefix_match: + real_prefix = prefix_match.group(0) + value = 'http://' + value[len(real_prefix):] + parsed = urlsplit(value) + if real_prefix: + value = real_prefix + value[7:] + scheme = _urlquote(real_prefix[:-3]) + else: + parsed = urlsplit(value) + + if scheme is None: + scheme = _urlquote(parsed.scheme) + hostname = parsed.hostname + if hostname is not None: + hostname = hostname.encode('idna') + # RFC 3986 allows userinfo to contain sub-delims + username = _urlquote(parsed.username, safe='!$&\'()*+,;=') + password = _urlquote(parsed.password, safe='!$&\'()*+,;=') + port = parsed.port + if port is not None: + port = str_cls(port).encode('ascii') + + netloc = b'' + if username is not None: + netloc += username + if password: + netloc += b':' + password + netloc += b'@' + if hostname is not None: + netloc += hostname + if port is not None: + default_http = scheme == b'http' and port == b'80' + default_https = scheme == b'https' and port == b'443' + if not default_http and not default_https: + netloc += b':' + port + + # RFC 3986 allows a path to contain sub-delims, plus "@" and ":" + path = _urlquote(parsed.path, safe='/!$&\'()*+,;=@:') + # RFC 3986 allows the query to contain sub-delims, plus "@", ":" , "/" and "?" + query = _urlquote(parsed.query, safe='/?!$&\'()*+,;=@:') + # RFC 3986 allows the fragment to contain sub-delims, plus "@", ":" , "/" and "?" + fragment = _urlquote(parsed.fragment, safe='/?!$&\'()*+,;=@:') + + if query is None and fragment is None and path == b'/': + path = None + + # Python 2.7 compat + if path is None: + path = '' + + output = urlunsplit((scheme, netloc, path, query, fragment)) + if isinstance(output, str_cls): + output = output.encode('latin1') + return output + + +def uri_to_iri(value): + """ + Converts an ASCII URI byte string into a unicode IRI + + :param value: + An ASCII-encoded byte string of the URI + + :return: + A unicode string of the IRI + """ + + if not isinstance(value, byte_cls): + raise TypeError(unwrap( + ''' + value must be a byte string, not %s + ''', + type_name(value) + )) + + parsed = urlsplit(value) + + scheme = parsed.scheme + if scheme is not None: + scheme = scheme.decode('ascii') + + username = _urlunquote(parsed.username, remap=[':', '@']) + password = _urlunquote(parsed.password, remap=[':', '@']) + hostname = parsed.hostname + if hostname: + hostname = hostname.decode('idna') + port = parsed.port + if port and not isinstance(port, int_types): + port = port.decode('ascii') + + netloc = '' + if username is not None: + netloc += username + if password: + netloc += ':' + password + netloc += '@' + if hostname is not None: + netloc += hostname + if port is not None: + netloc += ':' + str_cls(port) + + path = _urlunquote(parsed.path, remap=['/'], preserve=True) + query = _urlunquote(parsed.query, remap=['&', '='], preserve=True) + fragment = _urlunquote(parsed.fragment) + + return urlunsplit((scheme, netloc, path, query, fragment)) + + +def _iri_utf8_errors_handler(exc): + """ + Error handler for decoding UTF-8 parts of a URI into an IRI. Leaves byte + sequences encoded in %XX format, but as part of a unicode string. + + :param exc: + The UnicodeDecodeError exception + + :return: + A 2-element tuple of (replacement unicode string, integer index to + resume at) + """ + + bytes_as_ints = bytes_to_list(exc.object[exc.start:exc.end]) + replacements = ['%%%02x' % num for num in bytes_as_ints] + return (''.join(replacements), exc.end) + + +codecs.register_error('iriutf8', _iri_utf8_errors_handler) + + +def _urlquote(string, safe=''): + """ + Quotes a unicode string for use in a URL + + :param string: + A unicode string + + :param safe: + A unicode string of character to not encode + + :return: + None (if string is None) or an ASCII byte string of the quoted string + """ + + if string is None or string == '': + return None + + # Anything already hex quoted is pulled out of the URL and unquoted if + # possible + escapes = [] + if re.search('%[0-9a-fA-F]{2}', string): + # Try to unquote any percent values, restoring them if they are not + # valid UTF-8. Also, requote any safe chars since encoded versions of + # those are functionally different than the unquoted ones. + def _try_unescape(match): + byte_string = unquote_to_bytes(match.group(0)) + unicode_string = byte_string.decode('utf-8', 'iriutf8') + for safe_char in list(safe): + unicode_string = unicode_string.replace(safe_char, '%%%02x' % ord(safe_char)) + return unicode_string + string = re.sub('(?:%[0-9a-fA-F]{2})+', _try_unescape, string) + + # Once we have the minimal set of hex quoted values, removed them from + # the string so that they are not double quoted + def _extract_escape(match): + escapes.append(match.group(0).encode('ascii')) + return '\x00' + string = re.sub('%[0-9a-fA-F]{2}', _extract_escape, string) + + output = urlquote(string.encode('utf-8'), safe=safe.encode('utf-8')) + if not isinstance(output, byte_cls): + output = output.encode('ascii') + + # Restore the existing quoted values that we extracted + if len(escapes) > 0: + def _return_escape(_): + return escapes.pop(0) + output = re.sub(b'%00', _return_escape, output) + + return output + + +def _urlunquote(byte_string, remap=None, preserve=None): + """ + Unquotes a URI portion from a byte string into unicode using UTF-8 + + :param byte_string: + A byte string of the data to unquote + + :param remap: + A list of characters (as unicode) that should be re-mapped to a + %XX encoding. This is used when characters are not valid in part of a + URL. + + :param preserve: + A bool - indicates that the chars to be remapped if they occur in + non-hex form, should be preserved. E.g. / for URL path. + + :return: + A unicode string + """ + + if byte_string is None: + return byte_string + + if byte_string == b'': + return '' + + if preserve: + replacements = ['\x1A', '\x1C', '\x1D', '\x1E', '\x1F'] + preserve_unmap = {} + for char in remap: + replacement = replacements.pop(0) + preserve_unmap[replacement] = char + byte_string = byte_string.replace(char.encode('ascii'), replacement.encode('ascii')) + + byte_string = unquote_to_bytes(byte_string) + + if remap: + for char in remap: + byte_string = byte_string.replace(char.encode('ascii'), ('%%%02x' % ord(char)).encode('ascii')) + + output = byte_string.decode('utf-8', 'iriutf8') + + if preserve: + for replacement, original in preserve_unmap.items(): + output = output.replace(replacement, original) + + return output diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_iri.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_iri.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92c6cc279e5531658d5ceead14ea7a66844f7ca7 GIT binary patch literal 8246 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_ordereddict.py b/venv/lib/python2.7/site-packages/asn1crypto/_ordereddict.py new file mode 100644 index 0000000..2f18ab5 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/_ordereddict.py @@ -0,0 +1,135 @@ +# Copyright (c) 2009 Raymond Hettinger +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import sys + +if not sys.version_info < (2, 7): + + from collections import OrderedDict + +else: + + from UserDict import DictMixin + + class OrderedDict(dict, DictMixin): + + def __init__(self, *args, **kwds): + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__end + except AttributeError: + self.clear() + self.update(*args, **kwds) + + def clear(self): + self.__end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.__map = {} # key --> [key, prev, next] + dict.clear(self) + + def __setitem__(self, key, value): + if key not in self: + end = self.__end + curr = end[1] + curr[2] = end[1] = self.__map[key] = [key, curr, end] + dict.__setitem__(self, key, value) + + def __delitem__(self, key): + dict.__delitem__(self, key) + key, prev, next_ = self.__map.pop(key) + prev[2] = next_ + next_[1] = prev + + def __iter__(self): + end = self.__end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.__end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + def popitem(self, last=True): + if not self: + raise KeyError('dictionary is empty') + if last: + key = reversed(self).next() + else: + key = iter(self).next() + value = self.pop(key) + return key, value + + def __reduce__(self): + items = [[k, self[k]] for k in self] + tmp = self.__map, self.__end + del self.__map, self.__end + inst_dict = vars(self).copy() + self.__map, self.__end = tmp + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def keys(self): + return list(self) + + setdefault = DictMixin.setdefault + update = DictMixin.update + pop = DictMixin.pop + values = DictMixin.values + items = DictMixin.items + iterkeys = DictMixin.iterkeys + itervalues = DictMixin.itervalues + iteritems = DictMixin.iteritems + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + + def copy(self): + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + if isinstance(other, OrderedDict): + if len(self) != len(other): + return False + for p, q in zip(self.items(), other.items()): + if p != q: + return False + return True + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_ordereddict.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_ordereddict.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f6378f0b721b970f42bafab3051afc9ba2e240b GIT binary patch literal 5529 zcmd5=+j1Mn5$)Lp2m-u{lxQ(>RhY=CfboT*Ez4Glxtj5%Ql?W2B}@=2YY4j_msl*o zodHcMk{=>h9{qv&jeLM}P7ipI%8#ysC~c!>W_Pydboc3*4ga^$`13clc2_2UA%1^{ z%l-o*!G9yUNLwToIWm&WN*{yo=uk!SKn9_-Lovmsc2y;>$e=3is+eR(Qv9z*5}!2RzzsX3nu>o z9rnKvFtZIag|BPly+#$hGf<@>NvKLyl8P!bl2lcxNjfXA`CB9H`o!RNgDd7#bCS-> z(So!WR9TevqAE+$UQ%UQ+RLh3llC=LR;0b6%Br+iRk<$h>yp%U!W)t_R9TbsHAxmF znd7UUVBdg9 zPe*CjrO8IeZ48FiZESCJ%7gJBEu4L8<6!7E?j+3_8psE8bkmIw&qnDV%W_z{YiPw+ zTph=0k+?z81dnZejM^dXxdNZ%Qqxmmn3j5kYOzkcd{Rv*3v70;op41#>KI5&*Vp>ZZ#;;sP%q z15O&HBK?|_pK5dix=@}f(X2lMM1T)6B!U%a$c&weAKqb@E4n*K4j0G~9`q9i@*KRD zycqV%RZYHJ5snt9(X+~0aconUxpWZ6-U}CS_R}**vrjttIE|Reihg%omQ#j#8MeHO z%Qhgy%md_x*)-krxFp~jn-m}#qUGrZ976OwW=cO_hK$)~!32IV2MB2gKLi_~UjdWT zE0K6GuRxfjxrb1})nFVANB%bA8Id&f$NmcpX+fz%>ciWpfKSUeGm{ z+vVu5A&A;Vb{km-V5hgqvk26FUCIxs1F!YJ8V@1wI9`+em+`|~zGiALDj{kHYk)E#vsNG{OfNLu`rJd|u6dba*&1i1HPOXC4N|F`^i?C{5z{W3*p}=sXYk zt9i(c86wEuU^XJZ!2Z6pBYMiato#^7Cld2HqAZYNg_QnMCu0zth5hq(lcMgnUm*B(6nSWs)95wqZ=5$OkVBJJJx9y zM=Kn}HN`s3eJA*Zl=C^%NtvEOe9o8~!3usgN=e?l)CJ!`L74`IyN}i;Wf~1QVErJF zescF zF7?`#(yuj%B}&1@cE|6Dx=YzM!V3y{n8glK8_Z9~CgERGGD>3V75xmxlw8il*YxoV+grvX7ol6))0^a&-ABv9T`gP1+h4hIbSF?7Fu3hMrVL{u2DT*yZp{TBpN z8T5(D7f9K^`XoW1$gd1G=cVu*=xRzpXiqm>RwRIFd640L#|7Y zq!DXQbe-ZR#X7}%6hEc-1;r)>Lq%snAS7w8GtOPa&4%uX^gD(g2Ca_{<^fZbdEi3} z4S$0#!f0w~j^5-PRgbTfM8`ylbttg=9f%jM1)TU2~!=?y&|!#u|~ sDfC%=v2x#EY+CN}LkE4L`S%LoqL%IW0Q=2rFifd$K3ED?E6c(E0fDig>i_@% literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_perf/__init__.py b/venv/lib/python2.7/site-packages/asn1crypto/_perf/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_perf/__init__.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_perf/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b24887323d2104aa562b27b36fa44d5d9afc3916 GIT binary patch literal 200 zcmZSn%*z!}#~zi;00oRd+5w1*S%5?e14FO|NW@PANHCxg#f3mI{eq&*vc!^9{j$U& z{j~g?l+>bP{WKH(3`4Ub6T`ABlWb!%!;GXnOEZJ?w2Z8B10YDx(+|-v$SlxJD$UGE z(ak8S@~kq_Pb|(eOfIS{D9J}=#uua(rRm4VXXa&=#K-FuRF-f6ZMDhGPbtkwwF9}W H7>F4FZ!$63 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_perf/_big_num_ctypes.py b/venv/lib/python2.7/site-packages/asn1crypto/_perf/_big_num_ctypes.py new file mode 100644 index 0000000..8e37e9b --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/_perf/_big_num_ctypes.py @@ -0,0 +1,69 @@ +# coding: utf-8 + +""" +ctypes interface for BN_mod_inverse() function from OpenSSL. Exports the +following items: + + - libcrypto + - BN_bn2bin() + - BN_CTX_free() + - BN_CTX_new() + - BN_free() + - BN_mod_inverse() + - BN_new() + - BN_num_bits() + - BN_set_negative() + +Will raise asn1crypto._ffi.LibraryNotFoundError() if libcrypto can not be +found. Will raise asn1crypto._ffi.FFIEngineError() if there is an error +interfacing with libcrypto. +""" + +from __future__ import unicode_literals, division, absolute_import, print_function + +import sys + +from ctypes import CDLL, c_int, c_char_p, c_void_p +from ctypes.util import find_library + +from .._ffi import LibraryNotFoundError, FFIEngineError + + +try: + # On Python 2, the unicode string here may raise a UnicodeDecodeError as it + # tries to join a bytestring path to the unicode name "crypto" + libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto') + if not libcrypto_path: + raise LibraryNotFoundError('The library libcrypto could not be found') + + libcrypto = CDLL(libcrypto_path) + + libcrypto.BN_new.argtypes = [] + libcrypto.BN_new.restype = c_void_p + + libcrypto.BN_bin2bn.argtypes = [c_char_p, c_int, c_void_p] + libcrypto.BN_bin2bn.restype = c_void_p + + libcrypto.BN_bn2bin.argtypes = [c_void_p, c_char_p] + libcrypto.BN_bn2bin.restype = c_int + + libcrypto.BN_set_negative.argtypes = [c_void_p, c_int] + libcrypto.BN_set_negative.restype = None + + libcrypto.BN_num_bits.argtypes = [c_void_p] + libcrypto.BN_num_bits.restype = c_int + + libcrypto.BN_free.argtypes = [c_void_p] + libcrypto.BN_free.restype = None + + libcrypto.BN_CTX_new.argtypes = [] + libcrypto.BN_CTX_new.restype = c_void_p + + libcrypto.BN_CTX_free.argtypes = [c_void_p] + libcrypto.BN_CTX_free.restype = None + + libcrypto.BN_mod_inverse.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p] + libcrypto.BN_mod_inverse.restype = c_void_p + +except (AttributeError): + raise FFIEngineError('Error initializing ctypes') diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_perf/_big_num_ctypes.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_perf/_big_num_ctypes.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92343a36ca0656bbebd11ffe135a79576a676d1e GIT binary patch literal 1878 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_types.py b/venv/lib/python2.7/site-packages/asn1crypto/_types.py new file mode 100644 index 0000000..b9ca8cc --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/_types.py @@ -0,0 +1,46 @@ +# coding: utf-8 +from __future__ import unicode_literals, division, absolute_import, print_function + +import inspect +import sys + + +if sys.version_info < (3,): + str_cls = unicode # noqa + byte_cls = str + int_types = (int, long) # noqa + + def bytes_to_list(byte_string): + return [ord(b) for b in byte_string] + + chr_cls = chr + +else: + str_cls = str + byte_cls = bytes + int_types = int + + bytes_to_list = list + + def chr_cls(num): + return bytes([num]) + + +def type_name(value): + """ + Returns a user-readable name for the type of an object + + :param value: + A value to get the type name of + + :return: + A unicode string of the object's type name + """ + + if inspect.isclass(value): + cls = value + else: + cls = value.__class__ + if cls.__module__ in set(['builtins', '__builtin__']): + return cls.__name__ + return '%s.%s' % (cls.__module__, cls.__name__) diff --git a/venv/lib/python2.7/site-packages/asn1crypto/_types.pyc b/venv/lib/python2.7/site-packages/asn1crypto/_types.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7750ba6f11c237f8f98df5a82f2548a59d8e77d4 GIT binary patch literal 1714 zcmc&!+iuf95FOiz)1>Jg5D1VAQbk_cv`|%|LI_k|c&U(!gk%X8$6hB+ePeeVlnQu( zAK^dvD}I2Pb*i>MKsV83c5`-S&Ro{{yV862qZ351ST_B>`s{%IO-f8(3o?M*g1~~@ zhQNm0fxv;h1wjieM%a+GA!r*k=`I8=NEfCZh&ylwpft!O2)ZD95G;f2gIs}xY^_4v zf?oi^8pw4BHlTQ9FofJ(APFP47!bD&asy)5D7V<}>0pVXOgZ#Hiv+HdsEafzV=1x} zr3y2RjEU1(s?)N-HQIzDU1l{(k>*vY5LfA}QfYxAsf!2+c9J@D7Fi@XA#D4Ylk$+1 zF~B!~Hy=0Qy9G!a3w~Pg$%Zc-3W%?q7>R76RPlf<;4+EPoP25|Ph(`0xp(oa`T}gZkH)D0c`OU zP`iz7MxME#j?G_fIE|eJh@oxn>N}^V73)9bpy$!@CDy9YUg*_YsvRZ6I2>itE5clQ zNvS-XNRKPym5CP?UOAe|2z%!4Q5C8%_hw;M%Oi8b7GF099+uu%;^lo~u}l_MmGOJ^ z)?zZerUls@yKekF(M=3&!#JvWY`Cc~Ep*N8E5u?eM9o#-*1Ow!;F5-%b%IqCc%$nm z3$@0sxn^`BuxEC88P}PlEzgIRXy#K0b}U3QENtCyHW(`9jkOaK;M$n*c=~mp1T3#v zUAt@Dw>p+-d-GfjZZo(cnbcHt;^Q;g=V|h}{e0%^b21zDbB%0oMuSeTj!287H2GUp z%IH)r?&jtKDw8hrl3X0p!$mC$kd^eVaKQYMnNjz-E=>+6%IC;@u4;p(srR>NcbQwG n{pXj6<9X4v#7oYQen8@}-M9MAn&r}`Z+D%p!= 256: + return rc2_parameter_version + + if rc2_parameter_version is None: + return 4 # 32-bit default + + raise ValueError(unwrap( + ''' + Invalid RC2 parameter version found in EncryptionAlgorithm + parameters + ''' + )) + + if encryption_algo == 'pbes2': + key_length = self['parameters']['key_derivation_func']['parameters']['key_length'].native + if key_length is not None: + return key_length + + # If the KDF params don't specify the key size, we can infer it from + # the encryption scheme for all schemes except for RC5. However, in + # practical terms, neither OpenSSL or OS X support RC5 for PKCS#8 + # so it is unlikely to be an issue that is run into. + + return self['parameters']['encryption_scheme'].key_length + + if encryption_algo.find('.') == -1: + return { + 'pbes1_md2_des': 8, + 'pbes1_md5_des': 8, + 'pbes1_md2_rc2': 8, + 'pbes1_md5_rc2': 8, + 'pbes1_sha1_des': 8, + 'pbes1_sha1_rc2': 8, + 'pkcs12_sha1_rc4_128': 16, + 'pkcs12_sha1_rc4_40': 5, + 'pkcs12_sha1_tripledes_3key': 24, + 'pkcs12_sha1_tripledes_2key': 16, + 'pkcs12_sha1_rc2_128': 16, + 'pkcs12_sha1_rc2_40': 5, + }[encryption_algo] + + raise ValueError(unwrap( + ''' + Unrecognized encryption algorithm "%s" + ''', + encryption_algo + )) + + @property + def encryption_mode(self): + """ + Returns the name of the encryption mode to use. + + :return: + A unicode string from one of the following: "cbc", "ecb", "ofb", + "cfb", "wrap", "gcm", "ccm", "wrap_pad" + """ + + encryption_algo = self['algorithm'].native + + if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']): + return encryption_algo[7:] + + if encryption_algo[0:6] == 'pbes1_': + return 'cbc' + + if encryption_algo[0:7] == 'pkcs12_': + return 'cbc' + + if encryption_algo in set(['des', 'tripledes_3key', 'rc2', 'rc5']): + return 'cbc' + + if encryption_algo == 'pbes2': + return self['parameters']['encryption_scheme'].encryption_mode + + raise ValueError(unwrap( + ''' + Unrecognized encryption algorithm "%s" + ''', + encryption_algo + )) + + @property + def encryption_cipher(self): + """ + Returns the name of the symmetric encryption cipher to use. The key + length can be retrieved via the .key_length property to disabiguate + between different variations of TripleDES, AES, and the RC* ciphers. + + :return: + A unicode string from one of the following: "rc2", "rc5", "des", + "tripledes", "aes" + """ + + encryption_algo = self['algorithm'].native + + if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']): + return 'aes' + + if encryption_algo in set(['des', 'rc2', 'rc5']): + return encryption_algo + + if encryption_algo == 'tripledes_3key': + return 'tripledes' + + if encryption_algo == 'pbes2': + return self['parameters']['encryption_scheme'].encryption_cipher + + if encryption_algo.find('.') == -1: + return { + 'pbes1_md2_des': 'des', + 'pbes1_md5_des': 'des', + 'pbes1_md2_rc2': 'rc2', + 'pbes1_md5_rc2': 'rc2', + 'pbes1_sha1_des': 'des', + 'pbes1_sha1_rc2': 'rc2', + 'pkcs12_sha1_rc4_128': 'rc4', + 'pkcs12_sha1_rc4_40': 'rc4', + 'pkcs12_sha1_tripledes_3key': 'tripledes', + 'pkcs12_sha1_tripledes_2key': 'tripledes', + 'pkcs12_sha1_rc2_128': 'rc2', + 'pkcs12_sha1_rc2_40': 'rc2', + }[encryption_algo] + + raise ValueError(unwrap( + ''' + Unrecognized encryption algorithm "%s" + ''', + encryption_algo + )) + + @property + def encryption_block_size(self): + """ + Returns the block size of the encryption cipher, in bytes. + + :return: + An integer that is the block size in bytes + """ + + encryption_algo = self['algorithm'].native + + if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']): + return 16 + + cipher_map = { + 'des': 8, + 'tripledes_3key': 8, + 'rc2': 8, + } + if encryption_algo in cipher_map: + return cipher_map[encryption_algo] + + if encryption_algo == 'rc5': + return self['parameters'].parsed['block_size_in_bits'].native / 8 + + if encryption_algo == 'pbes2': + return self['parameters']['encryption_scheme'].encryption_block_size + + if encryption_algo.find('.') == -1: + return { + 'pbes1_md2_des': 8, + 'pbes1_md5_des': 8, + 'pbes1_md2_rc2': 8, + 'pbes1_md5_rc2': 8, + 'pbes1_sha1_des': 8, + 'pbes1_sha1_rc2': 8, + 'pkcs12_sha1_rc4_128': 0, + 'pkcs12_sha1_rc4_40': 0, + 'pkcs12_sha1_tripledes_3key': 8, + 'pkcs12_sha1_tripledes_2key': 8, + 'pkcs12_sha1_rc2_128': 8, + 'pkcs12_sha1_rc2_40': 8, + }[encryption_algo] + + raise ValueError(unwrap( + ''' + Unrecognized encryption algorithm "%s" + ''', + encryption_algo + )) + + @property + def encryption_iv(self): + """ + Returns the byte string of the initialization vector for the encryption + scheme. Only the PBES2 stores the IV in the params. For PBES1, the IV + is derived from the KDF and this property will return None. + + :return: + A byte string or None + """ + + encryption_algo = self['algorithm'].native + + if encryption_algo in set(['rc2', 'rc5']): + return self['parameters'].parsed['iv'].native + + # For DES/Triple DES and AES the IV is the entirety of the parameters + octet_string_iv_oids = set([ + 'des', + 'tripledes_3key', + 'aes128_cbc', + 'aes192_cbc', + 'aes256_cbc', + 'aes128_ofb', + 'aes192_ofb', + 'aes256_ofb', + ]) + if encryption_algo in octet_string_iv_oids: + return self['parameters'].native + + if encryption_algo == 'pbes2': + return self['parameters']['encryption_scheme'].encryption_iv + + # All of the PBES1 algos use their KDF to create the IV. For the pbkdf1, + # the KDF is told to generate a key that is an extra 8 bytes long, and + # that is used for the IV. For the PKCS#12 KDF, it is called with an id + # of 2 to generate the IV. In either case, we can't return the IV + # without knowing the user's password. + if encryption_algo.find('.') == -1: + return None + + raise ValueError(unwrap( + ''' + Unrecognized encryption algorithm "%s" + ''', + encryption_algo + )) + + +class Pbes2Params(Sequence): + _fields = [ + ('key_derivation_func', KdfAlgorithm), + ('encryption_scheme', EncryptionAlgorithm), + ] + + +class Pbmac1Params(Sequence): + _fields = [ + ('key_derivation_func', KdfAlgorithm), + ('message_auth_scheme', HmacAlgorithm), + ] + + +class Pkcs5MacId(ObjectIdentifier): + _map = { + '1.2.840.113549.1.5.14': 'pbmac1', + } + + +class Pkcs5MacAlgorithm(Sequence): + _fields = [ + ('algorithm', Pkcs5MacId), + ('parameters', Any), + ] + + _oid_pair = ('algorithm', 'parameters') + _oid_specs = { + 'pbmac1': Pbmac1Params, + } + + +EncryptionAlgorithm._oid_specs['pbes2'] = Pbes2Params diff --git a/venv/lib/python2.7/site-packages/asn1crypto/algos.pyc b/venv/lib/python2.7/site-packages/asn1crypto/algos.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94fc93e13285aa238e8a9b6667643859d7b7ddab GIT binary patch literal 34318 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/cms.py b/venv/lib/python2.7/site-packages/asn1crypto/cms.py new file mode 100644 index 0000000..2964f0a --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/cms.py @@ -0,0 +1,930 @@ +# coding: utf-8 + +""" +ASN.1 type classes for cryptographic message syntax (CMS). Structures are also +compatible with PKCS#7. Exports the following items: + + - AuthenticatedData() + - AuthEnvelopedData() + - CompressedData() + - ContentInfo() + - DigestedData() + - EncryptedData() + - EnvelopedData() + - SignedAndEnvelopedData() + - SignedData() + +Other type classes are defined that help compose the types listed above. +""" + +from __future__ import unicode_literals, division, absolute_import, print_function + +try: + import zlib +except (ImportError): + zlib = None + +from .algos import ( + _ForceNullParameters, + DigestAlgorithm, + EncryptionAlgorithm, + HmacAlgorithm, + KdfAlgorithm, + SignedDigestAlgorithm, +) +from .core import ( + Any, + BitString, + Choice, + Enumerated, + GeneralizedTime, + Integer, + ObjectIdentifier, + OctetBitString, + OctetString, + ParsableOctetString, + Sequence, + SequenceOf, + SetOf, + UTCTime, + UTF8String, +) +from .crl import CertificateList +from .keys import PublicKeyInfo +from .ocsp import OCSPResponse +from .x509 import Attributes, Certificate, Extensions, GeneralName, GeneralNames, Name + + +# These structures are taken from +# ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc + +class ExtendedCertificateInfo(Sequence): + _fields = [ + ('version', Integer), + ('certificate', Certificate), + ('attributes', Attributes), + ] + + +class ExtendedCertificate(Sequence): + _fields = [ + ('extended_certificate_info', ExtendedCertificateInfo), + ('signature_algorithm', SignedDigestAlgorithm), + ('signature', OctetBitString), + ] + + +# These structures are taken from https://tools.ietf.org/html/rfc5652, +# https://tools.ietf.org/html/rfc5083, http://tools.ietf.org/html/rfc2315, +# https://tools.ietf.org/html/rfc5940, https://tools.ietf.org/html/rfc3274, +# https://tools.ietf.org/html/rfc3281 + + +class CMSVersion(Integer): + _map = { + 0: 'v0', + 1: 'v1', + 2: 'v2', + 3: 'v3', + 4: 'v4', + 5: 'v5', + } + + +class CMSAttributeType(ObjectIdentifier): + _map = { + '1.2.840.113549.1.9.3': 'content_type', + '1.2.840.113549.1.9.4': 'message_digest', + '1.2.840.113549.1.9.5': 'signing_time', + '1.2.840.113549.1.9.6': 'counter_signature', + # https://tools.ietf.org/html/rfc3161#page-20 + '1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token', + # https://tools.ietf.org/html/rfc6211#page-5 + '1.2.840.113549.1.9.52': 'cms_algorithm_protection', + } + + +class Time(Choice): + _alternatives = [ + ('utc_time', UTCTime), + ('generalized_time', GeneralizedTime), + ] + + +class ContentType(ObjectIdentifier): + _map = { + '1.2.840.113549.1.7.1': 'data', + '1.2.840.113549.1.7.2': 'signed_data', + '1.2.840.113549.1.7.3': 'enveloped_data', + '1.2.840.113549.1.7.4': 'signed_and_enveloped_data', + '1.2.840.113549.1.7.5': 'digested_data', + '1.2.840.113549.1.7.6': 'encrypted_data', + '1.2.840.113549.1.9.16.1.2': 'authenticated_data', + '1.2.840.113549.1.9.16.1.9': 'compressed_data', + '1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data', + } + + +class CMSAlgorithmProtection(Sequence): + _fields = [ + ('digest_algorithm', DigestAlgorithm), + ('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}), + ('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}), + ] + + +class SetOfContentType(SetOf): + _child_spec = ContentType + + +class SetOfOctetString(SetOf): + _child_spec = OctetString + + +class SetOfTime(SetOf): + _child_spec = Time + + +class SetOfAny(SetOf): + _child_spec = Any + + +class SetOfCMSAlgorithmProtection(SetOf): + _child_spec = CMSAlgorithmProtection + + +class CMSAttribute(Sequence): + _fields = [ + ('type', CMSAttributeType), + ('values', None), + ] + + _oid_specs = {} + + def _values_spec(self): + return self._oid_specs.get(self['type'].native, SetOfAny) + + _spec_callbacks = { + 'values': _values_spec + } + + +class CMSAttributes(SetOf): + _child_spec = CMSAttribute + + +class IssuerSerial(Sequence): + _fields = [ + ('issuer', GeneralNames), + ('serial', Integer), + ('issuer_uid', OctetBitString, {'optional': True}), + ] + + +class AttCertVersion(Integer): + _map = { + 0: 'v1', + 1: 'v2', + } + + +class AttCertSubject(Choice): + _alternatives = [ + ('base_certificate_id', IssuerSerial, {'explicit': 0}), + ('subject_name', GeneralNames, {'explicit': 1}), + ] + + +class AttCertValidityPeriod(Sequence): + _fields = [ + ('not_before_time', GeneralizedTime), + ('not_after_time', GeneralizedTime), + ] + + +class AttributeCertificateInfoV1(Sequence): + _fields = [ + ('version', AttCertVersion, {'default': 'v1'}), + ('subject', AttCertSubject), + ('issuer', GeneralNames), + ('signature', SignedDigestAlgorithm), + ('serial_number', Integer), + ('att_cert_validity_period', AttCertValidityPeriod), + ('attributes', Attributes), + ('issuer_unique_id', OctetBitString, {'optional': True}), + ('extensions', Extensions, {'optional': True}), + ] + + +class AttributeCertificateV1(Sequence): + _fields = [ + ('ac_info', AttributeCertificateInfoV1), + ('signature_algorithm', SignedDigestAlgorithm), + ('signature', OctetBitString), + ] + + +class DigestedObjectType(Enumerated): + _map = { + 0: 'public_key', + 1: 'public_key_cert', + 2: 'other_objy_types', + } + + +class ObjectDigestInfo(Sequence): + _fields = [ + ('digested_object_type', DigestedObjectType), + ('other_object_type_id', ObjectIdentifier, {'optional': True}), + ('digest_algorithm', DigestAlgorithm), + ('object_digest', OctetBitString), + ] + + +class Holder(Sequence): + _fields = [ + ('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}), + ('entity_name', GeneralNames, {'implicit': 1, 'optional': True}), + ('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}), + ] + + +class V2Form(Sequence): + _fields = [ + ('issuer_name', GeneralNames, {'optional': True}), + ('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}), + ('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}), + ] + + +class AttCertIssuer(Choice): + _alternatives = [ + ('v1_form', GeneralNames), + ('v2_form', V2Form, {'explicit': 0}), + ] + + +class IetfAttrValue(Choice): + _alternatives = [ + ('octets', OctetString), + ('oid', ObjectIdentifier), + ('string', UTF8String), + ] + + +class IetfAttrValues(SequenceOf): + _child_spec = IetfAttrValue + + +class IetfAttrSyntax(Sequence): + _fields = [ + ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}), + ('values', IetfAttrValues), + ] + + +class SetOfIetfAttrSyntax(SetOf): + _child_spec = IetfAttrSyntax + + +class SvceAuthInfo(Sequence): + _fields = [ + ('service', GeneralName), + ('ident', GeneralName), + ('auth_info', OctetString, {'optional': True}), + ] + + +class SetOfSvceAuthInfo(SetOf): + _child_spec = SvceAuthInfo + + +class RoleSyntax(Sequence): + _fields = [ + ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}), + ('role_name', GeneralName, {'implicit': 1}), + ] + + +class SetOfRoleSyntax(SetOf): + _child_spec = RoleSyntax + + +class ClassList(BitString): + _map = { + 0: 'unmarked', + 1: 'unclassified', + 2: 'restricted', + 3: 'confidential', + 4: 'secret', + 5: 'top_secret', + } + + +class SecurityCategory(Sequence): + _fields = [ + ('type', ObjectIdentifier, {'implicit': 0}), + ('value', Any, {'implicit': 1}), + ] + + +class SetOfSecurityCategory(SetOf): + _child_spec = SecurityCategory + + +class Clearance(Sequence): + _fields = [ + ('policy_id', ObjectIdentifier, {'implicit': 0}), + ('class_list', ClassList, {'implicit': 1, 'default': 'unclassified'}), + ('security_categories', SetOfSecurityCategory, {'implicit': 2, 'optional': True}), + ] + + +class SetOfClearance(SetOf): + _child_spec = Clearance + + +class BigTime(Sequence): + _fields = [ + ('major', Integer), + ('fractional_seconds', Integer), + ('sign', Integer, {'optional': True}), + ] + + +class LeapData(Sequence): + _fields = [ + ('leap_time', BigTime), + ('action', Integer), + ] + + +class SetOfLeapData(SetOf): + _child_spec = LeapData + + +class TimingMetrics(Sequence): + _fields = [ + ('ntp_time', BigTime), + ('offset', BigTime), + ('delay', BigTime), + ('expiration', BigTime), + ('leap_event', SetOfLeapData, {'optional': True}), + ] + + +class SetOfTimingMetrics(SetOf): + _child_spec = TimingMetrics + + +class TimingPolicy(Sequence): + _fields = [ + ('policy_id', SequenceOf, {'spec': ObjectIdentifier}), + ('max_offset', BigTime, {'explicit': 0, 'optional': True}), + ('max_delay', BigTime, {'explicit': 1, 'optional': True}), + ] + + +class SetOfTimingPolicy(SetOf): + _child_spec = TimingPolicy + + +class AttCertAttributeType(ObjectIdentifier): + _map = { + '1.3.6.1.5.5.7.10.1': 'authentication_info', + '1.3.6.1.5.5.7.10.2': 'access_identity', + '1.3.6.1.5.5.7.10.3': 'charging_identity', + '1.3.6.1.5.5.7.10.4': 'group', + '2.5.4.72': 'role', + '2.5.4.55': 'clearance', + '1.3.6.1.4.1.601.10.4.1': 'timing_metrics', + '1.3.6.1.4.1.601.10.4.2': 'timing_policy', + } + + +class AttCertAttribute(Sequence): + _fields = [ + ('type', AttCertAttributeType), + ('values', None), + ] + + _oid_specs = { + 'authentication_info': SetOfSvceAuthInfo, + 'access_identity': SetOfSvceAuthInfo, + 'charging_identity': SetOfIetfAttrSyntax, + 'group': SetOfIetfAttrSyntax, + 'role': SetOfRoleSyntax, + 'clearance': SetOfClearance, + 'timing_metrics': SetOfTimingMetrics, + 'timing_policy': SetOfTimingPolicy, + } + + def _values_spec(self): + return self._oid_specs.get(self['type'].native, SetOfAny) + + _spec_callbacks = { + 'values': _values_spec + } + + +class AttCertAttributes(SequenceOf): + _child_spec = AttCertAttribute + + +class AttributeCertificateInfoV2(Sequence): + _fields = [ + ('version', AttCertVersion), + ('holder', Holder), + ('issuer', AttCertIssuer), + ('signature', SignedDigestAlgorithm), + ('serial_number', Integer), + ('att_cert_validity_period', AttCertValidityPeriod), + ('attributes', AttCertAttributes), + ('issuer_unique_id', OctetBitString, {'optional': True}), + ('extensions', Extensions, {'optional': True}), + ] + + +class AttributeCertificateV2(Sequence): + # Handle the situation where a V2 cert is encoded as V1 + _bad_tag = 1 + + _fields = [ + ('ac_info', AttributeCertificateInfoV2), + ('signature_algorithm', SignedDigestAlgorithm), + ('signature', OctetBitString), + ] + + +class OtherCertificateFormat(Sequence): + _fields = [ + ('other_cert_format', ObjectIdentifier), + ('other_cert', Any), + ] + + +class CertificateChoices(Choice): + _alternatives = [ + ('certificate', Certificate), + ('extended_certificate', ExtendedCertificate, {'implicit': 0}), + ('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}), + ('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}), + ('other', OtherCertificateFormat, {'implicit': 3}), + ] + + def validate(self, class_, tag, contents): + """ + Ensures that the class and tag specified exist as an alternative. This + custom version fixes parsing broken encodings there a V2 attribute + # certificate is encoded as a V1 + + :param class_: + The integer class_ from the encoded value header + + :param tag: + The integer tag from the encoded value header + + :param contents: + A byte string of the contents of the value - used when the object + is explicitly tagged + + :raises: + ValueError - when value is not a valid alternative + """ + + super(CertificateChoices, self).validate(class_, tag, contents) + if self._choice == 2: + if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2': + self._choice = 3 + + +class CertificateSet(SetOf): + _child_spec = CertificateChoices + + +class ContentInfo(Sequence): + _fields = [ + ('content_type', ContentType), + ('content', Any, {'explicit': 0, 'optional': True}), + ] + + _oid_pair = ('content_type', 'content') + _oid_specs = {} + + +class SetOfContentInfo(SetOf): + _child_spec = ContentInfo + + +class EncapsulatedContentInfo(Sequence): + _fields = [ + ('content_type', ContentType), + ('content', ParsableOctetString, {'explicit': 0, 'optional': True}), + ] + + _oid_pair = ('content_type', 'content') + _oid_specs = {} + + +class IssuerAndSerialNumber(Sequence): + _fields = [ + ('issuer', Name), + ('serial_number', Integer), + ] + + +class SignerIdentifier(Choice): + _alternatives = [ + ('issuer_and_serial_number', IssuerAndSerialNumber), + ('subject_key_identifier', OctetString, {'implicit': 0}), + ] + + +class DigestAlgorithms(SetOf): + _child_spec = DigestAlgorithm + + +class CertificateRevocationLists(SetOf): + _child_spec = CertificateList + + +class SCVPReqRes(Sequence): + _fields = [ + ('request', ContentInfo, {'explicit': 0, 'optional': True}), + ('response', ContentInfo), + ] + + +class OtherRevInfoFormatId(ObjectIdentifier): + _map = { + '1.3.6.1.5.5.7.16.2': 'ocsp_response', + '1.3.6.1.5.5.7.16.4': 'scvp', + } + + +class OtherRevocationInfoFormat(Sequence): + _fields = [ + ('other_rev_info_format', OtherRevInfoFormatId), + ('other_rev_info', Any), + ] + + _oid_pair = ('other_rev_info_format', 'other_rev_info') + _oid_specs = { + 'ocsp_response': OCSPResponse, + 'scvp': SCVPReqRes, + } + + +class RevocationInfoChoice(Choice): + _alternatives = [ + ('crl', CertificateList), + ('other', OtherRevocationInfoFormat, {'implicit': 1}), + ] + + +class RevocationInfoChoices(SetOf): + _child_spec = RevocationInfoChoice + + +class SignerInfo(Sequence): + _fields = [ + ('version', CMSVersion), + ('sid', SignerIdentifier), + ('digest_algorithm', DigestAlgorithm), + ('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}), + ('signature_algorithm', SignedDigestAlgorithm), + ('signature', OctetString), + ('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), + ] + + +class SignerInfos(SetOf): + _child_spec = SignerInfo + + +class SignedData(Sequence): + _fields = [ + ('version', CMSVersion), + ('digest_algorithms', DigestAlgorithms), + ('encap_content_info', None), + ('certificates', CertificateSet, {'implicit': 0, 'optional': True}), + ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}), + ('signer_infos', SignerInfos), + ] + + def _encap_content_info_spec(self): + # If the encap_content_info is version v1, then this could be a PKCS#7 + # structure, or a CMS structure. CMS wraps the encoded value in an + # Octet String tag. + + # If the version is greater than 1, it is definite CMS + if self['version'].native != 'v1': + return EncapsulatedContentInfo + + # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with + # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which + # allows Any + return ContentInfo + + _spec_callbacks = { + 'encap_content_info': _encap_content_info_spec + } + + +class OriginatorInfo(Sequence): + _fields = [ + ('certs', CertificateSet, {'implicit': 0, 'optional': True}), + ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}), + ] + + +class RecipientIdentifier(Choice): + _alternatives = [ + ('issuer_and_serial_number', IssuerAndSerialNumber), + ('subject_key_identifier', OctetString, {'implicit': 0}), + ] + + +class KeyEncryptionAlgorithmId(ObjectIdentifier): + _map = { + '1.2.840.113549.1.1.1': 'rsa', + '2.16.840.1.101.3.4.1.5': 'aes128_wrap', + '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad', + '2.16.840.1.101.3.4.1.25': 'aes192_wrap', + '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad', + '2.16.840.1.101.3.4.1.45': 'aes256_wrap', + '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad', + } + + +class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence): + _fields = [ + ('algorithm', KeyEncryptionAlgorithmId), + ('parameters', Any, {'optional': True}), + ] + + +class KeyTransRecipientInfo(Sequence): + _fields = [ + ('version', CMSVersion), + ('rid', RecipientIdentifier), + ('key_encryption_algorithm', KeyEncryptionAlgorithm), + ('encrypted_key', OctetString), + ] + + +class OriginatorIdentifierOrKey(Choice): + _alternatives = [ + ('issuer_and_serial_number', IssuerAndSerialNumber), + ('subject_key_identifier', OctetString, {'implicit': 0}), + ('originator_key', PublicKeyInfo, {'implicit': 1}), + ] + + +class OtherKeyAttribute(Sequence): + _fields = [ + ('key_attr_id', ObjectIdentifier), + ('key_attr', Any), + ] + + +class RecipientKeyIdentifier(Sequence): + _fields = [ + ('subject_key_identifier', OctetString), + ('date', GeneralizedTime, {'optional': True}), + ('other', OtherKeyAttribute, {'optional': True}), + ] + + +class KeyAgreementRecipientIdentifier(Choice): + _alternatives = [ + ('issuer_and_serial_number', IssuerAndSerialNumber), + ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}), + ] + + +class RecipientEncryptedKey(Sequence): + _fields = [ + ('rid', KeyAgreementRecipientIdentifier), + ('encrypted_key', OctetString), + ] + + +class RecipientEncryptedKeys(SequenceOf): + _child_spec = RecipientEncryptedKey + + +class KeyAgreeRecipientInfo(Sequence): + _fields = [ + ('version', CMSVersion), + ('originator', OriginatorIdentifierOrKey, {'explicit': 0}), + ('ukm', OctetString, {'explicit': 1, 'optional': True}), + ('key_encryption_algorithm', KeyEncryptionAlgorithm), + ('recipient_encrypted_keys', RecipientEncryptedKeys), + ] + + +class KEKIdentifier(Sequence): + _fields = [ + ('key_identifier', OctetString), + ('date', GeneralizedTime, {'optional': True}), + ('other', OtherKeyAttribute, {'optional': True}), + ] + + +class KEKRecipientInfo(Sequence): + _fields = [ + ('version', CMSVersion), + ('kekid', KEKIdentifier), + ('key_encryption_algorithm', KeyEncryptionAlgorithm), + ('encrypted_key', OctetString), + ] + + +class PasswordRecipientInfo(Sequence): + _fields = [ + ('version', CMSVersion), + ('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}), + ('key_encryption_algorithm', KeyEncryptionAlgorithm), + ('encrypted_key', OctetString), + ] + + +class OtherRecipientInfo(Sequence): + _fields = [ + ('ori_type', ObjectIdentifier), + ('ori_value', Any), + ] + + +class RecipientInfo(Choice): + _alternatives = [ + ('ktri', KeyTransRecipientInfo), + ('kari', KeyAgreeRecipientInfo, {'implicit': 1}), + ('kekri', KEKRecipientInfo, {'implicit': 2}), + ('pwri', PasswordRecipientInfo, {'implicit': 3}), + ('ori', OtherRecipientInfo, {'implicit': 4}), + ] + + +class RecipientInfos(SetOf): + _child_spec = RecipientInfo + + +class EncryptedContentInfo(Sequence): + _fields = [ + ('content_type', ContentType), + ('content_encryption_algorithm', EncryptionAlgorithm), + ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}), + ] + + +class EnvelopedData(Sequence): + _fields = [ + ('version', CMSVersion), + ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}), + ('recipient_infos', RecipientInfos), + ('encrypted_content_info', EncryptedContentInfo), + ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), + ] + + +class SignedAndEnvelopedData(Sequence): + _fields = [ + ('version', CMSVersion), + ('recipient_infos', RecipientInfos), + ('digest_algorithms', DigestAlgorithms), + ('encrypted_content_info', EncryptedContentInfo), + ('certificates', CertificateSet, {'implicit': 0, 'optional': True}), + ('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}), + ('signer_infos', SignerInfos), + ] + + +class DigestedData(Sequence): + _fields = [ + ('version', CMSVersion), + ('digest_algorithm', DigestAlgorithm), + ('encap_content_info', None), + ('digest', OctetString), + ] + + def _encap_content_info_spec(self): + # If the encap_content_info is version v1, then this could be a PKCS#7 + # structure, or a CMS structure. CMS wraps the encoded value in an + # Octet String tag. + + # If the version is greater than 1, it is definite CMS + if self['version'].native != 'v1': + return EncapsulatedContentInfo + + # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with + # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which + # allows Any + return ContentInfo + + _spec_callbacks = { + 'encap_content_info': _encap_content_info_spec + } + + +class EncryptedData(Sequence): + _fields = [ + ('version', CMSVersion), + ('encrypted_content_info', EncryptedContentInfo), + ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), + ] + + +class AuthenticatedData(Sequence): + _fields = [ + ('version', CMSVersion), + ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}), + ('recipient_infos', RecipientInfos), + ('mac_algorithm', HmacAlgorithm), + ('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}), + # This does not require the _spec_callbacks approach of SignedData and + # DigestedData since AuthenticatedData was not part of PKCS#7 + ('encap_content_info', EncapsulatedContentInfo), + ('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}), + ('mac', OctetString), + ('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}), + ] + + +class AuthEnvelopedData(Sequence): + _fields = [ + ('version', CMSVersion), + ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}), + ('recipient_infos', RecipientInfos), + ('auth_encrypted_content_info', EncryptedContentInfo), + ('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), + ('mac', OctetString), + ('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}), + ] + + +class CompressionAlgorithmId(ObjectIdentifier): + _map = { + '1.2.840.113549.1.9.16.3.8': 'zlib', + } + + +class CompressionAlgorithm(Sequence): + _fields = [ + ('algorithm', CompressionAlgorithmId), + ('parameters', Any, {'optional': True}), + ] + + +class CompressedData(Sequence): + _fields = [ + ('version', CMSVersion), + ('compression_algorithm', CompressionAlgorithm), + ('encap_content_info', EncapsulatedContentInfo), + ] + + _decompressed = None + + @property + def decompressed(self): + if self._decompressed is None: + if zlib is None: + raise SystemError('The zlib module is not available') + self._decompressed = zlib.decompress(self['encap_content_info']['content'].native) + return self._decompressed + + +ContentInfo._oid_specs = { + 'data': OctetString, + 'signed_data': SignedData, + 'enveloped_data': EnvelopedData, + 'signed_and_enveloped_data': SignedAndEnvelopedData, + 'digested_data': DigestedData, + 'encrypted_data': EncryptedData, + 'authenticated_data': AuthenticatedData, + 'compressed_data': CompressedData, + 'authenticated_enveloped_data': AuthEnvelopedData, +} + + +EncapsulatedContentInfo._oid_specs = { + 'signed_data': SignedData, + 'enveloped_data': EnvelopedData, + 'signed_and_enveloped_data': SignedAndEnvelopedData, + 'digested_data': DigestedData, + 'encrypted_data': EncryptedData, + 'authenticated_data': AuthenticatedData, + 'compressed_data': CompressedData, + 'authenticated_enveloped_data': AuthEnvelopedData, +} + + +CMSAttribute._oid_specs = { + 'content_type': SetOfContentType, + 'message_digest': SetOfOctetString, + 'signing_time': SetOfTime, + 'counter_signature': SignerInfos, + 'signature_time_stamp_token': SetOfContentInfo, + 'cms_algorithm_protection': SetOfCMSAlgorithmProtection, +} diff --git a/venv/lib/python2.7/site-packages/asn1crypto/cms.pyc b/venv/lib/python2.7/site-packages/asn1crypto/cms.pyc new file mode 100644 index 0000000000000000000000000000000000000000..338f7596446a8e5c8547f83730a6bc95ec471fbc GIT binary patch literal 40980 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/core.py b/venv/lib/python2.7/site-packages/asn1crypto/core.py new file mode 100644 index 0000000..97eeda3 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/core.py @@ -0,0 +1,5234 @@ +# coding: utf-8 + +""" +ASN.1 type classes for universal types. Exports the following items: + + - load() + - Any() + - Asn1Value() + - BitString() + - BMPString() + - Boolean() + - CharacterString() + - Choice() + - EmbeddedPdv() + - Enumerated() + - GeneralizedTime() + - GeneralString() + - GraphicString() + - IA5String() + - InstanceOf() + - Integer() + - IntegerBitString() + - IntegerOctetString() + - Null() + - NumericString() + - ObjectDescriptor() + - ObjectIdentifier() + - OctetBitString() + - OctetString() + - PrintableString() + - Real() + - RelativeOid() + - Sequence() + - SequenceOf() + - Set() + - SetOf() + - TeletexString() + - UniversalString() + - UTCTime() + - UTF8String() + - VideotexString() + - VisibleString() + - VOID + - Void() + +Other type classes are defined that help compose the types listed above. +""" + +from __future__ import unicode_literals, division, absolute_import, print_function + +from datetime import datetime, timedelta +import binascii +import copy +import math +import re +import sys + +from . import _teletex_codec +from ._errors import unwrap +from ._ordereddict import OrderedDict +from ._types import type_name, str_cls, byte_cls, int_types, chr_cls +from .parser import _parse, _dump_header +from .util import int_to_bytes, int_from_bytes, timezone, extended_datetime + +if sys.version_info <= (3,): + from cStringIO import StringIO as BytesIO + + range = xrange # noqa + _PY2 = True + +else: + from io import BytesIO + + _PY2 = False + + +_teletex_codec.register() + + +CLASS_NUM_TO_NAME_MAP = { + 0: 'universal', + 1: 'application', + 2: 'context', + 3: 'private', +} + +CLASS_NAME_TO_NUM_MAP = { + 'universal': 0, + 'application': 1, + 'context': 2, + 'private': 3, + 0: 0, + 1: 1, + 2: 2, + 3: 3, +} + +METHOD_NUM_TO_NAME_MAP = { + 0: 'primitive', + 1: 'constructed', +} + + +_OID_RE = re.compile(r'^\d+(\.\d+)*$') + + +# A global tracker to ensure that _setup() is called for every class, even +# if is has been called for a parent class. This allows different _fields +# definitions for child classes. Without such a construct, the child classes +# would just see the parent class attributes and would use them. +_SETUP_CLASSES = {} + + +def load(encoded_data, strict=False): + """ + Loads a BER/DER-encoded byte string and construct a universal object based + on the tag value: + + - 1: Boolean + - 2: Integer + - 3: BitString + - 4: OctetString + - 5: Null + - 6: ObjectIdentifier + - 7: ObjectDescriptor + - 8: InstanceOf + - 9: Real + - 10: Enumerated + - 11: EmbeddedPdv + - 12: UTF8String + - 13: RelativeOid + - 16: Sequence, + - 17: Set + - 18: NumericString + - 19: PrintableString + - 20: TeletexString + - 21: VideotexString + - 22: IA5String + - 23: UTCTime + - 24: GeneralizedTime + - 25: GraphicString + - 26: VisibleString + - 27: GeneralString + - 28: UniversalString + - 29: CharacterString + - 30: BMPString + + :param encoded_data: + A byte string of BER or DER-encoded data + + :param strict: + A boolean indicating if trailing data should be forbidden - if so, a + ValueError will be raised when trailing data exists + + :raises: + ValueError - when strict is True and trailing data is present + ValueError - when the encoded value tag a tag other than listed above + ValueError - when the ASN.1 header length is longer than the data + TypeError - when encoded_data is not a byte string + + :return: + An instance of the one of the universal classes + """ + + return Asn1Value.load(encoded_data, strict=strict) + + +class Asn1Value(object): + """ + The basis of all ASN.1 values + """ + + # The integer 0 for primitive, 1 for constructed + method = None + + # An integer 0 through 3 - see CLASS_NUM_TO_NAME_MAP for value + class_ = None + + # An integer 1 or greater indicating the tag number + tag = None + + # An alternate tag allowed for this type - used for handling broken + # structures where a string value is encoded using an incorrect tag + _bad_tag = None + + # If the value has been implicitly tagged + implicit = False + + # If explicitly tagged, a tuple of 2-element tuples containing the + # class int and tag int, from innermost to outermost + explicit = None + + # The BER/DER header bytes + _header = None + + # Raw encoded value bytes not including class, method, tag, length header + contents = None + + # The BER/DER trailer bytes + _trailer = b'' + + # The native python representation of the value - this is not used by + # some classes since they utilize _bytes or _unicode + _native = None + + @classmethod + def load(cls, encoded_data, strict=False, **kwargs): + """ + Loads a BER/DER-encoded byte string using the current class as the spec + + :param encoded_data: + A byte string of BER or DER-encoded data + + :param strict: + A boolean indicating if trailing data should be forbidden - if so, a + ValueError will be raised when trailing data exists + + :return: + An instance of the current class + """ + + if not isinstance(encoded_data, byte_cls): + raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data)) + + spec = None + if cls.tag is not None: + spec = cls + + value, _ = _parse_build(encoded_data, spec=spec, spec_params=kwargs, strict=strict) + return value + + def __init__(self, explicit=None, implicit=None, no_explicit=False, tag_type=None, class_=None, tag=None, + optional=None, default=None, contents=None): + """ + The optional parameter is not used, but rather included so we don't + have to delete it from the parameter dictionary when passing as keyword + args + + :param explicit: + An int tag number for explicit tagging, or a 2-element tuple of + class and tag. + + :param implicit: + An int tag number for implicit tagging, or a 2-element tuple of + class and tag. + + :param no_explicit: + If explicit tagging info should be removed from this instance. + Used internally to allow contructing the underlying value that + has been wrapped in an explicit tag. + + :param tag_type: + None for normal values, or one of "implicit", "explicit" for tagged + values. Deprecated in favor of explicit and implicit params. + + :param class_: + The class for the value - defaults to "universal" if tag_type is + None, otherwise defaults to "context". Valid values include: + - "universal" + - "application" + - "context" + - "private" + Deprecated in favor of explicit and implicit params. + + :param tag: + The integer tag to override - usually this is used with tag_type or + class_. Deprecated in favor of explicit and implicit params. + + :param optional: + Dummy parameter that allows "optional" key in spec param dicts + + :param default: + The default value to use if the value is currently None + + :param contents: + A byte string of the encoded contents of the value + + :raises: + ValueError - when implicit, explicit, tag_type, class_ or tag are invalid values + """ + + try: + if self.__class__ not in _SETUP_CLASSES: + cls = self.__class__ + # Allow explicit to be specified as a simple 2-element tuple + # instead of requiring the user make a nested tuple + if cls.explicit is not None and isinstance(cls.explicit[0], int_types): + cls.explicit = (cls.explicit, ) + if hasattr(cls, '_setup'): + self._setup() + _SETUP_CLASSES[cls] = True + + # Normalize tagging values + if explicit is not None: + if isinstance(explicit, int_types): + if class_ is None: + class_ = 'context' + explicit = (class_, explicit) + # Prevent both explicit and tag_type == 'explicit' + if tag_type == 'explicit': + tag_type = None + tag = None + + if implicit is not None: + if isinstance(implicit, int_types): + if class_ is None: + class_ = 'context' + implicit = (class_, implicit) + # Prevent both implicit and tag_type == 'implicit' + if tag_type == 'implicit': + tag_type = None + tag = None + + # Convert old tag_type API to explicit/implicit params + if tag_type is not None: + if class_ is None: + class_ = 'context' + if tag_type == 'explicit': + explicit = (class_, tag) + elif tag_type == 'implicit': + implicit = (class_, tag) + else: + raise ValueError(unwrap( + ''' + tag_type must be one of "implicit", "explicit", not %s + ''', + repr(tag_type) + )) + + if explicit is not None: + # Ensure we have a tuple of 2-element tuples + if len(explicit) == 2 and isinstance(explicit[1], int_types): + explicit = (explicit, ) + for class_, tag in explicit: + invalid_class = None + if isinstance(class_, int_types): + if class_ not in CLASS_NUM_TO_NAME_MAP: + invalid_class = class_ + else: + if class_ not in CLASS_NAME_TO_NUM_MAP: + invalid_class = class_ + class_ = CLASS_NAME_TO_NUM_MAP[class_] + if invalid_class is not None: + raise ValueError(unwrap( + ''' + explicit class must be one of "universal", "application", + "context", "private", not %s + ''', + repr(invalid_class) + )) + if tag is not None: + if not isinstance(tag, int_types): + raise TypeError(unwrap( + ''' + explicit tag must be an integer, not %s + ''', + type_name(tag) + )) + if self.explicit is None: + self.explicit = ((class_, tag), ) + else: + self.explicit = self.explicit + ((class_, tag), ) + + elif implicit is not None: + class_, tag = implicit + if class_ not in CLASS_NAME_TO_NUM_MAP: + raise ValueError(unwrap( + ''' + implicit class must be one of "universal", "application", + "context", "private", not %s + ''', + repr(class_) + )) + if tag is not None: + if not isinstance(tag, int_types): + raise TypeError(unwrap( + ''' + implicit tag must be an integer, not %s + ''', + type_name(tag) + )) + self.class_ = CLASS_NAME_TO_NUM_MAP[class_] + self.tag = tag + self.implicit = True + else: + if class_ is not None: + if class_ not in CLASS_NUM_TO_NAME_MAP: + raise ValueError(unwrap( + ''' + class_ must be one of "universal", "application", + "context", "private", not %s + ''', + repr(class_) + )) + self.class_ = CLASS_NAME_TO_NUM_MAP[class_] + + if tag is not None: + self.tag = tag + + if no_explicit: + self.explicit = None + + if contents is not None: + self.contents = contents + + elif default is not None: + self.set(default) + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args + raise e + + def __str__(self): + """ + Since str is different in Python 2 and 3, this calls the appropriate + method, __unicode__() or __bytes__() + + :return: + A unicode string + """ + + if _PY2: + return self.__bytes__() + else: + return self.__unicode__() + + def __repr__(self): + """ + :return: + A unicode string + """ + + if _PY2: + return '<%s %s b%s>' % (type_name(self), id(self), repr(self.dump())) + else: + return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump())) + + def __bytes__(self): + """ + A fall-back method for print() in Python 2 + + :return: + A byte string of the output of repr() + """ + + return self.__repr__().encode('utf-8') + + def __unicode__(self): + """ + A fall-back method for print() in Python 3 + + :return: + A unicode string of the output of repr() + """ + + return self.__repr__() + + def _new_instance(self): + """ + Constructs a new copy of the current object, preserving any tagging + + :return: + An Asn1Value object + """ + + new_obj = self.__class__() + new_obj.class_ = self.class_ + new_obj.tag = self.tag + new_obj.implicit = self.implicit + new_obj.explicit = self.explicit + return new_obj + + def __copy__(self): + """ + Implements the copy.copy() interface + + :return: + A new shallow copy of the current Asn1Value object + """ + + new_obj = self._new_instance() + new_obj._copy(self, copy.copy) + return new_obj + + def __deepcopy__(self, memo): + """ + Implements the copy.deepcopy() interface + + :param memo: + A dict for memoization + + :return: + A new deep copy of the current Asn1Value object + """ + + new_obj = self._new_instance() + memo[id(self)] = new_obj + new_obj._copy(self, copy.deepcopy) + return new_obj + + def copy(self): + """ + Copies the object, preserving any special tagging from it + + :return: + An Asn1Value object + """ + + return copy.deepcopy(self) + + def retag(self, tagging, tag=None): + """ + Copies the object, applying a new tagging to it + + :param tagging: + A dict containing the keys "explicit" and "implicit". Legacy + API allows a unicode string of "implicit" or "explicit". + + :param tag: + A integer tag number. Only used when tagging is a unicode string. + + :return: + An Asn1Value object + """ + + # This is required to preserve the old API + if not isinstance(tagging, dict): + tagging = {tagging: tag} + new_obj = self.__class__(explicit=tagging.get('explicit'), implicit=tagging.get('implicit')) + new_obj._copy(self, copy.deepcopy) + return new_obj + + def untag(self): + """ + Copies the object, removing any special tagging from it + + :return: + An Asn1Value object + """ + + new_obj = self.__class__() + new_obj._copy(self, copy.deepcopy) + return new_obj + + def _copy(self, other, copy_func): + """ + Copies the contents of another Asn1Value object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + if self.__class__ != other.__class__: + raise TypeError(unwrap( + ''' + Can not copy values from %s object to %s object + ''', + type_name(other), + type_name(self) + )) + + self.contents = other.contents + self._native = copy_func(other._native) + + def debug(self, nest_level=1): + """ + Show the binary data and parsed data in a tree structure + """ + + prefix = ' ' * nest_level + + # This interacts with Any and moves the tag, implicit, explicit, _header, + # contents, _footer to the parsed value so duplicate data isn't present + has_parsed = hasattr(self, 'parsed') + + _basic_debug(prefix, self) + if has_parsed: + self.parsed.debug(nest_level + 2) + elif hasattr(self, 'chosen'): + self.chosen.debug(nest_level + 2) + else: + if _PY2 and isinstance(self.native, byte_cls): + print('%s Native: b%s' % (prefix, repr(self.native))) + else: + print('%s Native: %s' % (prefix, self.native)) + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + contents = self.contents + + if self._header is None or force: + if isinstance(self, Constructable) and self._indefinite: + self.method = 0 + + header = _dump_header(self.class_, self.method, self.tag, self.contents) + + if self.explicit is not None: + for class_, tag in self.explicit: + header = _dump_header(class_, 1, tag, header + self.contents) + header + + self._header = header + self._trailer = b'' + + return self._header + contents + + +class ValueMap(): + """ + Basic functionality that allows for mapping values from ints or OIDs to + python unicode strings + """ + + # A dict from primitive value (int or OID) to unicode string. This needs + # to be defined in the source code + _map = None + + # A dict from unicode string to int/OID. This is automatically generated + # from _map the first time it is needed + _reverse_map = None + + def _setup(self): + """ + Generates _reverse_map from _map + """ + + cls = self.__class__ + if cls._map is None or cls._reverse_map is not None: + return + cls._reverse_map = {} + for key, value in cls._map.items(): + cls._reverse_map[value] = key + + +class Castable(object): + """ + A mixin to handle converting an object between different classes that + represent the same encoded value, but with different rules for converting + to and from native Python values + """ + + def cast(self, other_class): + """ + Converts the current object into an object of a different class. The + new class must use the ASN.1 encoding for the value. + + :param other_class: + The class to instantiate the new object from + + :return: + An instance of the type other_class + """ + + if other_class.tag != self.__class__.tag: + raise TypeError(unwrap( + ''' + Can not covert a value from %s object to %s object since they + use different tags: %d versus %d + ''', + type_name(other_class), + type_name(self), + other_class.tag, + self.__class__.tag + )) + + new_obj = other_class() + new_obj.class_ = self.class_ + new_obj.implicit = self.implicit + new_obj.explicit = self.explicit + new_obj._header = self._header + new_obj.contents = self.contents + new_obj._trailer = self._trailer + if isinstance(self, Constructable): + new_obj.method = self.method + new_obj._indefinite = self._indefinite + return new_obj + + +class Constructable(object): + """ + A mixin to handle string types that may be constructed from chunks + contained within an indefinite length BER-encoded container + """ + + # Instance attribute indicating if an object was indefinite + # length when parsed - affects parsing and dumping + _indefinite = False + + # Class attribute that indicates the offset into self.contents + # that contains the chunks of data to merge + _chunks_offset = 0 + + def _merge_chunks(self): + """ + :return: + A concatenation of the native values of the contained chunks + """ + + if not self._indefinite: + return self._as_chunk() + + pointer = self._chunks_offset + contents_len = len(self.contents) + output = None + + while pointer < contents_len: + # We pass the current class as the spec so content semantics are preserved + sub_value, pointer = _parse_build(self.contents, pointer, spec=self.__class__) + if output is None: + output = sub_value._merge_chunks() + else: + output += sub_value._merge_chunks() + + if output is None: + return self._as_chunk() + + return output + + def _as_chunk(self): + """ + A method to return a chunk of data that can be combined for + constructed method values + + :return: + A native Python value that can be added together. Examples include + byte strings, unicode strings or tuples. + """ + + if self._chunks_offset == 0: + return self.contents + return self.contents[self._chunks_offset:] + + def _copy(self, other, copy_func): + """ + Copies the contents of another Constructable object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(Constructable, self)._copy(other, copy_func) + self.method = other.method + self._indefinite = other._indefinite + + +class Void(Asn1Value): + """ + A representation of an optional value that is not present. Has .native + property and .dump() method to be compatible with other value classes. + """ + + contents = b'' + + def __eq__(self, other): + """ + :param other: + The other Primitive to compare to + + :return: + A boolean + """ + + return other.__class__ == self.__class__ + + def __nonzero__(self): + return False + + def __len__(self): + return 0 + + def __iter__(self): + return iter(()) + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + None + """ + + return None + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + return b'' + + +VOID = Void() + + +class Any(Asn1Value): + """ + A value class that can contain any value, and allows for easy parsing of + the underlying encoded value using a spec. This is normally contained in + a Structure that has an ObjectIdentifier field and _oid_pair and _oid_specs + defined. + """ + + # The parsed value object + _parsed = None + + def __init__(self, value=None, **kwargs): + """ + Sets the value of the object before passing to Asn1Value.__init__() + + :param value: + An Asn1Value object that will be set as the parsed value + """ + + Asn1Value.__init__(self, **kwargs) + + try: + if value is not None: + if not isinstance(value, Asn1Value): + raise TypeError(unwrap( + ''' + value must be an instance of Asn1Value, not %s + ''', + type_name(value) + )) + + self._parsed = (value, value.__class__, None) + self.contents = value.dump() + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args + raise e + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + The .native value from the parsed value object + """ + + if self._parsed is None: + self.parse() + + return self._parsed[0].native + + @property + def parsed(self): + """ + Returns the parsed object from .parse() + + :return: + The object returned by .parse() + """ + + if self._parsed is None: + self.parse() + + return self._parsed[0] + + def parse(self, spec=None, spec_params=None): + """ + Parses the contents generically, or using a spec with optional params + + :param spec: + A class derived from Asn1Value that defines what class_ and tag the + value should have, and the semantics of the encoded value. The + return value will be of this type. If omitted, the encoded value + will be decoded using the standard universal tag based on the + encoded tag number. + + :param spec_params: + A dict of params to pass to the spec object + + :return: + An object of the type spec, or if not present, a child of Asn1Value + """ + + if self._parsed is None or self._parsed[1:3] != (spec, spec_params): + try: + passed_params = spec_params or {} + _tag_type_to_explicit_implicit(passed_params) + if self.explicit is not None: + if 'explicit' in passed_params: + passed_params['explicit'] = self.explicit + passed_params['explicit'] + else: + passed_params['explicit'] = self.explicit + contents = self._header + self.contents + self._trailer + parsed_value, _ = _parse_build( + contents, + spec=spec, + spec_params=passed_params + ) + self._parsed = (parsed_value, spec, spec_params) + + # Once we've parsed the Any value, clear any attributes from this object + # since they are now duplicate + self.tag = None + self.explicit = None + self.implicit = False + self._header = b'' + self.contents = contents + self._trailer = b'' + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args + raise e + return self._parsed[0] + + def _copy(self, other, copy_func): + """ + Copies the contents of another Any object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(Any, self)._copy(other, copy_func) + self._parsed = copy_func(other._parsed) + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + if self._parsed is None: + self.parse() + + return self._parsed[0].dump(force=force) + + +class Choice(Asn1Value): + """ + A class to handle when a value may be one of several options + """ + + # The index in _alternatives of the validated alternative + _choice = None + + # The name of the chosen alternative + _name = None + + # The Asn1Value object for the chosen alternative + _parsed = None + + # A list of tuples in one of the following forms. + # + # Option 1, a unicode string field name and a value class + # + # ("name", Asn1ValueClass) + # + # Option 2, same as Option 1, but with a dict of class params + # + # ("name", Asn1ValueClass, {'explicit': 5}) + _alternatives = None + + # A dict that maps tuples of (class_, tag) to an index in _alternatives + _id_map = None + + # A dict that maps alternative names to an index in _alternatives + _name_map = None + + @classmethod + def load(cls, encoded_data, strict=False, **kwargs): + """ + Loads a BER/DER-encoded byte string using the current class as the spec + + :param encoded_data: + A byte string of BER or DER encoded data + + :param strict: + A boolean indicating if trailing data should be forbidden - if so, a + ValueError will be raised when trailing data exists + + :return: + A instance of the current class + """ + + if not isinstance(encoded_data, byte_cls): + raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data)) + + value, _ = _parse_build(encoded_data, spec=cls, spec_params=kwargs, strict=strict) + return value + + def _setup(self): + """ + Generates _id_map from _alternatives to allow validating contents + """ + + cls = self.__class__ + cls._id_map = {} + cls._name_map = {} + for index, info in enumerate(cls._alternatives): + if len(info) < 3: + info = info + ({},) + cls._alternatives[index] = info + id_ = _build_id_tuple(info[2], info[1]) + cls._id_map[id_] = index + cls._name_map[info[0]] = index + + def __init__(self, name=None, value=None, **kwargs): + """ + Checks to ensure implicit tagging is not being used since it is + incompatible with Choice, then forwards on to Asn1Value.__init__() + + :param name: + The name of the alternative to be set - used with value. + Alternatively this may be a dict with a single key being the name + and the value being the value, or a two-element tuple of the the + name and the value. + + :param value: + The alternative value to set - used with name + + :raises: + ValueError - when implicit param is passed (or legacy tag_type param is "implicit") + """ + + _tag_type_to_explicit_implicit(kwargs) + + Asn1Value.__init__(self, **kwargs) + + try: + if kwargs.get('implicit') is not None: + raise ValueError(unwrap( + ''' + The Choice type can not be implicitly tagged even if in an + implicit module - due to its nature any tagging must be + explicit + ''' + )) + + if name is not None: + if isinstance(name, dict): + if len(name) != 1: + raise ValueError(unwrap( + ''' + When passing a dict as the "name" argument to %s, + it must have a single key/value - however %d were + present + ''', + type_name(self), + len(name) + )) + name, value = list(name.items())[0] + + if isinstance(name, tuple): + if len(name) != 2: + raise ValueError(unwrap( + ''' + When passing a tuple as the "name" argument to %s, + it must have two elements, the name and value - + however %d were present + ''', + type_name(self), + len(name) + )) + value = name[1] + name = name[0] + + if name not in self._name_map: + raise ValueError(unwrap( + ''' + The name specified, "%s", is not a valid alternative + for %s + ''', + name, + type_name(self) + )) + + self._choice = self._name_map[name] + _, spec, params = self._alternatives[self._choice] + + if not isinstance(value, spec): + value = spec(value, **params) + else: + value = _fix_tagging(value, params) + self._parsed = value + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args + raise e + + @property + def name(self): + """ + :return: + A unicode string of the field name of the chosen alternative + """ + if not self._name: + self._name = self._alternatives[self._choice][0] + return self._name + + def parse(self): + """ + Parses the detected alternative + + :return: + An Asn1Value object of the chosen alternative + """ + + if self._parsed is not None: + return self._parsed + + try: + _, spec, params = self._alternatives[self._choice] + self._parsed, _ = _parse_build(self.contents, spec=spec, spec_params=params) + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args + raise e + + @property + def chosen(self): + """ + :return: + An Asn1Value object of the chosen alternative + """ + + return self.parse() + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + The .native value from the contained value object + """ + + return self.chosen.native + + def validate(self, class_, tag, contents): + """ + Ensures that the class and tag specified exist as an alternative + + :param class_: + The integer class_ from the encoded value header + + :param tag: + The integer tag from the encoded value header + + :param contents: + A byte string of the contents of the value - used when the object + is explicitly tagged + + :raises: + ValueError - when value is not a valid alternative + """ + + id_ = (class_, tag) + + if self.explicit is not None: + if self.explicit[-1] != id_: + raise ValueError(unwrap( + ''' + %s was explicitly tagged, but the value provided does not + match the class and tag + ''', + type_name(self) + )) + + ((class_, _, tag, _, _, _), _) = _parse(contents, len(contents)) + id_ = (class_, tag) + + if id_ in self._id_map: + self._choice = self._id_map[id_] + return + + # This means the Choice was implicitly tagged + if self.class_ is not None and self.tag is not None: + if len(self._alternatives) > 1: + raise ValueError(unwrap( + ''' + %s was implicitly tagged, but more than one alternative + exists + ''', + type_name(self) + )) + if id_ == (self.class_, self.tag): + self._choice = 0 + return + + asn1 = self._format_class_tag(class_, tag) + asn1s = [self._format_class_tag(pair[0], pair[1]) for pair in self._id_map] + + raise ValueError(unwrap( + ''' + Value %s did not match the class and tag of any of the alternatives + in %s: %s + ''', + asn1, + type_name(self), + ', '.join(asn1s) + )) + + def _format_class_tag(self, class_, tag): + """ + :return: + A unicode string of a human-friendly representation of the class and tag + """ + + return '[%s %s]' % (CLASS_NUM_TO_NAME_MAP[class_].upper(), tag) + + def _copy(self, other, copy_func): + """ + Copies the contents of another Choice object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(Choice, self)._copy(other, copy_func) + self._choice = other._choice + self._name = other._name + self._parsed = copy_func(other._parsed) + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + self.contents = self.chosen.dump(force=force) + if self._header is None or force: + self._header = b'' + if self.explicit is not None: + for class_, tag in self.explicit: + self._header = _dump_header(class_, 1, tag, self._header + self.contents) + self._header + return self._header + self.contents + + +class Concat(object): + """ + A class that contains two or more encoded child values concatentated + together. THIS IS NOT PART OF THE ASN.1 SPECIFICATION! This exists to handle + the x509.TrustedCertificate() class for OpenSSL certificates containing + extra information. + """ + + # A list of the specs of the concatenated values + _child_specs = None + + _children = None + + @classmethod + def load(cls, encoded_data, strict=False): + """ + Loads a BER/DER-encoded byte string using the current class as the spec + + :param encoded_data: + A byte string of BER or DER encoded data + + :param strict: + A boolean indicating if trailing data should be forbidden - if so, a + ValueError will be raised when trailing data exists + + :return: + A Concat object + """ + + return cls(contents=encoded_data, strict=strict) + + def __init__(self, value=None, contents=None, strict=False): + """ + :param value: + A native Python datatype to initialize the object value with + + :param contents: + A byte string of the encoded contents of the value + + :param strict: + A boolean indicating if trailing data should be forbidden - if so, a + ValueError will be raised when trailing data exists in contents + + :raises: + ValueError - when an error occurs with one of the children + TypeError - when an error occurs with one of the children + """ + + if contents is not None: + try: + contents_len = len(contents) + self._children = [] + + offset = 0 + for spec in self._child_specs: + if offset < contents_len: + child_value, offset = _parse_build(contents, pointer=offset, spec=spec) + else: + child_value = spec() + self._children.append(child_value) + + if strict and offset != contents_len: + extra_bytes = contents_len - offset + raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes) + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args + raise e + + if value is not None: + if self._children is None: + self._children = [None] * len(self._child_specs) + for index, data in enumerate(value): + self.__setitem__(index, data) + + def __str__(self): + """ + Since str is different in Python 2 and 3, this calls the appropriate + method, __unicode__() or __bytes__() + + :return: + A unicode string + """ + + if _PY2: + return self.__bytes__() + else: + return self.__unicode__() + + def __bytes__(self): + """ + A byte string of the DER-encoded contents + """ + + return self.dump() + + def __unicode__(self): + """ + :return: + A unicode string + """ + + return repr(self) + + def __repr__(self): + """ + :return: + A unicode string + """ + + return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump())) + + def __copy__(self): + """ + Implements the copy.copy() interface + + :return: + A new shallow copy of the Concat object + """ + + new_obj = self.__class__() + new_obj._copy(self, copy.copy) + return new_obj + + def __deepcopy__(self, memo): + """ + Implements the copy.deepcopy() interface + + :param memo: + A dict for memoization + + :return: + A new deep copy of the Concat object and all child objects + """ + + new_obj = self.__class__() + memo[id(self)] = new_obj + new_obj._copy(self, copy.deepcopy) + return new_obj + + def copy(self): + """ + Copies the object + + :return: + A Concat object + """ + + return copy.deepcopy(self) + + def _copy(self, other, copy_func): + """ + Copies the contents of another Concat object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + if self.__class__ != other.__class__: + raise TypeError(unwrap( + ''' + Can not copy values from %s object to %s object + ''', + type_name(other), + type_name(self) + )) + + self._children = copy_func(other._children) + + def debug(self, nest_level=1): + """ + Show the binary data and parsed data in a tree structure + """ + + prefix = ' ' * nest_level + print('%s%s Object #%s' % (prefix, type_name(self), id(self))) + print('%s Children:' % (prefix,)) + for child in self._children: + child.debug(nest_level + 2) + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + contents = b'' + for child in self._children: + contents += child.dump(force=force) + return contents + + @property + def contents(self): + """ + :return: + A byte string of the DER-encoded contents of the children + """ + + return self.dump() + + def __len__(self): + """ + :return: + Integer + """ + + return len(self._children) + + def __getitem__(self, key): + """ + Allows accessing children by index + + :param key: + An integer of the child index + + :raises: + KeyError - when an index is invalid + + :return: + The Asn1Value object of the child specified + """ + + if key > len(self._child_specs) - 1 or key < 0: + raise KeyError(unwrap( + ''' + No child is definition for position %d of %s + ''', + key, + type_name(self) + )) + + return self._children[key] + + def __setitem__(self, key, value): + """ + Allows settings children by index + + :param key: + An integer of the child index + + :param value: + An Asn1Value object to set the child to + + :raises: + KeyError - when an index is invalid + ValueError - when the value is not an instance of Asn1Value + """ + + if key > len(self._child_specs) - 1 or key < 0: + raise KeyError(unwrap( + ''' + No child is defined for position %d of %s + ''', + key, + type_name(self) + )) + + if not isinstance(value, Asn1Value): + raise ValueError(unwrap( + ''' + Value for child %s of %s is not an instance of + asn1crypto.core.Asn1Value + ''', + key, + type_name(self) + )) + + self._children[key] = value + + def __iter__(self): + """ + :return: + An iterator of child values + """ + + return iter(self._children) + + +class Primitive(Asn1Value): + """ + Sets the class_ and method attributes for primitive, universal values + """ + + class_ = 0 + + method = 0 + + def __init__(self, value=None, default=None, contents=None, **kwargs): + """ + Sets the value of the object before passing to Asn1Value.__init__() + + :param value: + A native Python datatype to initialize the object value with + + :param default: + The default value if no value is specified + + :param contents: + A byte string of the encoded contents of the value + """ + + Asn1Value.__init__(self, **kwargs) + + try: + if contents is not None: + self.contents = contents + + elif value is not None: + self.set(value) + + elif default is not None: + self.set(default) + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args + raise e + + def set(self, value): + """ + Sets the value of the object + + :param value: + A byte string + """ + + if not isinstance(value, byte_cls): + raise TypeError(unwrap( + ''' + %s value must be a byte string, not %s + ''', + type_name(self), + type_name(value) + )) + + self._native = value + self.contents = value + self._header = None + if self._trailer != b'': + self._trailer = b'' + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + if force: + native = self.native + self.contents = None + self.set(native) + + return Asn1Value.dump(self) + + def __ne__(self, other): + return not self == other + + def __eq__(self, other): + """ + :param other: + The other Primitive to compare to + + :return: + A boolean + """ + + if not isinstance(other, Primitive): + return False + + if self.contents != other.contents: + return False + + # We compare class tag numbers since object tag numbers could be + # different due to implicit or explicit tagging + if self.__class__.tag != other.__class__.tag: + return False + + if self.__class__ == other.__class__ and self.contents == other.contents: + return True + + # If the objects share a common base class that is not too low-level + # then we can compare the contents + self_bases = (set(self.__class__.__bases__) | set([self.__class__])) - set([Asn1Value, Primitive, ValueMap]) + other_bases = (set(other.__class__.__bases__) | set([other.__class__])) - set([Asn1Value, Primitive, ValueMap]) + if self_bases | other_bases: + return self.contents == other.contents + + # When tagging is going on, do the extra work of constructing new + # objects to see if the dumped representation are the same + if self.implicit or self.explicit or other.implicit or other.explicit: + return self.untag().dump() == other.untag().dump() + + return self.dump() == other.dump() + + +class AbstractString(Constructable, Primitive): + """ + A base class for all strings that have a known encoding. In general, we do + not worry ourselves with confirming that the decoded values match a specific + set of characters, only that they are decoded into a Python unicode string + """ + + # The Python encoding name to use when decoding or encoded the contents + _encoding = 'latin1' + + # Instance attribute of (possibly-merged) unicode string + _unicode = None + + def set(self, value): + """ + Sets the value of the string + + :param value: + A unicode string + """ + + if not isinstance(value, str_cls): + raise TypeError(unwrap( + ''' + %s value must be a unicode string, not %s + ''', + type_name(self), + type_name(value) + )) + + self._unicode = value + self.contents = value.encode(self._encoding) + self._header = None + if self._indefinite: + self._indefinite = False + self.method = 0 + if self._trailer != b'': + self._trailer = b'' + + def __unicode__(self): + """ + :return: + A unicode string + """ + + if self.contents is None: + return '' + if self._unicode is None: + self._unicode = self._merge_chunks().decode(self._encoding) + return self._unicode + + def _copy(self, other, copy_func): + """ + Copies the contents of another AbstractString object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(AbstractString, self)._copy(other, copy_func) + self._unicode = other._unicode + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A unicode string or None + """ + + if self.contents is None: + return None + + return self.__unicode__() + + +class Boolean(Primitive): + """ + Represents a boolean in both ASN.1 and Python + """ + + tag = 1 + + def set(self, value): + """ + Sets the value of the object + + :param value: + True, False or another value that works with bool() + """ + + self._native = bool(value) + self.contents = b'\x00' if not value else b'\xff' + self._header = None + if self._trailer != b'': + self._trailer = b'' + + # Python 2 + def __nonzero__(self): + """ + :return: + True or False + """ + return self.__bool__() + + def __bool__(self): + """ + :return: + True or False + """ + return self.contents != b'\x00' + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + True, False or None + """ + + if self.contents is None: + return None + + if self._native is None: + self._native = self.__bool__() + return self._native + + +class Integer(Primitive, ValueMap): + """ + Represents an integer in both ASN.1 and Python + """ + + tag = 2 + + def set(self, value): + """ + Sets the value of the object + + :param value: + An integer, or a unicode string if _map is set + + :raises: + ValueError - when an invalid value is passed + """ + + if isinstance(value, str_cls): + if self._map is None: + raise ValueError(unwrap( + ''' + %s value is a unicode string, but no _map provided + ''', + type_name(self) + )) + + if value not in self._reverse_map: + raise ValueError(unwrap( + ''' + %s value, %s, is not present in the _map + ''', + type_name(self), + value + )) + + value = self._reverse_map[value] + + elif not isinstance(value, int_types): + raise TypeError(unwrap( + ''' + %s value must be an integer or unicode string when a name_map + is provided, not %s + ''', + type_name(self), + type_name(value) + )) + + self._native = self._map[value] if self._map and value in self._map else value + + self.contents = int_to_bytes(value, signed=True) + self._header = None + if self._trailer != b'': + self._trailer = b'' + + def __int__(self): + """ + :return: + An integer + """ + return int_from_bytes(self.contents, signed=True) + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + An integer or None + """ + + if self.contents is None: + return None + + if self._native is None: + self._native = self.__int__() + if self._map is not None and self._native in self._map: + self._native = self._map[self._native] + return self._native + + +class BitString(Constructable, Castable, Primitive, ValueMap, object): + """ + Represents a bit string from ASN.1 as a Python tuple of 1s and 0s + """ + + tag = 3 + + _size = None + + # Used with _as_chunk() from Constructable + _chunk = None + _chunks_offset = 1 + + def _setup(self): + """ + Generates _reverse_map from _map + """ + + ValueMap._setup(self) + + cls = self.__class__ + if cls._map is not None: + cls._size = max(self._map.keys()) + 1 + + def set(self, value): + """ + Sets the value of the object + + :param value: + An integer or a tuple of integers 0 and 1 + + :raises: + ValueError - when an invalid value is passed + """ + + if isinstance(value, set): + if self._map is None: + raise ValueError(unwrap( + ''' + %s._map has not been defined + ''', + type_name(self) + )) + + bits = [0] * self._size + self._native = value + for index in range(0, self._size): + key = self._map.get(index) + if key is None: + continue + if key in value: + bits[index] = 1 + + value = ''.join(map(str_cls, bits)) + + elif value.__class__ == tuple: + if self._map is None: + self._native = value + else: + self._native = set() + for index, bit in enumerate(value): + if bit: + name = self._map.get(index, index) + self._native.add(name) + value = ''.join(map(str_cls, value)) + + else: + raise TypeError(unwrap( + ''' + %s value must be a tuple of ones and zeros or a set of unicode + strings, not %s + ''', + type_name(self), + type_name(value) + )) + + self._chunk = None + + if self._map is not None: + if len(value) > self._size: + raise ValueError(unwrap( + ''' + %s value must be at most %s bits long, specified was %s long + ''', + type_name(self), + self._size, + len(value) + )) + # A NamedBitList must have trailing zero bit truncated. See + # https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + # section 11.2, + # https://tools.ietf.org/html/rfc5280#page-134 and + # https://www.ietf.org/mail-archive/web/pkix/current/msg10443.html + value = value.rstrip('0') + size = len(value) + + size_mod = size % 8 + extra_bits = 0 + if size_mod != 0: + extra_bits = 8 - size_mod + value += '0' * extra_bits + + size_in_bytes = int(math.ceil(size / 8)) + + if extra_bits: + extra_bits_byte = int_to_bytes(extra_bits) + else: + extra_bits_byte = b'\x00' + + if value == '': + value_bytes = b'' + else: + value_bytes = int_to_bytes(int(value, 2)) + if len(value_bytes) != size_in_bytes: + value_bytes = (b'\x00' * (size_in_bytes - len(value_bytes))) + value_bytes + + self.contents = extra_bits_byte + value_bytes + self._header = None + if self._indefinite: + self._indefinite = False + self.method = 0 + if self._trailer != b'': + self._trailer = b'' + + def __getitem__(self, key): + """ + Retrieves a boolean version of one of the bits based on a name from the + _map + + :param key: + The unicode string of one of the bit names + + :raises: + ValueError - when _map is not set or the key name is invalid + + :return: + A boolean if the bit is set + """ + + is_int = isinstance(key, int_types) + if not is_int: + if not isinstance(self._map, dict): + raise ValueError(unwrap( + ''' + %s._map has not been defined + ''', + type_name(self) + )) + + if key not in self._reverse_map: + raise ValueError(unwrap( + ''' + %s._map does not contain an entry for "%s" + ''', + type_name(self), + key + )) + + if self._native is None: + self.native + + if self._map is None: + if len(self._native) >= key + 1: + return bool(self._native[key]) + return False + + if is_int: + key = self._map.get(key, key) + + return key in self._native + + def __setitem__(self, key, value): + """ + Sets one of the bits based on a name from the _map + + :param key: + The unicode string of one of the bit names + + :param value: + A boolean value + + :raises: + ValueError - when _map is not set or the key name is invalid + """ + + is_int = isinstance(key, int_types) + if not is_int: + if self._map is None: + raise ValueError(unwrap( + ''' + %s._map has not been defined + ''', + type_name(self) + )) + + if key not in self._reverse_map: + raise ValueError(unwrap( + ''' + %s._map does not contain an entry for "%s" + ''', + type_name(self), + key + )) + + if self._native is None: + self.native + + if self._map is None: + new_native = list(self._native) + max_key = len(new_native) - 1 + if key > max_key: + new_native.extend([0] * (key - max_key)) + new_native[key] = 1 if value else 0 + self._native = tuple(new_native) + + else: + if is_int: + key = self._map.get(key, key) + + if value: + if key not in self._native: + self._native.add(key) + else: + if key in self._native: + self._native.remove(key) + + self.set(self._native) + + def _as_chunk(self): + """ + Allows reconstructing indefinite length values + + :return: + A tuple of integers + """ + + extra_bits = int_from_bytes(self.contents[0:1]) + bit_string = '{0:b}'.format(int_from_bytes(self.contents[1:])) + byte_len = len(self.contents[1:]) + bit_len = len(bit_string) + + # Left-pad the bit string to a byte multiple to ensure we didn't + # lose any zero bits on the left + mod_bit_len = bit_len % 8 + if mod_bit_len != 0: + bit_string = ('0' * (8 - mod_bit_len)) + bit_string + bit_len = len(bit_string) + + if bit_len // 8 < byte_len: + missing_bytes = byte_len - (bit_len // 8) + bit_string = ('0' * (8 * missing_bytes)) + bit_string + + # Trim off the extra bits on the right used to fill the last byte + if extra_bits > 0: + bit_string = bit_string[0:0 - extra_bits] + + return tuple(map(int, tuple(bit_string))) + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + If a _map is set, a set of names, or if no _map is set, a tuple of + integers 1 and 0. None if no value. + """ + + # For BitString we default the value to be all zeros + if self.contents is None: + if self._map is None: + self.set(()) + else: + self.set(set()) + + if self._native is None: + bits = self._merge_chunks() + if self._map: + self._native = set() + for index, bit in enumerate(bits): + if bit: + name = self._map.get(index, index) + self._native.add(name) + else: + self._native = bits + return self._native + + +class OctetBitString(Constructable, Castable, Primitive): + """ + Represents a bit string in ASN.1 as a Python byte string + """ + + tag = 3 + + # Whenever dealing with octet-based bit strings, we really want the + # bytes, so we just ignore the unused bits portion since it isn't + # applicable to the current use case + # unused_bits = struct.unpack('>B', self.contents[0:1])[0] + _chunks_offset = 1 + + # Instance attribute of (possibly-merged) byte string + _bytes = None + + def set(self, value): + """ + Sets the value of the object + + :param value: + A byte string + + :raises: + ValueError - when an invalid value is passed + """ + + if not isinstance(value, byte_cls): + raise TypeError(unwrap( + ''' + %s value must be a byte string, not %s + ''', + type_name(self), + type_name(value) + )) + + self._bytes = value + # Set the unused bits to 0 + self.contents = b'\x00' + value + self._header = None + if self._indefinite: + self._indefinite = False + self.method = 0 + if self._trailer != b'': + self._trailer = b'' + + def __bytes__(self): + """ + :return: + A byte string + """ + + if self.contents is None: + return b'' + if self._bytes is None: + self._bytes = self._merge_chunks() + return self._bytes + + def _copy(self, other, copy_func): + """ + Copies the contents of another OctetBitString object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(OctetBitString, self)._copy(other, copy_func) + self._bytes = other._bytes + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A byte string or None + """ + + if self.contents is None: + return None + + return self.__bytes__() + + +class IntegerBitString(Constructable, Castable, Primitive): + """ + Represents a bit string in ASN.1 as a Python integer + """ + + tag = 3 + + _chunks_offset = 1 + + def set(self, value): + """ + Sets the value of the object + + :param value: + An integer + + :raises: + ValueError - when an invalid value is passed + """ + + if not isinstance(value, int_types): + raise TypeError(unwrap( + ''' + %s value must be an integer, not %s + ''', + type_name(self), + type_name(value) + )) + + self._native = value + # Set the unused bits to 0 + self.contents = b'\x00' + int_to_bytes(value, signed=True) + self._header = None + if self._indefinite: + self._indefinite = False + self.method = 0 + if self._trailer != b'': + self._trailer = b'' + + def _as_chunk(self): + """ + Allows reconstructing indefinite length values + + :return: + A unicode string of bits - 1s and 0s + """ + + extra_bits = int_from_bytes(self.contents[0:1]) + bit_string = '{0:b}'.format(int_from_bytes(self.contents[1:])) + + # Ensure we have leading zeros since these chunks may be concatenated together + mod_bit_len = len(bit_string) % 8 + if mod_bit_len != 0: + bit_string = ('0' * (8 - mod_bit_len)) + bit_string + + if extra_bits > 0: + return bit_string[0:0 - extra_bits] + + return bit_string + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + An integer or None + """ + + if self.contents is None: + return None + + if self._native is None: + extra_bits = int_from_bytes(self.contents[0:1]) + # Fast path + if not self._indefinite and extra_bits == 0: + self._native = int_from_bytes(self.contents[1:]) + else: + if self._indefinite and extra_bits > 0: + raise ValueError('Constructed bit string has extra bits on indefinite container') + self._native = int(self._merge_chunks(), 2) + return self._native + + +class OctetString(Constructable, Castable, Primitive): + """ + Represents a byte string in both ASN.1 and Python + """ + + tag = 4 + + # Instance attribute of (possibly-merged) byte string + _bytes = None + + def set(self, value): + """ + Sets the value of the object + + :param value: + A byte string + """ + + if not isinstance(value, byte_cls): + raise TypeError(unwrap( + ''' + %s value must be a byte string, not %s + ''', + type_name(self), + type_name(value) + )) + + self._bytes = value + self.contents = value + self._header = None + if self._indefinite: + self._indefinite = False + self.method = 0 + if self._trailer != b'': + self._trailer = b'' + + def __bytes__(self): + """ + :return: + A byte string + """ + + if self.contents is None: + return b'' + if self._bytes is None: + self._bytes = self._merge_chunks() + return self._bytes + + def _copy(self, other, copy_func): + """ + Copies the contents of another OctetString object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(OctetString, self)._copy(other, copy_func) + self._bytes = other._bytes + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A byte string or None + """ + + if self.contents is None: + return None + + return self.__bytes__() + + +class IntegerOctetString(Constructable, Castable, Primitive): + """ + Represents a byte string in ASN.1 as a Python integer + """ + + tag = 4 + + def set(self, value): + """ + Sets the value of the object + + :param value: + An integer + + :raises: + ValueError - when an invalid value is passed + """ + + if not isinstance(value, int_types): + raise TypeError(unwrap( + ''' + %s value must be an integer, not %s + ''', + type_name(self), + type_name(value) + )) + + self._native = value + self.contents = int_to_bytes(value, signed=False) + self._header = None + if self._indefinite: + self._indefinite = False + self.method = 0 + if self._trailer != b'': + self._trailer = b'' + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + An integer or None + """ + + if self.contents is None: + return None + + if self._native is None: + self._native = int_from_bytes(self._merge_chunks()) + return self._native + + +class ParsableOctetString(Constructable, Castable, Primitive): + + tag = 4 + + _parsed = None + + # Instance attribute of (possibly-merged) byte string + _bytes = None + + def __init__(self, value=None, parsed=None, **kwargs): + """ + Allows providing a parsed object that will be serialized to get the + byte string value + + :param value: + A native Python datatype to initialize the object value with + + :param parsed: + If value is None and this is an Asn1Value object, this will be + set as the parsed value, and the value will be obtained by calling + .dump() on this object. + """ + + set_parsed = False + if value is None and parsed is not None and isinstance(parsed, Asn1Value): + value = parsed.dump() + set_parsed = True + + Primitive.__init__(self, value=value, **kwargs) + + if set_parsed: + self._parsed = (parsed, parsed.__class__, None) + + def set(self, value): + """ + Sets the value of the object + + :param value: + A byte string + """ + + if not isinstance(value, byte_cls): + raise TypeError(unwrap( + ''' + %s value must be a byte string, not %s + ''', + type_name(self), + type_name(value) + )) + + self._bytes = value + self.contents = value + self._header = None + if self._indefinite: + self._indefinite = False + self.method = 0 + if self._trailer != b'': + self._trailer = b'' + + def parse(self, spec=None, spec_params=None): + """ + Parses the contents generically, or using a spec with optional params + + :param spec: + A class derived from Asn1Value that defines what class_ and tag the + value should have, and the semantics of the encoded value. The + return value will be of this type. If omitted, the encoded value + will be decoded using the standard universal tag based on the + encoded tag number. + + :param spec_params: + A dict of params to pass to the spec object + + :return: + An object of the type spec, or if not present, a child of Asn1Value + """ + + if self._parsed is None or self._parsed[1:3] != (spec, spec_params): + parsed_value, _ = _parse_build(self.__bytes__(), spec=spec, spec_params=spec_params) + self._parsed = (parsed_value, spec, spec_params) + return self._parsed[0] + + def __bytes__(self): + """ + :return: + A byte string + """ + + if self.contents is None: + return b'' + if self._bytes is None: + self._bytes = self._merge_chunks() + return self._bytes + + def _copy(self, other, copy_func): + """ + Copies the contents of another ParsableOctetString object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(ParsableOctetString, self)._copy(other, copy_func) + self._bytes = other._bytes + self._parsed = copy_func(other._parsed) + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A byte string or None + """ + + if self.contents is None: + return None + + if self._parsed is not None: + return self._parsed[0].native + else: + return self.__bytes__() + + @property + def parsed(self): + """ + Returns the parsed object from .parse() + + :return: + The object returned by .parse() + """ + + if self._parsed is None: + self.parse() + + return self._parsed[0] + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + if force: + if self._parsed is not None: + native = self.parsed.dump(force=force) + else: + native = self.native + self.contents = None + self.set(native) + + return Asn1Value.dump(self) + + +class ParsableOctetBitString(ParsableOctetString): + + tag = 3 + + # Whenever dealing with octet-based bit strings, we really want the + # bytes, so we just ignore the unused bits portion since it isn't + # applicable to the current use case + # unused_bits = struct.unpack('>B', self.contents[0:1])[0] + _chunks_offset = 1 + + def set(self, value): + """ + Sets the value of the object + + :param value: + A byte string + + :raises: + ValueError - when an invalid value is passed + """ + + if not isinstance(value, byte_cls): + raise TypeError(unwrap( + ''' + %s value must be a byte string, not %s + ''', + type_name(self), + type_name(value) + )) + + self._bytes = value + # Set the unused bits to 0 + self.contents = b'\x00' + value + self._header = None + if self._indefinite: + self._indefinite = False + self.method = 0 + if self._trailer != b'': + self._trailer = b'' + + +class Null(Primitive): + """ + Represents a null value in ASN.1 as None in Python + """ + + tag = 5 + + contents = b'' + + def set(self, value): + """ + Sets the value of the object + + :param value: + None + """ + + self.contents = b'' + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + None + """ + + return None + + +class ObjectIdentifier(Primitive, ValueMap): + """ + Represents an object identifier in ASN.1 as a Python unicode dotted + integer string + """ + + tag = 6 + + # A unicode string of the dotted form of the object identifier + _dotted = None + + @classmethod + def map(cls, value): + """ + Converts a dotted unicode string OID into a mapped unicode string + + :param value: + A dotted unicode string OID + + :raises: + ValueError - when no _map dict has been defined on the class + TypeError - when value is not a unicode string + + :return: + A mapped unicode string + """ + + if cls._map is None: + raise ValueError(unwrap( + ''' + %s._map has not been defined + ''', + type_name(cls) + )) + + if not isinstance(value, str_cls): + raise TypeError(unwrap( + ''' + value must be a unicode string, not %s + ''', + type_name(value) + )) + + return cls._map.get(value, value) + + @classmethod + def unmap(cls, value): + """ + Converts a mapped unicode string value into a dotted unicode string OID + + :param value: + A mapped unicode string OR dotted unicode string OID + + :raises: + ValueError - when no _map dict has been defined on the class or the value can't be unmapped + TypeError - when value is not a unicode string + + :return: + A dotted unicode string OID + """ + + if cls not in _SETUP_CLASSES: + cls()._setup() + _SETUP_CLASSES[cls] = True + + if cls._map is None: + raise ValueError(unwrap( + ''' + %s._map has not been defined + ''', + type_name(cls) + )) + + if not isinstance(value, str_cls): + raise TypeError(unwrap( + ''' + value must be a unicode string, not %s + ''', + type_name(value) + )) + + if value in cls._reverse_map: + return cls._reverse_map[value] + + if not _OID_RE.match(value): + raise ValueError(unwrap( + ''' + %s._map does not contain an entry for "%s" + ''', + type_name(cls), + value + )) + + return value + + def set(self, value): + """ + Sets the value of the object + + :param value: + A unicode string. May be a dotted integer string, or if _map is + provided, one of the mapped values. + + :raises: + ValueError - when an invalid value is passed + """ + + if not isinstance(value, str_cls): + raise TypeError(unwrap( + ''' + %s value must be a unicode string, not %s + ''', + type_name(self), + type_name(value) + )) + + self._native = value + + if self._map is not None: + if value in self._reverse_map: + value = self._reverse_map[value] + + self.contents = b'' + first = None + for index, part in enumerate(value.split('.')): + part = int(part) + + # The first two parts are merged into a single byte + if index == 0: + first = part + continue + elif index == 1: + part = (first * 40) + part + + encoded_part = chr_cls(0x7F & part) + part = part >> 7 + while part > 0: + encoded_part = chr_cls(0x80 | (0x7F & part)) + encoded_part + part = part >> 7 + self.contents += encoded_part + + self._header = None + if self._trailer != b'': + self._trailer = b'' + + def __unicode__(self): + """ + :return: + A unicode string + """ + + return self.dotted + + @property + def dotted(self): + """ + :return: + A unicode string of the object identifier in dotted notation, thus + ignoring any mapped value + """ + + if self._dotted is None: + output = [] + + part = 0 + for byte in self.contents: + if _PY2: + byte = ord(byte) + part = part * 128 + part += byte & 127 + # Last byte in subidentifier has the eighth bit set to 0 + if byte & 0x80 == 0: + if len(output) == 0: + output.append(str_cls(part // 40)) + output.append(str_cls(part % 40)) + else: + output.append(str_cls(part)) + part = 0 + + self._dotted = '.'.join(output) + return self._dotted + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A unicode string or None. If _map is not defined, the unicode string + is a string of dotted integers. If _map is defined and the dotted + string is present in the _map, the mapped value is returned. + """ + + if self.contents is None: + return None + + if self._native is None: + self._native = self.dotted + if self._map is not None and self._native in self._map: + self._native = self._map[self._native] + return self._native + + +class ObjectDescriptor(Primitive): + """ + Represents an object descriptor from ASN.1 - no Python implementation + """ + + tag = 7 + + +class InstanceOf(Primitive): + """ + Represents an instance from ASN.1 - no Python implementation + """ + + tag = 8 + + +class Real(Primitive): + """ + Represents a real number from ASN.1 - no Python implementation + """ + + tag = 9 + + +class Enumerated(Integer): + """ + Represents a enumerated list of integers from ASN.1 as a Python + unicode string + """ + + tag = 10 + + def set(self, value): + """ + Sets the value of the object + + :param value: + An integer or a unicode string from _map + + :raises: + ValueError - when an invalid value is passed + """ + + if not isinstance(value, int_types) and not isinstance(value, str_cls): + raise TypeError(unwrap( + ''' + %s value must be an integer or a unicode string, not %s + ''', + type_name(self), + type_name(value) + )) + + if isinstance(value, str_cls): + if value not in self._reverse_map: + raise ValueError(unwrap( + ''' + %s value "%s" is not a valid value + ''', + type_name(self), + value + )) + + value = self._reverse_map[value] + + elif value not in self._map: + raise ValueError(unwrap( + ''' + %s value %s is not a valid value + ''', + type_name(self), + value + )) + + Integer.set(self, value) + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A unicode string or None + """ + + if self.contents is None: + return None + + if self._native is None: + self._native = self._map[self.__int__()] + return self._native + + +class UTF8String(AbstractString): + """ + Represents a UTF-8 string from ASN.1 as a Python unicode string + """ + + tag = 12 + _encoding = 'utf-8' + + +class RelativeOid(ObjectIdentifier): + """ + Represents an object identifier in ASN.1 as a Python unicode dotted + integer string + """ + + tag = 13 + + +class Sequence(Asn1Value): + """ + Represents a sequence of fields from ASN.1 as a Python object with a + dict-like interface + """ + + tag = 16 + + class_ = 0 + method = 1 + + # A list of child objects, in order of _fields + children = None + + # Sequence overrides .contents to be a property so that the mutated state + # of child objects can be checked to ensure everything is up-to-date + _contents = None + + # Variable to track if the object has been mutated + _mutated = False + + # A list of tuples in one of the following forms. + # + # Option 1, a unicode string field name and a value class + # + # ("name", Asn1ValueClass) + # + # Option 2, same as Option 1, but with a dict of class params + # + # ("name", Asn1ValueClass, {'explicit': 5}) + _fields = [] + + # A dict with keys being the name of a field and the value being a unicode + # string of the method name on self to call to get the spec for that field + _spec_callbacks = None + + # A dict that maps unicode string field names to an index in _fields + _field_map = None + + # A list in the same order as _fields that has tuples in the form (class_, tag) + _field_ids = None + + # An optional 2-element tuple that defines the field names of an OID field + # and the field that the OID should be used to help decode. Works with the + # _oid_specs attribute. + _oid_pair = None + + # A dict with keys that are unicode string OID values and values that are + # Asn1Value classes to use for decoding a variable-type field. + _oid_specs = None + + # A 2-element tuple of the indexes in _fields of the OID and value fields + _oid_nums = None + + # Predetermined field specs to optimize away calls to _determine_spec() + _precomputed_specs = None + + def __init__(self, value=None, default=None, **kwargs): + """ + Allows setting field values before passing everything else along to + Asn1Value.__init__() + + :param value: + A native Python datatype to initialize the object value with + + :param default: + The default value if no value is specified + """ + + Asn1Value.__init__(self, **kwargs) + + check_existing = False + if value is None and default is not None: + check_existing = True + if self.children is None: + if self.contents is None: + check_existing = False + else: + self._parse_children() + value = default + + if value is not None: + try: + # Fields are iterated in definition order to allow things like + # OID-based specs. Otherwise sometimes the value would be processed + # before the OID field, resulting in invalid value object creation. + if self._fields: + keys = [info[0] for info in self._fields] + unused_keys = set(value.keys()) + else: + keys = value.keys() + unused_keys = set(keys) + + for key in keys: + # If we are setting defaults, but a real value has already + # been set for the field, then skip it + if check_existing: + index = self._field_map[key] + if index < len(self.children) and self.children[index] is not VOID: + if key in unused_keys: + unused_keys.remove(key) + continue + + if key in value: + self.__setitem__(key, value[key]) + unused_keys.remove(key) + + if len(unused_keys): + raise ValueError(unwrap( + ''' + One or more unknown fields was passed to the constructor + of %s: %s + ''', + type_name(self), + ', '.join(sorted(list(unused_keys))) + )) + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args + raise e + + @property + def contents(self): + """ + :return: + A byte string of the DER-encoded contents of the sequence + """ + + if self.children is None: + return self._contents + + if self._is_mutated(): + self._set_contents() + + return self._contents + + @contents.setter + def contents(self, value): + """ + :param value: + A byte string of the DER-encoded contents of the sequence + """ + + self._contents = value + + def _is_mutated(self): + """ + :return: + A boolean - if the sequence or any children (recursively) have been + mutated + """ + + mutated = self._mutated + if self.children is not None: + for child in self.children: + if isinstance(child, Sequence) or isinstance(child, SequenceOf): + mutated = mutated or child._is_mutated() + + return mutated + + def _lazy_child(self, index): + """ + Builds a child object if the child has only been parsed into a tuple so far + """ + + child = self.children[index] + if child.__class__ == tuple: + child = self.children[index] = _build(*child) + return child + + def __len__(self): + """ + :return: + Integer + """ + # We inline this check to prevent method invocation each time + if self.children is None: + self._parse_children() + + return len(self.children) + + def __getitem__(self, key): + """ + Allows accessing fields by name or index + + :param key: + A unicode string of the field name, or an integer of the field index + + :raises: + KeyError - when a field name or index is invalid + + :return: + The Asn1Value object of the field specified + """ + + # We inline this check to prevent method invocation each time + if self.children is None: + self._parse_children() + + if not isinstance(key, int_types): + if key not in self._field_map: + raise KeyError(unwrap( + ''' + No field named "%s" defined for %s + ''', + key, + type_name(self) + )) + key = self._field_map[key] + + if key >= len(self.children): + raise KeyError(unwrap( + ''' + No field numbered %s is present in this %s + ''', + key, + type_name(self) + )) + + try: + return self._lazy_child(key) + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args + raise e + + def __setitem__(self, key, value): + """ + Allows settings fields by name or index + + :param key: + A unicode string of the field name, or an integer of the field index + + :param value: + A native Python datatype to set the field value to. This method will + construct the appropriate Asn1Value object from _fields. + + :raises: + ValueError - when a field name or index is invalid + """ + + # We inline this check to prevent method invocation each time + if self.children is None: + self._parse_children() + + if not isinstance(key, int_types): + if key not in self._field_map: + raise KeyError(unwrap( + ''' + No field named "%s" defined for %s + ''', + key, + type_name(self) + )) + key = self._field_map[key] + + field_name, field_spec, value_spec, field_params, _ = self._determine_spec(key) + + new_value = self._make_value(field_name, field_spec, value_spec, field_params, value) + + invalid_value = False + if isinstance(new_value, Any): + invalid_value = new_value.parsed is None + elif isinstance(new_value, Choice): + invalid_value = new_value.chosen.contents is None + else: + invalid_value = new_value.contents is None + + if invalid_value: + raise ValueError(unwrap( + ''' + Value for field "%s" of %s is not set + ''', + field_name, + type_name(self) + )) + + self.children[key] = new_value + + if self._native is not None: + self._native[self._fields[key][0]] = self.children[key].native + self._mutated = True + + def __delitem__(self, key): + """ + Allows deleting optional or default fields by name or index + + :param key: + A unicode string of the field name, or an integer of the field index + + :raises: + ValueError - when a field name or index is invalid, or the field is not optional or defaulted + """ + + # We inline this check to prevent method invocation each time + if self.children is None: + self._parse_children() + + if not isinstance(key, int_types): + if key not in self._field_map: + raise KeyError(unwrap( + ''' + No field named "%s" defined for %s + ''', + key, + type_name(self) + )) + key = self._field_map[key] + + name, _, params = self._fields[key] + if not params or ('default' not in params and 'optional' not in params): + raise ValueError(unwrap( + ''' + Can not delete the value for the field "%s" of %s since it is + not optional or defaulted + ''', + name, + type_name(self) + )) + + if 'optional' in params: + self.children[key] = VOID + if self._native is not None: + self._native[name] = None + else: + self.__setitem__(key, None) + self._mutated = True + + def __iter__(self): + """ + :return: + An iterator of field key names + """ + + for info in self._fields: + yield info[0] + + def _set_contents(self, force=False): + """ + Updates the .contents attribute of the value with the encoded value of + all of the child objects + + :param force: + Ensure all contents are in DER format instead of possibly using + cached BER-encoded data + """ + + if self.children is None: + self._parse_children() + + contents = BytesIO() + for index, info in enumerate(self._fields): + child = self.children[index] + if child is None: + child_dump = b'' + elif child.__class__ == tuple: + if force: + child_dump = self._lazy_child(index).dump(force=force) + else: + child_dump = child[3] + child[4] + child[5] + else: + child_dump = child.dump(force=force) + # Skip values that are the same as the default + if info[2] and 'default' in info[2]: + default_value = info[1](**info[2]) + if default_value.dump() == child_dump: + continue + contents.write(child_dump) + self._contents = contents.getvalue() + + self._header = None + if self._trailer != b'': + self._trailer = b'' + + def _setup(self): + """ + Generates _field_map, _field_ids and _oid_nums for use in parsing + """ + + cls = self.__class__ + cls._field_map = {} + cls._field_ids = [] + cls._precomputed_specs = [] + for index, field in enumerate(cls._fields): + if len(field) < 3: + field = field + ({},) + cls._fields[index] = field + cls._field_map[field[0]] = index + cls._field_ids.append(_build_id_tuple(field[2], field[1])) + + if cls._oid_pair is not None: + cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]]) + + for index, field in enumerate(cls._fields): + has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks + is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index + if has_callback or is_mapped_oid: + cls._precomputed_specs.append(None) + else: + cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None)) + + def _determine_spec(self, index): + """ + Determine how a value for a field should be constructed + + :param index: + The field number + + :return: + A tuple containing the following elements: + - unicode string of the field name + - Asn1Value class of the field spec + - Asn1Value class of the value spec + - None or dict of params to pass to the field spec + - None or Asn1Value class indicating the value spec was derived from an OID or a spec callback + """ + + name, field_spec, field_params = self._fields[index] + value_spec = field_spec + spec_override = None + + if self._spec_callbacks is not None and name in self._spec_callbacks: + callback = self._spec_callbacks[name] + spec_override = callback(self) + if spec_override: + # Allow a spec callback to specify both the base spec and + # the override, for situations such as OctetString and parse_as + if spec_override.__class__ == tuple and len(spec_override) == 2: + field_spec, value_spec = spec_override + if value_spec is None: + value_spec = field_spec + spec_override = None + # When no field spec is specified, use a single return value as that + elif field_spec is None: + field_spec = spec_override + value_spec = field_spec + spec_override = None + else: + value_spec = spec_override + + elif self._oid_nums is not None and self._oid_nums[1] == index: + oid = self._lazy_child(self._oid_nums[0]).native + if oid in self._oid_specs: + spec_override = self._oid_specs[oid] + value_spec = spec_override + + return (name, field_spec, value_spec, field_params, spec_override) + + def _make_value(self, field_name, field_spec, value_spec, field_params, value): + """ + Contructs an appropriate Asn1Value object for a field + + :param field_name: + A unicode string of the field name + + :param field_spec: + An Asn1Value class that is the field spec + + :param value_spec: + An Asn1Value class that is the vaue spec + + :param field_params: + None or a dict of params for the field spec + + :param value: + The value to construct an Asn1Value object from + + :return: + An instance of a child class of Asn1Value + """ + + if value is None and 'optional' in field_params: + return VOID + + specs_different = field_spec != value_spec + is_any = issubclass(field_spec, Any) + + if issubclass(value_spec, Choice): + if not isinstance(value, Asn1Value): + raise ValueError(unwrap( + ''' + Can not set a native python value to %s, which has the + choice type of %s - value must be an instance of Asn1Value + ''', + field_name, + type_name(value_spec) + )) + if not isinstance(value, value_spec): + wrapper = value_spec() + wrapper.validate(value.class_, value.tag, value.contents) + wrapper._parsed = value + new_value = wrapper + else: + new_value = value + + elif isinstance(value, field_spec): + new_value = value + if specs_different: + new_value.parse(value_spec) + + elif (not specs_different or is_any) and not isinstance(value, value_spec): + new_value = value_spec(value, **field_params) + + else: + if isinstance(value, value_spec): + new_value = value + else: + new_value = value_spec(value) + + # For when the field is OctetString or OctetBitString with embedded + # values we need to wrap the value in the field spec to get the + # appropriate encoded value. + if specs_different and not is_any: + wrapper = field_spec(value=new_value.dump(), **field_params) + wrapper._parsed = (new_value, new_value.__class__, None) + new_value = wrapper + + new_value = _fix_tagging(new_value, field_params) + + return new_value + + def _parse_children(self, recurse=False): + """ + Parses the contents and generates Asn1Value objects based on the + definitions from _fields. + + :param recurse: + If child objects that are Sequence or SequenceOf objects should + be recursively parsed + + :raises: + ValueError - when an error occurs parsing child objects + """ + + cls = self.__class__ + if self._contents is None: + if self._fields: + self.children = [VOID] * len(self._fields) + for index, (_, _, params) in enumerate(self._fields): + if 'default' in params: + if cls._precomputed_specs[index]: + field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index] + else: + field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index) + self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None) + return + + try: + self.children = [] + contents_length = len(self._contents) + child_pointer = 0 + field = 0 + field_len = len(self._fields) + parts = None + again = child_pointer < contents_length + while again: + if parts is None: + parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer) + again = child_pointer < contents_length + + if field < field_len: + _, field_spec, value_spec, field_params, spec_override = ( + cls._precomputed_specs[field] or self._determine_spec(field)) + + # If the next value is optional or default, allow it to be absent + if field_params and ('optional' in field_params or 'default' in field_params): + if self._field_ids[field] != (parts[0], parts[2]) and field_spec != Any: + + # See if the value is a valid choice before assuming + # that we have a missing optional or default value + choice_match = False + if issubclass(field_spec, Choice): + try: + tester = field_spec(**field_params) + tester.validate(parts[0], parts[2], parts[4]) + choice_match = True + except (ValueError): + pass + + if not choice_match: + if 'optional' in field_params: + self.children.append(VOID) + else: + self.children.append(field_spec(**field_params)) + field += 1 + again = True + continue + + if field_spec is None or (spec_override and issubclass(field_spec, Any)): + field_spec = value_spec + spec_override = None + + if spec_override: + child = parts + (field_spec, field_params, value_spec) + else: + child = parts + (field_spec, field_params) + + # Handle situations where an optional or defaulted field definition is incorrect + elif field_len > 0 and field + 1 <= field_len: + missed_fields = [] + prev_field = field - 1 + while prev_field >= 0: + prev_field_info = self._fields[prev_field] + if len(prev_field_info) < 3: + break + if 'optional' in prev_field_info[2] or 'default' in prev_field_info[2]: + missed_fields.append(prev_field_info[0]) + prev_field -= 1 + plural = 's' if len(missed_fields) > 1 else '' + missed_field_names = ', '.join(missed_fields) + raise ValueError(unwrap( + ''' + Data for field %s (%s class, %s method, tag %s) does + not match the field definition%s of %s + ''', + field + 1, + CLASS_NUM_TO_NAME_MAP.get(parts[0]), + METHOD_NUM_TO_NAME_MAP.get(parts[1]), + parts[2], + plural, + missed_field_names + )) + + else: + child = parts + + if recurse: + child = _build(*child) + if isinstance(child, (Sequence, SequenceOf)): + child._parse_children(recurse=True) + + self.children.append(child) + field += 1 + parts = None + + index = len(self.children) + while index < field_len: + name, field_spec, field_params = self._fields[index] + if 'default' in field_params: + self.children.append(field_spec(**field_params)) + elif 'optional' in field_params: + self.children.append(VOID) + else: + raise ValueError(unwrap( + ''' + Field "%s" is missing from structure + ''', + name + )) + index += 1 + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args + raise e + + def spec(self, field_name): + """ + Determines the spec to use for the field specified. Depending on how + the spec is determined (_oid_pair or _spec_callbacks), it may be + necessary to set preceding field values before calling this. Usually + specs, if dynamic, are controlled by a preceding ObjectIdentifier + field. + + :param field_name: + A unicode string of the field name to get the spec for + + :return: + A child class of asn1crypto.core.Asn1Value that the field must be + encoded using + """ + + if not isinstance(field_name, str_cls): + raise TypeError(unwrap( + ''' + field_name must be a unicode string, not %s + ''', + type_name(field_name) + )) + + if self._fields is None: + raise ValueError(unwrap( + ''' + Unable to retrieve spec for field %s in the class %s because + _fields has not been set + ''', + repr(field_name), + type_name(self) + )) + + index = self._field_map[field_name] + info = self._determine_spec(index) + + return info[2] + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + An OrderedDict or None. If an OrderedDict, all child values are + recursively converted to native representation also. + """ + + if self.contents is None: + return None + + if self._native is None: + if self.children is None: + self._parse_children(recurse=True) + try: + self._native = OrderedDict() + for index, child in enumerate(self.children): + if child.__class__ == tuple: + child = _build(*child) + self.children[index] = child + try: + name = self._fields[index][0] + except (IndexError): + name = str_cls(index) + self._native[name] = child.native + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args + raise e + return self._native + + def _copy(self, other, copy_func): + """ + Copies the contents of another Sequence object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(Sequence, self)._copy(other, copy_func) + if self.children is not None: + self.children = [] + for child in other.children: + if child.__class__ == tuple: + self.children.append(child) + else: + self.children.append(child.copy()) + + def debug(self, nest_level=1): + """ + Show the binary data and parsed data in a tree structure + """ + + if self.children is None: + self._parse_children() + + prefix = ' ' * nest_level + _basic_debug(prefix, self) + for field_name in self: + child = self._lazy_child(self._field_map[field_name]) + if child is not VOID: + print('%s Field "%s"' % (prefix, field_name)) + child.debug(nest_level + 3) + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + if force: + self._set_contents(force=force) + + if self._fields and self.children is not None: + for index, (field_name, _, params) in enumerate(self._fields): + if self.children[index] is not VOID: + continue + if 'default' in params or 'optional' in params: + continue + raise ValueError(unwrap( + ''' + Field "%s" is missing from structure + ''', + field_name + )) + + return Asn1Value.dump(self) + + +class SequenceOf(Asn1Value): + """ + Represents a sequence (ordered) of a single type of values from ASN.1 as a + Python object with a list-like interface + """ + + tag = 16 + + class_ = 0 + method = 1 + + # A list of child objects + children = None + + # SequenceOf overrides .contents to be a property so that the mutated state + # of child objects can be checked to ensure everything is up-to-date + _contents = None + + # Variable to track if the object has been mutated + _mutated = False + + # An Asn1Value class to use when parsing children + _child_spec = None + + def __init__(self, value=None, default=None, contents=None, spec=None, **kwargs): + """ + Allows setting child objects and the _child_spec via the spec parameter + before passing everything else along to Asn1Value.__init__() + + :param value: + A native Python datatype to initialize the object value with + + :param default: + The default value if no value is specified + + :param contents: + A byte string of the encoded contents of the value + + :param spec: + A class derived from Asn1Value to use to parse children + """ + + if spec: + self._child_spec = spec + + Asn1Value.__init__(self, **kwargs) + + try: + if contents is not None: + self.contents = contents + else: + if value is None and default is not None: + value = default + + if value is not None: + for index, child in enumerate(value): + self.__setitem__(index, child) + + # Make sure a blank list is serialized + if self.contents is None: + self._set_contents() + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args + raise e + + @property + def contents(self): + """ + :return: + A byte string of the DER-encoded contents of the sequence + """ + + if self.children is None: + return self._contents + + if self._is_mutated(): + self._set_contents() + + return self._contents + + @contents.setter + def contents(self, value): + """ + :param value: + A byte string of the DER-encoded contents of the sequence + """ + + self._contents = value + + def _is_mutated(self): + """ + :return: + A boolean - if the sequence or any children (recursively) have been + mutated + """ + + mutated = self._mutated + if self.children is not None: + for child in self.children: + if isinstance(child, Sequence) or isinstance(child, SequenceOf): + mutated = mutated or child._is_mutated() + + return mutated + + def _lazy_child(self, index): + """ + Builds a child object if the child has only been parsed into a tuple so far + """ + + child = self.children[index] + if child.__class__ == tuple: + child = _build(*child) + self.children[index] = child + return child + + def _make_value(self, value): + """ + Constructs a _child_spec value from a native Python data type, or + an appropriate Asn1Value object + + :param value: + A native Python value, or some child of Asn1Value + + :return: + An object of type _child_spec + """ + + if isinstance(value, self._child_spec): + new_value = value + + elif issubclass(self._child_spec, Any): + if isinstance(value, Asn1Value): + new_value = value + else: + raise ValueError(unwrap( + ''' + Can not set a native python value to %s where the + _child_spec is Any - value must be an instance of Asn1Value + ''', + type_name(self) + )) + + elif issubclass(self._child_spec, Choice): + if not isinstance(value, Asn1Value): + raise ValueError(unwrap( + ''' + Can not set a native python value to %s where the + _child_spec is the choice type %s - value must be an + instance of Asn1Value + ''', + type_name(self), + self._child_spec.__name__ + )) + if not isinstance(value, self._child_spec): + wrapper = self._child_spec() + wrapper.validate(value.class_, value.tag, value.contents) + wrapper._parsed = value + value = wrapper + new_value = value + + else: + return self._child_spec(value=value) + + params = {} + if self._child_spec.explicit: + params['explicit'] = self._child_spec.explicit + if self._child_spec.implicit: + params['implicit'] = (self._child_spec.class_, self._child_spec.tag) + return _fix_tagging(new_value, params) + + def __len__(self): + """ + :return: + An integer + """ + # We inline this checks to prevent method invocation each time + if self.children is None: + self._parse_children() + + return len(self.children) + + def __getitem__(self, key): + """ + Allows accessing children via index + + :param key: + Integer index of child + """ + + # We inline this checks to prevent method invocation each time + if self.children is None: + self._parse_children() + + return self._lazy_child(key) + + def __setitem__(self, key, value): + """ + Allows overriding a child via index + + :param key: + Integer index of child + + :param value: + Native python datatype that will be passed to _child_spec to create + new child object + """ + + # We inline this checks to prevent method invocation each time + if self.children is None: + self._parse_children() + + new_value = self._make_value(value) + + # If adding at the end, create a space for the new value + if key == len(self.children): + self.children.append(None) + if self._native is not None: + self._native.append(None) + + self.children[key] = new_value + + if self._native is not None: + self._native[key] = self.children[key].native + + self._mutated = True + + def __delitem__(self, key): + """ + Allows removing a child via index + + :param key: + Integer index of child + """ + + # We inline this checks to prevent method invocation each time + if self.children is None: + self._parse_children() + + self.children.pop(key) + if self._native is not None: + self._native.pop(key) + + self._mutated = True + + def __iter__(self): + """ + :return: + An iter() of child objects + """ + + # We inline this checks to prevent method invocation each time + if self.children is None: + self._parse_children() + + for index in range(0, len(self.children)): + yield self._lazy_child(index) + + def __contains__(self, item): + """ + :param item: + An object of the type cls._child_spec + + :return: + A boolean if the item is contained in this SequenceOf + """ + + if item is None or item is VOID: + return False + + if not isinstance(item, self._child_spec): + raise TypeError(unwrap( + ''' + Checking membership in %s is only available for instances of + %s, not %s + ''', + type_name(self), + type_name(self._child_spec), + type_name(item) + )) + + for child in self: + if child == item: + return True + + return False + + def append(self, value): + """ + Allows adding a child to the end of the sequence + + :param value: + Native python datatype that will be passed to _child_spec to create + new child object + """ + + # We inline this checks to prevent method invocation each time + if self.children is None: + self._parse_children() + + self.children.append(self._make_value(value)) + + if self._native is not None: + self._native.append(self.children[-1].native) + + self._mutated = True + + def _set_contents(self, force=False): + """ + Encodes all child objects into the contents for this object + + :param force: + Ensure all contents are in DER format instead of possibly using + cached BER-encoded data + """ + + if self.children is None: + self._parse_children() + + contents = BytesIO() + for child in self: + contents.write(child.dump(force=force)) + self._contents = contents.getvalue() + self._header = None + if self._trailer != b'': + self._trailer = b'' + + def _parse_children(self, recurse=False): + """ + Parses the contents and generates Asn1Value objects based on the + definitions from _child_spec. + + :param recurse: + If child objects that are Sequence or SequenceOf objects should + be recursively parsed + + :raises: + ValueError - when an error occurs parsing child objects + """ + + try: + self.children = [] + if self._contents is None: + return + contents_length = len(self._contents) + child_pointer = 0 + while child_pointer < contents_length: + parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer) + if self._child_spec: + child = parts + (self._child_spec,) + else: + child = parts + if recurse: + child = _build(*child) + if isinstance(child, (Sequence, SequenceOf)): + child._parse_children(recurse=True) + self.children.append(child) + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args + raise e + + def spec(self): + """ + Determines the spec to use for child values. + + :return: + A child class of asn1crypto.core.Asn1Value that child values must be + encoded using + """ + + return self._child_spec + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A list or None. If a list, all child values are recursively + converted to native representation also. + """ + + if self.contents is None: + return None + + if self._native is None: + if self.children is None: + self._parse_children(recurse=True) + try: + self._native = [child.native for child in self] + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args + raise e + return self._native + + def _copy(self, other, copy_func): + """ + Copies the contents of another SequenceOf object to itself + + :param object: + Another instance of the same class + + :param copy_func: + An reference of copy.copy() or copy.deepcopy() to use when copying + lists, dicts and objects + """ + + super(SequenceOf, self)._copy(other, copy_func) + if self.children is not None: + self.children = [] + for child in other.children: + if child.__class__ == tuple: + self.children.append(child) + else: + self.children.append(child.copy()) + + def debug(self, nest_level=1): + """ + Show the binary data and parsed data in a tree structure + """ + + if self.children is None: + self._parse_children() + + prefix = ' ' * nest_level + _basic_debug(prefix, self) + for child in self: + child.debug(nest_level + 1) + + def dump(self, force=False): + """ + Encodes the value using DER + + :param force: + If the encoded contents already exist, clear them and regenerate + to ensure they are in DER format instead of BER format + + :return: + A byte string of the DER-encoded value + """ + + if force: + self._set_contents(force=force) + + return Asn1Value.dump(self) + + +class Set(Sequence): + """ + Represents a set of fields (unordered) from ASN.1 as a Python object with a + dict-like interface + """ + + method = 1 + class_ = 0 + tag = 17 + + # A dict of 2-element tuples in the form (class_, tag) as keys and integers + # as values that are the index of the field in _fields + _field_ids = None + + def _setup(self): + """ + Generates _field_map, _field_ids and _oid_nums for use in parsing + """ + + cls = self.__class__ + cls._field_map = {} + cls._field_ids = {} + cls._precomputed_specs = [] + for index, field in enumerate(cls._fields): + if len(field) < 3: + field = field + ({},) + cls._fields[index] = field + cls._field_map[field[0]] = index + cls._field_ids[_build_id_tuple(field[2], field[1])] = index + + if cls._oid_pair is not None: + cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]]) + + for index, field in enumerate(cls._fields): + has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks + is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index + if has_callback or is_mapped_oid: + cls._precomputed_specs.append(None) + else: + cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None)) + + def _parse_children(self, recurse=False): + """ + Parses the contents and generates Asn1Value objects based on the + definitions from _fields. + + :param recurse: + If child objects that are Sequence or SequenceOf objects should + be recursively parsed + + :raises: + ValueError - when an error occurs parsing child objects + """ + + cls = self.__class__ + if self._contents is None: + if self._fields: + self.children = [VOID] * len(self._fields) + for index, (_, _, params) in enumerate(self._fields): + if 'default' in params: + if cls._precomputed_specs[index]: + field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index] + else: + field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index) + self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None) + return + + try: + child_map = {} + contents_length = len(self.contents) + child_pointer = 0 + seen_field = 0 + while child_pointer < contents_length: + parts, child_pointer = _parse(self.contents, contents_length, pointer=child_pointer) + + id_ = (parts[0], parts[2]) + + field = self._field_ids.get(id_) + if field is None: + raise ValueError(unwrap( + ''' + Data for field %s (%s class, %s method, tag %s) does + not match any of the field definitions + ''', + seen_field, + CLASS_NUM_TO_NAME_MAP.get(parts[0]), + METHOD_NUM_TO_NAME_MAP.get(parts[1]), + parts[2], + )) + + _, field_spec, value_spec, field_params, spec_override = ( + cls._precomputed_specs[field] or self._determine_spec(field)) + + if field_spec is None or (spec_override and issubclass(field_spec, Any)): + field_spec = value_spec + spec_override = None + + if spec_override: + child = parts + (field_spec, field_params, value_spec) + else: + child = parts + (field_spec, field_params) + + if recurse: + child = _build(*child) + if isinstance(child, (Sequence, SequenceOf)): + child._parse_children(recurse=True) + + child_map[field] = child + seen_field += 1 + + total_fields = len(self._fields) + + for index in range(0, total_fields): + if index in child_map: + continue + + name, field_spec, value_spec, field_params, spec_override = ( + cls._precomputed_specs[index] or self._determine_spec(index)) + + if field_spec is None or (spec_override and issubclass(field_spec, Any)): + field_spec = value_spec + spec_override = None + + missing = False + + if not field_params: + missing = True + elif 'optional' not in field_params and 'default' not in field_params: + missing = True + elif 'optional' in field_params: + child_map[index] = VOID + elif 'default' in field_params: + child_map[index] = field_spec(**field_params) + + if missing: + raise ValueError(unwrap( + ''' + Missing required field "%s" from %s + ''', + name, + type_name(self) + )) + + self.children = [] + for index in range(0, total_fields): + self.children.append(child_map[index]) + + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args + raise e + + def _set_contents(self, force=False): + """ + Encodes all child objects into the contents for this object. + + This method is overridden because a Set needs to be encoded by + removing defaulted fields and then sorting the fields by tag. + + :param force: + Ensure all contents are in DER format instead of possibly using + cached BER-encoded data + """ + + if self.children is None: + self._parse_children() + + child_tag_encodings = [] + for index, child in enumerate(self.children): + child_encoding = child.dump(force=force) + + # Skip encoding defaulted children + name, spec, field_params = self._fields[index] + if 'default' in field_params: + if spec(**field_params).dump() == child_encoding: + continue + + child_tag_encodings.append((child.tag, child_encoding)) + child_tag_encodings.sort(key=lambda ct: ct[0]) + + self._contents = b''.join([ct[1] for ct in child_tag_encodings]) + self._header = None + if self._trailer != b'': + self._trailer = b'' + + +class SetOf(SequenceOf): + """ + Represents a set (unordered) of a single type of values from ASN.1 as a + Python object with a list-like interface + """ + + tag = 17 + + def _set_contents(self, force=False): + """ + Encodes all child objects into the contents for this object. + + This method is overridden because a SetOf needs to be encoded by + sorting the child encodings. + + :param force: + Ensure all contents are in DER format instead of possibly using + cached BER-encoded data + """ + + if self.children is None: + self._parse_children() + + child_encodings = [] + for child in self: + child_encodings.append(child.dump(force=force)) + + self._contents = b''.join(sorted(child_encodings)) + self._header = None + if self._trailer != b'': + self._trailer = b'' + + +class EmbeddedPdv(Sequence): + """ + A sequence structure + """ + + tag = 11 + + +class NumericString(AbstractString): + """ + Represents a numeric string from ASN.1 as a Python unicode string + """ + + tag = 18 + _encoding = 'latin1' + + +class PrintableString(AbstractString): + """ + Represents a printable string from ASN.1 as a Python unicode string + """ + + tag = 19 + _encoding = 'latin1' + + +class TeletexString(AbstractString): + """ + Represents a teletex string from ASN.1 as a Python unicode string + """ + + tag = 20 + _encoding = 'teletex' + + +class VideotexString(OctetString): + """ + Represents a videotex string from ASN.1 as a Python byte string + """ + + tag = 21 + + +class IA5String(AbstractString): + """ + Represents an IA5 string from ASN.1 as a Python unicode string + """ + + tag = 22 + _encoding = 'ascii' + + +class AbstractTime(AbstractString): + """ + Represents a time from ASN.1 as a Python datetime.datetime object + """ + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A datetime.datetime object in the UTC timezone or None + """ + + if self.contents is None: + return None + + if self._native is None: + string = str_cls(self) + has_timezone = re.search('[-\\+]', string) + + # We don't know what timezone it is in, or it is UTC because of a Z + # suffix, so we just assume UTC + if not has_timezone: + string = string.rstrip('Z') + date = self._date_by_len(string) + self._native = date.replace(tzinfo=timezone.utc) + + else: + # Python 2 doesn't support the %z format code, so we have to manually + # process the timezone offset. + date = self._date_by_len(string[0:-5]) + + hours = int(string[-4:-2]) + minutes = int(string[-2:]) + delta = timedelta(hours=abs(hours), minutes=minutes) + if hours < 0: + date -= delta + else: + date += delta + + self._native = date.replace(tzinfo=timezone.utc) + + return self._native + + +class UTCTime(AbstractTime): + """ + Represents a UTC time from ASN.1 as a Python datetime.datetime object in UTC + """ + + tag = 23 + + def set(self, value): + """ + Sets the value of the object + + :param value: + A unicode string or a datetime.datetime object + + :raises: + ValueError - when an invalid value is passed + """ + + if isinstance(value, datetime): + value = value.strftime('%y%m%d%H%M%SZ') + if _PY2: + value = value.decode('ascii') + + AbstractString.set(self, value) + # Set it to None and let the class take care of converting the next + # time that .native is called + self._native = None + + def _date_by_len(self, string): + """ + Parses a date from a string based on its length + + :param string: + A unicode string to parse + + :return: + A datetime.datetime object or a unicode string + """ + + strlen = len(string) + + year_num = int(string[0:2]) + if year_num < 50: + prefix = '20' + else: + prefix = '19' + + if strlen == 10: + return datetime.strptime(prefix + string, '%Y%m%d%H%M') + + if strlen == 12: + return datetime.strptime(prefix + string, '%Y%m%d%H%M%S') + + return string + + +class GeneralizedTime(AbstractTime): + """ + Represents a generalized time from ASN.1 as a Python datetime.datetime + object or asn1crypto.util.extended_datetime object in UTC + """ + + tag = 24 + + def set(self, value): + """ + Sets the value of the object + + :param value: + A unicode string, a datetime.datetime object or an + asn1crypto.util.extended_datetime object + + :raises: + ValueError - when an invalid value is passed + """ + + if isinstance(value, (datetime, extended_datetime)): + value = value.strftime('%Y%m%d%H%M%SZ') + if _PY2: + value = value.decode('ascii') + + AbstractString.set(self, value) + # Set it to None and let the class take care of converting the next + # time that .native is called + self._native = None + + def _date_by_len(self, string): + """ + Parses a date from a string based on its length + + :param string: + A unicode string to parse + + :return: + A datetime.datetime object, asn1crypto.util.extended_datetime object or + a unicode string + """ + + strlen = len(string) + + date_format = None + if strlen == 10: + date_format = '%Y%m%d%H' + elif strlen == 12: + date_format = '%Y%m%d%H%M' + elif strlen == 14: + date_format = '%Y%m%d%H%M%S' + elif strlen == 18: + date_format = '%Y%m%d%H%M%S.%f' + + if date_format: + if len(string) >= 4 and string[0:4] == '0000': + # Year 2000 shares a calendar with year 0, and is supported natively + t = datetime.strptime('2000' + string[4:], date_format) + return extended_datetime( + 0, + t.month, + t.day, + t.hour, + t.minute, + t.second, + t.microsecond, + t.tzinfo + ) + return datetime.strptime(string, date_format) + + return string + + +class GraphicString(AbstractString): + """ + Represents a graphic string from ASN.1 as a Python unicode string + """ + + tag = 25 + # This is technically not correct since this type can contain any charset + _encoding = 'latin1' + + +class VisibleString(AbstractString): + """ + Represents a visible string from ASN.1 as a Python unicode string + """ + + tag = 26 + _encoding = 'latin1' + + +class GeneralString(AbstractString): + """ + Represents a general string from ASN.1 as a Python unicode string + """ + + tag = 27 + # This is technically not correct since this type can contain any charset + _encoding = 'latin1' + + +class UniversalString(AbstractString): + """ + Represents a universal string from ASN.1 as a Python unicode string + """ + + tag = 28 + _encoding = 'utf-32-be' + + +class CharacterString(AbstractString): + """ + Represents a character string from ASN.1 as a Python unicode string + """ + + tag = 29 + # This is technically not correct since this type can contain any charset + _encoding = 'latin1' + + +class BMPString(AbstractString): + """ + Represents a BMP string from ASN.1 as a Python unicode string + """ + + tag = 30 + _encoding = 'utf-16-be' + + +def _basic_debug(prefix, self): + """ + Prints out basic information about an Asn1Value object. Extracted for reuse + among different classes that customize the debug information. + + :param prefix: + A unicode string of spaces to prefix output line with + + :param self: + The object to print the debugging information about + """ + + print('%s%s Object #%s' % (prefix, type_name(self), id(self))) + if self._header: + print('%s Header: 0x%s' % (prefix, binascii.hexlify(self._header or b'').decode('utf-8'))) + + has_header = self.method is not None and self.class_ is not None and self.tag is not None + if has_header: + method_name = METHOD_NUM_TO_NAME_MAP.get(self.method) + class_name = CLASS_NUM_TO_NAME_MAP.get(self.class_) + + if self.explicit is not None: + for class_, tag in self.explicit: + print( + '%s %s tag %s (explicitly tagged)' % + ( + prefix, + CLASS_NUM_TO_NAME_MAP.get(class_), + tag + ) + ) + if has_header: + print('%s %s %s %s' % (prefix, method_name, class_name, self.tag)) + + elif self.implicit: + if has_header: + print('%s %s %s tag %s (implicitly tagged)' % (prefix, method_name, class_name, self.tag)) + + elif has_header: + print('%s %s %s tag %s' % (prefix, method_name, class_name, self.tag)) + + print('%s Data: 0x%s' % (prefix, binascii.hexlify(self.contents or b'').decode('utf-8'))) + + +def _tag_type_to_explicit_implicit(params): + """ + Converts old-style "tag_type" and "tag" params to "explicit" and "implicit" + + :param params: + A dict of parameters to convert from tag_type/tag to explicit/implicit + """ + + if 'tag_type' in params: + if params['tag_type'] == 'explicit': + params['explicit'] = (params.get('class', 2), params['tag']) + elif params['tag_type'] == 'implicit': + params['implicit'] = (params.get('class', 2), params['tag']) + del params['tag_type'] + del params['tag'] + if 'class' in params: + del params['class'] + + +def _fix_tagging(value, params): + """ + Checks if a value is properly tagged based on the spec, and re/untags as + necessary + + :param value: + An Asn1Value object + + :param params: + A dict of spec params + + :return: + An Asn1Value that is properly tagged + """ + + _tag_type_to_explicit_implicit(params) + + retag = False + if 'implicit' not in params: + if value.implicit is not False: + retag = True + else: + if isinstance(params['implicit'], tuple): + class_, tag = params['implicit'] + else: + tag = params['implicit'] + class_ = 'context' + if value.implicit is False: + retag = True + elif value.class_ != CLASS_NAME_TO_NUM_MAP[class_] or value.tag != tag: + retag = True + + if params.get('explicit') != value.explicit: + retag = True + + if retag: + return value.retag(params) + return value + + +def _build_id_tuple(params, spec): + """ + Builds a 2-element tuple used to identify fields by grabbing the class_ + and tag from an Asn1Value class and the params dict being passed to it + + :param params: + A dict of params to pass to spec + + :param spec: + An Asn1Value class + + :return: + A 2-element integer tuple in the form (class_, tag) + """ + + # Handle situations where the the spec is not known at setup time + if spec is None: + return (None, None) + + required_class = spec.class_ + required_tag = spec.tag + + _tag_type_to_explicit_implicit(params) + + if 'explicit' in params: + if isinstance(params['explicit'], tuple): + required_class, required_tag = params['explicit'] + else: + required_class = 2 + required_tag = params['explicit'] + elif 'implicit' in params: + if isinstance(params['implicit'], tuple): + required_class, required_tag = params['implicit'] + else: + required_class = 2 + required_tag = params['implicit'] + if required_class is not None and not isinstance(required_class, int_types): + required_class = CLASS_NAME_TO_NUM_MAP[required_class] + + required_class = params.get('class_', required_class) + required_tag = params.get('tag', required_tag) + + return (required_class, required_tag) + + +_UNIVERSAL_SPECS = { + 1: Boolean, + 2: Integer, + 3: BitString, + 4: OctetString, + 5: Null, + 6: ObjectIdentifier, + 7: ObjectDescriptor, + 8: InstanceOf, + 9: Real, + 10: Enumerated, + 11: EmbeddedPdv, + 12: UTF8String, + 13: RelativeOid, + 16: Sequence, + 17: Set, + 18: NumericString, + 19: PrintableString, + 20: TeletexString, + 21: VideotexString, + 22: IA5String, + 23: UTCTime, + 24: GeneralizedTime, + 25: GraphicString, + 26: VisibleString, + 27: GeneralString, + 28: UniversalString, + 29: CharacterString, + 30: BMPString +} + + +def _build(class_, method, tag, header, contents, trailer, spec=None, spec_params=None, nested_spec=None): + """ + Builds an Asn1Value object generically, or using a spec with optional params + + :param class_: + An integer representing the ASN.1 class + + :param method: + An integer representing the ASN.1 method + + :param tag: + An integer representing the ASN.1 tag + + :param header: + A byte string of the ASN.1 header (class, method, tag, length) + + :param contents: + A byte string of the ASN.1 value + + :param trailer: + A byte string of any ASN.1 trailer (only used by indefinite length encodings) + + :param spec: + A class derived from Asn1Value that defines what class_ and tag the + value should have, and the semantics of the encoded value. The + return value will be of this type. If omitted, the encoded value + will be decoded using the standard universal tag based on the + encoded tag number. + + :param spec_params: + A dict of params to pass to the spec object + + :param nested_spec: + For certain Asn1Value classes (such as OctetString and BitString), the + contents can be further parsed and interpreted as another Asn1Value. + This parameter controls the spec for that sub-parsing. + + :return: + An object of the type spec, or if not specified, a child of Asn1Value + """ + + if spec_params is not None: + _tag_type_to_explicit_implicit(spec_params) + + if header is None: + return VOID + + header_set = False + + # If an explicit specification was passed in, make sure it matches + if spec is not None: + if spec_params: + value = spec(contents=contents, **spec_params) + else: + value = spec(contents=contents) + + if spec is Any: + pass + + elif value.explicit: + original_explicit = value.explicit + explicit_info = reversed(original_explicit) + parsed_class = class_ + parsed_method = method + parsed_tag = tag + to_parse = contents + explicit_header = header + explicit_trailer = trailer or b'' + for expected_class, expected_tag in explicit_info: + if parsed_class != expected_class: + raise ValueError(unwrap( + ''' + Error parsing %s - explicitly-tagged class should have been + %s, but %s was found + ''', + type_name(value), + CLASS_NUM_TO_NAME_MAP.get(expected_class), + CLASS_NUM_TO_NAME_MAP.get(parsed_class, parsed_class) + )) + if parsed_method != 1: + raise ValueError(unwrap( + ''' + Error parsing %s - explicitly-tagged method should have + been %s, but %s was found + ''', + type_name(value), + METHOD_NUM_TO_NAME_MAP.get(1), + METHOD_NUM_TO_NAME_MAP.get(parsed_method, parsed_method) + )) + if parsed_tag != expected_tag: + raise ValueError(unwrap( + ''' + Error parsing %s - explicitly-tagged tag should have been + %s, but %s was found + ''', + type_name(value), + expected_tag, + parsed_tag + )) + info, _ = _parse(to_parse, len(to_parse)) + parsed_class, parsed_method, parsed_tag, parsed_header, to_parse, parsed_trailer = info + explicit_header += parsed_header + explicit_trailer = parsed_trailer + explicit_trailer + value = _build(*info, spec=spec, spec_params={'no_explicit': True}) + value._header = explicit_header + value._trailer = explicit_trailer + value.explicit = original_explicit + header_set = True + + elif isinstance(value, Choice): + value.validate(class_, tag, contents) + try: + # Force parsing the Choice now + value.contents = header + value.contents + header = b'' + value.parse() + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(value),) + args + raise e + + else: + if class_ != value.class_: + raise ValueError(unwrap( + ''' + Error parsing %s - class should have been %s, but %s was + found + ''', + type_name(value), + CLASS_NUM_TO_NAME_MAP.get(value.class_), + CLASS_NUM_TO_NAME_MAP.get(class_, class_) + )) + if method != value.method: + # Allow parsing a primitive method as constructed if the value + # is indefinite length. This is to allow parsing BER. + ber_indef = method == 1 and value.method == 0 and trailer == b'\x00\x00' + if not ber_indef or not isinstance(value, Constructable): + raise ValueError(unwrap( + ''' + Error parsing %s - method should have been %s, but %s was found + ''', + type_name(value), + METHOD_NUM_TO_NAME_MAP.get(value.method), + METHOD_NUM_TO_NAME_MAP.get(method, method) + )) + else: + value.method = method + value._indefinite = True + if tag != value.tag and tag != value._bad_tag: + raise ValueError(unwrap( + ''' + Error parsing %s - tag should have been %s, but %s was found + ''', + type_name(value), + value.tag, + tag + )) + + # For explicitly tagged, un-speced parsings, we use a generic container + # since we will be parsing the contents and discarding the outer object + # anyway a little further on + elif spec_params and 'explicit' in spec_params: + original_value = Asn1Value(contents=contents, **spec_params) + original_explicit = original_value.explicit + + to_parse = contents + explicit_header = header + explicit_trailer = trailer or b'' + for expected_class, expected_tag in reversed(original_explicit): + info, _ = _parse(to_parse, len(to_parse)) + _, _, _, parsed_header, to_parse, parsed_trailer = info + explicit_header += parsed_header + explicit_trailer = parsed_trailer + explicit_trailer + value = _build(*info, spec=spec, spec_params={'no_explicit': True}) + value._header = header + value._header + value._trailer += trailer or b'' + value.explicit = original_explicit + header_set = True + + # If no spec was specified, allow anything and just process what + # is in the input data + else: + if tag not in _UNIVERSAL_SPECS: + raise ValueError(unwrap( + ''' + Unknown element - %s class, %s method, tag %s + ''', + CLASS_NUM_TO_NAME_MAP.get(class_), + METHOD_NUM_TO_NAME_MAP.get(method), + tag + )) + + spec = _UNIVERSAL_SPECS[tag] + + value = spec(contents=contents, class_=class_) + ber_indef = method == 1 and value.method == 0 and trailer == b'\x00\x00' + if ber_indef and isinstance(value, Constructable): + value._indefinite = True + value.method = method + + if not header_set: + value._header = header + value._trailer = trailer or b'' + + # Destroy any default value that our contents have overwritten + value._native = None + + if nested_spec: + try: + value.parse(nested_spec) + except (ValueError, TypeError) as e: + args = e.args[1:] + e.args = (e.args[0] + '\n while parsing %s' % type_name(value),) + args + raise e + + return value + + +def _parse_build(encoded_data, pointer=0, spec=None, spec_params=None, strict=False): + """ + Parses a byte string generically, or using a spec with optional params + + :param encoded_data: + A byte string that contains BER-encoded data + + :param pointer: + The index in the byte string to parse from + + :param spec: + A class derived from Asn1Value that defines what class_ and tag the + value should have, and the semantics of the encoded value. The + return value will be of this type. If omitted, the encoded value + will be decoded using the standard universal tag based on the + encoded tag number. + + :param spec_params: + A dict of params to pass to the spec object + + :param strict: + A boolean indicating if trailing data should be forbidden - if so, a + ValueError will be raised when trailing data exists + + :return: + A 2-element tuple: + - 0: An object of the type spec, or if not specified, a child of Asn1Value + - 1: An integer indicating how many bytes were consumed + """ + + encoded_len = len(encoded_data) + info, new_pointer = _parse(encoded_data, encoded_len, pointer) + if strict and new_pointer != pointer + encoded_len: + extra_bytes = pointer + encoded_len - new_pointer + raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes) + return (_build(*info, spec=spec, spec_params=spec_params), new_pointer) diff --git a/venv/lib/python2.7/site-packages/asn1crypto/core.pyc b/venv/lib/python2.7/site-packages/asn1crypto/core.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f38d47d393259e6e31d1caa29d9fa7d95c3e1e9d GIT binary patch literal 146373 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 QGq2B#&m6}0eS9YW7c+1rF#rGn literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/csr.py b/venv/lib/python2.7/site-packages/asn1crypto/csr.py new file mode 100644 index 0000000..7ea2848 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/csr.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" +ASN.1 type classes for certificate signing requests (CSR). Exports the +following items: + + - CertificatationRequest() + +Other type classes are defined that help compose the types listed above. +""" + +from __future__ import unicode_literals, division, absolute_import, print_function + +from .algos import SignedDigestAlgorithm +from .core import ( + Any, + Integer, + ObjectIdentifier, + OctetBitString, + Sequence, + SetOf, +) +from .keys import PublicKeyInfo +from .x509 import DirectoryString, Extensions, Name + + +# The structures in this file are taken from https://tools.ietf.org/html/rfc2986 +# and https://tools.ietf.org/html/rfc2985 + + +class Version(Integer): + _map = { + 0: 'v1', + } + + +class CSRAttributeType(ObjectIdentifier): + _map = { + '1.2.840.113549.1.9.7': 'challenge_password', + '1.2.840.113549.1.9.9': 'extended_certificate_attributes', + '1.2.840.113549.1.9.14': 'extension_request', + } + + +class SetOfDirectoryString(SetOf): + _child_spec = DirectoryString + + +class Attribute(Sequence): + _fields = [ + ('type', ObjectIdentifier), + ('values', SetOf, {'spec': Any}), + ] + + +class SetOfAttributes(SetOf): + _child_spec = Attribute + + +class SetOfExtensions(SetOf): + _child_spec = Extensions + + +class CRIAttribute(Sequence): + _fields = [ + ('type', CSRAttributeType), + ('values', Any), + ] + + _oid_pair = ('type', 'values') + _oid_specs = { + 'challenge_password': SetOfDirectoryString, + 'extended_certificate_attributes': SetOfAttributes, + 'extension_request': SetOfExtensions, + } + + +class CRIAttributes(SetOf): + _child_spec = CRIAttribute + + +class CertificationRequestInfo(Sequence): + _fields = [ + ('version', Version), + ('subject', Name), + ('subject_pk_info', PublicKeyInfo), + ('attributes', CRIAttributes, {'implicit': 0, 'optional': True}), + ] + + +class CertificationRequest(Sequence): + _fields = [ + ('certification_request_info', CertificationRequestInfo), + ('signature_algorithm', SignedDigestAlgorithm), + ('signature', OctetBitString), + ] diff --git a/venv/lib/python2.7/site-packages/asn1crypto/csr.pyc b/venv/lib/python2.7/site-packages/asn1crypto/csr.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df5c657e63a051d4ad3514a539a95a4c16134235 GIT binary patch literal 4316 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

    O<9DD?_%G^LV?x<8_# z6B&t0^y<&)_4lkNAH2J3L0pi)!b1w4w;rtd4G|R_KFlPT*AHNQLLP{1ZACt9X;>g) zDx2Ee8YB#e5RY9K3MP}d z1G~4Wds?RSoUYVUJGSgse4!~j0m?2;iNR7BF*FzK(@f4Yq4Hx(kJ)z-IUF)!Ui&S+ zBrl7F2?DgR&TZIlGW!aWf~V!~S&AZ?U%ZPerVdA)$bv?MzkQJUF+ z({Al$Ki|Rk{}5NM15pLEWv;~jUBE{*JjJv8FC>?TDrbYITkJCVQQN0ILltpku5 z`38?NY{026Y{2EGvp!rl+q5DKeU|Ja@JSr3!ZORTII+B_-j?%5P&U_GH-jWJu57Yk zAzykqecne){uEb%1f0OrBL?!x*@mC$Ion)ABmM$c&NigP-Rn!4EWDZ9Bb}g+S5QPHtR~7p|F>M$p9D{o+!}wW*c!xC2JiOkRL_ z+y3^g-6o~x(Urf%rBOLRp2PT?P*QcE#@5Npm2KzAyBTv4_a=y!VJ<$bT2Rf0Svv&c z?V;JqsoQ2MF(X$HABDiQ6TBl`cP8JCn2oG%g|fm?6wF4eC|v5b#_}rfM6;osw68Ha zg`}6F<~qLrJ6uL1$x#|1Jx$9FqEAu ztXFXZhJ_mrt6>L6)PQiH=38Ljl(mEw1^)&I$~sAj-(ew3`Dv3ct0|SNonS(N;7Z&y zh+1s&tj(_N4vp&rwB#Rgi4m&(QGzL#Jm_YqIYctle}bEiLrpOt@aA^lErNHj%t;6j z(>-zzv{nPTKyJrNKrRAe@MwVC{qi`Hy zI9`T%hXLuZ(Y=IuJB{{M>Ds2ma5g;#-fN#hc@1&A!Mn3e=tH%qnanT|@k~raBSVDn z?2Ak;F}chaxODPNfe+#_|Axzeu19_VT?Mz}!0ZapRRFU8B8e#9o(jUsRm)(N+aRps zZ}Hb*xdR++h3*F3E^h69Y%OnCL8BI?9#L1<0s;%{^sK2bf={Mdx5QbZL0R9et)UV@ zSZ8vC$f9esTeuadE(3UUR8Ci5D^(3gOv+sXu~H6|+S3QuLfAOnq>;(m@In z@2nN45L)!-rI;S#A?%tBtw#ZZU9saSvZEQLLMbd^SG$BU37vG)(3cF0?$wSYnldHZ zg9f8bWxp^x3P+Mn+evF!AMx%-Og>>EtMuEv6F1T=-hIsE$4Cm5O75PiUiBfq|IfJM z=a7^fO2(-)F+MRNab((((L!}e0*Z}6(~sYZK||M>HfRE%7@fdWq8orU5PbrZV-B_p zLi;m>l}n*SK!K$hGO&_{+PFA?7j-wJ1V$J^wm@ryf>t16ekt`s2TlUSx6;ZLLoL?$VBt- zBX|p8r*R+tq%>|48%e-2;pjsunDx1*k!82hn728c1GpLLJ5jxOaO4bE{Mdn~a<+Ql7-htGSZCj3+L-Shve%NqJaJ^_KP|&@+(7l3zj) z`Rwd0TQPlU`tojDiSMGRpOFnpD{;T9#C-|7u?;(HT~H{a%G0!1P|AS{n|+xSF4)8|bP<*5 zp7BUmT(P6qluarL4N_)%uPLXm79_G_Qrp#@)Kj?YrF8#2e1DY;HHjN4;AQ`5rsA=+ z+c4IX`==Qwq#D(W><$0Ma&6FI3I zNKkC+l;;HDr%u`uF)aul=6Uu^L8D{#J8G4pipH{tl_F(jq2B7d`4&|rW#7#Y;rS%b zmf`zr*Ee2|z+sURvgwofr=i8MH<%IczM)wHk0&S$OpiF8r*aQ>q61EVE3mtS($q&gHSBMnD$%)e z8(MAlyk(S*#q*%e!4A{YdH^>=hM{y%EOV|vS7hR9Dzi|xVwaF;KU!5-I=WHc8S;!i zg*o{yYU_?XamxLvJUN4Na)y?)b{J)w4gtlIP^K~-yb(3)0e2&1CxnzNGR(jlTuE?m ziK#zr32QuPrlE%oOeq|(8z^EbTlN9M>+cnkS{ee+mWT#OYuWQep|LOz4_dbSk8L#7 z6u<4BkDg@G)1-1X*`&LKr6`X&w(MUFUx@?id-_O!i_e&0f8?~+rg^^8u*@Rxa!W`A z!0WEb)vz93K7VDpbSelO@LlXZBcj%Z6zOK|5~9%#FO5tFdFjUeyP=!NgT*QFeH206 z3=_8rP*~#|gyGwqsQNe@x;eVpib6yVIDn7+rF5Ip`LP`ud}X)ctb~33C!bQ< z<0<>eJC35kh>W|AZuO2B5r7Rw))&st^64FNFaid>9bLsSd4OTWU&Q2b5!6BaM(-Kw zK#v_kPH}(~QiMI-9^~W)Y;jzj!d)-tKiF0&Fu#V$+fYr}U)+(5Pd@4Sxt>pY@S7TE zpR-9Xgvg@MIOz?S8YGkQy3D1V@7goJd0z;jO`!f7+5~_pTnm&x+YbV~lD;~)?8bC7 zK9J0jHr)TQ_JgqHk+d8k1w62ZTnJUpOKXrM03F!_T>vM~r3{hDpEhHNZF@-M*ohKk z&uB6GHWOB8FEimN?hc3c3R-fI^dvMe)W@A6a>x{IlQmK4O5#fJtBDc%|v4HbpQ?>a;^-#31TZ^u7o@$zx!<#YT6C?~9oGTX+VUmlL>l-*|#gL>Q#e^gmakCvsbkqyx9ZtyMBB4VJ z^sXvda2dg3xSU5A3Tx*%LW>R|rCPv0`nQ{ROTCLP6^At0ukw+7?)hH7H8kQ>F(XFv z^Oz_vI!*?&9{(9ibR2n#Jp9}Km?9id3+aYbLdEEl(R*C>Djz->b6C;1JeoZ&*z$t6 zW{(TDyx`I7ae>DMkNSXFcwJ=63;Q5m@0_B!dxgwz@|MY10dgMUQQ7J?Vei}ACVx=g z@`4j!(EnqI$tdrB;dYjOIpj!=Cz3;s@>7j?$Wh1>y}rV6B{=yAYsRo_b}1clG$Ox` zPH)})a$0?Hy1e^k6uVz2;(EFJW$Pff&#vv|pCOHCx;)@6eoEe#X^e^e29vW)&M}!` zB0_K$ce`B}6uX5+{JbE`Q$TdT>y9j3;GQCkju?F~VEx+=QY^#GhFMMLlU-IrYrqQr7D^CdYtu(2yUJ zBDj77{V5UK+y@rx1GNX4 zN4v5Hhnhz8Xz1G`Oh%cEF%kHWrio3uXhU33zWscpR%}z(le0JBq15M4)1xeP!xtFK zsZ{brkBm*1m_CVvU9`nXAux>iCoJZ@%;Y4K(@aPY`yD1?m&(aAa_G}F=FKy?&V+b} zeS-;yNAHpPkaxl)g7SRIM~;rY#N;j$2}2Y|h#>dN%%kOQdrV+6DqDaEF@S~DNTePz ziJY?cjy`GrJ<=y;KZg2F_DxoPHZfV*UpYB6IW##sIgE7Qf|2e4I^)4a(wb2@*d(E#{IzL7|QJZKRYT5$^ZZW literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/parser.py b/venv/lib/python2.7/site-packages/asn1crypto/parser.py new file mode 100644 index 0000000..07f53ab --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/parser.py @@ -0,0 +1,289 @@ +# coding: utf-8 + +""" +Functions for parsing and dumping using the ASN.1 DER encoding. Exports the +following items: + + - emit() + - parse() + - peek() + +Other type classes are defined that help compose the types listed above. +""" + +from __future__ import unicode_literals, division, absolute_import, print_function + +import sys + +from ._types import byte_cls, chr_cls, type_name +from .util import int_from_bytes, int_to_bytes + +_PY2 = sys.version_info <= (3,) +_INSUFFICIENT_DATA_MESSAGE = 'Insufficient data - %s bytes requested but only %s available' + + +def emit(class_, method, tag, contents): + """ + Constructs a byte string of an ASN.1 DER-encoded value + + This is typically not useful. Instead, use one of the standard classes from + asn1crypto.core, or construct a new class with specific fields, and call the + .dump() method. + + :param class_: + An integer ASN.1 class value: 0 (universal), 1 (application), + 2 (context), 3 (private) + + :param method: + An integer ASN.1 method value: 0 (primitive), 1 (constructed) + + :param tag: + An integer ASN.1 tag value + + :param contents: + A byte string of the encoded byte contents + + :return: + A byte string of the ASN.1 DER value (header and contents) + """ + + if not isinstance(class_, int): + raise TypeError('class_ must be an integer, not %s' % type_name(class_)) + + if class_ < 0 or class_ > 3: + raise ValueError('class_ must be one of 0, 1, 2 or 3, not %s' % class_) + + if not isinstance(method, int): + raise TypeError('method must be an integer, not %s' % type_name(method)) + + if method < 0 or method > 1: + raise ValueError('method must be 0 or 1, not %s' % method) + + if not isinstance(tag, int): + raise TypeError('tag must be an integer, not %s' % type_name(tag)) + + if tag < 0: + raise ValueError('tag must be greater than zero, not %s' % tag) + + if not isinstance(contents, byte_cls): + raise TypeError('contents must be a byte string, not %s' % type_name(contents)) + + return _dump_header(class_, method, tag, contents) + contents + + +def parse(contents, strict=False): + """ + Parses a byte string of ASN.1 BER/DER-encoded data. + + This is typically not useful. Instead, use one of the standard classes from + asn1crypto.core, or construct a new class with specific fields, and call the + .load() class method. + + :param contents: + A byte string of BER/DER-encoded data + + :param strict: + A boolean indicating if trailing data should be forbidden - if so, a + ValueError will be raised when trailing data exists + + :raises: + ValueError - when the contents do not contain an ASN.1 header or are truncated in some way + TypeError - when contents is not a byte string + + :return: + A 6-element tuple: + - 0: integer class (0 to 3) + - 1: integer method + - 2: integer tag + - 3: byte string header + - 4: byte string content + - 5: byte string trailer + """ + + if not isinstance(contents, byte_cls): + raise TypeError('contents must be a byte string, not %s' % type_name(contents)) + + contents_len = len(contents) + info, consumed = _parse(contents, contents_len) + if strict and consumed != contents_len: + raise ValueError('Extra data - %d bytes of trailing data were provided' % (contents_len - consumed)) + return info + + +def peek(contents): + """ + Parses a byte string of ASN.1 BER/DER-encoded data to find the length + + This is typically used to look into an encoded value to see how long the + next chunk of ASN.1-encoded data is. Primarily it is useful when a + value is a concatenation of multiple values. + + :param contents: + A byte string of BER/DER-encoded data + + :raises: + ValueError - when the contents do not contain an ASN.1 header or are truncated in some way + TypeError - when contents is not a byte string + + :return: + An integer with the number of bytes occupied by the ASN.1 value + """ + + if not isinstance(contents, byte_cls): + raise TypeError('contents must be a byte string, not %s' % type_name(contents)) + + info, consumed = _parse(contents, len(contents)) + return consumed + + +def _parse(encoded_data, data_len, pointer=0, lengths_only=False): + """ + Parses a byte string into component parts + + :param encoded_data: + A byte string that contains BER-encoded data + + :param data_len: + The integer length of the encoded data + + :param pointer: + The index in the byte string to parse from + + :param lengths_only: + A boolean to cause the call to return a 2-element tuple of the integer + number of bytes in the header and the integer number of bytes in the + contents. Internal use only. + + :return: + A 2-element tuple: + - 0: A tuple of (class_, method, tag, header, content, trailer) + - 1: An integer indicating how many bytes were consumed + """ + + if data_len < pointer + 2: + raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (2, data_len - pointer)) + + start = pointer + first_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer] + pointer += 1 + + tag = first_octet & 31 + # Base 128 length using 8th bit as continuation indicator + if tag == 31: + tag = 0 + while True: + num = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer] + pointer += 1 + tag *= 128 + tag += num & 127 + if num >> 7 == 0: + break + + length_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer] + pointer += 1 + + if length_octet >> 7 == 0: + if lengths_only: + return (pointer, pointer + (length_octet & 127)) + contents_end = pointer + (length_octet & 127) + + else: + length_octets = length_octet & 127 + if length_octets: + pointer += length_octets + contents_end = pointer + int_from_bytes(encoded_data[pointer - length_octets:pointer], signed=False) + if lengths_only: + return (pointer, contents_end) + + else: + # To properly parse indefinite length values, we need to scan forward + # parsing headers until we find a value with a length of zero. If we + # just scanned looking for \x00\x00, nested indefinite length values + # would not work. + contents_end = pointer + # Unfortunately we need to understand the contents of the data to + # properly scan forward, which bleeds some representation info into + # the parser. This condition handles the unused bits byte in + # constructed bit strings. + if tag == 3: + contents_end += 1 + while contents_end < data_len: + sub_header_end, contents_end = _parse(encoded_data, data_len, contents_end, lengths_only=True) + if contents_end == sub_header_end and encoded_data[contents_end - 2:contents_end] == b'\x00\x00': + break + if lengths_only: + return (pointer, contents_end) + if contents_end > data_len: + raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (contents_end, data_len)) + return ( + ( + first_octet >> 6, + (first_octet >> 5) & 1, + tag, + encoded_data[start:pointer], + encoded_data[pointer:contents_end - 2], + b'\x00\x00' + ), + contents_end + ) + + if contents_end > data_len: + raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (contents_end, data_len)) + return ( + ( + first_octet >> 6, + (first_octet >> 5) & 1, + tag, + encoded_data[start:pointer], + encoded_data[pointer:contents_end], + b'' + ), + contents_end + ) + + +def _dump_header(class_, method, tag, contents): + """ + Constructs the header bytes for an ASN.1 object + + :param class_: + An integer ASN.1 class value: 0 (universal), 1 (application), + 2 (context), 3 (private) + + :param method: + An integer ASN.1 method value: 0 (primitive), 1 (constructed) + + :param tag: + An integer ASN.1 tag value + + :param contents: + A byte string of the encoded byte contents + + :return: + A byte string of the ASN.1 DER header + """ + + header = b'' + + id_num = 0 + id_num |= class_ << 6 + id_num |= method << 5 + + if tag >= 31: + header += chr_cls(id_num | 31) + while tag > 0: + continuation_bit = 0x80 if tag > 0x7F else 0 + header += chr_cls(continuation_bit | (tag & 0x7F)) + tag = tag >> 7 + else: + header += chr_cls(id_num | tag) + + length = len(contents) + if length <= 127: + header += chr_cls(length) + else: + length_bytes = int_to_bytes(length) + header += chr_cls(0x80 | len(length_bytes)) + header += length_bytes + + return header diff --git a/venv/lib/python2.7/site-packages/asn1crypto/parser.pyc b/venv/lib/python2.7/site-packages/asn1crypto/parser.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e86d5ba8067feb91657ea359860393bf596fc103 GIT binary patch literal 8012 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 S4q522>g4kDHz!{>{@`B^CHRW~ literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/pdf.py b/venv/lib/python2.7/site-packages/asn1crypto/pdf.py new file mode 100644 index 0000000..b72c886 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/pdf.py @@ -0,0 +1,84 @@ +# coding: utf-8 + +""" +ASN.1 type classes for PDF signature structures. Adds extra oid mapping and +value parsing to asn1crypto.x509.Extension() and asn1crypto.xms.CMSAttribute(). +""" + +from __future__ import unicode_literals, division, absolute_import, print_function + +from .cms import CMSAttributeType, CMSAttribute +from .core import ( + Boolean, + Integer, + Null, + ObjectIdentifier, + OctetString, + Sequence, + SequenceOf, + SetOf, +) +from .crl import CertificateList +from .ocsp import OCSPResponse +from .x509 import ( + Extension, + ExtensionId, + GeneralName, + KeyPurposeId, +) + + +class AdobeArchiveRevInfo(Sequence): + _fields = [ + ('version', Integer) + ] + + +class AdobeTimestamp(Sequence): + _fields = [ + ('version', Integer), + ('location', GeneralName), + ('requires_auth', Boolean, {'optional': True, 'default': False}), + ] + + +class OtherRevInfo(Sequence): + _fields = [ + ('type', ObjectIdentifier), + ('value', OctetString), + ] + + +class SequenceOfCertificateList(SequenceOf): + _child_spec = CertificateList + + +class SequenceOfOCSPResponse(SequenceOf): + _child_spec = OCSPResponse + + +class SequenceOfOtherRevInfo(SequenceOf): + _child_spec = OtherRevInfo + + +class RevocationInfoArchival(Sequence): + _fields = [ + ('crl', SequenceOfCertificateList, {'explicit': 0, 'optional': True}), + ('ocsp', SequenceOfOCSPResponse, {'explicit': 1, 'optional': True}), + ('other_rev_info', SequenceOfOtherRevInfo, {'explicit': 2, 'optional': True}), + ] + + +class SetOfRevocationInfoArchival(SetOf): + _child_spec = RevocationInfoArchival + + +ExtensionId._map['1.2.840.113583.1.1.9.2'] = 'adobe_archive_rev_info' +ExtensionId._map['1.2.840.113583.1.1.9.1'] = 'adobe_timestamp' +ExtensionId._map['1.2.840.113583.1.1.10'] = 'adobe_ppklite_credential' +Extension._oid_specs['adobe_archive_rev_info'] = AdobeArchiveRevInfo +Extension._oid_specs['adobe_timestamp'] = AdobeTimestamp +Extension._oid_specs['adobe_ppklite_credential'] = Null +KeyPurposeId._map['1.2.840.113583.1.1.5'] = 'pdf_signing' +CMSAttributeType._map['1.2.840.113583.1.1.8'] = 'adobe_revocation_info_archival' +CMSAttribute._oid_specs['adobe_revocation_info_archival'] = SetOfRevocationInfoArchival diff --git a/venv/lib/python2.7/site-packages/asn1crypto/pdf.pyc b/venv/lib/python2.7/site-packages/asn1crypto/pdf.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7106cf0954783a0c6d0d0be747395b029a047ade GIT binary patch literal 3981 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 o-zc9e)k+_nsg-Kewb|NCZJ{I#OI`X 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 12: + raise ValueError('month is out of range') + + if day < 0 or day > _DAYS_PER_MONTH_YEAR_0[month]: + raise ValueError('day is out of range') + + self.year = year + self.month = month + self.day = day + + def _format(self, format): + """ + Performs strftime(), always returning a unicode string + + :param format: + A strftime() format string + + :return: + A unicode string of the formatted date + """ + + format = format.replace('%Y', '0000') + # Year 0 is 1BC and a leap year. Leap years repeat themselves + # every 28 years. Because of adjustments and the proleptic gregorian + # calendar, the simplest way to format is to substitute year 2000. + temp = date(2000, self.month, self.day) + if '%c' in format: + c_out = temp.strftime('%c') + # Handle full years + c_out = c_out.replace('2000', '0000') + c_out = c_out.replace('%', '%%') + format = format.replace('%c', c_out) + if '%x' in format: + x_out = temp.strftime('%x') + # Handle formats such as 08/16/2000 or 16.08.2000 + x_out = x_out.replace('2000', '0000') + x_out = x_out.replace('%', '%%') + format = format.replace('%x', x_out) + return temp.strftime(format) + + def isoformat(self): + """ + Formats the date as %Y-%m-%d + + :return: + The date formatted to %Y-%m-%d as a unicode string in Python 3 + and a byte string in Python 2 + """ + + return self.strftime('0000-%m-%d') + + def strftime(self, format): + """ + Formats the date using strftime() + + :param format: + The strftime() format string + + :return: + The formatted date as a unicode string in Python 3 and a byte + string in Python 2 + """ + + output = self._format(format) + if py2: + return output.encode('utf-8') + return output + + def replace(self, year=None, month=None, day=None): + """ + Returns a new datetime.date or asn1crypto.util.extended_date + object with the specified components replaced + + :return: + A datetime.date or asn1crypto.util.extended_date object + """ + + if year is None: + year = self.year + if month is None: + month = self.month + if day is None: + day = self.day + + if year > 0: + cls = date + else: + cls = extended_date + + return cls( + year, + month, + day + ) + + def __str__(self): + if py2: + return self.__bytes__() + else: + return self.__unicode__() + + def __bytes__(self): + return self.__unicode__().encode('utf-8') + + def __unicode__(self): + return self._format('%Y-%m-%d') + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + return self.__cmp__(other) == 0 + + def __ne__(self, other): + return not self.__eq__(other) + + def _comparison_error(self, other): + raise TypeError(unwrap( + ''' + An asn1crypto.util.extended_date object can only be compared to + an asn1crypto.util.extended_date or datetime.date object, not %s + ''', + type_name(other) + )) + + def __cmp__(self, other): + if isinstance(other, date): + return -1 + + if not isinstance(other, self.__class__): + self._comparison_error(other) + + st = ( + self.year, + self.month, + self.day + ) + ot = ( + other.year, + other.month, + other.day + ) + + if st < ot: + return -1 + if st > ot: + return 1 + return 0 + + def __lt__(self, other): + return self.__cmp__(other) < 0 + + def __le__(self, other): + return self.__cmp__(other) <= 0 + + def __gt__(self, other): + return self.__cmp__(other) > 0 + + def __ge__(self, other): + return self.__cmp__(other) >= 0 + + +class extended_datetime(object): + """ + A datetime.datetime-like object that can represent the year 0. This is just + to handle 0000-01-01 found in some certificates. + """ + + year = None + month = None + day = None + hour = None + minute = None + second = None + microsecond = None + tzinfo = None + + def __init__(self, year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): + """ + :param year: + The integer 0 + + :param month: + An integer from 1 to 12 + + :param day: + An integer from 1 to 31 + + :param hour: + An integer from 0 to 23 + + :param minute: + An integer from 0 to 59 + + :param second: + An integer from 0 to 59 + + :param microsecond: + An integer from 0 to 999999 + """ + + if year != 0: + raise ValueError('year must be 0') + + if month < 1 or month > 12: + raise ValueError('month is out of range') + + if day < 0 or day > _DAYS_PER_MONTH_YEAR_0[month]: + raise ValueError('day is out of range') + + if hour < 0 or hour > 23: + raise ValueError('hour is out of range') + + if minute < 0 or minute > 59: + raise ValueError('minute is out of range') + + if second < 0 or second > 59: + raise ValueError('second is out of range') + + if microsecond < 0 or microsecond > 999999: + raise ValueError('microsecond is out of range') + + self.year = year + self.month = month + self.day = day + self.hour = hour + self.minute = minute + self.second = second + self.microsecond = microsecond + self.tzinfo = tzinfo + + def date(self): + """ + :return: + An asn1crypto.util.extended_date of the date + """ + + return extended_date(self.year, self.month, self.day) + + def time(self): + """ + :return: + A datetime.time object of the time + """ + + return time(self.hour, self.minute, self.second, self.microsecond, self.tzinfo) + + def utcoffset(self): + """ + :return: + None or a datetime.timedelta() of the offset from UTC + """ + + if self.tzinfo is None: + return None + return self.tzinfo.utcoffset(self.replace(year=2000)) + + def dst(self): + """ + :return: + None or a datetime.timedelta() of the daylight savings time offset + """ + + if self.tzinfo is None: + return None + return self.tzinfo.dst(self.replace(year=2000)) + + def tzname(self): + """ + :return: + None or the name of the timezone as a unicode string in Python 3 + and a byte string in Python 2 + """ + + if self.tzinfo is None: + return None + return self.tzinfo.tzname(self.replace(year=2000)) + + def _format(self, format): + """ + Performs strftime(), always returning a unicode string + + :param format: + A strftime() format string + + :return: + A unicode string of the formatted datetime + """ + + format = format.replace('%Y', '0000') + # Year 0 is 1BC and a leap year. Leap years repeat themselves + # every 28 years. Because of adjustments and the proleptic gregorian + # calendar, the simplest way to format is to substitute year 2000. + temp = datetime( + 2000, + self.month, + self.day, + self.hour, + self.minute, + self.second, + self.microsecond, + self.tzinfo + ) + if '%c' in format: + c_out = temp.strftime('%c') + # Handle full years + c_out = c_out.replace('2000', '0000') + c_out = c_out.replace('%', '%%') + format = format.replace('%c', c_out) + if '%x' in format: + x_out = temp.strftime('%x') + # Handle formats such as 08/16/2000 or 16.08.2000 + x_out = x_out.replace('2000', '0000') + x_out = x_out.replace('%', '%%') + format = format.replace('%x', x_out) + return temp.strftime(format) + + def isoformat(self, sep='T'): + """ + Formats the date as "%Y-%m-%d %H:%M:%S" with the sep param between the + date and time portions + + :param set: + A single character of the separator to place between the date and + time + + :return: + The formatted datetime as a unicode string in Python 3 and a byte + string in Python 2 + """ + + if self.microsecond == 0: + return self.strftime('0000-%%m-%%d%s%%H:%%M:%%S' % sep) + return self.strftime('0000-%%m-%%d%s%%H:%%M:%%S.%%f' % sep) + + def strftime(self, format): + """ + Formats the date using strftime() + + :param format: + The strftime() format string + + :return: + The formatted date as a unicode string in Python 3 and a byte + string in Python 2 + """ + + output = self._format(format) + if py2: + return output.encode('utf-8') + return output + + def replace(self, year=None, month=None, day=None, hour=None, minute=None, + second=None, microsecond=None, tzinfo=None): + """ + Returns a new datetime.datetime or asn1crypto.util.extended_datetime + object with the specified components replaced + + :return: + A datetime.datetime or asn1crypto.util.extended_datetime object + """ + + if year is None: + year = self.year + if month is None: + month = self.month + if day is None: + day = self.day + if hour is None: + hour = self.hour + if minute is None: + minute = self.minute + if second is None: + second = self.second + if microsecond is None: + microsecond = self.microsecond + if tzinfo is None: + tzinfo = self.tzinfo + + if year > 0: + cls = datetime + else: + cls = extended_datetime + + return cls( + year, + month, + day, + hour, + minute, + second, + microsecond, + tzinfo + ) + + def __str__(self): + if py2: + return self.__bytes__() + else: + return self.__unicode__() + + def __bytes__(self): + return self.__unicode__().encode('utf-8') + + def __unicode__(self): + format = '%Y-%m-%d %H:%M:%S' + if self.microsecond != 0: + format += '.%f' + return self._format(format) + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + return self.__cmp__(other) == 0 + + def __ne__(self, other): + return not self.__eq__(other) + + def _comparison_error(self, other): + """ + Raises a TypeError about the other object not being suitable for + comparison + + :param other: + The object being compared to + """ + + raise TypeError(unwrap( + ''' + An asn1crypto.util.extended_datetime object can only be compared to + an asn1crypto.util.extended_datetime or datetime.datetime object, + not %s + ''', + type_name(other) + )) + + def __cmp__(self, other): + so = self.utcoffset() + oo = other.utcoffset() + + if (so is not None and oo is None) or (so is None and oo is not None): + raise TypeError("can't compare offset-naive and offset-aware datetimes") + + if isinstance(other, datetime): + return -1 + + if not isinstance(other, self.__class__): + self._comparison_error(other) + + st = ( + self.year, + self.month, + self.day, + self.hour, + self.minute, + self.second, + self.microsecond, + so + ) + ot = ( + other.year, + other.month, + other.day, + other.hour, + other.minute, + other.second, + other.microsecond, + oo + ) + + if st < ot: + return -1 + if st > ot: + return 1 + return 0 + + def __lt__(self, other): + return self.__cmp__(other) < 0 + + def __le__(self, other): + return self.__cmp__(other) <= 0 + + def __gt__(self, other): + return self.__cmp__(other) > 0 + + def __ge__(self, other): + return self.__cmp__(other) >= 0 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/util.pyc b/venv/lib/python2.7/site-packages/asn1crypto/util.pyc new file mode 100644 index 0000000000000000000000000000000000000000..096311c540f7c92624b2bf8f12457d523d02538e GIT binary patch literal 22571 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/asn1crypto/version.py b/venv/lib/python2.7/site-packages/asn1crypto/version.py new file mode 100644 index 0000000..31da728 --- /dev/null +++ b/venv/lib/python2.7/site-packages/asn1crypto/version.py @@ -0,0 +1,6 @@ +# coding: utf-8 +from __future__ import unicode_literals, division, absolute_import, print_function + + +__version__ = '0.23.0' +__version_info__ = (0, 23, 0) diff --git a/venv/lib/python2.7/site-packages/asn1crypto/version.pyc b/venv/lib/python2.7/site-packages/asn1crypto/version.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45177ecb180cc04cee8b2a7e5a5e58d4af3fbac1 GIT binary patch literal 434 zcmYjNJx{|h5WO^Mi;DQz*qO4lPTHyx5<;w95GqVrOd2PRi(^O5C8!p;9?n z&-b40>&Nyd>bf%dK<3 zdGGSfr7jHTA=SVcnmtiQrn(e!)}@veMhTk0iX|)Km0iZ&e)+jr#pPB%tfE~}?!O|6 yoo4T>mi2VoN+qTx9@ob?OB)?$_E4kwpPn4e>O+5{$I6IS 128: + raise ValueError(unwrap( + ''' + %s value contains a CIDR range bigger than 128, the maximum + value for an IPv6 address + ''', + type_name(self) + )) + cidr_size = 128 + else: + family = socket.AF_INET + if cidr > 32: + raise ValueError(unwrap( + ''' + %s value contains a CIDR range bigger than 32, the maximum + value for an IPv4 address + ''', + type_name(self) + )) + cidr_size = 32 + + cidr_bytes = b'' + if has_cidr: + cidr_mask = '1' * cidr + cidr_mask += '0' * (cidr_size - len(cidr_mask)) + cidr_bytes = int_to_bytes(int(cidr_mask, 2)) + cidr_bytes = (b'\x00' * ((cidr_size // 8) - len(cidr_bytes))) + cidr_bytes + + self._native = original_value + self.contents = inet_pton(family, value) + cidr_bytes + self._bytes = self.contents + self._header = None + if self._trailer != b'': + self._trailer = b'' + + @property + def native(self): + """ + The a native Python datatype representation of this value + + :return: + A unicode string or None + """ + + if self.contents is None: + return None + + if self._native is None: + byte_string = self.__bytes__() + byte_len = len(byte_string) + cidr_int = None + if byte_len in set([32, 16]): + value = inet_ntop(socket.AF_INET6, byte_string[0:16]) + if byte_len > 16: + cidr_int = int_from_bytes(byte_string[16:]) + elif byte_len in set([8, 4]): + value = inet_ntop(socket.AF_INET, byte_string[0:4]) + if byte_len > 4: + cidr_int = int_from_bytes(byte_string[4:]) + if cidr_int is not None: + cidr_bits = '{0:b}'.format(cidr_int) + cidr = len(cidr_bits.rstrip('0')) + value = value + '/' + str_cls(cidr) + self._native = value + return self._native + + def __ne__(self, other): + return not self == other + + def __eq__(self, other): + """ + :param other: + Another IPAddress object + + :return: + A boolean + """ + + if not isinstance(other, IPAddress): + return False + + return self.__bytes__() == other.__bytes__() + + +class Attribute(Sequence): + _fields = [ + ('type', ObjectIdentifier), + ('values', SetOf, {'spec': Any}), + ] + + +class Attributes(SequenceOf): + _child_spec = Attribute + + +class KeyUsage(BitString): + _map = { + 0: 'digital_signature', + 1: 'non_repudiation', + 2: 'key_encipherment', + 3: 'data_encipherment', + 4: 'key_agreement', + 5: 'key_cert_sign', + 6: 'crl_sign', + 7: 'encipher_only', + 8: 'decipher_only', + } + + +class PrivateKeyUsagePeriod(Sequence): + _fields = [ + ('not_before', GeneralizedTime, {'implicit': 0, 'optional': True}), + ('not_after', GeneralizedTime, {'implicit': 1, 'optional': True}), + ] + + +class NotReallyTeletexString(TeletexString): + """ + OpenSSL (and probably some other libraries) puts ISO-8859-1 + into TeletexString instead of ITU T.61. We use Windows-1252 when + decoding since it is a superset of ISO-8859-1, and less likely to + cause encoding issues, but we stay strict with encoding to prevent + us from creating bad data. + """ + + _decoding_encoding = 'cp1252' + + def __unicode__(self): + """ + :return: + A unicode string + """ + + if self.contents is None: + return '' + if self._unicode is None: + self._unicode = self._merge_chunks().decode(self._decoding_encoding) + return self._unicode + + +@contextmanager +def strict_teletex(): + try: + NotReallyTeletexString._decoding_encoding = 'teletex' + yield + finally: + NotReallyTeletexString._decoding_encoding = 'cp1252' + + +class DirectoryString(Choice): + _alternatives = [ + ('teletex_string', NotReallyTeletexString), + ('printable_string', PrintableString), + ('universal_string', UniversalString), + ('utf8_string', UTF8String), + ('bmp_string', BMPString), + # This is an invalid/bad alternative, but some broken certs use it + ('ia5_string', IA5String), + ] + + +class NameType(ObjectIdentifier): + _map = { + '2.5.4.3': 'common_name', + '2.5.4.4': 'surname', + '2.5.4.5': 'serial_number', + '2.5.4.6': 'country_name', + '2.5.4.7': 'locality_name', + '2.5.4.8': 'state_or_province_name', + '2.5.4.9': 'street_address', + '2.5.4.10': 'organization_name', + '2.5.4.11': 'organizational_unit_name', + '2.5.4.12': 'title', + '2.5.4.15': 'business_category', + '2.5.4.17': 'postal_code', + '2.5.4.20': 'telephone_number', + '2.5.4.41': 'name', + '2.5.4.42': 'given_name', + '2.5.4.43': 'initials', + '2.5.4.44': 'generation_qualifier', + '2.5.4.45': 'unique_identifier', + '2.5.4.46': 'dn_qualifier', + '2.5.4.65': 'pseudonym', + '2.5.4.97': 'organization_identifier', + # https://tools.ietf.org/html/rfc2985#page-26 + '1.2.840.113549.1.9.1': 'email_address', + # Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf + '1.3.6.1.4.1.311.60.2.1.1': 'incorporation_locality', + '1.3.6.1.4.1.311.60.2.1.2': 'incorporation_state_or_province', + '1.3.6.1.4.1.311.60.2.1.3': 'incorporation_country', + # https://tools.ietf.org/html/rfc2247#section-4 + '0.9.2342.19200300.100.1.25': 'domain_component', + # http://www.alvestrand.no/objectid/0.2.262.1.10.7.20.html + '0.2.262.1.10.7.20': 'name_distinguisher', + } + + # This order is largely based on observed order seen in EV certs from + # Symantec and DigiCert. Some of the uncommon name-related fields are + # just placed in what seems like a reasonable order. + preferred_order = [ + 'incorporation_country', + 'incorporation_state_or_province', + 'incorporation_locality', + 'business_category', + 'serial_number', + 'country_name', + 'postal_code', + 'state_or_province_name', + 'locality_name', + 'street_address', + 'organization_name', + 'organizational_unit_name', + 'title', + 'common_name', + 'initials', + 'generation_qualifier', + 'surname', + 'given_name', + 'name', + 'pseudonym', + 'dn_qualifier', + 'telephone_number', + 'email_address', + 'domain_component', + 'name_distinguisher', + 'organization_identifier', + ] + + @classmethod + def preferred_ordinal(cls, attr_name): + """ + Returns an ordering value for a particular attribute key. + + Unrecognized attributes and OIDs will be sorted lexically at the end. + + :return: + An orderable value. + + """ + + attr_name = cls.map(attr_name) + if attr_name in cls.preferred_order: + ordinal = cls.preferred_order.index(attr_name) + else: + ordinal = len(cls.preferred_order) + + return (ordinal, attr_name) + + @property + def human_friendly(self): + """ + :return: + A human-friendly unicode string to display to users + """ + + return { + 'common_name': 'Common Name', + 'surname': 'Surname', + 'serial_number': 'Serial Number', + 'country_name': 'Country', + 'locality_name': 'Locality', + 'state_or_province_name': 'State/Province', + 'street_address': 'Street Address', + 'organization_name': 'Organization', + 'organizational_unit_name': 'Organizational Unit', + 'title': 'Title', + 'business_category': 'Business Category', + 'postal_code': 'Postal Code', + 'telephone_number': 'Telephone Number', + 'name': 'Name', + 'given_name': 'Given Name', + 'initials': 'Initials', + 'generation_qualifier': 'Generation Qualifier', + 'unique_identifier': 'Unique Identifier', + 'dn_qualifier': 'DN Qualifier', + 'pseudonym': 'Pseudonym', + 'email_address': 'Email Address', + 'incorporation_locality': 'Incorporation Locality', + 'incorporation_state_or_province': 'Incorporation State/Province', + 'incorporation_country': 'Incorporation Country', + 'domain_component': 'Domain Component', + 'name_distinguisher': 'Name Distinguisher', + 'organization_identifier': 'Organization Identifier', + }.get(self.native, self.native) + + +class NameTypeAndValue(Sequence): + _fields = [ + ('type', NameType), + ('value', Any), + ] + + _oid_pair = ('type', 'value') + _oid_specs = { + 'common_name': DirectoryString, + 'surname': DirectoryString, + 'serial_number': DirectoryString, + 'country_name': DirectoryString, + 'locality_name': DirectoryString, + 'state_or_province_name': DirectoryString, + 'street_address': DirectoryString, + 'organization_name': DirectoryString, + 'organizational_unit_name': DirectoryString, + 'title': DirectoryString, + 'business_category': DirectoryString, + 'postal_code': DirectoryString, + 'telephone_number': PrintableString, + 'name': DirectoryString, + 'given_name': DirectoryString, + 'initials': DirectoryString, + 'generation_qualifier': DirectoryString, + 'unique_identifier': OctetBitString, + 'dn_qualifier': DirectoryString, + 'pseudonym': DirectoryString, + # https://tools.ietf.org/html/rfc2985#page-26 + 'email_address': EmailAddress, + # Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf + 'incorporation_locality': DirectoryString, + 'incorporation_state_or_province': DirectoryString, + 'incorporation_country': DirectoryString, + 'domain_component': DNSName, + 'name_distinguisher': DirectoryString, + 'organization_identifier': DirectoryString, + } + + _prepped = None + + @property + def prepped_value(self): + """ + Returns the value after being processed by the internationalized string + preparation as specified by RFC 5280 + + :return: + A unicode string + """ + + if self._prepped is None: + self._prepped = self._ldap_string_prep(self['value'].native) + return self._prepped + + def __ne__(self, other): + return not self == other + + def __eq__(self, other): + """ + Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 + + :param other: + Another NameTypeAndValue object + + :return: + A boolean + """ + + if not isinstance(other, NameTypeAndValue): + return False + + if other['type'].native != self['type'].native: + return False + + return other.prepped_value == self.prepped_value + + def _ldap_string_prep(self, string): + """ + Implements the internationalized string preparation algorithm from + RFC 4518. https://tools.ietf.org/html/rfc4518#section-2 + + :param string: + A unicode string to prepare + + :return: + A prepared unicode string, ready for comparison + """ + + # Map step + string = re.sub('[\u00ad\u1806\u034f\u180b-\u180d\ufe0f-\uff00\ufffc]+', '', string) + string = re.sub('[\u0009\u000a\u000b\u000c\u000d\u0085]', ' ', string) + if sys.maxunicode == 0xffff: + # Some installs of Python 2.7 don't support 8-digit unicode escape + # ranges, so we have to break them into pieces + # Original was: \U0001D173-\U0001D17A and \U000E0020-\U000E007F + string = re.sub('\ud834[\udd73-\udd7a]|\udb40[\udc20-\udc7f]|\U000e0001', '', string) + else: + string = re.sub('[\U0001D173-\U0001D17A\U000E0020-\U000E007F\U000e0001]', '', string) + string = re.sub( + '[\u0000-\u0008\u000e-\u001f\u007f-\u0084\u0086-\u009f\u06dd\u070f\u180e\u200c-\u200f' + '\u202a-\u202e\u2060-\u2063\u206a-\u206f\ufeff\ufff9-\ufffb]+', + '', + string + ) + string = string.replace('\u200b', '') + string = re.sub('[\u00a0\u1680\u2000-\u200a\u2028-\u2029\u202f\u205f\u3000]', ' ', string) + + string = ''.join(map(stringprep.map_table_b2, string)) + + # Normalize step + string = unicodedata.normalize('NFKC', string) + + # Prohibit step + for char in string: + if stringprep.in_table_a1(char): + raise ValueError(unwrap( + ''' + X.509 Name objects may not contain unassigned code points + ''' + )) + + if stringprep.in_table_c8(char): + raise ValueError(unwrap( + ''' + X.509 Name objects may not contain change display or + zzzzdeprecated characters + ''' + )) + + if stringprep.in_table_c3(char): + raise ValueError(unwrap( + ''' + X.509 Name objects may not contain private use characters + ''' + )) + + if stringprep.in_table_c4(char): + raise ValueError(unwrap( + ''' + X.509 Name objects may not contain non-character code points + ''' + )) + + if stringprep.in_table_c5(char): + raise ValueError(unwrap( + ''' + X.509 Name objects may not contain surrogate code points + ''' + )) + + if char == '\ufffd': + raise ValueError(unwrap( + ''' + X.509 Name objects may not contain the replacement character + ''' + )) + + # Check bidirectional step - here we ensure that we are not mixing + # left-to-right and right-to-left text in the string + has_r_and_al_cat = False + has_l_cat = False + for char in string: + if stringprep.in_table_d1(char): + has_r_and_al_cat = True + elif stringprep.in_table_d2(char): + has_l_cat = True + + if has_r_and_al_cat: + first_is_r_and_al = stringprep.in_table_d1(string[0]) + last_is_r_and_al = stringprep.in_table_d1(string[-1]) + + if has_l_cat or not first_is_r_and_al or not last_is_r_and_al: + raise ValueError(unwrap( + ''' + X.509 Name object contains a malformed bidirectional + sequence + ''' + )) + + # Insignificant space handling step + string = ' ' + re.sub(' +', ' ', string).strip() + ' ' + + return string + + +class RelativeDistinguishedName(SetOf): + _child_spec = NameTypeAndValue + + @property + def hashable(self): + """ + :return: + A unicode string that can be used as a dict key or in a set + """ + + output = [] + values = self._get_values(self) + for key in sorted(values.keys()): + output.append('%s: %s' % (key, values[key])) + # Unit separator is used here since the normalization process for + # values moves any such character, and the keys are all dotted integers + # or under_score_words + return '\x1F'.join(output) + + def __ne__(self, other): + return not self == other + + def __eq__(self, other): + """ + Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 + + :param other: + Another RelativeDistinguishedName object + + :return: + A boolean + """ + + if not isinstance(other, RelativeDistinguishedName): + return False + + if len(self) != len(other): + return False + + self_types = self._get_types(self) + other_types = self._get_types(other) + + if self_types != other_types: + return False + + self_values = self._get_values(self) + other_values = self._get_values(other) + + for type_name_ in self_types: + if self_values[type_name_] != other_values[type_name_]: + return False + + return True + + def _get_types(self, rdn): + """ + Returns a set of types contained in an RDN + + :param rdn: + A RelativeDistinguishedName object + + :return: + A set object with unicode strings of NameTypeAndValue type field + values + """ + + return set([ntv['type'].native for ntv in rdn]) + + def _get_values(self, rdn): + """ + Returns a dict of prepped values contained in an RDN + + :param rdn: + A RelativeDistinguishedName object + + :return: + A dict object with unicode strings of NameTypeAndValue value field + values that have been prepped for comparison + """ + + output = {} + [output.update([(ntv['type'].native, ntv.prepped_value)]) for ntv in rdn] + return output + + +class RDNSequence(SequenceOf): + _child_spec = RelativeDistinguishedName + + @property + def hashable(self): + """ + :return: + A unicode string that can be used as a dict key or in a set + """ + + # Record separator is used here since the normalization process for + # values moves any such character, and the keys are all dotted integers + # or under_score_words + return '\x1E'.join(rdn.hashable for rdn in self) + + def __ne__(self, other): + return not self == other + + def __eq__(self, other): + """ + Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 + + :param other: + Another RDNSequence object + + :return: + A boolean + """ + + if not isinstance(other, RDNSequence): + return False + + if len(self) != len(other): + return False + + for index, self_rdn in enumerate(self): + if other[index] != self_rdn: + return False + + return True + + +class Name(Choice): + _alternatives = [ + ('', RDNSequence), + ] + + _human_friendly = None + _sha1 = None + _sha256 = None + + @classmethod + def build(cls, name_dict, use_printable=False): + """ + Creates a Name object from a dict of unicode string keys and values. + The keys should be from NameType._map, or a dotted-integer OID unicode + string. + + :param name_dict: + A dict of name information, e.g. {"common_name": "Will Bond", + "country_name": "US", "organization": "Codex Non Sufficit LC"} + + :param use_printable: + A bool - if PrintableString should be used for encoding instead of + UTF8String. This is for backwards compatibility with old software. + + :return: + An x509.Name object + """ + + rdns = [] + if not use_printable: + encoding_name = 'utf8_string' + encoding_class = UTF8String + else: + encoding_name = 'printable_string' + encoding_class = PrintableString + + # Sort the attributes according to NameType.preferred_order + name_dict = OrderedDict( + sorted( + name_dict.items(), + key=lambda item: NameType.preferred_ordinal(item[0]) + ) + ) + + for attribute_name, attribute_value in name_dict.items(): + attribute_name = NameType.map(attribute_name) + if attribute_name == 'email_address': + value = EmailAddress(attribute_value) + elif attribute_name == 'domain_component': + value = DNSName(attribute_value) + elif attribute_name in set(['dn_qualifier', 'country_name', 'serial_number']): + value = DirectoryString( + name='printable_string', + value=PrintableString(attribute_value) + ) + else: + value = DirectoryString( + name=encoding_name, + value=encoding_class(attribute_value) + ) + + rdns.append(RelativeDistinguishedName([ + NameTypeAndValue({ + 'type': attribute_name, + 'value': value + }) + ])) + + return cls(name='', value=RDNSequence(rdns)) + + @property + def hashable(self): + """ + :return: + A unicode string that can be used as a dict key or in a set + """ + + return self.chosen.hashable + + def __len__(self): + return len(self.chosen) + + def __ne__(self, other): + return not self == other + + def __eq__(self, other): + """ + Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1 + + :param other: + Another Name object + + :return: + A boolean + """ + + if not isinstance(other, Name): + return False + return self.chosen == other.chosen + + @property + def native(self): + if self._native is None: + self._native = OrderedDict() + for rdn in self.chosen.native: + for type_val in rdn: + field_name = type_val['type'] + if field_name in self._native: + existing = self._native[field_name] + if not isinstance(existing, list): + existing = self._native[field_name] = [existing] + existing.append(type_val['value']) + else: + self._native[field_name] = type_val['value'] + return self._native + + @property + def human_friendly(self): + """ + :return: + A human-friendly unicode string containing the parts of the name + """ + + if self._human_friendly is None: + data = OrderedDict() + last_field = None + for rdn in self.chosen: + for type_val in rdn: + field_name = type_val['type'].human_friendly + last_field = field_name + if field_name in data: + data[field_name] = [data[field_name]] + data[field_name].append(type_val['value']) + else: + data[field_name] = type_val['value'] + to_join = [] + keys = data.keys() + if last_field == 'Country': + keys = reversed(list(keys)) + for key in keys: + value = data[key] + native_value = self._recursive_humanize(value) + to_join.append('%s: %s' % (key, native_value)) + + has_comma = False + for element in to_join: + if element.find(',') != -1: + has_comma = True + break + + separator = ', ' if not has_comma else '; ' + self._human_friendly = separator.join(to_join[::-1]) + + return self._human_friendly + + def _recursive_humanize(self, value): + """ + Recursively serializes data compiled from the RDNSequence + + :param value: + An Asn1Value object, or a list of Asn1Value objects + + :return: + A unicode string + """ + + if isinstance(value, list): + return', '.join( + reversed([self._recursive_humanize(sub_value) for sub_value in value]) + ) + return value.native + + @property + def sha1(self): + """ + :return: + The SHA1 hash of the DER-encoded bytes of this name + """ + + if self._sha1 is None: + self._sha1 = hashlib.sha1(self.dump()).digest() + return self._sha1 + + @property + def sha256(self): + """ + :return: + The SHA-256 hash of the DER-encoded bytes of this name + """ + + if self._sha256 is None: + self._sha256 = hashlib.sha256(self.dump()).digest() + return self._sha256 + + +class AnotherName(Sequence): + _fields = [ + ('type_id', ObjectIdentifier), + ('value', Any, {'explicit': 0}), + ] + + +class CountryName(Choice): + class_ = 1 + tag = 1 + + _alternatives = [ + ('x121_dcc_code', NumericString), + ('iso_3166_alpha2_code', PrintableString), + ] + + +class AdministrationDomainName(Choice): + class_ = 1 + tag = 2 + + _alternatives = [ + ('numeric', NumericString), + ('printable', PrintableString), + ] + + +class PrivateDomainName(Choice): + _alternatives = [ + ('numeric', NumericString), + ('printable', PrintableString), + ] + + +class PersonalName(Set): + _fields = [ + ('surname', PrintableString, {'implicit': 0}), + ('given_name', PrintableString, {'implicit': 1, 'optional': True}), + ('initials', PrintableString, {'implicit': 2, 'optional': True}), + ('generation_qualifier', PrintableString, {'implicit': 3, 'optional': True}), + ] + + +class TeletexPersonalName(Set): + _fields = [ + ('surname', TeletexString, {'implicit': 0}), + ('given_name', TeletexString, {'implicit': 1, 'optional': True}), + ('initials', TeletexString, {'implicit': 2, 'optional': True}), + ('generation_qualifier', TeletexString, {'implicit': 3, 'optional': True}), + ] + + +class OrganizationalUnitNames(SequenceOf): + _child_spec = PrintableString + + +class TeletexOrganizationalUnitNames(SequenceOf): + _child_spec = TeletexString + + +class BuiltInStandardAttributes(Sequence): + _fields = [ + ('country_name', CountryName, {'optional': True}), + ('administration_domain_name', AdministrationDomainName, {'optional': True}), + ('network_address', NumericString, {'implicit': 0, 'optional': True}), + ('terminal_identifier', PrintableString, {'implicit': 1, 'optional': True}), + ('private_domain_name', PrivateDomainName, {'explicit': 2, 'optional': True}), + ('organization_name', PrintableString, {'implicit': 3, 'optional': True}), + ('numeric_user_identifier', NumericString, {'implicit': 4, 'optional': True}), + ('personal_name', PersonalName, {'implicit': 5, 'optional': True}), + ('organizational_unit_names', OrganizationalUnitNames, {'implicit': 6, 'optional': True}), + ] + + +class BuiltInDomainDefinedAttribute(Sequence): + _fields = [ + ('type', PrintableString), + ('value', PrintableString), + ] + + +class BuiltInDomainDefinedAttributes(SequenceOf): + _child_spec = BuiltInDomainDefinedAttribute + + +class TeletexDomainDefinedAttribute(Sequence): + _fields = [ + ('type', TeletexString), + ('value', TeletexString), + ] + + +class TeletexDomainDefinedAttributes(SequenceOf): + _child_spec = TeletexDomainDefinedAttribute + + +class PhysicalDeliveryCountryName(Choice): + _alternatives = [ + ('x121_dcc_code', NumericString), + ('iso_3166_alpha2_code', PrintableString), + ] + + +class PostalCode(Choice): + _alternatives = [ + ('numeric_code', NumericString), + ('printable_code', PrintableString), + ] + + +class PDSParameter(Set): + _fields = [ + ('printable_string', PrintableString, {'optional': True}), + ('teletex_string', TeletexString, {'optional': True}), + ] + + +class PrintableAddress(SequenceOf): + _child_spec = PrintableString + + +class UnformattedPostalAddress(Set): + _fields = [ + ('printable_address', PrintableAddress, {'optional': True}), + ('teletex_string', TeletexString, {'optional': True}), + ] + + +class E1634Address(Sequence): + _fields = [ + ('number', NumericString, {'implicit': 0}), + ('sub_address', NumericString, {'implicit': 1, 'optional': True}), + ] + + +class NAddresses(SetOf): + _child_spec = OctetString + + +class PresentationAddress(Sequence): + _fields = [ + ('p_selector', OctetString, {'explicit': 0, 'optional': True}), + ('s_selector', OctetString, {'explicit': 1, 'optional': True}), + ('t_selector', OctetString, {'explicit': 2, 'optional': True}), + ('n_addresses', NAddresses, {'explicit': 3}), + ] + + +class ExtendedNetworkAddress(Choice): + _alternatives = [ + ('e163_4_address', E1634Address), + ('psap_address', PresentationAddress, {'implicit': 0}) + ] + + +class TerminalType(Integer): + _map = { + 3: 'telex', + 4: 'teletex', + 5: 'g3_facsimile', + 6: 'g4_facsimile', + 7: 'ia5_terminal', + 8: 'videotex', + } + + +class ExtensionAttributeType(Integer): + _map = { + 1: 'common_name', + 2: 'teletex_common_name', + 3: 'teletex_organization_name', + 4: 'teletex_personal_name', + 5: 'teletex_organization_unit_names', + 6: 'teletex_domain_defined_attributes', + 7: 'pds_name', + 8: 'physical_delivery_country_name', + 9: 'postal_code', + 10: 'physical_delivery_office_name', + 11: 'physical_delivery_office_number', + 12: 'extension_of_address_components', + 13: 'physical_delivery_personal_name', + 14: 'physical_delivery_organization_name', + 15: 'extension_physical_delivery_address_components', + 16: 'unformatted_postal_address', + 17: 'street_address', + 18: 'post_office_box_address', + 19: 'poste_restante_address', + 20: 'unique_postal_name', + 21: 'local_postal_attributes', + 22: 'extended_network_address', + 23: 'terminal_type', + } + + +class ExtensionAttribute(Sequence): + _fields = [ + ('extension_attribute_type', ExtensionAttributeType, {'implicit': 0}), + ('extension_attribute_value', Any, {'explicit': 1}), + ] + + _oid_pair = ('extension_attribute_type', 'extension_attribute_value') + _oid_specs = { + 'common_name': PrintableString, + 'teletex_common_name': TeletexString, + 'teletex_organization_name': TeletexString, + 'teletex_personal_name': TeletexPersonalName, + 'teletex_organization_unit_names': TeletexOrganizationalUnitNames, + 'teletex_domain_defined_attributes': TeletexDomainDefinedAttributes, + 'pds_name': PrintableString, + 'physical_delivery_country_name': PhysicalDeliveryCountryName, + 'postal_code': PostalCode, + 'physical_delivery_office_name': PDSParameter, + 'physical_delivery_office_number': PDSParameter, + 'extension_of_address_components': PDSParameter, + 'physical_delivery_personal_name': PDSParameter, + 'physical_delivery_organization_name': PDSParameter, + 'extension_physical_delivery_address_components': PDSParameter, + 'unformatted_postal_address': UnformattedPostalAddress, + 'street_address': PDSParameter, + 'post_office_box_address': PDSParameter, + 'poste_restante_address': PDSParameter, + 'unique_postal_name': PDSParameter, + 'local_postal_attributes': PDSParameter, + 'extended_network_address': ExtendedNetworkAddress, + 'terminal_type': TerminalType, + } + + +class ExtensionAttributes(SequenceOf): + _child_spec = ExtensionAttribute + + +class ORAddress(Sequence): + _fields = [ + ('built_in_standard_attributes', BuiltInStandardAttributes), + ('built_in_domain_defined_attributes', BuiltInDomainDefinedAttributes, {'optional': True}), + ('extension_attributes', ExtensionAttributes, {'optional': True}), + ] + + +class EDIPartyName(Sequence): + _fields = [ + ('name_assigner', DirectoryString, {'implicit': 0, 'optional': True}), + ('party_name', DirectoryString, {'implicit': 1}), + ] + + +class GeneralName(Choice): + _alternatives = [ + ('other_name', AnotherName, {'implicit': 0}), + ('rfc822_name', EmailAddress, {'implicit': 1}), + ('dns_name', DNSName, {'implicit': 2}), + ('x400_address', ORAddress, {'implicit': 3}), + ('directory_name', Name, {'explicit': 4}), + ('edi_party_name', EDIPartyName, {'implicit': 5}), + ('uniform_resource_identifier', URI, {'implicit': 6}), + ('ip_address', IPAddress, {'implicit': 7}), + ('registered_id', ObjectIdentifier, {'implicit': 8}), + ] + + def __ne__(self, other): + return not self == other + + def __eq__(self, other): + """ + Does not support other_name, x400_address or edi_party_name + + :param other: + The other GeneralName to compare to + + :return: + A boolean + """ + + if self.name in ('other_name', 'x400_address', 'edi_party_name'): + raise ValueError(unwrap( + ''' + Comparison is not supported for GeneralName objects of + choice %s + ''', + self.name + )) + + if other.name in ('other_name', 'x400_address', 'edi_party_name'): + raise ValueError(unwrap( + ''' + Comparison is not supported for GeneralName objects of choice + %s''', + other.name + )) + + if self.name != other.name: + return False + + return self.chosen == other.chosen + + +class GeneralNames(SequenceOf): + _child_spec = GeneralName + + +class Time(Choice): + _alternatives = [ + ('utc_time', UTCTime), + ('general_time', GeneralizedTime), + ] + + +class Validity(Sequence): + _fields = [ + ('not_before', Time), + ('not_after', Time), + ] + + +class BasicConstraints(Sequence): + _fields = [ + ('ca', Boolean, {'default': False}), + ('path_len_constraint', Integer, {'optional': True}), + ] + + +class AuthorityKeyIdentifier(Sequence): + _fields = [ + ('key_identifier', OctetString, {'implicit': 0, 'optional': True}), + ('authority_cert_issuer', GeneralNames, {'implicit': 1, 'optional': True}), + ('authority_cert_serial_number', Integer, {'implicit': 2, 'optional': True}), + ] + + +class DistributionPointName(Choice): + _alternatives = [ + ('full_name', GeneralNames, {'implicit': 0}), + ('name_relative_to_crl_issuer', RelativeDistinguishedName, {'implicit': 1}), + ] + + +class ReasonFlags(BitString): + _map = { + 0: 'unused', + 1: 'key_compromise', + 2: 'ca_compromise', + 3: 'affiliation_changed', + 4: 'superseded', + 5: 'cessation_of_operation', + 6: 'certificate_hold', + 7: 'privilege_withdrawn', + 8: 'aa_compromise', + } + + +class GeneralSubtree(Sequence): + _fields = [ + ('base', GeneralName), + ('minimum', Integer, {'implicit': 0, 'default': 0}), + ('maximum', Integer, {'implicit': 1, 'optional': True}), + ] + + +class GeneralSubtrees(SequenceOf): + _child_spec = GeneralSubtree + + +class NameConstraints(Sequence): + _fields = [ + ('permitted_subtrees', GeneralSubtrees, {'implicit': 0, 'optional': True}), + ('excluded_subtrees', GeneralSubtrees, {'implicit': 1, 'optional': True}), + ] + + +class DistributionPoint(Sequence): + _fields = [ + ('distribution_point', DistributionPointName, {'explicit': 0, 'optional': True}), + ('reasons', ReasonFlags, {'implicit': 1, 'optional': True}), + ('crl_issuer', GeneralNames, {'implicit': 2, 'optional': True}), + ] + + _url = False + + @property + def url(self): + """ + :return: + None or a unicode string of the distribution point's URL + """ + + if self._url is False: + self._url = None + name = self['distribution_point'] + if name.name != 'full_name': + raise ValueError(unwrap( + ''' + CRL distribution points that are relative to the issuer are + not supported + ''' + )) + + for general_name in name.chosen: + if general_name.name == 'uniform_resource_identifier': + url = general_name.native + if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')): + self._url = url + break + + return self._url + + +class CRLDistributionPoints(SequenceOf): + _child_spec = DistributionPoint + + +class DisplayText(Choice): + _alternatives = [ + ('ia5_string', IA5String), + ('visible_string', VisibleString), + ('bmp_string', BMPString), + ('utf8_string', UTF8String), + ] + + +class NoticeNumbers(SequenceOf): + _child_spec = Integer + + +class NoticeReference(Sequence): + _fields = [ + ('organization', DisplayText), + ('notice_numbers', NoticeNumbers), + ] + + +class UserNotice(Sequence): + _fields = [ + ('notice_ref', NoticeReference, {'optional': True}), + ('explicit_text', DisplayText, {'optional': True}), + ] + + +class PolicyQualifierId(ObjectIdentifier): + _map = { + '1.3.6.1.5.5.7.2.1': 'certification_practice_statement', + '1.3.6.1.5.5.7.2.2': 'user_notice', + } + + +class PolicyQualifierInfo(Sequence): + _fields = [ + ('policy_qualifier_id', PolicyQualifierId), + ('qualifier', Any), + ] + + _oid_pair = ('policy_qualifier_id', 'qualifier') + _oid_specs = { + 'certification_practice_statement': IA5String, + 'user_notice': UserNotice, + } + + +class PolicyQualifierInfos(SequenceOf): + _child_spec = PolicyQualifierInfo + + +class PolicyIdentifier(ObjectIdentifier): + _map = { + '2.5.29.32.0': 'any_policy', + } + + +class PolicyInformation(Sequence): + _fields = [ + ('policy_identifier', PolicyIdentifier), + ('policy_qualifiers', PolicyQualifierInfos, {'optional': True}) + ] + + +class CertificatePolicies(SequenceOf): + _child_spec = PolicyInformation + + +class PolicyMapping(Sequence): + _fields = [ + ('issuer_domain_policy', PolicyIdentifier), + ('subject_domain_policy', PolicyIdentifier), + ] + + +class PolicyMappings(SequenceOf): + _child_spec = PolicyMapping + + +class PolicyConstraints(Sequence): + _fields = [ + ('require_explicit_policy', Integer, {'implicit': 0, 'optional': True}), + ('inhibit_policy_mapping', Integer, {'implicit': 1, 'optional': True}), + ] + + +class KeyPurposeId(ObjectIdentifier): + _map = { + # https://tools.ietf.org/html/rfc5280#page-45 + '2.5.29.37.0': 'any_extended_key_usage', + '1.3.6.1.5.5.7.3.1': 'server_auth', + '1.3.6.1.5.5.7.3.2': 'client_auth', + '1.3.6.1.5.5.7.3.3': 'code_signing', + '1.3.6.1.5.5.7.3.4': 'email_protection', + '1.3.6.1.5.5.7.3.5': 'ipsec_end_system', + '1.3.6.1.5.5.7.3.6': 'ipsec_tunnel', + '1.3.6.1.5.5.7.3.7': 'ipsec_user', + '1.3.6.1.5.5.7.3.8': 'time_stamping', + '1.3.6.1.5.5.7.3.9': 'ocsp_signing', + # http://tools.ietf.org/html/rfc3029.html#page-9 + '1.3.6.1.5.5.7.3.10': 'dvcs', + # http://tools.ietf.org/html/rfc6268.html#page-16 + '1.3.6.1.5.5.7.3.13': 'eap_over_ppp', + '1.3.6.1.5.5.7.3.14': 'eap_over_lan', + # https://tools.ietf.org/html/rfc5055#page-76 + '1.3.6.1.5.5.7.3.15': 'scvp_server', + '1.3.6.1.5.5.7.3.16': 'scvp_client', + # https://tools.ietf.org/html/rfc4945#page-31 + '1.3.6.1.5.5.7.3.17': 'ipsec_ike', + # https://tools.ietf.org/html/rfc5415#page-38 + '1.3.6.1.5.5.7.3.18': 'capwap_ac', + '1.3.6.1.5.5.7.3.19': 'capwap_wtp', + # https://tools.ietf.org/html/rfc5924#page-8 + '1.3.6.1.5.5.7.3.20': 'sip_domain', + # https://tools.ietf.org/html/rfc6187#page-7 + '1.3.6.1.5.5.7.3.21': 'secure_shell_client', + '1.3.6.1.5.5.7.3.22': 'secure_shell_server', + # https://tools.ietf.org/html/rfc6494#page-7 + '1.3.6.1.5.5.7.3.23': 'send_router', + '1.3.6.1.5.5.7.3.24': 'send_proxied_router', + '1.3.6.1.5.5.7.3.25': 'send_owner', + '1.3.6.1.5.5.7.3.26': 'send_proxied_owner', + # https://tools.ietf.org/html/rfc6402#page-10 + '1.3.6.1.5.5.7.3.27': 'cmc_ca', + '1.3.6.1.5.5.7.3.28': 'cmc_ra', + '1.3.6.1.5.5.7.3.29': 'cmc_archive', + # https://tools.ietf.org/html/draft-ietf-sidr-bgpsec-pki-profiles-15#page-6 + '1.3.6.1.5.5.7.3.30': 'bgpspec_router', + # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378132(v=vs.85).aspx + # and https://support.microsoft.com/en-us/kb/287547 + '1.3.6.1.4.1.311.10.3.1': 'microsoft_trust_list_signing', + '1.3.6.1.4.1.311.10.3.2': 'microsoft_time_stamp_signing', + '1.3.6.1.4.1.311.10.3.3': 'microsoft_server_gated', + '1.3.6.1.4.1.311.10.3.3.1': 'microsoft_serialized', + '1.3.6.1.4.1.311.10.3.4': 'microsoft_efs', + '1.3.6.1.4.1.311.10.3.4.1': 'microsoft_efs_recovery', + '1.3.6.1.4.1.311.10.3.5': 'microsoft_whql', + '1.3.6.1.4.1.311.10.3.6': 'microsoft_nt5', + '1.3.6.1.4.1.311.10.3.7': 'microsoft_oem_whql', + '1.3.6.1.4.1.311.10.3.8': 'microsoft_embedded_nt', + '1.3.6.1.4.1.311.10.3.9': 'microsoft_root_list_signer', + '1.3.6.1.4.1.311.10.3.10': 'microsoft_qualified_subordination', + '1.3.6.1.4.1.311.10.3.11': 'microsoft_key_recovery', + '1.3.6.1.4.1.311.10.3.12': 'microsoft_document_signing', + '1.3.6.1.4.1.311.10.3.13': 'microsoft_lifetime_signing', + '1.3.6.1.4.1.311.10.3.14': 'microsoft_mobile_device_software', + # https://opensource.apple.com/source + # - /Security/Security-57031.40.6/Security/libsecurity_keychain/lib/SecPolicy.cpp + # - /libsecurity_cssm/libsecurity_cssm-36064/lib/oidsalg.c + '1.2.840.113635.100.1.2': 'apple_x509_basic', + '1.2.840.113635.100.1.3': 'apple_ssl', + '1.2.840.113635.100.1.4': 'apple_local_cert_gen', + '1.2.840.113635.100.1.5': 'apple_csr_gen', + '1.2.840.113635.100.1.6': 'apple_revocation_crl', + '1.2.840.113635.100.1.7': 'apple_revocation_ocsp', + '1.2.840.113635.100.1.8': 'apple_smime', + '1.2.840.113635.100.1.9': 'apple_eap', + '1.2.840.113635.100.1.10': 'apple_software_update_signing', + '1.2.840.113635.100.1.11': 'apple_ipsec', + '1.2.840.113635.100.1.12': 'apple_ichat', + '1.2.840.113635.100.1.13': 'apple_resource_signing', + '1.2.840.113635.100.1.14': 'apple_pkinit_client', + '1.2.840.113635.100.1.15': 'apple_pkinit_server', + '1.2.840.113635.100.1.16': 'apple_code_signing', + '1.2.840.113635.100.1.17': 'apple_package_signing', + '1.2.840.113635.100.1.18': 'apple_id_validation', + '1.2.840.113635.100.1.20': 'apple_time_stamping', + '1.2.840.113635.100.1.21': 'apple_revocation', + '1.2.840.113635.100.1.22': 'apple_passbook_signing', + '1.2.840.113635.100.1.23': 'apple_mobile_store', + '1.2.840.113635.100.1.24': 'apple_escrow_service', + '1.2.840.113635.100.1.25': 'apple_profile_signer', + '1.2.840.113635.100.1.26': 'apple_qa_profile_signer', + '1.2.840.113635.100.1.27': 'apple_test_mobile_store', + '1.2.840.113635.100.1.28': 'apple_otapki_signer', + '1.2.840.113635.100.1.29': 'apple_test_otapki_signer', + '1.2.840.113625.100.1.30': 'apple_id_validation_record_signing_policy', + '1.2.840.113625.100.1.31': 'apple_smp_encryption', + '1.2.840.113625.100.1.32': 'apple_test_smp_encryption', + '1.2.840.113635.100.1.33': 'apple_server_authentication', + '1.2.840.113635.100.1.34': 'apple_pcs_escrow_service', + } + + +class ExtKeyUsageSyntax(SequenceOf): + _child_spec = KeyPurposeId + + +class AccessMethod(ObjectIdentifier): + _map = { + '1.3.6.1.5.5.7.48.1': 'ocsp', + '1.3.6.1.5.5.7.48.2': 'ca_issuers', + '1.3.6.1.5.5.7.48.3': 'time_stamping', + '1.3.6.1.5.5.7.48.5': 'ca_repository', + } + + +class AccessDescription(Sequence): + _fields = [ + ('access_method', AccessMethod), + ('access_location', GeneralName), + ] + + +class AuthorityInfoAccessSyntax(SequenceOf): + _child_spec = AccessDescription + + +class SubjectInfoAccessSyntax(SequenceOf): + _child_spec = AccessDescription + + +# https://tools.ietf.org/html/rfc7633 +class Features(SequenceOf): + _child_spec = Integer + + +class EntrustVersionInfo(Sequence): + _fields = [ + ('entrust_vers', GeneralString), + ('entrust_info_flags', BitString) + ] + + +class NetscapeCertificateType(BitString): + _map = { + 0: 'ssl_client', + 1: 'ssl_server', + 2: 'email', + 3: 'object_signing', + 4: 'reserved', + 5: 'ssl_ca', + 6: 'email_ca', + 7: 'object_signing_ca', + } + + +class ExtensionId(ObjectIdentifier): + _map = { + '2.5.29.9': 'subject_directory_attributes', + '2.5.29.14': 'key_identifier', + '2.5.29.15': 'key_usage', + '2.5.29.16': 'private_key_usage_period', + '2.5.29.17': 'subject_alt_name', + '2.5.29.18': 'issuer_alt_name', + '2.5.29.19': 'basic_constraints', + '2.5.29.30': 'name_constraints', + '2.5.29.31': 'crl_distribution_points', + '2.5.29.32': 'certificate_policies', + '2.5.29.33': 'policy_mappings', + '2.5.29.35': 'authority_key_identifier', + '2.5.29.36': 'policy_constraints', + '2.5.29.37': 'extended_key_usage', + '2.5.29.46': 'freshest_crl', + '2.5.29.54': 'inhibit_any_policy', + '1.3.6.1.5.5.7.1.1': 'authority_information_access', + '1.3.6.1.5.5.7.1.11': 'subject_information_access', + # https://tools.ietf.org/html/rfc7633 + '1.3.6.1.5.5.7.1.24': 'tls_feature', + '1.3.6.1.5.5.7.48.1.5': 'ocsp_no_check', + '1.2.840.113533.7.65.0': 'entrust_version_extension', + '2.16.840.1.113730.1.1': 'netscape_certificate_type', + # https://tools.ietf.org/html/rfc6962.html#page-14 + '1.3.6.1.4.1.11129.2.4.2': 'signed_certificate_timestamp_list', + } + + +class Extension(Sequence): + _fields = [ + ('extn_id', ExtensionId), + ('critical', Boolean, {'default': False}), + ('extn_value', ParsableOctetString), + ] + + _oid_pair = ('extn_id', 'extn_value') + _oid_specs = { + 'subject_directory_attributes': Attributes, + 'key_identifier': OctetString, + 'key_usage': KeyUsage, + 'private_key_usage_period': PrivateKeyUsagePeriod, + 'subject_alt_name': GeneralNames, + 'issuer_alt_name': GeneralNames, + 'basic_constraints': BasicConstraints, + 'name_constraints': NameConstraints, + 'crl_distribution_points': CRLDistributionPoints, + 'certificate_policies': CertificatePolicies, + 'policy_mappings': PolicyMappings, + 'authority_key_identifier': AuthorityKeyIdentifier, + 'policy_constraints': PolicyConstraints, + 'extended_key_usage': ExtKeyUsageSyntax, + 'freshest_crl': CRLDistributionPoints, + 'inhibit_any_policy': Integer, + 'authority_information_access': AuthorityInfoAccessSyntax, + 'subject_information_access': SubjectInfoAccessSyntax, + 'tls_feature': Features, + 'ocsp_no_check': Null, + 'entrust_version_extension': EntrustVersionInfo, + 'netscape_certificate_type': NetscapeCertificateType, + 'signed_certificate_timestamp_list': OctetString, + } + + +class Extensions(SequenceOf): + _child_spec = Extension + + +class Version(Integer): + _map = { + 0: 'v1', + 1: 'v2', + 2: 'v3', + } + + +class TbsCertificate(Sequence): + _fields = [ + ('version', Version, {'explicit': 0, 'default': 'v1'}), + ('serial_number', Integer), + ('signature', SignedDigestAlgorithm), + ('issuer', Name), + ('validity', Validity), + ('subject', Name), + ('subject_public_key_info', PublicKeyInfo), + ('issuer_unique_id', OctetBitString, {'implicit': 1, 'optional': True}), + ('subject_unique_id', OctetBitString, {'implicit': 2, 'optional': True}), + ('extensions', Extensions, {'explicit': 3, 'optional': True}), + ] + + +class Certificate(Sequence): + _fields = [ + ('tbs_certificate', TbsCertificate), + ('signature_algorithm', SignedDigestAlgorithm), + ('signature_value', OctetBitString), + ] + + _processed_extensions = False + _critical_extensions = None + _subject_directory_attributes = None + _key_identifier_value = None + _key_usage_value = None + _subject_alt_name_value = None + _issuer_alt_name_value = None + _basic_constraints_value = None + _name_constraints_value = None + _crl_distribution_points_value = None + _certificate_policies_value = None + _policy_mappings_value = None + _authority_key_identifier_value = None + _policy_constraints_value = None + _freshest_crl_value = None + _inhibit_any_policy_value = None + _extended_key_usage_value = None + _authority_information_access_value = None + _subject_information_access_value = None + _tls_feature_value = None + _ocsp_no_check_value = None + _issuer_serial = None + _authority_issuer_serial = False + _crl_distribution_points = None + _delta_crl_distribution_points = None + _valid_domains = None + _valid_ips = None + _self_issued = None + _self_signed = None + _sha1 = None + _sha256 = None + + def _set_extensions(self): + """ + Sets common named extensions to private attributes and creates a list + of critical extensions + """ + + self._critical_extensions = set() + + for extension in self['tbs_certificate']['extensions']: + name = extension['extn_id'].native + attribute_name = '_%s_value' % name + if hasattr(self, attribute_name): + setattr(self, attribute_name, extension['extn_value'].parsed) + if extension['critical'].native: + self._critical_extensions.add(name) + + self._processed_extensions = True + + @property + def critical_extensions(self): + """ + Returns a set of the names (or OID if not a known extension) of the + extensions marked as critical + + :return: + A set of unicode strings + """ + + if not self._processed_extensions: + self._set_extensions() + return self._critical_extensions + + @property + def subject_directory_attributes_value(self): + """ + This extension is used to contain additional identification attributes + about the subject. + + :return: + None or an Attributes object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._key_identifier_value + + @property + def key_identifier_value(self): + """ + This extension is used to help in creating certificate validation paths. + It contains an identifier that should generally, but is not guaranteed + to, be unique. + + :return: + None or an OctetString object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._key_identifier_value + + @property + def key_usage_value(self): + """ + This extension is used to define the purpose of the public key + contained within the certificate. + + :return: + None or a KeyUsage + """ + + if not self._processed_extensions: + self._set_extensions() + return self._key_usage_value + + @property + def subject_alt_name_value(self): + """ + This extension allows for additional names to be associate with the + subject of the certificate. While it may contain a whole host of + possible names, it is usually used to allow certificates to be used + with multiple different domain names. + + :return: + None or a GeneralNames object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._subject_alt_name_value + + @property + def issuer_alt_name_value(self): + """ + This extension allows associating one or more alternative names with + the issuer of the certificate. + + :return: + None or an x509.GeneralNames object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._issuer_alt_name_value + + @property + def basic_constraints_value(self): + """ + This extension is used to determine if the subject of the certificate + is a CA, and if so, what the maximum number of intermediate CA certs + after this are, before an end-entity certificate is found. + + :return: + None or a BasicConstraints object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._basic_constraints_value + + @property + def name_constraints_value(self): + """ + This extension is used in CA certificates, and is used to limit the + possible names of certificates issued. + + :return: + None or a NameConstraints object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._name_constraints_value + + @property + def crl_distribution_points_value(self): + """ + This extension is used to help in locating the CRL for this certificate. + + :return: + None or a CRLDistributionPoints object + extension + """ + + if not self._processed_extensions: + self._set_extensions() + return self._crl_distribution_points_value + + @property + def certificate_policies_value(self): + """ + This extension defines policies in CA certificates under which + certificates may be issued. In end-entity certificates, the inclusion + of a policy indicates the issuance of the certificate follows the + policy. + + :return: + None or a CertificatePolicies object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._certificate_policies_value + + @property + def policy_mappings_value(self): + """ + This extension allows mapping policy OIDs to other OIDs. This is used + to allow different policies to be treated as equivalent in the process + of validation. + + :return: + None or a PolicyMappings object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._policy_mappings_value + + @property + def authority_key_identifier_value(self): + """ + This extension helps in identifying the public key with which to + validate the authenticity of the certificate. + + :return: + None or an AuthorityKeyIdentifier object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._authority_key_identifier_value + + @property + def policy_constraints_value(self): + """ + This extension is used to control if policy mapping is allowed and + when policies are required. + + :return: + None or a PolicyConstraints object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._policy_constraints_value + + @property + def freshest_crl_value(self): + """ + This extension is used to help locate any available delta CRLs + + :return: + None or an CRLDistributionPoints object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._freshest_crl_value + + @property + def inhibit_any_policy_value(self): + """ + This extension is used to prevent mapping of the any policy to + specific requirements + + :return: + None or a Integer object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._inhibit_any_policy_value + + @property + def extended_key_usage_value(self): + """ + This extension is used to define additional purposes for the public key + beyond what is contained in the basic constraints. + + :return: + None or an ExtKeyUsageSyntax object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._extended_key_usage_value + + @property + def authority_information_access_value(self): + """ + This extension is used to locate the CA certificate used to sign this + certificate, or the OCSP responder for this certificate. + + :return: + None or an AuthorityInfoAccessSyntax object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._authority_information_access_value + + @property + def subject_information_access_value(self): + """ + This extension is used to access information about the subject of this + certificate. + + :return: + None or a SubjectInfoAccessSyntax object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._subject_information_access_value + + @property + def tls_feature_value(self): + """ + This extension is used to list the TLS features a server must respond + with if a client initiates a request supporting them. + + :return: + None or a Features object + """ + + if not self._processed_extensions: + self._set_extensions() + return self._tls_feature_value + + @property + def ocsp_no_check_value(self): + """ + This extension is used on certificates of OCSP responders, indicating + that revocation information for the certificate should never need to + be verified, thus preventing possible loops in path validation. + + :return: + None or a Null object (if present) + """ + + if not self._processed_extensions: + self._set_extensions() + return self._ocsp_no_check_value + + @property + def signature(self): + """ + :return: + A byte string of the signature + """ + + return self['signature_value'].native + + @property + def signature_algo(self): + """ + :return: + A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa", "ecdsa" + """ + + return self['signature_algorithm'].signature_algo + + @property + def hash_algo(self): + """ + :return: + A unicode string of "md2", "md5", "sha1", "sha224", "sha256", + "sha384", "sha512", "sha512_224", "sha512_256" + """ + + return self['signature_algorithm'].hash_algo + + @property + def public_key(self): + """ + :return: + The PublicKeyInfo object for this certificate + """ + + return self['tbs_certificate']['subject_public_key_info'] + + @property + def subject(self): + """ + :return: + The Name object for the subject of this certificate + """ + + return self['tbs_certificate']['subject'] + + @property + def issuer(self): + """ + :return: + The Name object for the issuer of this certificate + """ + + return self['tbs_certificate']['issuer'] + + @property + def serial_number(self): + """ + :return: + An integer of the certificate's serial number + """ + + return self['tbs_certificate']['serial_number'].native + + @property + def key_identifier(self): + """ + :return: + None or a byte string of the certificate's key identifier from the + key identifier extension + """ + + if not self.key_identifier_value: + return None + + return self.key_identifier_value.native + + @property + def issuer_serial(self): + """ + :return: + A byte string of the SHA-256 hash of the issuer concatenated with + the ascii character ":", concatenated with the serial number as + an ascii string + """ + + if self._issuer_serial is None: + self._issuer_serial = self.issuer.sha256 + b':' + str_cls(self.serial_number).encode('ascii') + return self._issuer_serial + + @property + def authority_key_identifier(self): + """ + :return: + None or a byte string of the key_identifier from the authority key + identifier extension + """ + + if not self.authority_key_identifier_value: + return None + + return self.authority_key_identifier_value['key_identifier'].native + + @property + def authority_issuer_serial(self): + """ + :return: + None or a byte string of the SHA-256 hash of the isser from the + authority key identifier extension concatenated with the ascii + character ":", concatenated with the serial number from the + authority key identifier extension as an ascii string + """ + + if self._authority_issuer_serial is False: + akiv = self.authority_key_identifier_value + if akiv and akiv['authority_cert_issuer'].native: + issuer = self.authority_key_identifier_value['authority_cert_issuer'][0].chosen + # We untag the element since it is tagged via being a choice from GeneralName + issuer = issuer.untag() + authority_serial = self.authority_key_identifier_value['authority_cert_serial_number'].native + self._authority_issuer_serial = issuer.sha256 + b':' + str_cls(authority_serial).encode('ascii') + else: + self._authority_issuer_serial = None + return self._authority_issuer_serial + + @property + def crl_distribution_points(self): + """ + Returns complete CRL URLs - does not include delta CRLs + + :return: + A list of zero or more DistributionPoint objects + """ + + if self._crl_distribution_points is None: + self._crl_distribution_points = self._get_http_crl_distribution_points(self.crl_distribution_points_value) + return self._crl_distribution_points + + @property + def delta_crl_distribution_points(self): + """ + Returns delta CRL URLs - does not include complete CRLs + + :return: + A list of zero or more DistributionPoint objects + """ + + if self._delta_crl_distribution_points is None: + self._delta_crl_distribution_points = self._get_http_crl_distribution_points(self.freshest_crl_value) + return self._delta_crl_distribution_points + + def _get_http_crl_distribution_points(self, crl_distribution_points): + """ + Fetches the DistributionPoint object for non-relative, HTTP CRLs + referenced by the certificate + + :param crl_distribution_points: + A CRLDistributionPoints object to grab the DistributionPoints from + + :return: + A list of zero or more DistributionPoint objects + """ + + output = [] + + if crl_distribution_points is None: + return [] + + for distribution_point in crl_distribution_points: + distribution_point_name = distribution_point['distribution_point'] + if distribution_point_name is VOID: + continue + # RFC 5280 indicates conforming CA should not use the relative form + if distribution_point_name.name == 'name_relative_to_crl_issuer': + continue + # This library is currently only concerned with HTTP-based CRLs + for general_name in distribution_point_name.chosen: + if general_name.name == 'uniform_resource_identifier': + output.append(distribution_point) + + return output + + @property + def ocsp_urls(self): + """ + :return: + A list of zero or more unicode strings of the OCSP URLs for this + cert + """ + + if not self.authority_information_access_value: + return [] + + output = [] + for entry in self.authority_information_access_value: + if entry['access_method'].native == 'ocsp': + location = entry['access_location'] + if location.name != 'uniform_resource_identifier': + continue + url = location.native + if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')): + output.append(url) + return output + + @property + def valid_domains(self): + """ + :return: + A list of unicode strings of valid domain names for the certificate. + Wildcard certificates will have a domain in the form: *.example.com + """ + + if self._valid_domains is None: + self._valid_domains = [] + + # For the subject alt name extension, we can look at the name of + # the choice selected since it distinguishes between domain names, + # email addresses, IPs, etc + if self.subject_alt_name_value: + for general_name in self.subject_alt_name_value: + if general_name.name == 'dns_name' and general_name.native not in self._valid_domains: + self._valid_domains.append(general_name.native) + + # If there was no subject alt name extension, and the common name + # in the subject looks like a domain, that is considered the valid + # list. This is done because according to + # https://tools.ietf.org/html/rfc6125#section-6.4.4, the common + # name should not be used if the subject alt name is present. + else: + pattern = re.compile('^(\\*\\.)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-]*[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$') + for rdn in self.subject.chosen: + for name_type_value in rdn: + if name_type_value['type'].native == 'common_name': + value = name_type_value['value'].native + if pattern.match(value): + self._valid_domains.append(value) + + return self._valid_domains + + @property + def valid_ips(self): + """ + :return: + A list of unicode strings of valid IP addresses for the certificate + """ + + if self._valid_ips is None: + self._valid_ips = [] + + if self.subject_alt_name_value: + for general_name in self.subject_alt_name_value: + if general_name.name == 'ip_address': + self._valid_ips.append(general_name.native) + + return self._valid_ips + + @property + def ca(self): + """ + :return; + A boolean - if the certificate is marked as a CA + """ + + return self.basic_constraints_value and self.basic_constraints_value['ca'].native + + @property + def max_path_length(self): + """ + :return; + None or an integer of the maximum path length + """ + + if not self.ca: + return None + return self.basic_constraints_value['path_len_constraint'].native + + @property + def self_issued(self): + """ + :return: + A boolean - if the certificate is self-issued, as defined by RFC + 5280 + """ + + if self._self_issued is None: + self._self_issued = self.subject == self.issuer + return self._self_issued + + @property + def self_signed(self): + """ + :return: + A unicode string of "yes", "no" or "maybe". The "maybe" result will + be returned if the certificate does not contain a key identifier + extension, but is issued by the subject. In this case the + certificate signature will need to be verified using the subject + public key to determine a "yes" or "no" answer. + """ + + if self._self_signed is None: + self._self_signed = 'no' + if self.self_issued: + if self.key_identifier: + if not self.authority_key_identifier: + self._self_signed = 'yes' + elif self.authority_key_identifier == self.key_identifier: + self._self_signed = 'yes' + else: + self._self_signed = 'maybe' + return self._self_signed + + @property + def sha1(self): + """ + :return: + The SHA-1 hash of the DER-encoded bytes of this complete certificate + """ + + if self._sha1 is None: + self._sha1 = hashlib.sha1(self.dump()).digest() + return self._sha1 + + @property + def sha1_fingerprint(self): + """ + :return: + A unicode string of the SHA-1 hash, formatted using hex encoding + with a space between each pair of characters, all uppercase + """ + + return ' '.join('%02X' % c for c in bytes_to_list(self.sha1)) + + @property + def sha256(self): + """ + :return: + The SHA-256 hash of the DER-encoded bytes of this complete + certificate + """ + + if self._sha256 is None: + self._sha256 = hashlib.sha256(self.dump()).digest() + return self._sha256 + + @property + def sha256_fingerprint(self): + """ + :return: + A unicode string of the SHA-256 hash, formatted using hex encoding + with a space between each pair of characters, all uppercase + """ + + return ' '.join('%02X' % c for c in bytes_to_list(self.sha256)) + + def is_valid_domain_ip(self, domain_ip): + """ + Check if a domain name or IP address is valid according to the + certificate + + :param domain_ip: + A unicode string of a domain name or IP address + + :return: + A boolean - if the domain or IP is valid for the certificate + """ + + if not isinstance(domain_ip, str_cls): + raise TypeError(unwrap( + ''' + domain_ip must be a unicode string, not %s + ''', + type_name(domain_ip) + )) + + encoded_domain_ip = domain_ip.encode('idna').decode('ascii').lower() + + is_ipv6 = encoded_domain_ip.find(':') != -1 + is_ipv4 = not is_ipv6 and re.match('^\\d+\\.\\d+\\.\\d+\\.\\d+$', encoded_domain_ip) + is_domain = not is_ipv6 and not is_ipv4 + + # Handle domain name checks + if is_domain: + if not self.valid_domains: + return False + + domain_labels = encoded_domain_ip.split('.') + + for valid_domain in self.valid_domains: + encoded_valid_domain = valid_domain.encode('idna').decode('ascii').lower() + valid_domain_labels = encoded_valid_domain.split('.') + + # The domain must be equal in label length to match + if len(valid_domain_labels) != len(domain_labels): + continue + + if valid_domain_labels == domain_labels: + return True + + is_wildcard = self._is_wildcard_domain(encoded_valid_domain) + if is_wildcard and self._is_wildcard_match(domain_labels, valid_domain_labels): + return True + + return False + + # Handle IP address checks + if not self.valid_ips: + return False + + family = socket.AF_INET if is_ipv4 else socket.AF_INET6 + normalized_ip = inet_pton(family, encoded_domain_ip) + + for valid_ip in self.valid_ips: + valid_family = socket.AF_INET if valid_ip.find('.') != -1 else socket.AF_INET6 + normalized_valid_ip = inet_pton(valid_family, valid_ip) + + if normalized_valid_ip == normalized_ip: + return True + + return False + + def _is_wildcard_domain(self, domain): + """ + Checks if a domain is a valid wildcard according to + https://tools.ietf.org/html/rfc6125#section-6.4.3 + + :param domain: + A unicode string of the domain name, where any U-labels from an IDN + have been converted to A-labels + + :return: + A boolean - if the domain is a valid wildcard domain + """ + + # The * character must be present for a wildcard match, and if there is + # most than one, it is an invalid wildcard specification + if domain.count('*') != 1: + return False + + labels = domain.lower().split('.') + + if not labels: + return False + + # Wildcards may only appear in the left-most label + if labels[0].find('*') == -1: + return False + + # Wildcards may not be embedded in an A-label from an IDN + if labels[0][0:4] == 'xn--': + return False + + return True + + def _is_wildcard_match(self, domain_labels, valid_domain_labels): + """ + Determines if the labels in a domain are a match for labels from a + wildcard valid domain name + + :param domain_labels: + A list of unicode strings, with A-label form for IDNs, of the labels + in the domain name to check + + :param valid_domain_labels: + A list of unicode strings, with A-label form for IDNs, of the labels + in a wildcard domain pattern + + :return: + A boolean - if the domain matches the valid domain + """ + + first_domain_label = domain_labels[0] + other_domain_labels = domain_labels[1:] + + wildcard_label = valid_domain_labels[0] + other_valid_domain_labels = valid_domain_labels[1:] + + # The wildcard is only allowed in the first label, so if + # The subsequent labels are not equal, there is no match + if other_domain_labels != other_valid_domain_labels: + return False + + if wildcard_label == '*': + return True + + wildcard_regex = re.compile('^' + wildcard_label.replace('*', '.*') + '$') + if wildcard_regex.match(first_domain_label): + return True + + return False + + +# The structures are taken from the OpenSSL source file x_x509a.c, and specify +# extra information that is added to X.509 certificates to store trust +# information about the certificate. + +class KeyPurposeIdentifiers(SequenceOf): + _child_spec = KeyPurposeId + + +class SequenceOfAlgorithmIdentifiers(SequenceOf): + _child_spec = AlgorithmIdentifier + + +class CertificateAux(Sequence): + _fields = [ + ('trust', KeyPurposeIdentifiers, {'optional': True}), + ('reject', KeyPurposeIdentifiers, {'implicit': 0, 'optional': True}), + ('alias', UTF8String, {'optional': True}), + ('keyid', OctetString, {'optional': True}), + ('other', SequenceOfAlgorithmIdentifiers, {'implicit': 1, 'optional': True}), + ] + + +class TrustedCertificate(Concat): + _child_specs = [Certificate, CertificateAux] diff --git a/venv/lib/python2.7/site-packages/asn1crypto/x509.pyc b/venv/lib/python2.7/site-packages/asn1crypto/x509.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4e2fb090118ed230ccfa00baa2e454b657c9ec6 GIT binary patch literal 99727 zcmeFa349#ac_;W906~Jcc!;9T5+zxXM1Z(?NR~vAluS#8=msg;kf>Ips{l0F2iVn3 z0y<(HJ`$ga9mh^)l6Z38PGaY@Gs@cY%g)YBHpwQF&F&;KYdLYUv*S2%HnTIEY-a!e z@2mH!s?h*JQengUTaaDHt5>hy@xAYU-|PIFP3up5+uF&3iT*lqe)zdg6E5@^;~O)H zW5)O$rj#+|4l~(d%AIDi)0Df+WS1$gF_UXdhB-P-soRv-n#r|#-(^bcOu5HQ_UQc@ zQ(A8(*Gp-*-e4v-*z1jEa-+T8WF|M+>&<3zv%TJ8Cbt;B+xTluX{#w;XC|*hxwv0v zO503%yP4c>$~(;D4o&SbrJbgHy_vjT@7J5sE>ph2Ox|G1yUpZoQ@+tm-l)$un9@zA ze6yLn*_3ZFlecK{95CfUGdXC=LuPWwl!wjauqlt2$q`c?HIt*JJZ2`xOnJYV+;7SU%;W)6 zK4>NnYF#&((jim6-%Q@G_nS@W0aJdfnS84$KWHW&H06iPWPxYQ%Y-)VwADdBpTder#4OfVp+H@MVe#@}s% zK}o&Qr9Nu>n@r$I>dh|oG2`E2OSsjgzRmcznP5cndM@?23Dz3_cDc`($+sJSj|uLO zOn10Uj~o9^6Wk}Mce&IjjQ&fk4qgl{=K&P_qo(3jlb7^tQdij{0D7)A9AVhHvYpl^{`8wH2x#Dgd;BXY2zQYd5^i&XN>=- z&HI>3J!Aa0*|r^bsm~h!?Kbssmzp#F6Si&daH-E3f83V)q)W{k|Afu^PM11m{H(3n zgi9?L|D+w`Q!dpv{!=#ZX_p!p|6R6b?{=xv#-B7nuZ+dhE_KHE&)C#6E_K%U&)RZx zF12X<=WHwTF7>SOr)=JWOFd_N-=+pGwPgHhTeBILS~mWyEw|`WE5<)-^PY35RpXaz zxn-9+XZ(syt-93n#-FpP=Ur;e_%&N@=u$)D*X^`!xYWAwFW3?;y3~g8=WTr#Tuo^S1w!}y=E<^D65`a$FWkS*bdUFwI7|06c_M_uZNjsIgd^~YW6M~wdy zw%ng|sUJ1|Pg#iiX_xvjw{Y|i8jc?+x{_w1LP@{suzou8LwCm%Hg5)>%BhjaJ^nDPBoCZ_a5FKiC@=* zWApW(5*DkKD8pkxC8*^~Ibs+}ix-Nl zW_=58@>5~8ghu6xD7aRyZ${c&tyrn&rW=()9oc#_NRspd-U;UG<$NVS6Vx=FpDOy5 z{CJVsG_4y~jmpJZey+EJ@2+Q_S}|9z<{Gu4+~Ukzr0OdhkmbpmAJhW>Xt7Z5B_~}6 z6K&YYTm@ZNUyHl2Udt8Gj7_+nTEI}S5cYt6XgiV*mu9N?$ZYwzA5=KL7^a;_pD50t zD~}dug0SxL^xlLgb$;w{WkJ68NU=VFajwkh-8)W1cl`Pz)oLloSL$rvk=bgo5a?yK z0vM9sj7GTleBhrfqRy;ml$I#<_~Fq+smIZ&=*~KOa=cM0$xGvna!@N4qHG+>C#TK^ zg?ge<9H}P@^`IVCS$dI4(R=KV6Zu-0pDG2CHA?5epWq<#L6k zPD=+(1oiqFNv

    4Lcc>0>DF}%u|)(g#e!`MQQA`Qzwr|SFp%aCm%f!Jz@b*0Sw~` zu>DUxdHkpX1fQR1OqGg-$Ag9AmFcPi^+qHUI5F%p{sNZ*t+i@7N+Q@`+SGHEdUZ~Q zQSRpI0AJSV==cQZT>+Q!N5FlAQrkXU1d!Um+~e3m=?TIb#JBh2w#z_D?Cqa=NULefd-w~F}VR;e%Gv-`}**GB$9PdShu8F>L{YTt!?Z6A;m=1I73dSu`1;8<;B@WR=VbHihUvs0CWV*@kOvu7_3;BTg~ z@8rI@;#}WUqge9$X6w%%e|~6RKCBEDY76L#KXG|hY7cvdWV@n6VG;1B0Af}BbuAMMbowAjbF#>>%Hjj*!e~t*lEGb zhYsCMEqJr_`doNu-@ZDgT-aX>>eKzz+RVP$dbzZ(HeDDUIxuiYi1`5g)VIHX2nag* zJ2aQC<;$M*;vtvHhleYY=taZtRb@gY-mC@nMy=BHk~gK3-W4Syt|%=mR>FE7^Ce5j zk!HuqD&gAw$h!77Rzw z{W;vEhI))c4TONX0gQzqe@!m{2>6fT&zM&;rlP}-snWre8bpdt0t9BxZD+gr+S#>y zuk^!s}~0Hb$TxaiFWkx@UU6^=qt(fJ??y+nuEVIBxug49leG9Ihds|i zXv2iP$mOK-a=CKVZH>=072`*}EqL)=8Ux|WDq@Xe#BL&#C@ z?&!{Rcl31jY!yO%Dto+uRQYqHZ7*&eX(JUA>c)#!1P*kKG|6FphYl_v^@`B}r|B94 zpv2_H+~+OSP{0eg=#go?p7?^(8X~gJ`}H!dJ29@Om32D>on9KQPl;?o(P2qAz z7E!8YxEx@CtKx7JP>-V#*%2NHnLlCqIfB4^qQ{ zz>94p)a=iHfnV5#gIU|7gqgUNkN6Zx;fQOk#gVo`*`hn=n|Vk)W1 zTau|1X$~r6UnqAioP(w%`v6CtfN`?c2(sgRU&v4^wv!)M9*xi}G9j_(RCQh?quFX$ zrwE-ril;HwzorQP7(V?!;uqeELy{@o31W3e$CgOq6ZVvtmn|nT7YzJCTmW>)8>|)H z;5E60(gK{WU>c~ffbR*t;1oJc?U=x;C~bz z#4d#ZfsYAhJjn<6wLt_Sd-0#}3pexoU`jS-c4l^V+>m+8x2W*(cWex~kVyC-f_C8f z*SJX`>7=3+>S}_nAVjm-ZR5cMJYaKy>(mWL=bA`;Zhb(mLLv zV8gR(M^xK%uCSDp@u5e|DLLe*O;?CoM5B{azPUEb$JFIOeE>Qj;1@F z*keAzMHW^vH@>h#7U zEr{@!v*?)fK~o%3ZueZJwDb@7DP|T0b5CYF6b0Km1~OYaZpz%$u@Oq=8}N%1oUv5# zFy7PNAgd)*N+`};tvUyV0`EbgMDIm9 zN$_1Ne1MBm;bR?T4q}o5%d|hCco8QJWa6o~U?K{%8+!Gscl?BxSBWZ!b=eJSPF)$)iO1PgFCKb@d_{_bZXDct82G9D|-@|LiVC3&IyTQuh8dbkx$9|*(Te97Fx`iFWmV-`hWls2Q-pJhRG&jz>@Qh?s)z6y^%=#~? z#u_PjOr8y|g51e5cb)NJze3`6N!-D@k)Hi^1{X};8~+9e2kWgh*ozF4 z%gD27ZIej<`C^5hE0|!%Ph1$W^K)mS7cwom0Bbd^!|^<=WwSW)}uEN#?fpyi>Lmu7jjd}Su^O3?Mtd#2(IxEkA6c@}Bw zQ1N9H-}uB8eq*XQ1NRO6%HYs}y<%J}=jV&%M!Drj#S|faNKM_{GI!Bql;c2=oU90{rnnB5K1a%B)wy6*;Cxlz!plZdL zVkKWvBc^Nxl<<8b}Zw7nK%BXZsV zx$8EhUymnFw&n=1cZAb;7#|~^1j6sJdUq&im;~CSNe45$g(xB7HXRB?G69)G22~${ zuu`n&vl#HCkPxEZb%}?4^o7ux0BR~q=6e!p|6p=@NtK^jVQmUM(!f4}F9Nhdn3ID`A92W@Y-iZb9W);uR*Yo1!SPSN$ z-iH1ckC85(4q)5_<0QnNl~^u_`^Vu3;65yfs7QXch@Z~yBAGDJHM}rzXzC?J0&?6p z-pdJr?Sd*BASk;zBQa)f2N={QxahgkqE~FKRW9?678W~_f4geQY`eOew#c^#k)6s9@<7_5t9qBoE*@>St;2vD0 zc;cj<<27lSB8k|%TEZ(1G%xM+<)p1E73NhDHjJ-kv8pSQ-sfWfx|4_=);tKs1UXTm6J0h~ir~gj(kMhW zn>TMlmh2roP}8nF27HQ3enQTa*?TR8&Fn?g^ojeyT(B-Z;2anz| zozd9{Ee!-a{YU_FQ}j}PrWOS9hR|1=%moWlf#Mn##J(uhv`R&Sa)TM|2Xoa*X`x7t zOp>9~mwIS2UsY9#8+tJbL7h0KaDfbMQ18EhuYQ)py#p8Bna<4Grhnqf57%{iLt8jF z0Z;j=@1TJ_A<*y$E|RDL-LIVF7|;V@0*C=%f%(8E;0b{%;wMBIT~?3QAX0+*D>oHj z{YW(S>_n`ZfI6&Lm%)IyIk+w;tcZA-J3kH8q$+^u(b>~cDE{YH#R zZp_rFA{?*Qvq8R8T1YwhyFPYks841SefJ2KaY`bYam z`iJE@#PX+f`iSt3A($AjzLiFKDySvi8f|bK3)M!YUR!7`a!g(=RSUAbtNH2v2DuCn zNhocqwH!Es3#7%(*$&9O!gLR?oG-F8CMs}Hm}x8w%U6oe3-hf75E*F01_v59;3k;` zEx`oD>OeL%k#kV=SoLDPlu90wZ%j47E5MkL<7#0nFkMK#IVwGib-5G}=sJ^pxL@!9 zQNtWmb!egXV*KHu0TDi%sxvYuJm(BBMKoIR8zV#V0oZx!7?&{dwUOZlIp-N!c}!+B zC(G-&2sW8(MB0R2z;e%A(XEqBX3??rmndLNSlqcVX!zC2LOJo`*l2@zC)wexzi@EB ziYs(ra6`+=5B3lB9~c?v9~>MW9XZ%P*pHt;3jm~A!y;uJXbV{~zJvY4{bR^Fg5U7q zVE@E^4C8!+8}d8D9HI(&Y2rTjVVwILTNrMPhrA^9n&h=;eE-)3zCPg;E_B9b&EWbe;cI=A4+RkRu)Kt zRfcAnYqiO(CX89M&SyRAW!AvOf_qMjBhS@Lt;IR!h`T9Ah*gYXUwM!k4&?d9b<>3pjGtjh>sLOI!u zTc|aL52O5&ufqvCl=V2l@pdClh%B`kr!AyU zW6+R*MvZ}zf{KlSl7fbffs%qcje(MaT8)8{f^Ln0l7fznfs%rjje(MakdA?pf|QMc zl7gs>fs%rfje(MavW;sTHv$g?}7Q>m4E0<$aP0lL0?z39s#PCN84JT}YIn>J+ljC=5$0$f6*>zLuymG*i-<3& zD~H%Snxd{t5MA;xNq9~U%`*Ir`mGVk&IENauC!aXA@Z`|x}3#zZzFv;ggTnFixsTR z3fETm>oel1o=|530h{dmaS+>qgxXQJ!R&|lL`+Q|!BtEqAcMg-m6PSEu+F%#A->KjBM z4FU>F7AQBg5s(bWc!DaMClGL+*60azoOdvG@C0(s6KozlfvWQa(+5u=?mWQ)0>uVt zJnvu#;R&RkC)h)H0>uv?r9yn>9SA>9kfH-{3ZVbIgD}k#*Z`g&QwNZ2!42>ZqBT!o z3K+g}4}(<(5O;5}k}6mW30*h|0r)m1B1|Qi23~BV5PJu@DK_4bW(arJlKv)XZkoap zWu|0SB0-DER4QCXHYL?;l1GWaQ}T`wkY&ZrG`(w0*_tU?OQPjyRTFVa(W92)AZxu? z0&Gc7(iCJdy;y=MtQ6;`U$^4bl1Q9QZW57}!N`j_-yt-d3?pcSD$VbcTL?Z#$(Y^r zG_WgsDmH6mIsPTQ>ljNb4#92_i9urTf%HPb2r7*N6b6uC5YC2KV7gEx98E+b|4@xt znQ`TTk*BAp@C}HDL(?l+2Pq)?=n;=WZ(>Pm3AQ%P$GWmbw;{7-TqPi~l2E$@b8}d^ z_%LonmdKU-yj45O)73%4I76els%PG(NW!S}HtV-!ZvGZ^iTP1B0>73nF^7>{2lTo1 znUPBj?8Nv}&}rp5^QWdQ(q31*fO=D*78qi6md6-so| z#52iVGZ{GB!z2Ng125zMs}d@TdEmIOdG54%HZ95nSA5O$Hk)VjqCD`**E}Vg2TuP@ z-@4A``A(Z>Ybp;)0LQ~F{zI-MV1>8E8P5Nq!T-~+Wx}VF$1XGfptg9-wit^6v=(2> z)OU#Q>A%ddl{;-ZZjs()&i~5{{-5SjhRF`*z?&HL?Yck%UG9>0Xp(r3hL3c>t8^nz z-DV@-)LQOL)N--|#0z5>4ZGMmbUe>qZ(cKI7oP1>CE-LbnU%&KFrN-j9EW3rxS(j{ ztfhz-$XtSG+0ct((RM|Vc8!b<9_YVRR5xaFQQa2DbW?Jt8%`UjvVgsK=k~S-)Z9rZ2tkj5x%4Skr(9x8mv7KlAygzy3>~>-+jI{rZ^~ zzy7l?KmGNe|4iT4f8q5rFaFJEUVcS%CQtv>_rLFReK`C&l0MV-H=lXsbv`@Oc!*y& zed{*&-S(coFTM9m@9+E45B|IF|6|nTqi?+Y;l4Ls{@5EY{}fI?_r@!q>3idqAAaK% z+`aPIZ+zkPZ@m6%ecyQf3#cK*jW=HYkksYrFMZ}K-}mwxFTad;KKRDVKY`OvzVY&B z-+1K*zxwjaX9VYtKl=EQMgi}*5oJHvKaHhIBp)GmtQdpVjBCZBH5usNd`Q13urjoc zcym>NQ>;(3CGp(&@Kt=LfQ242fm7U7Yb`7MJpO$8Nf)49LXBp@b0KDCLcy1+(A6|N z3fm~ID3|)q^i?z*9%y~8{7d)o)Kz>6a#gK5gPyzeX9#BBc>OmTSJN^w&cHCGd_j;= zJX$S>wumoA>)+`~)-ul`c(q_k7a)Z4fPYt+Ja^F-2Lf^EYFW^t$SNtY0a-WReGNHz zy%bOoHxcXX0K(<`=^~Z`oUji$SE3*r-Ycgaz& z-H|JDwy)s|9p>a(n@tG#w;ijfci@d}U3YXSo8N`ch*z^yjEu{Y!-Sd+niTb87Oz9; z(Ok9YW8rMEmVK2EDYIv9=HUq*_TeCKC)p^Gh9WFxzmrcztw)|a_8`x)*>R7{)iu@f zQ6i|Y+uw!@x|nR~ybN8R)%1zi>H1DA+TM)#QQPag*~p*-+5AF~)F1n#d!!KZ#|bWK zJPL1tIHf~}7rAG+FjBCwNdPIX+t%n&;L|$|wOruMbpdw|)mSckLukM=*m}YHcbeT$Cti=YGUt2E zY4Y~U>LV(eI>=Aq8xH5KNYMZd2Mn|YScYM{g}DsIUE))p?vJnl!(I&i2NK|3=?WJA zvb(}Vh=VE|(rwaWK^i%z&sEabMRsZp76gIPGz}}!VYRhY zAyIjRf@|?&44BsvCdIi4m}{1Z`o2!UrU->=vB&|7d~WL!p^&h{pNugLSr}Ka>kvX# z>4Kj7*$~#)sQQI;izrAM@DsRbp}oL3D7f-Mgfi+b_Nndy&@8$Og=XY)P^k+60k_P3 z#^sj4zs#*F58O(TSamo576SUwGq*;o?I0!XhQP!Vi+ELvIR7eyI0g*n6ictmzV=Fz zC6UXOYD<*Dijw4K(LPm@04GK0ob!vsBFz3ApJs80X|gCzl-)p7a?K~xQUi?0dved9 z<#w8q9nt5}oFkAktEkj-?U{O_hk1~YdNXRHdKktVfnS8g9^rXYW=CdS9QvAAS77)~ z)?aWf;Ogj^?U8$osNXW?*$#7lJuz>jWcwy^JIrP^!-DT*6(+mdGMYe+#Dx_vdvtt} zBCX~xia>tVupvI}675`F(bGC&2^F|VNym}%WTBI575Q5oTbC5; z39ca&Y%&=jn+OcU77v26gM)wxWFkfC1^B$NS|&0h$>0l;g* zwv^kgw9=xm^9f_>Uq!0jn1j?3=!!&9WjcF}Pu*QTzLAP-OAFIp3Q>LfsyRC z9|dHTKhA97YAFnWf?%oT3c1>7^-qBWmOp$}Q7gq^;8Dyh<$yu#j{=nnHf5%C?8bjQ z29%Y$RjS8E@)vT&1ht{4(wWVX6D8{TROUQz0GCPdopJT*;P{H{C8B-*K$dVC5AL-b z*O1cj12pu`&($9MAP1Pu>DC>2lu2gIWj?j1idlBo%eH1_{kJCD`(f7rWqXOF2(rR5 z06;F6?VazB105Yb<0T@eiY&J~;(8xYmh}O!tlZ&>L)rM}I5kfqm;C?^B3TI&3J#-9P`w}Z_!xm=D=uOVb2nnC ztm|m@lM+^ZDFP8UK(4MO`pB~TA!bEkvq=^I@A%P4K7z_lowL#0nNGe% z*Z%)Np^htvV7ElvG$0NQHe)(i=1tL4255sN7GiMXDfwBvBIZM^f@a0w4u(KybO%H6 z%I4xCbN-Y$4Wh`;V1V!rEVfdE*G$Jm?-q9ONst_ekdAOYD}(q6<0Q-g@-UpOHcHUWLpI@}Su3{mbK&}4YMD@W6#*grK3Xgp zmkX;3>}OovRNtIf6%YjwsiT#}dO`n8zxTo(u()Th*t6H$lk^^AD!rNK8GXl_XiQ^=Lab1J;>ezt772?` zw82XUEv06uxz60U3fmMGr#-BfPj2<*#hoacIo}(C$bhX0U3snfxr!&dka0vUIpK%-Ck}qe z^^ruiuHDhH$n58lSRi5KkBDl5yd3QWn9LO20K9OW0W7PmHV$zw;@`4BBSu_Rg|Z6X z=rLNkoFR^B|MUo z>0_TUL7g(kb$O{+35Z3rpT$8}%y6Sj?Z@}=!4o`CVo;^PtGxOJ9)tvbj8~*Nx|sFb zaV6FWHvwhcY6`rik|6WC`J;tbU5K+8@4FQ7J{GrUx4uYo5l6*If?}k>Z5rh@sE+K- z_wyX$1GqEWY31pLZ3st1Ve3S+r!8H(p(bYZC;o1d=i6Y?fbzJr2gkLU8@e3S6Y_7UF;R0xaeHO`~tg^bnuRH~# z*#$NFw+o;A9#yekOz70ffaAX)Ei$$LB)Uf8ZZhQHTX6&jjr~SHz-zFkU6JVrpXxLZ zz~2qY*lq;sSg^vR^qKRc_D)M?KBS$d;gk90b2jz`$AUV^nDD9mHjVV`!#oJh}Eh|K!=2tW<~@CMQBfmwy-uL z(|U@$*9(aKK9n*DOTEF&_c71WGk2Mn5c_!}B`b(|$O9Rcc1OfkLg4BR=EV6MGx&e{ z#SJEWG6R9G0!b1=xW6k+-~bAGGh*(wc-j%jgCZXRf!-Hw*0-i3ki|fUQfKB?)NkzsI0lprB|di zPp*&PHRTq69#=An7%_=);@O{jSNy(67Q!it&y~hei6R6OAxMN^$bWfx6YEVG zxlP#FP<>;oZQ9Q{%YM9x(|ZgTW-Yykx}lfagn!-OC$G!g&~d$7aTgVx_BVm|+=RPs zXs@k>sD=^_O9V`8KyN=&9u#r!$h&IeTdTv4A%~U_`RM+!y=UsuoZaB{?EMqBOZu-V@s(*7y%02 zfeK!2q6)0sBLo{#D5^BOGxx+H1UPB}2-JK=Q~-J?(ES0@ee!2A@W8zoY(^WCY-#i* zLr+&G*JUly7xg|9Z#z8b(S1e?=}0)5*zQi^YwH7OBvKelW08q)nuG7npdcBUqAUz? z<^&(`i6VwZc}`r05a}@p>+NRsvtLE$OmGl{^}^h}T?sLX@tZdUXI44{eM6&TS1}4C z6&wYWBIA&K0}0aIQR1KCKKo}lw7uj19F=%B-SJTv`$t*F$9SOXA`7^V*up>L)mM1< z8V?`kK{)x};nll%pctGbu1gq%IsXMmD>~qaXZiJb+RN3olrXbj#`k}`6JW=M3NQnR zs-YVWt6Lt}(gRCzXU~=`TesZZbKRB=Vlh4pM}I`Ap$t^O8}dhp6)VBLxCq2z>{}}V z7(c|=L`+O7t2G9vi?oSOHxk`RIOd`s^WjC7D^Z4E-;{ux%4o+UB5``D;c0t7&A&h; zK=%@{dFjp<@kyzELN{wa?Zt)bCq~gkpMfQm2*zMD(N!9Rjy=^)dj{XsII~n-%nuF? z=KMlIV^8hiv#^>Q9vmBk@AModojg$gF4to+`9xQi6W<(eaDF3RRTtpbaMeyQ{NM5Y z^X$ZRxDc%vv|aTZaC6u%V{tPSRHA^_*bgi0RoIZwtBXSWxn3pwNv~?4Ug9hGe< z@TL1`4a!Kk#;l&6`8q20KK2ZUTViKZLyjQASml*3r9g?mCy1&Z+-fcj>)SH`&A?fq-C z?}rlY<$9S%8pTrmcm;u=Dn2a4hh4BgH?-tkWN1l1o6swmL||A!qC&8N+!9F=m6uW5 zfpHn{Ce93u+b!|jfpODMfN|H#6JT5hz=_}4VBdkeNBSKEs6ntDd`EmzlJCGbWt}`h zteW&Y*U{aD?;wV2>d8zG_lF1AQhU`pxSK=VB$xRVr-QiD5>B#$*`eDG1oey6+Bq9L zvjutJcd)P({1TSX#bG{`PVgZ(8nOb(qLoUJZdgvcb;LKJ7ZU0-Vv%yN*4C0=0XV49 zno-qBT1D%vTNe;Ml1>kJ2u+H{WDR96gI+St3I2f$p`tQ!HVHvhYsNXLQVcv3P33DXuwZ;$gLPtw&)*rDAquxQHj&lqPx%0Y;Vs@VbemenJu`qcjAG90&{8v=skK#_;o{``IP>!gpWb@|S z-;!d;|BW{O2evUHJ2&9|ROG!1A6cDB%`JVCK!&QO7-VehelnJq0W)lXa($};X8sP< z`DzMgIPs1Rjt!42*^BohN7KYxiR#Fy**F}sQXc3EA){Nc`Q(&oGK~6ou^OmZEg&df z4CL*egny5!|Ho8^62*^4op}{n05Vu@r}zI4D)HBe=|_?4L}Gu|W|-mRXsvD(j^FAD zFST=7E3ISn4rJgiF}|qQ5h_Zm8wJm^<7LYU#D4@H=hitftT|aQHGla^80RL6loGH> zoh?Dc5&~$&f@ct_sDO^J8Z>id9RP)dDxqZqBJJ>n{e%UgnPv z*HjDk-|*>wh-WtpI7F8xBaOsKc-lEW#RBo4PGnwH z6tqx8jEU}6%uF-Gx#@f%EMn{KKs6GQI+92gyvtPXykxZ~x}PFp;sW$3Rp^~%n{##I zcofOm$9RAPM5527_pfQka|y(nHGp0MR66{P?CvKp93r%pQ_8g-jL+irXfUv~!-@w3 zONbWlr%83#KkmLu3IqM9b8|%KSmR|`)Wmun)p$`OWgjLrQ>wHgc*<5VHcMKk1sFH7 z)r@_dDj}iS!kC!G?TJrCNsok)?jaYyS*K{A*c)x)K(&>0aPxHpq7ln?{QaQS^cS7)2ioS{X$jCq~i7iBa@%VibLx7)2i^M$w0Lfl>5v z$0+(ZF^WD;jG~Vdqv+$rDEbJI&nWsZIxvdcNznR%tQw^3IWKFW*Hj9cJa)K zvy0bcEI>H6kF!02G8=?si|dl<%VN=`5$H;A=gQD#3S+JSSvKRzOQT4s>tbAEk*MzL zLwpzaZ%f3uL^&y(xKea@1(@&>NU#O|TMqRtgY}j`c+26s7@Aw4xy2YxJy9HLY%v3t zhj-cJJE5o|a+2NNMGDFOG{#aDqIdF&mh3F;omr}Lvs6-M{|gUPC}pW3$dd2Pk_XHF z46b74``R;t9jL@!;@L4&gx09tmlF+9Fs?XR9J56J@M0@2KA}=8X|kf*WexPKQ`<%J zPE=x?9TREB$R0hJZ5HOpafv|wR@XG8BuQZo5;Y}r&=2@C(p)TVdr=Y=>8r<{u!uLK z7%urle9{WEq-q#XFnx_Z$qY;KhH1?!Ifoe6I9wh!d#QaB`LZ-bsX~oC&~`Dqi{o2sJDj#$!j1Lzi7&NO@y9y1q!IwzPT#6dy}=ba>J#HL{!JymEPsO`XtoSjjrw z&t#3cK1O#s6(ZRzdcTS+tHa-B4LTNFj5V>sSBfNDHzrH_xUnAu#{V@gboyS3TZ*6^ z`^>5`34(f*glHc!0l+EQq#kjuz&I$Y#A&ioJTZ_2rY3rEv$#_r2@Fn@gm545qd*b@ zeMCu!^s!!&uu9qTsH2SI3adRZMtw^Xh;PM z^qc0uN^?yS6&8VVeq><4@$w=O660x@XzU29xn-VHLEv~NL5qG7L3SPNU|>w+CLSt9 z#*(0@P;Jy8geAN*2=1azE5^zn5dk@3wO|H5umN|iM4)PZ?^`pRQiU+e9yakRW_F=0 zFnJyqP^FwjCu0E})&}0o;3imO!Zmo3j>Vu@WAdu(BEc1Z$hlT>p0qh-T_Ms_Iptl= z&vkic8P;WjC8Au3-y&;^*{h8&;^5Y(9Iaw85+mD(jX7*Yi#0>^eV2jX>m|X1kw}8n zm?u^e0TA+KeKoy6iK|_tL@zN>xuXHaX~fXLWulnY3z8W1BgiMVD@e}((I+NrDvVyb zs*PH*%?!Z7zawrd1jhbIbOKjop}EN_S7mV(7ZSRz(?UE1aIZqyfRMk7o;31r-e;rF zEc(V>p-93qt>Up;NvB-#dz|ap-{RqE9yqI4<0|j-oQOo3vfit!Gqa5W$q|HNTjw?e zOzkBWOYq2l!P_Tz*vEs=@h|g=geQBPSCc#t$>~CwAztmrp%=fz;hHK&yHUHmZK--^ z(L>Ar+l}=t!ha-y`O1Ax__4M#x@%F1Pgo=iPgEk;lf}eh9TKwT+{{`yPY7bH7jku! zBXeg)_8TurLNibF7L=c*@~Z9Th;`_SPq8c52jX_dhG01;C}@4bsgEwzAsXz=x*!X8 zKpYE4Ap;%LMijF z4t{$*I`l{54uu#)Tza@spM@E)h0-cAwD#X z3M1aBUxS?vWUdiQuowmk)fBG^c`+JA$%5ml^3KENQ!2{B!yGoM!Ddsw8ktD|AQMQ0 z3Zx0PBLd(Kpqd>z;3}TWjar1$7g{~__GL?C$8^`6ycf=MAX5^$mZG}4PP3WnrnQO0Fqq!uB4dx{ z;EhLs4qJc~Va!5~tgH#<3#A6_9PTBKKr=#T16K#9vlTV@x9n=pBhpIQICv4ITs)c2 zBmYXe+c7z`y~ga1sunT3p;}BmQ6>lGS!|y~v#bjQENiWZnZ*RmcUw=r~EIG}>lU2c zpb5KCLmBlbBZ?tv2~ZeRTTZ(*|IR3+)zLFYqNr(nNA~%xonVw51U}OkYG>D(*YHiT zP~-jDCm4E5zj@;PC(QX1{GW_|MvB}(jbcSt%U~>sM+^NFL+nCrDH}PeBe;#rlI&sK zM_e8QDp|j9Q0J= zRXsd%RY;bX(qXmCaVZ_GkdWDWeeTe{eIl~(I^+#uhkI$;2fXG3-F^G=-;zDCHA}zCw72sx#>4$M#G7MDX3=k0ft`G%M1Me`y~wK!_%-FdcVN=|8Sx3d zk~KyZ!_RRqysbF*AQn|mW^+gLdO-4(iV(?aWQF0S7@=LWjcM=VEsKv^CRf+AdDr3l zf6V3)U#Mu|b#`}%cyT2A#3HoCjFOmRs%&?(7iW(|9O-7!l%7&q zf=HIGUK;8cn6$0%b3HnA4LfulDng|d|4DS@@oF8K^l@=GxpJrxMwNz^c21IAXyoPu z)Cl_~&C3SUFmhE2v2f6dx?ZNflE%BFN2Wjuu)lacYX3F!TkQ5MtJQW@-3_S3HujD3 zTNr!-^(iP?6ad_mLY~V~(t&%>1@`1*KZs;r_Ay!TwSF+uuLbKd6|93+A<}Tjm;CZ9@Hx z=uVH_Nl;UvUc7^vI~1<9i@Wp?-dPIKM~;`W6a^iQ2o6B~;&BN%9&A0V`6L*s7?IJ- zowvgWb*3j+|4l~ z5+wbw`{CB9nQ1X{S58X!skSp9H=`0GY;U9qpq5Qr*+K#D<~x6+LbtJ+>eU3pph!?JUL0EOs8MM{jU5C<3o&?V34z5qPqAr|q2m9(4Q37_gv8 zC5?uu_(Y?Ir9nX}#`GT0qli$w!xAc*Kxhfkbu6@g!0bUaDb}e(UYBiJk>~dte;+C_ zVEjRxhKxUq(}?j$aT+uJew+>%{~%6>jDJ5)4;cTgI3c9?LpVKb{KGgsV*DdG9X0+j zoE|m)V>rFd_{VX2yYU~#=?UY%1E+E0KZ(-`T4$`0vJP z()dr~^o;S(;PkBVb2vR`{5(!m1|q?j@5BCs)3ottaGHguCr)RLe-5XT@yj?>u>TTH zbH+c9Q_c7xPIcoqaJpdpi#W|2e*vfGjsF5pFB<G6JTc< zgmANTt|9RYqLMfl7H2A$j4cZrZje6<5ZJ5)*$L}uAw5+qEwheD*5X_k6mnRAoeLM> z|5|RDbyPmCS?i5TB`CGbHWqo;vP1?iYnf@kt~Y_F6J@$G(MrpF2jrX8LI`EkG7UZ` z`zZJq3ZW>&(}E#7cR-2>u-?1MQJ9;XYn^X6ov)Oyw9Yr8V_LYtRs9^;*4akmY&x>7 zvyF+Qr5#&57qrf_UosW)a~HX4z0f+-0qOfF)5ZD{tvo2XLO4L{T8Nfq4GoA~h*4~S zc!aY7Tq%}m#L(d4?8|h`&`>lh0CKfz11{ICD={3EifjPn`6A}oa@j|;Wd!8v#mZ8J zj>@;Ni&k9dGP%dZ#i39}9O!)OO73?#YD?reAgyH?`C4HX5vf`ibWl`iQ!{fR*6=Ua z(BT2`5-Jx9wJNs)%++fRES}|t3vQl}fZK^M0xik#;234?&@5SGZ z(Ao^tGQK=&`NiP|nby=>MW~6M$2;U3TEByOl5dXR3Z}!QKQYo&F=XaWCYCYUHHHYy_ zwJLlh9VB25EC~n)8@H!A*vgb*G_Tft1h^EsK`yf87y+-c@c7%Lfv(q=er>R+%6_$g zJ&8g1ERJ9L)uEg7Fr2 z)y%=)1wqWUe~0=Hj12S-4i1kEk7AzTvVTZWw&o8*3sx;M>ip1*x=>x50%1;Ey6_PJ zMSZ6b)^f{c9+e5GnX%5leW^UAjGB zOz3o^uSFOlM9`*SnJ*=$FH~2x>P6uSfmN1yX(TZv!P>wBQhOT+d+AOXm1kPH^LesF zD|>G&@g8=MuIEv;gI^x(2}JRsy&>nPt^>5B&&_qd)P$ZFG%-vPbL)6~2CQ}jK|SRE}wj&!VLs{WEk4ML)Cbgb=c@umw?f@fWq zc%IDL;#&0f$L8x$37w+6KCyt2Qss5HKtJhs z1XwK5!WJ7_CE!;b*=Aa*yj15w-Jl5BLjQ>(Esvzu*O3EYrD^1bkGE>4TZ!VxHPk}# zZ&}>1WJGbb0BXA;aPUG4sR<>HuC|$Q7Y5_M<6y8qVlQohI~|mxoaRNrNDl5UWeRAq zVoaRYWt4MpIKwbY1pB23oeqC&Dc}`uAL{J74lf{cxBcZ8MSRt>gkC;RC?nvQ7 z(Q2p5f*w)U9IZC8bsxs=&p393>zHg=W=leyfNj#SgsrS-pJn59^uD#?TGB7gSd2(3eQUvu*W*rlG z*VYQ#oJ%~6RF?fh?jv7-mN^ax_=%bdEAQ+w;4oFnLHUp@gD$9vLsG!m3^hbJI#;TX4wGL#nP&tY{T1a-9td=VY7~v+(_+8q_U8gIICtHxf9} z38F-+>>M2)hU?|nD6E|1-4Hud5WOsFwkt4Y>m0g*!9#OQU!a3zKL}S_D z++kVAOOTX^d-nf^3&pX^Ig`P00c+Rc>#wW05ZrPSn{*-eCa5Zwb#gry_s~M@D6aWJ zq$jvGFuo=uapD9I2S&!^c3zt`5+~wEZN%MHjl_x2QH;d7O(St4Y7`@J?$Ah_$jL~Y zJ2evL^%{v286No~XpX5SXY> zDaix7gp|ZwGD(O{nR<2(#Sx_9;B7+LTc8q$iI>OE~ffuTCC)paJZD;Y{s5sk>jWWO^qb>Xn`S_EOR^Uz(6)Mg$0?f1>WO0#h+|}v~ENO z+hHvpQ!}4LUX*9kSc*u+^1oz=)5vIflyf^jeksHf@3(4UEe%q=5?J9;6s2y-oZMM< zhpvcXlvrW9HJ;@HZ{>{_c=ZwwvWAL*EV5kVndMTREFA>1^bgB!;DIhnS*ma}ZUaTd zEXAlSC5|jxnI&VLC5P5_*XKS|Vk;Kng$GbC4K8S%pHnEUh2|}OE~_n$S!VLeF@`|Jn zi?FiVq=~8PC}|KI5HLnJNNzZpeu51r5fu?H zgUoT+gnMUZJ%b~HOiAEz4t9i@beu#4j8^kR1DGONL~;-z;Q*1-y=R2SB%%@>iTIKz zJrS}e1~tUGkuoA&D%_C8t8WelRA$>?hE#r_Y=Hggpzsy4q)9&RJiG+HebDp$aLot9#JVf{;aplTU zUHhj;*-MgCsTH77ODTZ*BbdxdKqZ99KB~O1iz~@_A#_GJIWPETP6B*z1jmIV7%m(E zi#USM!Vzp1j^Lee1e1j$cq|+NdpLr_!VwG>j$o{C1YdsRpAJx3PR0_hvoKWdwW=JZ?U(J$nCB6_K4ixW^a$mt!HnK$?fg-_EEXr zV{adm+dJ&-+vN66dwbmYckz1i?UMc$oBp`m-feH6klS8+`wqFi$KH<1?Y;K)Nx8kx z-ky-#z4rEQiA-xKyV?i*a-L(hS3i&6Xvv!^HGuXaoh|i*)pfk0YUu=^(Ktav3v!fngwk0d`~Z z?>>5F+Gy|z%%I(8I~Y~MM*!3gb3NinASwXzB5(u(r`Ga}Nujrhj|z!w_t`b(wN8_% zAPW+@<^9@C%ySk2RJ&OUz%XudQW2bpfIndl`#Z(P8^#ax(xG|nKWywEN8O$NlLwT`$WNaxULL5h9p^B2epjWBGyWT5}N_tVa#kEk)i4}xefy?7sWMM zDFk{&h$;!nfDK869!anO`cP0Q1MNfHIdND!3g6u&ahH#MfWT}X0(}Ig1d&u8SE@m|@v8(lJ~diWLu_kGaEL!#%6LRwHo&2e{($Q*g|dh%XUq z*nf!;a*=E*-eI?)fv3g~S8CHJ=_E{RD-pay0MAI855r&4go5R*_42i6%Uv9c;q1E zif*2}RA|QQo>s}UrEZjCCTp>@PQU1e>*}!WNx-D*j3#WGFO{knLy6g*z_Lmw!E0f* zzz4NjK$y!w28P4p%8Jm89o6J$d8cRL8tN76pqLAG5`!3DL}1Ino5hxBc*_+8PbrDi zBm7>tm#+yKKv;*;f+Gh~*Cb2`JIDzQdg00<_;_W66E4Ex9U;P|C1yro`!axa`#2G{^P&Zcm zmE(X%nj)cJf(NM6q@{~&lHLoe1aOF?7TNf;ZvWna&egF8U&bfgU@rkWAn?&pM)r1K zeM<2O&?;d=UV#Z$R+>x@HWDN!#Jh;_cp2kLq<$oJFS*pP3VJ7HT!o`bOx3z-Uw4Cg zb@krHLV1`4ns!9I<)8C{Q{%(g95~_ea~OL`-kt z6tqg_DD@pnxGiZ7|L#p1R7xwZqnc)_a_^yMt@jk)nx-ryDIc=f#o1zE))kW&U#d$M z$U{am(>uNtR>tfXDqlhPV=DSwX_(`At-=B-;7f3HuzgWH*F0hYw%|SiY|7RmpDRiI z2rdKU7Kis~2DoO>VsQSX!q$0_trEDRUqfPenyS|W^`$Czu8tA>JAB3UdJ|AZ;zksb z#SSc#al*>$c2~UX_vFQh8o1JcU{nZ**?I?_Dy<;WHrNDF&@q4vR107M2)YEBNNMVd z18~KJVRLYsj?m`DXa=QFrU;DJnJ%bM+Wpm24Z!0#*r3ZxXE z*-opoK&e1RNi4%u4yeQ_=!LtTS%qOVX4nA@V@gLJa(M;vc^FWpC18BTqYCAp_1c62 zAr23Bso}j1O_azdvbBravwc>G(Ii*NIFsbX4o}oFST(Avq8sq5;}U*tnE_9*c2xG% zs?g?6TNGe10y4=A=M=6agnEpzW`$2K8GVHJmiSPY!S3m_y$ptr9!!cO7giz5M=2wk zyy#AZIF?(Fdf|A&kL0l-4*%`(N z7b_k;aCmiWQ&YPX)|9EW*fn#N3>v4_Qk8qB8@j8*lz+Igp^J3r3Ega@N>`n2nqE2z zITb8aAxw)>1sIj+7T5teHDZKB0l;L7HZFrq9&28LyrQudxh&6eN*9IjUk|}ihRHZebw^OE%;NbM;rD|1WZu(hVk?vz0ds9Ym z;`LH|r)PJ(yEURWEW>N`dPynjgFIWNSn}= zICS%KUC?sBti#^a0_<116^&I?IHyhbZYy6-bt!r~KGAmPBDz1iO8*$Uiv42NI#00W zy9ph3$!<#f$+4&Q)IwN}5jW~wAsoCgIJ#$VoD_z<^TRw(L4g->Uvh|DZDW5~=|x%F zk$%|j-p%HLY(9J0o%(}U)~RKGh<#S}r9Z>j{2*^}9vT|4SEFNl_PXw*`i;+r57_6U zgHi<2aFvVSlRLcYUR}y_Sx16E1qaw!8KJfh!W0JKSKT12TMXG;MiLn^Z7@v9oxz6@wmk9UX(39l>dev}{e&LYiJYYCoP>k4nT9`;zO<7KoyC zcTS=J*9R>TD!Y>w+;lGj!zw>(nd2mBb_KTd`i4!-cIxWr#6*Su_2u{AyRWzh)vx68 zJCKgS`tIuJzqmesuw3_Xf+gm&5cN)^tzb$YhV{ZKycU@ru-~OFn2UT_mWRGY>+2K| zt_rHZsBVAKqCbH)l|dqMLVuzkL#z_Zmb}rein5G1;jV`8{ zD7I#J)7Yh((v>TpRI4e^VjqEVSxD0O zU6kdzvE?wey-+lm3KL{_BXu@?~dc8d%+26dSFWM>!K+`5g1a%w0SyTZFxcChC)`YogL#5Ni3iFXyel?o(PM7c4;BjsA7o$os!|-h^@^-uMevX;GckPJi!;jmCe5l3;1DKw@Qln zd{BdISo6d;e$k%Lk-QVrJKaTGfno`-K^f=z?Pvr7?$>kNn0zT0$n0?pecS09$9svk z+~E)^DBTVJ*kkM*7?vF1BotiAPJXpxEWWE!r6q^&Vf0+KhB3@etcHQ4E9qi60iFRd{zu8~Y&n~~{Ru2~0hRf3s0|E$6P(%Hyd$rI`xqo~D$=_lIb+K22TjBY~S zNjTA9Wq7`f^^`4x8y<4?VzGz$g+-OJj*DDqJ5$R~$+ueMB2`R$w!SLF(r-w4Z-^!Uo zmtM268^o@wgNx`lX1Y7J;I|da>2FX0k;I=fN@f#fZzX^b12~B|wGa%V9;F^VQ;axD zkqj{7bk^L$3Bk}1hz5a4!Rdsl2#)lWonuJM7@dBkq@br=49N#Jv-W<@QwW`yZ@A5z ze?Q-m$pq~{FIk$#JPrWGTsJwmouW?kf?QTDdr;1DRLN{C_WbI)Lln8ihFli~_=m>+cij zl#nK8u?Baoq~J~b2gm|&BdER4oWBn=;4cj#bDTwVB+;E9Ov-#&3SVc=_MrS{NQ~wu zI7yD4c|4jBoH(2gm@@d_r#TTMZVIF~d;*kaJ;@KJ%2%Vt@Y9l#Isa92{?q(_`uvB? z>4cJo@Y47K4i1nnF>hK-6>+6bEsc%bg;J*HctJkr&go*wFXU^8xDv0B2%*k_VR$x= z6`XlnUgT^>EPcqkw?CN2j)|q99}JVLvCI#@5^9v-V`$8?z0chHO#eL(^*(gy>3rYw zhx;Z6`VO8+-96KH=HA4!dmcjm`=W$1FAVK{=}y`5K?1l^Z=_2tsl~aJ{RCfNuao7&>gFr}C?Q}WT5e%BL0d>3Bs+}lT;H1g zBHyRBSx6hJr>5}i5u~+;kkqM2N;SX6DR?td%{quvYkDvRZ_nI<>+J~m!QYn5?Mhe3 zsdeHfbOm!Rf?N^|2v*N6nugDr`Gam6-q&gx>ZHR=6lx))BARs1CAE|MXam#p>H+`w z3C0!y2N8mGQ$mpf{1{Hx<8#<~GRi$J!z|GtIfU5u2YYli1CGE9p+{T<6bZMFWe`N` z>iS8J@@CY{ti>o}4-4`OUaU~&*vh!Z%KWN^-ibUPNVu7)aT*8LO%VdR-z5-VKucW3 zqJOAJ`s^a%1m?inF!&|gpgMVYKDw7B3}GR!-FJ+0O?nd-O48aiW!UUO{>RvZylmzC z&{Ek7mPxgE%UF!lJ?E6Ii_A=Rm9+TrV2RUALYFSac0S1AL1N*8>It%#R*{io^>itb zBAS%5wMKJ3%l;*$H)~<)xO_1mgjSh=1jQ79T?waoDS!=w(sZB5BJj3?`cJ*IMPkc7 zdc*-Rp?`Gfz<^7LR5dhtL(f;5R(Zx(%puf-inq3FUq~4f)%$ff6d(hwG%gpApS%`u zgUaVsg1UA;(}f4)1>}Y2BxjciA0h{(dCnK3M9o7UshE0tzC_t0%3Mv-0@Cxw`_XBx zkC$MA(##LlY>+OTt2Ig-1$%zzokk^;#B9?q-#6ceN+H2BZ?6-U+ycpDC{!mbMrP?5gM)!*5TKZK*a@o^f zA)i$YBFN|XWoLLex2nKj>-bv)f4VW64OB4ezm1t~nJtjC3#hOJsv~X@in$*bgkvF; z29> zg%_)+PQZx!g7Pxiui&eShu+}TS9$nT9{vo6c4H)|&Yw6m1fJ#gxaXZH=%J>-JM8%m z^Iq`Uf`fp4K=O{_hyM}j{Va024rtlMhZ!Y|ec9x(8F%|$GK}E)Y0K8hG#kt#=m=g) zdifGti2HWl3$Zp8w4~@ zz>QGC2^K!rX+o}~0%V=pLWbJMb;ex(ROY-$w-JlR4!Ub#=w0K=F!A;5Z{mRd0VmTQ zE-J)eng{#Gs%fMb2lVPlSxepl zibpCAWoH~DLY)Y0yej86RxcQc`%o&w z%AEh4G^>Y+Wb=1qpb!&Rq^&H1Uxq4ly{UapK7JkZu^?pq9Cc?CDB!eI7B$~y!jl=f z=`yuKroP>r-C-)-h8H`{OB+lbDvJ%a2R54d(^BX*wCD-*(kAobCh0$Eu=Zc=Cl{5n zSxP}GHc3BjF)!l(MydS!r1IzAmysH2BEWNNzb<@(gpzOKy!MJa#a*$#gTCl_qU0_5m3-_UBTUkv;(x=R>=gFwGyZ+g z^rsGYN}m2+Dz>u2JW$%r9^!%OhAhyII{9T!@k;C|CwN8mZx&3J$-c~k_}M(iw19^! z4gfp|_Qfy9Wy>!oVzfVxE_&rk*=?crZ*}Hu^EC=D8g7$_bYMAZSkoGY*#WN7nQ)SOEfoI z!o7T`Le{ucd>--1QNeZYb=;7v)3T=Xsf_14Um&KqERr7f0=Y0FodoZ;@Vz%b`IBw%knyeS*4hpm3l&kO{&6iutjRkvtYdtQePsdJvBR zS)NKhgi;2C;C5hkKAMw9a0!cI@6)N(O-sR8h{}^dS(x1U2t!%0PN6FIt~GPkq3sR( zi$Q(5zgnBwH(M{4_SL2fV}nDZcZAra5@!CsG3KCY^5X^MZNq z)lF^C>88JkgAr_n&CH?4;$gnh*QeHn|F^hv`;DrK;_#X2bfz=CObd1w6eztxEg)** zg9Zt=a4A@E14^ngv}H;fhg4_Uh!BX78jY9uV8Gzz6*SSrXJ35azwpiYqKS8ncdfr~ z?V0Jc^5S(knXmioIWz2Y_FDU_v-X<3FdHVcQsqn-YHT1nt~zg{5#vpGR=Qm!O-V|6 zrcbd348?E}>Z3ybMV;I*3UiZM5@kE30-f<>EYYx1uP*IPApQ&rRmXH(4 zVPRBknGoDlJRd%#Z?a(U+4)+9*i~8I)RY3jE6bNAH>)>P)*~9zEQaR)Y!+#e2v)nl zsy#Ng)CzEo(A6qJd6ZqM50zM(#dml)4$RF^7G!fySYxCBde2-zmBv?_ghG^OX@l_C z^1JARW!wByyB3X#;Vl3A)@jk`%8YZlk>v^1n&$mAUA3Mn2W!=KM)kS`#Y9Jg&Ki%I zbMv+#+vyJzy=DZUiorUN2uJ=^cCi!8A`J6>ukglY!R{}UQ$^)z4JQ*i*=~Zi{N1AJ zlFd(7PQQF89-naN4Z36T2Z~yY=X9M$ftPf)k1+~ZJV!?+mWk_?;O5AyPZN%b_{bnX zQ>#hJMV>3q#AHao#biww{wzVpHg-vnF+*Hob@_=Kr8%&b`2AMCZX4JEc7fesFBk>~ zzz8@9JU9#<1V_Orcmx~+jNrZio&dTHNB%6h0GZy z!P%~Ot>AI@k5eiEggbMCI3qs?%v=8)rH?tI=P8+Q=mkn|0PX-D0a%bd zEB&8YXZ#)d|3^|1z^iH|86VTK&yul!u*K8MvTfS3dbOATQewX?+iIl55ov81Bc)c` z987m-UA8aVq1xtbOSVhQ=x-*yBi&VCf0biP+=&X)mg=R&m9_Sw@DssgM`mQMSIsl7p3GvT;e3(oH7q z^X4$B`TWU7QvE6G7!9!}>6xOIps~QLYNAC<%3_|p26kt(H>VWL#j2a(>ANsB7H0c2 z&#BDE74+ z>f372wFS`~d`&I)PYWU1DK|N*yjuBO4x=aHW*K=--!}+$2vgpg(JoAld!A>^3sIRB zD|rMXOedH-Wt`nB;1YOUFc(HHUo1`+OXiW0XB4kWams5jk9-ry;6%vDTc*c8<%XJ= z@kp;d`Q(VJD+Mo(d3HF|egH+jypp%^0e!TumB%gbi9Ye>a_OM74B+wbbf;<N0;Y^SqliBT&Vvi!BA5d&gLlCP;5zsOd1X^;WUparyoHjoAF zpaXOQ+^@b1tN<&)&EOWW3akceKsQ(mdO$C*+hsqc0k96N2ZP{NFa$P$jbIb79I=}z znE`96ZKIqGYbd!#vFfPU=7igFYWl=%A-@&*FMTK^u`_ instead. + + diff --git a/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/INSTALLER b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/METADATA b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/METADATA new file mode 100644 index 0000000..78e5e36 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/METADATA @@ -0,0 +1,26 @@ +Metadata-Version: 2.0 +Name: bs4 +Version: 0.0.1 +Summary: Screen-scraping library +Home-page: https://pypi.python.org/pypi/beautifulsoup4 +Author: Leonard Richardson +Author-email: leonardr@segfault.org +License: MIT +Download-URL: http://www.crummy.com/software/BeautifulSoup/bs4/download/ +Description-Content-Type: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Topic :: Text Processing :: Markup :: XML +Classifier: Topic :: Text Processing :: Markup :: SGML +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Dist: beautifulsoup4 + +Use `beautifulsoup4 `_ instead. + + diff --git a/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/RECORD b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/RECORD new file mode 100644 index 0000000..6304b3f --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/RECORD @@ -0,0 +1,7 @@ +bs4-0.0.1.dist-info/DESCRIPTION.rst,sha256=SgkcLU0iY4GYni8ndeg5AhdmfhYxwI8P997RM-gJEto,79 +bs4-0.0.1.dist-info/METADATA,sha256=wad6HrkF5RbP3nyRW3JqiZVVY-c6gxHeJ6zpBCW7-_E,973 +bs4-0.0.1.dist-info/RECORD,, +bs4-0.0.1.dist-info/WHEEL,sha256=F38j99qfcoNzHo88G-kisXWtI3MVVEd9JWjaAPcHMTc,93 +bs4-0.0.1.dist-info/metadata.json,sha256=S6_iVboQ8j2ZDRYtEcvBwj_7fiiRYJSa2uCQYWXNT3Q,1053 +bs4-0.0.1.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +bs4-0.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 diff --git a/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/WHEEL b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/WHEEL new file mode 100644 index 0000000..1b49229 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0) +Root-Is-Purelib: true +Tag: cp27-none-any + diff --git a/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/metadata.json b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/metadata.json new file mode 100644 index 0000000..dd018d4 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Text Processing :: Markup :: HTML", "Topic :: Text Processing :: Markup :: XML", "Topic :: Text Processing :: Markup :: SGML", "Topic :: Software Development :: Libraries :: Python Modules"], "description_content_type": "UNKNOWN", "download_url": "http://www.crummy.com/software/BeautifulSoup/bs4/download/", "extensions": {"python.details": {"contacts": [{"email": "leonardr@segfault.org", "name": "Leonard Richardson", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://pypi.python.org/pypi/beautifulsoup4"}}}, "extras": [], "generator": "bdist_wheel (0.30.0)", "license": "MIT", "metadata_version": "2.0", "name": "bs4", "run_requires": [{"requires": ["beautifulsoup4"]}], "summary": "Screen-scraping library", "version": "0.0.1"} \ No newline at end of file diff --git a/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/top_level.txt b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/top_level.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4-0.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ + diff --git a/venv/lib/python2.7/site-packages/bs4/__init__.py b/venv/lib/python2.7/site-packages/bs4/__init__.py new file mode 100644 index 0000000..7a80452 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/__init__.py @@ -0,0 +1,529 @@ +"""Beautiful Soup +Elixir and Tonic +"The Screen-Scraper's Friend" +http://www.crummy.com/software/BeautifulSoup/ + +Beautiful Soup uses a pluggable XML or HTML parser to parse a +(possibly invalid) document into a tree representation. Beautiful Soup +provides methods and Pythonic idioms that make it easy to navigate, +search, and modify the parse tree. + +Beautiful Soup works with Python 2.7 and up. It works better if lxml +and/or html5lib is installed. + +For more than you ever wanted to know about Beautiful Soup, see the +documentation: +http://www.crummy.com/software/BeautifulSoup/bs4/doc/ + +""" + +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +__author__ = "Leonard Richardson (leonardr@segfault.org)" +__version__ = "4.6.0" +__copyright__ = "Copyright (c) 2004-2017 Leonard Richardson" +__license__ = "MIT" + +__all__ = ['BeautifulSoup'] + +import os +import re +import traceback +import warnings + +from .builder import builder_registry, ParserRejectedMarkup +from .dammit import UnicodeDammit +from .element import ( + CData, + Comment, + DEFAULT_OUTPUT_ENCODING, + Declaration, + Doctype, + NavigableString, + PageElement, + ProcessingInstruction, + ResultSet, + SoupStrainer, + Tag, + ) + +# The very first thing we do is give a useful error if someone is +# running this code under Python 3 without converting it. +'You are trying to run the Python 2 version of Beautiful Soup under Python 3. This will not work.'<>'You need to convert the code, either by installing it (`python setup.py install`) or by running 2to3 (`2to3 -w bs4`).' + +class BeautifulSoup(Tag): + """ + This class defines the basic interface called by the tree builders. + + These methods will be called by the parser: + reset() + feed(markup) + + The tree builder may call these methods from its feed() implementation: + handle_starttag(name, attrs) # See note about return value + handle_endtag(name) + handle_data(data) # Appends to the current data node + endData(containerClass=NavigableString) # Ends the current data node + + No matter how complicated the underlying parser is, you should be + able to build a tree using 'start tag' events, 'end tag' events, + 'data' events, and "done with data" events. + + If you encounter an empty-element tag (aka a self-closing tag, + like HTML's
    tag), call handle_starttag and then + handle_endtag. + """ + ROOT_TAG_NAME = u'[document]' + + # If the end-user gives no indication which tree builder they + # want, look for one with these features. + DEFAULT_BUILDER_FEATURES = ['html', 'fast'] + + ASCII_SPACES = '\x20\x0a\x09\x0c\x0d' + + NO_PARSER_SPECIFIED_WARNING = "No parser was explicitly specified, so I'm using the best available %(markup_type)s parser for this system (\"%(parser)s\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n\nThe code that caused this warning is on line %(line_number)s of the file %(filename)s. To get rid of this warning, change code that looks like this:\n\n BeautifulSoup(YOUR_MARKUP})\n\nto this:\n\n BeautifulSoup(YOUR_MARKUP, \"%(parser)s\")\n" + + def __init__(self, markup="", features=None, builder=None, + parse_only=None, from_encoding=None, exclude_encodings=None, + **kwargs): + """The Soup object is initialized as the 'root tag', and the + provided markup (which can be a string or a file-like object) + is fed into the underlying parser.""" + + if 'convertEntities' in kwargs: + warnings.warn( + "BS4 does not respect the convertEntities argument to the " + "BeautifulSoup constructor. Entities are always converted " + "to Unicode characters.") + + if 'markupMassage' in kwargs: + del kwargs['markupMassage'] + warnings.warn( + "BS4 does not respect the markupMassage argument to the " + "BeautifulSoup constructor. The tree builder is responsible " + "for any necessary markup massage.") + + if 'smartQuotesTo' in kwargs: + del kwargs['smartQuotesTo'] + warnings.warn( + "BS4 does not respect the smartQuotesTo argument to the " + "BeautifulSoup constructor. Smart quotes are always converted " + "to Unicode characters.") + + if 'selfClosingTags' in kwargs: + del kwargs['selfClosingTags'] + warnings.warn( + "BS4 does not respect the selfClosingTags argument to the " + "BeautifulSoup constructor. The tree builder is responsible " + "for understanding self-closing tags.") + + if 'isHTML' in kwargs: + del kwargs['isHTML'] + warnings.warn( + "BS4 does not respect the isHTML argument to the " + "BeautifulSoup constructor. Suggest you use " + "features='lxml' for HTML and features='lxml-xml' for " + "XML.") + + def deprecated_argument(old_name, new_name): + if old_name in kwargs: + warnings.warn( + 'The "%s" argument to the BeautifulSoup constructor ' + 'has been renamed to "%s."' % (old_name, new_name)) + value = kwargs[old_name] + del kwargs[old_name] + return value + return None + + parse_only = parse_only or deprecated_argument( + "parseOnlyThese", "parse_only") + + from_encoding = from_encoding or deprecated_argument( + "fromEncoding", "from_encoding") + + if from_encoding and isinstance(markup, unicode): + warnings.warn("You provided Unicode markup but also provided a value for from_encoding. Your from_encoding will be ignored.") + from_encoding = None + + if len(kwargs) > 0: + arg = kwargs.keys().pop() + raise TypeError( + "__init__() got an unexpected keyword argument '%s'" % arg) + + if builder is None: + original_features = features + if isinstance(features, basestring): + features = [features] + if features is None or len(features) == 0: + features = self.DEFAULT_BUILDER_FEATURES + builder_class = builder_registry.lookup(*features) + if builder_class is None: + raise FeatureNotFound( + "Couldn't find a tree builder with the features you " + "requested: %s. Do you need to install a parser library?" + % ",".join(features)) + builder = builder_class() + if not (original_features == builder.NAME or + original_features in builder.ALTERNATE_NAMES): + if builder.is_xml: + markup_type = "XML" + else: + markup_type = "HTML" + + caller = traceback.extract_stack()[0] + filename = caller[0] + line_number = caller[1] + warnings.warn(self.NO_PARSER_SPECIFIED_WARNING % dict( + filename=filename, + line_number=line_number, + parser=builder.NAME, + markup_type=markup_type)) + + self.builder = builder + self.is_xml = builder.is_xml + self.known_xml = self.is_xml + self.builder.soup = self + + self.parse_only = parse_only + + if hasattr(markup, 'read'): # It's a file-type object. + markup = markup.read() + elif len(markup) <= 256 and ( + (isinstance(markup, bytes) and not b'<' in markup) + or (isinstance(markup, unicode) and not u'<' in markup) + ): + # Print out warnings for a couple beginner problems + # involving passing non-markup to Beautiful Soup. + # Beautiful Soup will still parse the input as markup, + # just in case that's what the user really wants. + if (isinstance(markup, unicode) + and not os.path.supports_unicode_filenames): + possible_filename = markup.encode("utf8") + else: + possible_filename = markup + is_file = False + try: + is_file = os.path.exists(possible_filename) + except Exception, e: + # This is almost certainly a problem involving + # characters not valid in filenames on this + # system. Just let it go. + pass + if is_file: + if isinstance(markup, unicode): + markup = markup.encode("utf8") + warnings.warn( + '"%s" looks like a filename, not markup. You should' + ' probably open this file and pass the filehandle into' + ' Beautiful Soup.' % markup) + self._check_markup_is_url(markup) + + for (self.markup, self.original_encoding, self.declared_html_encoding, + self.contains_replacement_characters) in ( + self.builder.prepare_markup( + markup, from_encoding, exclude_encodings=exclude_encodings)): + self.reset() + try: + self._feed() + break + except ParserRejectedMarkup: + pass + + # Clear out the markup and remove the builder's circular + # reference to this object. + self.markup = None + self.builder.soup = None + + def __copy__(self): + copy = type(self)( + self.encode('utf-8'), builder=self.builder, from_encoding='utf-8' + ) + + # Although we encoded the tree to UTF-8, that may not have + # been the encoding of the original markup. Set the copy's + # .original_encoding to reflect the original object's + # .original_encoding. + copy.original_encoding = self.original_encoding + return copy + + def __getstate__(self): + # Frequently a tree builder can't be pickled. + d = dict(self.__dict__) + if 'builder' in d and not self.builder.picklable: + d['builder'] = None + return d + + @staticmethod + def _check_markup_is_url(markup): + """ + Check if markup looks like it's actually a url and raise a warning + if so. Markup can be unicode or str (py2) / bytes (py3). + """ + if isinstance(markup, bytes): + space = b' ' + cant_start_with = (b"http:", b"https:") + elif isinstance(markup, unicode): + space = u' ' + cant_start_with = (u"http:", u"https:") + else: + return + + if any(markup.startswith(prefix) for prefix in cant_start_with): + if not space in markup: + if isinstance(markup, bytes): + decoded_markup = markup.decode('utf-8', 'replace') + else: + decoded_markup = markup + warnings.warn( + '"%s" looks like a URL. Beautiful Soup is not an' + ' HTTP client. You should probably use an HTTP client like' + ' requests to get the document behind the URL, and feed' + ' that document to Beautiful Soup.' % decoded_markup + ) + + def _feed(self): + # Convert the document to Unicode. + self.builder.reset() + + self.builder.feed(self.markup) + # Close out any unfinished strings and close all the open tags. + self.endData() + while self.currentTag.name != self.ROOT_TAG_NAME: + self.popTag() + + def reset(self): + Tag.__init__(self, self, self.builder, self.ROOT_TAG_NAME) + self.hidden = 1 + self.builder.reset() + self.current_data = [] + self.currentTag = None + self.tagStack = [] + self.preserve_whitespace_tag_stack = [] + self.pushTag(self) + + def new_tag(self, name, namespace=None, nsprefix=None, **attrs): + """Create a new tag associated with this soup.""" + return Tag(None, self.builder, name, namespace, nsprefix, attrs) + + def new_string(self, s, subclass=NavigableString): + """Create a new NavigableString associated with this soup.""" + return subclass(s) + + def insert_before(self, successor): + raise NotImplementedError("BeautifulSoup objects don't support insert_before().") + + def insert_after(self, successor): + raise NotImplementedError("BeautifulSoup objects don't support insert_after().") + + def popTag(self): + tag = self.tagStack.pop() + if self.preserve_whitespace_tag_stack and tag == self.preserve_whitespace_tag_stack[-1]: + self.preserve_whitespace_tag_stack.pop() + #print "Pop", tag.name + if self.tagStack: + self.currentTag = self.tagStack[-1] + return self.currentTag + + def pushTag(self, tag): + #print "Push", tag.name + if self.currentTag: + self.currentTag.contents.append(tag) + self.tagStack.append(tag) + self.currentTag = self.tagStack[-1] + if tag.name in self.builder.preserve_whitespace_tags: + self.preserve_whitespace_tag_stack.append(tag) + + def endData(self, containerClass=NavigableString): + if self.current_data: + current_data = u''.join(self.current_data) + # If whitespace is not preserved, and this string contains + # nothing but ASCII spaces, replace it with a single space + # or newline. + if not self.preserve_whitespace_tag_stack: + strippable = True + for i in current_data: + if i not in self.ASCII_SPACES: + strippable = False + break + if strippable: + if '\n' in current_data: + current_data = '\n' + else: + current_data = ' ' + + # Reset the data collector. + self.current_data = [] + + # Should we add this string to the tree at all? + if self.parse_only and len(self.tagStack) <= 1 and \ + (not self.parse_only.text or \ + not self.parse_only.search(current_data)): + return + + o = containerClass(current_data) + self.object_was_parsed(o) + + def object_was_parsed(self, o, parent=None, most_recent_element=None): + """Add an object to the parse tree.""" + parent = parent or self.currentTag + previous_element = most_recent_element or self._most_recent_element + + next_element = previous_sibling = next_sibling = None + if isinstance(o, Tag): + next_element = o.next_element + next_sibling = o.next_sibling + previous_sibling = o.previous_sibling + if not previous_element: + previous_element = o.previous_element + + o.setup(parent, previous_element, next_element, previous_sibling, next_sibling) + + self._most_recent_element = o + parent.contents.append(o) + + if parent.next_sibling: + # This node is being inserted into an element that has + # already been parsed. Deal with any dangling references. + index = len(parent.contents)-1 + while index >= 0: + if parent.contents[index] is o: + break + index -= 1 + else: + raise ValueError( + "Error building tree: supposedly %r was inserted " + "into %r after the fact, but I don't see it!" % ( + o, parent + ) + ) + if index == 0: + previous_element = parent + previous_sibling = None + else: + previous_element = previous_sibling = parent.contents[index-1] + if index == len(parent.contents)-1: + next_element = parent.next_sibling + next_sibling = None + else: + next_element = next_sibling = parent.contents[index+1] + + o.previous_element = previous_element + if previous_element: + previous_element.next_element = o + o.next_element = next_element + if next_element: + next_element.previous_element = o + o.next_sibling = next_sibling + if next_sibling: + next_sibling.previous_sibling = o + o.previous_sibling = previous_sibling + if previous_sibling: + previous_sibling.next_sibling = o + + def _popToTag(self, name, nsprefix=None, inclusivePop=True): + """Pops the tag stack up to and including the most recent + instance of the given tag. If inclusivePop is false, pops the tag + stack up to but *not* including the most recent instqance of + the given tag.""" + #print "Popping to %s" % name + if name == self.ROOT_TAG_NAME: + # The BeautifulSoup object itself can never be popped. + return + + most_recently_popped = None + + stack_size = len(self.tagStack) + for i in range(stack_size - 1, 0, -1): + t = self.tagStack[i] + if (name == t.name and nsprefix == t.prefix): + if inclusivePop: + most_recently_popped = self.popTag() + break + most_recently_popped = self.popTag() + + return most_recently_popped + + def handle_starttag(self, name, namespace, nsprefix, attrs): + """Push a start tag on to the stack. + + If this method returns None, the tag was rejected by the + SoupStrainer. You should proceed as if the tag had not occurred + in the document. For instance, if this was a self-closing tag, + don't call handle_endtag. + """ + + # print "Start tag %s: %s" % (name, attrs) + self.endData() + + if (self.parse_only and len(self.tagStack) <= 1 + and (self.parse_only.text + or not self.parse_only.search_tag(name, attrs))): + return None + + tag = Tag(self, self.builder, name, namespace, nsprefix, attrs, + self.currentTag, self._most_recent_element) + if tag is None: + return tag + if self._most_recent_element: + self._most_recent_element.next_element = tag + self._most_recent_element = tag + self.pushTag(tag) + return tag + + def handle_endtag(self, name, nsprefix=None): + #print "End tag: " + name + self.endData() + self._popToTag(name, nsprefix) + + def handle_data(self, data): + self.current_data.append(data) + + def decode(self, pretty_print=False, + eventual_encoding=DEFAULT_OUTPUT_ENCODING, + formatter="minimal"): + """Returns a string or Unicode representation of this document. + To get Unicode, pass None for encoding.""" + + if self.is_xml: + # Print the XML declaration + encoding_part = '' + if eventual_encoding != None: + encoding_part = ' encoding="%s"' % eventual_encoding + prefix = u'\n' % encoding_part + else: + prefix = u'' + if not pretty_print: + indent_level = None + else: + indent_level = 0 + return prefix + super(BeautifulSoup, self).decode( + indent_level, eventual_encoding, formatter) + +# Alias to make it easier to type import: 'from bs4 import _soup' +_s = BeautifulSoup +_soup = BeautifulSoup + +class BeautifulStoneSoup(BeautifulSoup): + """Deprecated interface to an XML parser.""" + + def __init__(self, *args, **kwargs): + kwargs['features'] = 'xml' + warnings.warn( + 'The BeautifulStoneSoup class is deprecated. Instead of using ' + 'it, pass features="xml" into the BeautifulSoup constructor.') + super(BeautifulStoneSoup, self).__init__(*args, **kwargs) + + +class StopParsing(Exception): + pass + +class FeatureNotFound(ValueError): + pass + + +#By default, act as an HTML pretty-printer. +if __name__ == '__main__': + import sys + soup = BeautifulSoup(sys.stdin) + print soup.prettify() diff --git a/venv/lib/python2.7/site-packages/bs4/__init__.pyc b/venv/lib/python2.7/site-packages/bs4/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe2b56054ff817d9711f065dc62599df21b03d86 GIT binary patch literal 18390 zcmdU1TWlQHc|NndyzGh+DN3S5OP0p8WiB0RDcSN(m8{SdWy_H$W=L5HQ)fKfnI(tZ z-C50<70H+ikXT8aGzie<(hE?aC|WcwP_#vX0tpJF2#NrG>_cCQq5=Gnr?xLeAKC&< zzwbXYyQJ*6(TmtpoWnEc{BzEk|NQs!kMjSvzjXhLeM?o9{^arZlel!tQp#6q38kf$ zEam6aQcn4KwUk$WK`j-O-=kL0)ua4g<@c$2uUbOI)ce#@Usmr|OZ{2BsFsS#$8Ay7 zORBL?E$vf{0kt%sEVhp2zItrQU{OdWTUJbl<64u&v zdm(DKO0)HFGmLGo>D!A@Gpv@z7FPp%p&AE4^9=rYtsoxP_SHBHn*La6HAz|*rlvMF zHY(M)-Dqr8s!?M~N3~?bi-W1o;2e9ZRO;NzWOiEz+V<>Ly}h#HE!PA4GdHf=QEb1y zh`%i_)XM5i}FD0MN4&tkaHzRvc)wdPx{H zEB5YLORYG%8~T{J5hSaTj}_o$=eJPD``V!&Mh$Hzt6pL^y!F5i6Fczq78la=?uIK~ z5=@qK;KkL|NqMvp`C$$Hz>}<57E$@o%Wg#Ry0$mMWHp`4ezx+W4A5>>>}!c_0G5L! z!E1*#yS~||m$0@eU}QCE)Ss`1%XX;osygxN^}xp*SJBsq;(+UI+FMcE4({UV4X>F5 zK9{`Sj5cg~eL&e)jCy^Jkttd+tU1 z!viLHJb2^UVzM89J3CAI3V)8Dxe(Gsl|k4l8A7q#4(ompyK%4*>LlJu4x@2iNXrS< zf-2B-!;9D3tumjJL2rQ!B0sp|H5y@3-p6JxcIJu)g6d-}YLMoVqo`k*y*hpC`l5UD z*5drFMR#^?=H``abFU?Q>`G9rd$FKZp1TrNldV>e45DvNNC`B*ki=ngMd0VXm0-3W z$k;~!GapCQ02JR`xrQx|+f|ZtQbdmvXdrR{q%wdzzC4EU!e$T)dKSGE{Wdy23wi(> zf*`jr2+1LCH-%6Qx!cd$pcai$?Wpzuec0_L@RpJ4a}|4W6|}bz*6VgNGQ?WZ?R1i6 zV5qGcH8Ef!QxJ!fb^vxU|&>x~mR-jR!MW9QdLV7agaa{R3 zfBV#Z=oP4jehOGBkD^pcD%eMTK^cxQA>a2&`+fykPsjt=IQ!LoOa!4mBr+es2PxwT zGn~qJC=}hPbp`ie1gas1=Eyl{KzJPDz&!#paz1Wqzmk2PgC?kXv8(I8rW5l zFWd$8icn1%NkizEfgoW!5>&`y`N8Lm1iv8gHl#APx;&BI)j%=jhH&0QXT)7ILHcgV zLb!$+M7bl6gQf_(;P@|V5v7WG>v=<=z zK*m8T8ek_FC1z>jE(RS0+}-BvxULN!6?<00YQx-fmJ zMngR*>OrqY?YeI-n-z)D#hPVvGxgb~#IeT(bv9mpoI0hMV1RL~e^-kvWt?x>1)??` z^P^^9bR9d#(h*YHxmGips#%TNBsnNSJ7~0$tuukyNzP%Hy>$;u(m}m;rdp3=QD~o( zIqM-bGtC6pA{UqASNO!lq#>6Fwq8^$kkXU~cWrA$n%X6>$mcRG_*PQDE%mKbYMxF+ zSJ|cFz<#|CiUp`ok-Fh&JJ=-V!vt1|ZUxn_76v|aYh+&=Z@|D2xl0ZUbYgpVy|6Ag zKb_LPONB6@vjJ-meF^2P-qK0Xu*+ko%Vw?#JvNcb;I?jqJs~i4a~xyZuxFr08k5*X z*g*!jM$Tg(N?{xF-2=5#5SxJ~DPu#l+Av*efzayRFitSA9W+skn$$v*l+ZoE>bx0ulbeVtLX1lQ*#1m+* z2@Tgm7=)+G{6prQ(0KjGUI`LA4t)dE9S>WNon6^EYdwl!ZwaAr<_nNAyUd01XK&te z+#A!*r*6&PgA5YZ{a@fF?OhvENAN*#0v7j-@_eF-E4{qvqu>%A&Ip#Zifehn0e zMGHKi^<8EKx0h0o0(Fdl^kg8*0@Bj~>Ft2@WguS>kiHH`e+Q(PfqY*;iXD(r2J$r} zUd2B3Ri*CrtL=hn{jJ)D8Wcz7-JH5tP}@DK^-t0WT{o!M*u%znz)Esz+fuMP(8yc! zrb9Bi|0Ln?zObM0ns_tlzV(8NXDr;V;YCpPvAkDQ38oxY+eI}3xG!6LY#aLfNwwY& z?Jgatkw>31mIxw-hQ=>saV5As2xRZFr^c&^{`5gP_b_V;iGDMkSg6w3X5QS z0OJ(6GV4w~XAp&l+z|mes92X03t{~zOZ={lC>KLwKhZd<5)6qgIU&gW>m2H9$K@4) z{Quydp@lenT&-Iw{y{$7Y6Jf-IsYU9*87z1&$VD6q*^6%y=MNyUx4b#EBlVyVw; z1Lg1UUdDHK4=)szlIIhgNAO4F0WnXpf%wGz=4y&7xX)+>nfsU@#G13Ny!9#ds|I~f z3lhhrEK4~dk3B;ST3ds1^9i|`zkTQL^Mzzm)_kg9Sr+a;gX=cvj$83G39z$2s4tYC zq8RyO6qKa2@9k)r-iq=6!X$+I`vu5UC?JS+dpwR{lT%k4mlSQH+Gq)-?ye6(PCv&k zZ>+*QgQ{#ocH2;};($;gcs7OY84;Ogy3FLUId2W~iJQ$CKV)H4#H~pkfZ1k(HNtlR zpQ~3F&cjcKrAfa5Rv@%w<{^l;kO9M0SuxIhYDMi5*U%@a6BNZ2m`7#;ac{i(hPOpk zC&N+GM0V=LQ7yzCyu4Uf#JMv_xB;sR&X)f6$1QIc=))|Id$!YNCi3{+cmYH&0-IXi zYi`-ifbN|aZ)IE4Fv~J4)tEo|bQ?yhUX1iNK5nJEKp$qM3!KBgBa=K7D(S+~GMh1m z*&-ZH{aYWq#NEITv&dftokEVVSerf#t_N*K?0qj57iwCJ`a2)DP6P8W%UeM3ipCv- zFSL_tfd^+I(3i#;z!{g_mVg$mrQMxpIsgcKRjLeH!6L;bEtYd%`T}DmmRTNXL zIJ^s&X6mjNPt`CCn0TsoeromH3-S4Lch}CZKlj49)#c{PFPvSet*&jH#m`D}YH_L+ zw$6x0bLP1%?~T{4Of6?IP7O(Veu_aW*A1It;<|`DB*eAPn4vgOZYGAl#Dy@1q^tp} z*UDQ5tdiAd6|Cd{+QbCD*{p8?vv6$bLr9Ywp-sXvbW~^I#7dX98C5H~>oZV@MO%>+c2QMm9!9NcMx zHv<2H4Z^XnMADi?i_(Y?hD!Yj1UO@e!^;U{ag!3t0%HhGk%J_(CuEd41rj#f;XMeO zo57^Zpi-PH86^%pKU5f9X1LhqJQt;>ozz~^8@LrF+2K1FrD(zjRA6RE!ML3|({#Y# z)os}kf&j+N5$A;r-(sjm@B-CpoKK@fJIYPednGxDxr5DWz3m5G8ksAfL9=s=#V86P zvk*=tMO`(JsAAiME1k#KPtJtDB(H>>)Y8z3S`sx}gs(Xp$5AZ9Am)Ruk>Df8&jOjR z-nw@E%B|O?Q6US-@Hr=4WTFUA;DY z#l1c4%rU&mdHk@N2nN#7lnlyvcT=Vy2>IQ40u_OSKw|*N`2-s%fR?wQTw&HK6&VrM z@{(1U#dxsYY5`B$O|k1{6sP4agoy(g<0^PGFpZmtFl$-G>}EA+NwoGb26L;cL3Q0t zi7~{WaoxxeoKzq_oA$^c21uwOLO?uhdi4%DBs{e7C8!+uE<+UEu2bkrqe>dV?p7VR zr3;U_GXqGLD^WP9xs0DVB$zS7=V8Gn7=)PrJ^;E<8{Q^ZxwUH)-d$SP>xRzLd%@Q#lLwgpBu4? zs1Kqn=6Z8O&^;wU_u^mCI><5jFIUVFX4pDz9q%2)n8P_jVE0PIS$URA#~EfRX+n) zFnF&3_xO$9Ct@)+0u!k3n&+ErU&8=6+d=#b5v4q14roLLG7%9eob4dYVnQqLGprbVgf^z_xc-3}J$xG*p?1(t0+ey~Ln#Kqq0;ECkva3!~_$V&5?S zdFq&_iidtVw6tArZ9O|-PvJ-gDvNi|O_=C4U3?LXwlJL>$ZIk)Yx;tiICh)FC0*@q z*PLt(8IRlY94<|v4jzB&FcD5<37G<|Z(4T{jH63IYMV1gJ8fQUJJcktKXc~F;VNfE zyu+Zbg_}lBQ>T=1Jz8GYJS)Ap641JhUm3#EwGnk)`6SvU)tCB50ROQ4cgwl{U=9I2 zdK!Z;onK#EoVTlWq(dYhZ4^rEd>5PvN~gB5oEb5yO(QWogkV&iMmF0py$R}2U!w(i z2^}y5I$q6u8)HYxE_@^}PQvCuFu!YtiYPaB0trjE zU~HK15AqJonVU`-j?^iU9C7XcLan)wjU&6|tv;`D1`a2qC!T7WVL zr+PK`N9ECSqC@OGPSjIqsNDYCp=OZL*0AfYis~rncI8_5Z~F zkm$y_KPKRD0*nCzHT_pDpqD$uC4UN+K7j)0F`L2t!LFc$4G8k@O${4OM{5Q?H_zD- z?c9)aT{y&1HI$?3G-v=}N=L0SCqW~#3v|ME*hM5=M{`p03F+Mk9iqIcjiwQ=Mo#$m zh{#2kFv5jBK1W=VzErN7N6D)rO2`95msl)DrRo>awhLDeBn2SU|BLWuUY9c%3!40- zg&K8xS$wX&LI_`!2r+Sn=XcpV z>xio$VK8x*0|eNE@UhZJa zlF0Bci>>D#4qILgha(xXoG;_yE@qr}d5dcgY&Qv^rU;QWUfh8XQaJHJniuM!(58GB z#er4BeB~|NhhGudBy~uuQRd2`N$yiUPG1c7O2xO+3IWjsmp1LoXRey$7#j0u6H_`w zwzI{88la0gF`pm?_6T_n6Z0+;VN_QNHqHt7|3&N2N08Dw0Mhrzv8^Bih%qvqHcbZw z-6lf89Z0c+#{q8?ve-NHd{<wA*j+D7G&oBVCtcBzkY!8Gah$F9BNGQQAwhfVyf+}G53io=|y*`p0_7s?97-n6#93&=r zAqbTKfPCMl01T^78-RWeb7x%yCwhyVkQpa<3Sda~>4BGIOn5OFk(EP25le{qJQz6s zz`~ZZE=fw@iDO7i+I&qCkU-4HJNoCe8+l5jc$O(bKUMRTRLCN-)JuTB^H=INg3q9J zPM6CLOJP|M2E*W;PI5-`+IWfPk?yFRbhLmjzFfb0a6NqZ^XYPd5C*9F9(?{No(H;s zCA>c3qmo+{e@ouJpj=6eB3jUe5-;_>boCIDZzAZ0M}tcIH`3LoT+D(lG~y`$2(tKo zz4U$Vd?1-)1t=?V%WZ7@w2z}Yq<5R_ku;Lrs} z6;+;6q=}!#nUY8ZeKFyD1aCV1-3De-@LZKbLVSZ$9pU& zK7`xfWah823&}Df9-QA`FS&<@G|2a-CHYZ{W@OO$4vX)x_$~^W4H2ARbFU=Ex3G$c z62n17@suEU0Mf#^bU1CujY2KKCdeN`DAjeaOp*+tbia4JbC2Z~pphUVnP>OV+ z{x0AW>GHd%kQ7C>M0aK&bmVg*DGMmz=<1p~dChgy46_)P#o z(xXPifC1p;bHuNcL3!Jo-9pKIMMgGhgaxvP$N`LzHQl)kZP;Oof5bB9qn0_8g@uOb zDh?cNBu0Tbcw!qic?c`ikLVls8wn63(r&yqJ$}tHRaZjfN7J{(XFN6Yyhamdk+dlu z5Kh`Sgze1P8ENO-%-($lLB(f&@e0tRlRG^5#nhca7$od2!NfC!qjwlt@T`uD~`3pN5pO{b6X7uh~^(_}~*b4kqc>ZROU&L_aK;HC|4y~$n=y0LfAh<#ZdLT zP`#|dB%0er(jao$Npk`x#;|@PtBZ&S{XvNi00I=hU`#BI1f?L_$wW@r0*#3hnh%;( z^a6Di^xJ!6mj%-o|DGsRfphnXN&qNCstIyIc^bouPe@EfGxRo(Sd;CM-uZiH5+kE#+{^E=}pM}22pykhf%H*x`)0O{%JI=K|Q*++gV!1pn60-iTx zD)}%3(Ns*_Jwg#ZI9HY+DvhlN%uDB+XfvcOU;Z(~WB5s8hSPk49-#AW7NQI219WXo z!(;ET7aOIVdn~?65L|oVUUS_kE`%cRLO&vJoZxy&r5ul(5#soXj ztUTamaAk)^bXhw5VW=7;Zvw3t7>7pm*d0Oc@1tgdeVxFbpk=R+!EN6~82><2P_-$9 zsXrWkq5VQu#4p&_7_Z{u?08Y}X5Ir}*C!Pxg+b%Jde41WPWql)#!vZ{+!bX>?6QHJ zxQ163-Of-iMWJkQ3l;OeJjE7`4o&Ps4MPE!DbsK}0zD7)ON+aJ8yL6<$HOuf0SI{r za9Y`Dgjoy|wud5=J_ZN}#y;!;G-4ze33+vNK~AM4OU_Bfj|bVsd?lWVX3289zxC~W z7LuKibs2ood^?gp2Yt-MEDAJ9r^~YPD$X!oRnt<%hcG60?-Gv$+te8sFC%v;`(*Oc z*tyDCbX|U>BtEUE+&OcMe-XeU9*ou5#z)f*NyDk5Fvo2qd@*NXy(S5?C*CX(k5#_5 z!r^f@xreFb*l+EZ zgEig_TXSU_U1^>JgZZv2veku8;J5MFo-5?&y4XgfK#1}30-kVwjm2daay}qOH6CvR z6oLWBvLvh;y(Q;;a`GfcH_jIcSz_@e7WY|vg$4IdVm3xP(R6mc!Gdzi`2!Yz$l{M! zyupIpVKx($y^`TVQZHhDP2}_*LFP|k047Z@Z1&;r6$gragC~lmVrj52P$(icP{hx` z$-$Qgj~0&)^c3^3_bq&uvNO1zfFY>6t7w%UQthj_^idSR^3LyTfk1p>i*HORLL@SA zrISSqC7pdtDt5Je+An@*T&Z%@~ZqX%V#Kw*cBVkzLk zISICcGo3d%7NbFnFo|Ey4#pRo_J2Eh}>$?QQ{S+0FuIaqb+F!6BsdhDg4=(}HUAllKW8DUM`h0_ojCk2E|nV&I?qXZFLt&yk8k;*6Fy9^{eUzC3kpR& z)x(`P>tbDMk2VwGFZmi^8IWOV<|Jf^W$;Iv~q|&^B&zfDgOq2@gq;ehq$H;0F zL$1>TaozNP9l$*;FV|(Zo&5I?9SD3=8{jyvqX}TTLlayDwB+l?fpdvd2&+xAMj0g8 ztP-*DGR1(?%l3M`oyCz%|=<$1MX z?CS*Lb~?Y!f>?1#VY3mBl|}3BR%XJwEhRcsN6UJ literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/bs4/builder/__init__.py b/venv/lib/python2.7/site-packages/bs4/builder/__init__.py new file mode 100644 index 0000000..fdb3362 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/builder/__init__.py @@ -0,0 +1,333 @@ +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from collections import defaultdict +import itertools +import sys +from bs4.element import ( + CharsetMetaAttributeValue, + ContentMetaAttributeValue, + HTMLAwareEntitySubstitution, + whitespace_re + ) + +__all__ = [ + 'HTMLTreeBuilder', + 'SAXTreeBuilder', + 'TreeBuilder', + 'TreeBuilderRegistry', + ] + +# Some useful features for a TreeBuilder to have. +FAST = 'fast' +PERMISSIVE = 'permissive' +STRICT = 'strict' +XML = 'xml' +HTML = 'html' +HTML_5 = 'html5' + + +class TreeBuilderRegistry(object): + + def __init__(self): + self.builders_for_feature = defaultdict(list) + self.builders = [] + + def register(self, treebuilder_class): + """Register a treebuilder based on its advertised features.""" + for feature in treebuilder_class.features: + self.builders_for_feature[feature].insert(0, treebuilder_class) + self.builders.insert(0, treebuilder_class) + + def lookup(self, *features): + if len(self.builders) == 0: + # There are no builders at all. + return None + + if len(features) == 0: + # They didn't ask for any features. Give them the most + # recently registered builder. + return self.builders[0] + + # Go down the list of features in order, and eliminate any builders + # that don't match every feature. + features = list(features) + features.reverse() + candidates = None + candidate_set = None + while len(features) > 0: + feature = features.pop() + we_have_the_feature = self.builders_for_feature.get(feature, []) + if len(we_have_the_feature) > 0: + if candidates is None: + candidates = we_have_the_feature + candidate_set = set(candidates) + else: + # Eliminate any candidates that don't have this feature. + candidate_set = candidate_set.intersection( + set(we_have_the_feature)) + + # The only valid candidates are the ones in candidate_set. + # Go through the original list of candidates and pick the first one + # that's in candidate_set. + if candidate_set is None: + return None + for candidate in candidates: + if candidate in candidate_set: + return candidate + return None + +# The BeautifulSoup class will take feature lists from developers and use them +# to look up builders in this registry. +builder_registry = TreeBuilderRegistry() + +class TreeBuilder(object): + """Turn a document into a Beautiful Soup object tree.""" + + NAME = "[Unknown tree builder]" + ALTERNATE_NAMES = [] + features = [] + + is_xml = False + picklable = False + preserve_whitespace_tags = set() + empty_element_tags = None # A tag will be considered an empty-element + # tag when and only when it has no contents. + + # A value for these tag/attribute combinations is a space- or + # comma-separated list of CDATA, rather than a single CDATA. + cdata_list_attributes = {} + + + def __init__(self): + self.soup = None + + def reset(self): + pass + + def can_be_empty_element(self, tag_name): + """Might a tag with this name be an empty-element tag? + + The final markup may or may not actually present this tag as + self-closing. + + For instance: an HTMLBuilder does not consider a

    tag to be + an empty-element tag (it's not in + HTMLBuilder.empty_element_tags). This means an empty

    tag + will be presented as "

    ", not "

    ". + + The default implementation has no opinion about which tags are + empty-element tags, so a tag will be presented as an + empty-element tag if and only if it has no contents. + "" will become "", and "bar" will + be left alone. + """ + if self.empty_element_tags is None: + return True + return tag_name in self.empty_element_tags + + def feed(self, markup): + raise NotImplementedError() + + def prepare_markup(self, markup, user_specified_encoding=None, + document_declared_encoding=None): + return markup, None, None, False + + def test_fragment_to_document(self, fragment): + """Wrap an HTML fragment to make it look like a document. + + Different parsers do this differently. For instance, lxml + introduces an empty tag, and html5lib + doesn't. Abstracting this away lets us write simple tests + which run HTML fragments through the parser and compare the + results against other HTML fragments. + + This method should not be used outside of tests. + """ + return fragment + + def set_up_substitutions(self, tag): + return False + + def _replace_cdata_list_attribute_values(self, tag_name, attrs): + """Replaces class="foo bar" with class=["foo", "bar"] + + Modifies its input in place. + """ + if not attrs: + return attrs + if self.cdata_list_attributes: + universal = self.cdata_list_attributes.get('*', []) + tag_specific = self.cdata_list_attributes.get( + tag_name.lower(), None) + for attr in attrs.keys(): + if attr in universal or (tag_specific and attr in tag_specific): + # We have a "class"-type attribute whose string + # value is a whitespace-separated list of + # values. Split it into a list. + value = attrs[attr] + if isinstance(value, basestring): + values = whitespace_re.split(value) + else: + # html5lib sometimes calls setAttributes twice + # for the same tag when rearranging the parse + # tree. On the second call the attribute value + # here is already a list. If this happens, + # leave the value alone rather than trying to + # split it again. + values = value + attrs[attr] = values + return attrs + +class SAXTreeBuilder(TreeBuilder): + """A Beautiful Soup treebuilder that listens for SAX events.""" + + def feed(self, markup): + raise NotImplementedError() + + def close(self): + pass + + def startElement(self, name, attrs): + attrs = dict((key[1], value) for key, value in list(attrs.items())) + #print "Start %s, %r" % (name, attrs) + self.soup.handle_starttag(name, attrs) + + def endElement(self, name): + #print "End %s" % name + self.soup.handle_endtag(name) + + def startElementNS(self, nsTuple, nodeName, attrs): + # Throw away (ns, nodeName) for now. + self.startElement(nodeName, attrs) + + def endElementNS(self, nsTuple, nodeName): + # Throw away (ns, nodeName) for now. + self.endElement(nodeName) + #handler.endElementNS((ns, node.nodeName), node.nodeName) + + def startPrefixMapping(self, prefix, nodeValue): + # Ignore the prefix for now. + pass + + def endPrefixMapping(self, prefix): + # Ignore the prefix for now. + # handler.endPrefixMapping(prefix) + pass + + def characters(self, content): + self.soup.handle_data(content) + + def startDocument(self): + pass + + def endDocument(self): + pass + + +class HTMLTreeBuilder(TreeBuilder): + """This TreeBuilder knows facts about HTML. + + Such as which tags are empty-element tags. + """ + + preserve_whitespace_tags = HTMLAwareEntitySubstitution.preserve_whitespace_tags + empty_element_tags = set([ + # These are from HTML5. + 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr', + + # These are from HTML4, removed in HTML5. + 'spacer', 'frame' + ]) + + # The HTML standard defines these attributes as containing a + # space-separated list of values, not a single value. That is, + # class="foo bar" means that the 'class' attribute has two values, + # 'foo' and 'bar', not the single value 'foo bar'. When we + # encounter one of these attributes, we will parse its value into + # a list of values if possible. Upon output, the list will be + # converted back into a string. + cdata_list_attributes = { + "*" : ['class', 'accesskey', 'dropzone'], + "a" : ['rel', 'rev'], + "link" : ['rel', 'rev'], + "td" : ["headers"], + "th" : ["headers"], + "td" : ["headers"], + "form" : ["accept-charset"], + "object" : ["archive"], + + # These are HTML5 specific, as are *.accesskey and *.dropzone above. + "area" : ["rel"], + "icon" : ["sizes"], + "iframe" : ["sandbox"], + "output" : ["for"], + } + + def set_up_substitutions(self, tag): + # We are only interested in tags + if tag.name != 'meta': + return False + + http_equiv = tag.get('http-equiv') + content = tag.get('content') + charset = tag.get('charset') + + # We are interested in tags that say what encoding the + # document was originally in. This means HTML 5-style + # tags that provide the "charset" attribute. It also means + # HTML 4-style tags that provide the "content" + # attribute and have "http-equiv" set to "content-type". + # + # In both cases we will replace the value of the appropriate + # attribute with a standin object that can take on any + # encoding. + meta_encoding = None + if charset is not None: + # HTML 5 style: + # + meta_encoding = charset + tag['charset'] = CharsetMetaAttributeValue(charset) + + elif (content is not None and http_equiv is not None + and http_equiv.lower() == 'content-type'): + # HTML 4 style: + # + tag['content'] = ContentMetaAttributeValue(content) + + return (meta_encoding is not None) + +def register_treebuilders_from(module): + """Copy TreeBuilders from the given module into this module.""" + # I'm fairly sure this is not the best way to do this. + this_module = sys.modules['bs4.builder'] + for name in module.__all__: + obj = getattr(module, name) + + if issubclass(obj, TreeBuilder): + setattr(this_module, name, obj) + this_module.__all__.append(name) + # Register the builder while we're at it. + this_module.builder_registry.register(obj) + +class ParserRejectedMarkup(Exception): + pass + +# Builders are registered in reverse order of priority, so that custom +# builder registrations will take precedence. In general, we want lxml +# to take precedence over html5lib, because it's faster. And we only +# want to use HTMLParser as a last result. +from . import _htmlparser +register_treebuilders_from(_htmlparser) +try: + from . import _html5lib + register_treebuilders_from(_html5lib) +except ImportError: + # They don't have html5lib installed. + pass +try: + from . import _lxml + register_treebuilders_from(_lxml) +except ImportError: + # They don't have lxml installed. + pass diff --git a/venv/lib/python2.7/site-packages/bs4/builder/__init__.pyc b/venv/lib/python2.7/site-packages/bs4/builder/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5529d99f681fa52fb25a9185b3cba80e38e76be8 GIT binary patch literal 12500 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/bs4/builder/_html5lib.py b/venv/lib/python2.7/site-packages/bs4/builder/_html5lib.py new file mode 100644 index 0000000..5f54893 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/builder/_html5lib.py @@ -0,0 +1,426 @@ +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +__all__ = [ + 'HTML5TreeBuilder', + ] + +import warnings +import re +from bs4.builder import ( + PERMISSIVE, + HTML, + HTML_5, + HTMLTreeBuilder, + ) +from bs4.element import ( + NamespacedAttribute, + whitespace_re, +) +import html5lib +from html5lib.constants import ( + namespaces, + prefixes, + ) +from bs4.element import ( + Comment, + Doctype, + NavigableString, + Tag, + ) + +try: + # Pre-0.99999999 + from html5lib.treebuilders import _base as treebuilder_base + new_html5lib = False +except ImportError, e: + # 0.99999999 and up + from html5lib.treebuilders import base as treebuilder_base + new_html5lib = True + +class HTML5TreeBuilder(HTMLTreeBuilder): + """Use html5lib to build a tree.""" + + NAME = "html5lib" + + features = [NAME, PERMISSIVE, HTML_5, HTML] + + def prepare_markup(self, markup, user_specified_encoding, + document_declared_encoding=None, exclude_encodings=None): + # Store the user-specified encoding for use later on. + self.user_specified_encoding = user_specified_encoding + + # document_declared_encoding and exclude_encodings aren't used + # ATM because the html5lib TreeBuilder doesn't use + # UnicodeDammit. + if exclude_encodings: + warnings.warn("You provided a value for exclude_encoding, but the html5lib tree builder doesn't support exclude_encoding.") + yield (markup, None, None, False) + + # These methods are defined by Beautiful Soup. + def feed(self, markup): + if self.soup.parse_only is not None: + warnings.warn("You provided a value for parse_only, but the html5lib tree builder doesn't support parse_only. The entire document will be parsed.") + parser = html5lib.HTMLParser(tree=self.create_treebuilder) + + extra_kwargs = dict() + if not isinstance(markup, unicode): + if new_html5lib: + extra_kwargs['override_encoding'] = self.user_specified_encoding + else: + extra_kwargs['encoding'] = self.user_specified_encoding + doc = parser.parse(markup, **extra_kwargs) + + # Set the character encoding detected by the tokenizer. + if isinstance(markup, unicode): + # We need to special-case this because html5lib sets + # charEncoding to UTF-8 if it gets Unicode input. + doc.original_encoding = None + else: + original_encoding = parser.tokenizer.stream.charEncoding[0] + if not isinstance(original_encoding, basestring): + # In 0.99999999 and up, the encoding is an html5lib + # Encoding object. We want to use a string for compatibility + # with other tree builders. + original_encoding = original_encoding.name + doc.original_encoding = original_encoding + + def create_treebuilder(self, namespaceHTMLElements): + self.underlying_builder = TreeBuilderForHtml5lib( + namespaceHTMLElements, self.soup) + return self.underlying_builder + + def test_fragment_to_document(self, fragment): + """See `TreeBuilder`.""" + return u'%s' % fragment + + +class TreeBuilderForHtml5lib(treebuilder_base.TreeBuilder): + + def __init__(self, namespaceHTMLElements, soup=None): + if soup: + self.soup = soup + else: + from bs4 import BeautifulSoup + self.soup = BeautifulSoup("", "html.parser") + super(TreeBuilderForHtml5lib, self).__init__(namespaceHTMLElements) + + def documentClass(self): + self.soup.reset() + return Element(self.soup, self.soup, None) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + doctype = Doctype.for_name_and_ids(name, publicId, systemId) + self.soup.object_was_parsed(doctype) + + def elementClass(self, name, namespace): + tag = self.soup.new_tag(name, namespace) + return Element(tag, self.soup, namespace) + + def commentClass(self, data): + return TextNode(Comment(data), self.soup) + + def fragmentClass(self): + from bs4 import BeautifulSoup + self.soup = BeautifulSoup("", "html.parser") + self.soup.name = "[document_fragment]" + return Element(self.soup, self.soup, None) + + def appendChild(self, node): + # XXX This code is not covered by the BS4 tests. + self.soup.append(node.element) + + def getDocument(self): + return self.soup + + def getFragment(self): + return treebuilder_base.TreeBuilder.getFragment(self).element + + def testSerializer(self, element): + from bs4 import BeautifulSoup + rv = [] + doctype_re = re.compile(r'^(.*?)(?: PUBLIC "(.*?)"(?: "(.*?)")?| SYSTEM "(.*?)")?$') + + def serializeElement(element, indent=0): + if isinstance(element, BeautifulSoup): + pass + if isinstance(element, Doctype): + m = doctype_re.match(element) + if m: + name = m.group(1) + if m.lastindex > 1: + publicId = m.group(2) or "" + systemId = m.group(3) or m.group(4) or "" + rv.append("""|%s""" % + (' ' * indent, name, publicId, systemId)) + else: + rv.append("|%s" % (' ' * indent, name)) + else: + rv.append("|%s" % (' ' * indent,)) + elif isinstance(element, Comment): + rv.append("|%s" % (' ' * indent, element)) + elif isinstance(element, NavigableString): + rv.append("|%s\"%s\"" % (' ' * indent, element)) + else: + if element.namespace: + name = "%s %s" % (prefixes[element.namespace], + element.name) + else: + name = element.name + rv.append("|%s<%s>" % (' ' * indent, name)) + if element.attrs: + attributes = [] + for name, value in element.attrs.items(): + if isinstance(name, NamespacedAttribute): + name = "%s %s" % (prefixes[name.namespace], name.name) + if isinstance(value, list): + value = " ".join(value) + 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.children: + serializeElement(child, indent) + serializeElement(element, 0) + + return "\n".join(rv) + +class AttrList(object): + def __init__(self, element): + self.element = element + self.attrs = dict(self.element.attrs) + def __iter__(self): + return list(self.attrs.items()).__iter__() + def __setitem__(self, name, value): + # If this attribute is a multi-valued attribute for this element, + # turn its value into a list. + list_attr = HTML5TreeBuilder.cdata_list_attributes + if (name in list_attr['*'] + or (self.element.name in list_attr + and name in list_attr[self.element.name])): + # A node that is being cloned may have already undergone + # this procedure. + if not isinstance(value, list): + value = whitespace_re.split(value) + self.element[name] = value + def items(self): + return list(self.attrs.items()) + def keys(self): + return list(self.attrs.keys()) + def __len__(self): + return len(self.attrs) + def __getitem__(self, name): + return self.attrs[name] + def __contains__(self, name): + return name in list(self.attrs.keys()) + + +class Element(treebuilder_base.Node): + def __init__(self, element, soup, namespace): + treebuilder_base.Node.__init__(self, element.name) + self.element = element + self.soup = soup + self.namespace = namespace + + def appendChild(self, node): + string_child = child = None + if isinstance(node, basestring): + # Some other piece of code decided to pass in a string + # instead of creating a TextElement object to contain the + # string. + string_child = child = node + elif isinstance(node, Tag): + # Some other piece of code decided to pass in a Tag + # instead of creating an Element object to contain the + # Tag. + child = node + elif node.element.__class__ == NavigableString: + string_child = child = node.element + node.parent = self + else: + child = node.element + node.parent = self + + if not isinstance(child, basestring) and child.parent is not None: + node.element.extract() + + if (string_child and self.element.contents + and self.element.contents[-1].__class__ == NavigableString): + # We are appending a string onto another string. + # TODO This has O(n^2) performance, for input like + # "aaa..." + old_element = self.element.contents[-1] + new_element = self.soup.new_string(old_element + string_child) + old_element.replace_with(new_element) + self.soup._most_recent_element = new_element + else: + if isinstance(node, basestring): + # Create a brand new NavigableString from this string. + child = self.soup.new_string(node) + + # Tell Beautiful Soup to act as if it parsed this element + # immediately after the parent's last descendant. (Or + # immediately after the parent, if it has no children.) + if self.element.contents: + most_recent_element = self.element._last_descendant(False) + elif self.element.next_element is not None: + # Something from further ahead in the parse tree is + # being inserted into this earlier element. This is + # very annoying because it means an expensive search + # for the last element in the tree. + most_recent_element = self.soup._last_descendant() + else: + most_recent_element = self.element + + self.soup.object_was_parsed( + child, parent=self.element, + most_recent_element=most_recent_element) + + def getAttributes(self): + if isinstance(self.element, Comment): + return {} + return AttrList(self.element) + + def setAttributes(self, attributes): + + if attributes is not None and len(attributes) > 0: + + converted_attributes = [] + for name, value in list(attributes.items()): + if isinstance(name, tuple): + new_name = NamespacedAttribute(*name) + del attributes[name] + attributes[new_name] = value + + self.soup.builder._replace_cdata_list_attribute_values( + self.name, attributes) + for name, value in attributes.items(): + self.element[name] = value + + # The attributes may contain variables that need substitution. + # Call set_up_substitutions manually. + # + # The Tag constructor called this method when the Tag was created, + # but we just set/changed the attributes, so call it again. + self.soup.builder.set_up_substitutions(self.element) + attributes = property(getAttributes, setAttributes) + + def insertText(self, data, insertBefore=None): + text = TextNode(self.soup.new_string(data), self.soup) + if insertBefore: + self.insertBefore(text, insertBefore) + else: + self.appendChild(text) + + def insertBefore(self, node, refNode): + index = self.element.index(refNode.element) + if (node.element.__class__ == NavigableString and self.element.contents + and self.element.contents[index-1].__class__ == NavigableString): + # (See comments in appendChild) + old_node = self.element.contents[index-1] + new_str = self.soup.new_string(old_node + node.element) + old_node.replace_with(new_str) + else: + self.element.insert(index, node.element) + node.parent = self + + def removeChild(self, node): + node.element.extract() + + def reparentChildren(self, new_parent): + """Move all of this tag's children into another tag.""" + # print "MOVE", self.element.contents + # print "FROM", self.element + # print "TO", new_parent.element + + element = self.element + new_parent_element = new_parent.element + # Determine what this tag's next_element will be once all the children + # are removed. + final_next_element = element.next_sibling + + new_parents_last_descendant = new_parent_element._last_descendant(False, False) + if len(new_parent_element.contents) > 0: + # The new parent already contains children. We will be + # appending this tag's children to the end. + new_parents_last_child = new_parent_element.contents[-1] + new_parents_last_descendant_next_element = new_parents_last_descendant.next_element + else: + # The new parent contains no children. + new_parents_last_child = None + new_parents_last_descendant_next_element = new_parent_element.next_element + + to_append = element.contents + if len(to_append) > 0: + # Set the first child's previous_element and previous_sibling + # to elements within the new parent + first_child = to_append[0] + if new_parents_last_descendant: + first_child.previous_element = new_parents_last_descendant + else: + first_child.previous_element = new_parent_element + first_child.previous_sibling = new_parents_last_child + if new_parents_last_descendant: + new_parents_last_descendant.next_element = first_child + else: + new_parent_element.next_element = first_child + if new_parents_last_child: + new_parents_last_child.next_sibling = first_child + + # Find the very last element being moved. It is now the + # parent's last descendant. It has no .next_sibling and + # its .next_element is whatever the previous last + # descendant had. + last_childs_last_descendant = to_append[-1]._last_descendant(False, True) + + last_childs_last_descendant.next_element = new_parents_last_descendant_next_element + if new_parents_last_descendant_next_element: + # TODO: This code has no test coverage and I'm not sure + # how to get html5lib to go through this path, but it's + # just the other side of the previous line. + new_parents_last_descendant_next_element.previous_element = last_childs_last_descendant + last_childs_last_descendant.next_sibling = None + + for child in to_append: + child.parent = new_parent_element + new_parent_element.contents.append(child) + + # Now that this element has no children, change its .next_element. + element.contents = [] + element.next_element = final_next_element + + # print "DONE WITH MOVE" + # print "FROM", self.element + # print "TO", new_parent_element + + def cloneNode(self): + tag = self.soup.new_tag(self.element.name, self.namespace) + node = Element(tag, self.soup, self.namespace) + for key,value in self.attributes: + node.attributes[key] = value + return node + + def hasContent(self): + return self.element.contents + + def getNameTuple(self): + if self.namespace == None: + return namespaces["html"], self.name + else: + return self.namespace, self.name + + nameTuple = property(getNameTuple) + +class TextNode(Element): + def __init__(self, element, soup): + treebuilder_base.Node.__init__(self, None) + self.element = element + self.soup = soup + + def cloneNode(self): + raise NotImplementedError diff --git a/venv/lib/python2.7/site-packages/bs4/builder/_html5lib.pyc b/venv/lib/python2.7/site-packages/bs4/builder/_html5lib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16a7613ffb31b7fe831ee3fa248b819a14577f64 GIT binary patch literal 17021 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/bs4/builder/_htmlparser.py b/venv/lib/python2.7/site-packages/bs4/builder/_htmlparser.py new file mode 100644 index 0000000..67890b3 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/builder/_htmlparser.py @@ -0,0 +1,314 @@ +"""Use the HTMLParser library to parse HTML files that aren't too bad.""" + +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +__all__ = [ + 'HTMLParserTreeBuilder', + ] + +from HTMLParser import HTMLParser + +try: + from HTMLParser import HTMLParseError +except ImportError, e: + # HTMLParseError is removed in Python 3.5. Since it can never be + # thrown in 3.5, we can just define our own class as a placeholder. + class HTMLParseError(Exception): + pass + +import sys +import warnings + +# Starting in Python 3.2, the HTMLParser constructor takes a 'strict' +# argument, which we'd like to set to False. Unfortunately, +# http://bugs.python.org/issue13273 makes strict=True a better bet +# before Python 3.2.3. +# +# At the end of this file, we monkeypatch HTMLParser so that +# strict=True works well on Python 3.2.2. +major, minor, release = sys.version_info[:3] +CONSTRUCTOR_TAKES_STRICT = major == 3 and minor == 2 and release >= 3 +CONSTRUCTOR_STRICT_IS_DEPRECATED = major == 3 and minor == 3 +CONSTRUCTOR_TAKES_CONVERT_CHARREFS = major == 3 and minor >= 4 + + +from bs4.element import ( + CData, + Comment, + Declaration, + Doctype, + ProcessingInstruction, + ) +from bs4.dammit import EntitySubstitution, UnicodeDammit + +from bs4.builder import ( + HTML, + HTMLTreeBuilder, + STRICT, + ) + + +HTMLPARSER = 'html.parser' + +class BeautifulSoupHTMLParser(HTMLParser): + + def __init__(self, *args, **kwargs): + HTMLParser.__init__(self, *args, **kwargs) + + # Keep a list of empty-element tags that were encountered + # without an explicit closing tag. If we encounter a closing tag + # of this type, we'll associate it with one of those entries. + # + # This isn't a stack because we don't care about the + # order. It's a list of closing tags we've already handled and + # will ignore, assuming they ever show up. + self.already_closed_empty_element = [] + + def handle_startendtag(self, name, attrs): + # This is only called when the markup looks like + # . + + # is_startend() tells handle_starttag not to close the tag + # just because its name matches a known empty-element tag. We + # know that this is an empty-element tag and we want to call + # handle_endtag ourselves. + tag = self.handle_starttag(name, attrs, handle_empty_element=False) + self.handle_endtag(name) + + def handle_starttag(self, name, attrs, handle_empty_element=True): + # XXX namespace + attr_dict = {} + for key, value in attrs: + # Change None attribute values to the empty string + # for consistency with the other tree builders. + if value is None: + value = '' + attr_dict[key] = value + attrvalue = '""' + #print "START", name + tag = self.soup.handle_starttag(name, None, None, attr_dict) + if tag and tag.is_empty_element and handle_empty_element: + # Unlike other parsers, html.parser doesn't send separate end tag + # events for empty-element tags. (It's handled in + # handle_startendtag, but only if the original markup looked like + # .) + # + # So we need to call handle_endtag() ourselves. Since we + # know the start event is identical to the end event, we + # don't want handle_endtag() to cross off any previous end + # events for tags of this name. + self.handle_endtag(name, check_already_closed=False) + + # But we might encounter an explicit closing tag for this tag + # later on. If so, we want to ignore it. + self.already_closed_empty_element.append(name) + + def handle_endtag(self, name, check_already_closed=True): + #print "END", name + if check_already_closed and name in self.already_closed_empty_element: + # This is a redundant end tag for an empty-element tag. + # We've already called handle_endtag() for it, so just + # check it off the list. + # print "ALREADY CLOSED", name + self.already_closed_empty_element.remove(name) + else: + self.soup.handle_endtag(name) + + def handle_data(self, data): + self.soup.handle_data(data) + + def handle_charref(self, name): + # XXX workaround for a bug in HTMLParser. Remove this once + # it's fixed in all supported versions. + # http://bugs.python.org/issue13633 + if name.startswith('x'): + real_name = int(name.lstrip('x'), 16) + elif name.startswith('X'): + real_name = int(name.lstrip('X'), 16) + else: + real_name = int(name) + + try: + data = unichr(real_name) + except (ValueError, OverflowError), e: + data = u"\N{REPLACEMENT CHARACTER}" + + self.handle_data(data) + + def handle_entityref(self, name): + character = EntitySubstitution.HTML_ENTITY_TO_CHARACTER.get(name) + if character is not None: + data = character + else: + data = "&%s;" % name + self.handle_data(data) + + def handle_comment(self, data): + self.soup.endData() + self.soup.handle_data(data) + self.soup.endData(Comment) + + def handle_decl(self, data): + self.soup.endData() + if data.startswith("DOCTYPE "): + data = data[len("DOCTYPE "):] + elif data == 'DOCTYPE': + # i.e. "" + data = '' + self.soup.handle_data(data) + self.soup.endData(Doctype) + + def unknown_decl(self, data): + if data.upper().startswith('CDATA['): + cls = CData + data = data[len('CDATA['):] + else: + cls = Declaration + self.soup.endData() + self.soup.handle_data(data) + self.soup.endData(cls) + + def handle_pi(self, data): + self.soup.endData() + self.soup.handle_data(data) + self.soup.endData(ProcessingInstruction) + + +class HTMLParserTreeBuilder(HTMLTreeBuilder): + + is_xml = False + picklable = True + NAME = HTMLPARSER + features = [NAME, HTML, STRICT] + + def __init__(self, *args, **kwargs): + if CONSTRUCTOR_TAKES_STRICT and not CONSTRUCTOR_STRICT_IS_DEPRECATED: + kwargs['strict'] = False + if CONSTRUCTOR_TAKES_CONVERT_CHARREFS: + kwargs['convert_charrefs'] = False + self.parser_args = (args, kwargs) + + def prepare_markup(self, markup, user_specified_encoding=None, + document_declared_encoding=None, exclude_encodings=None): + """ + :return: A 4-tuple (markup, original encoding, encoding + declared within markup, whether any characters had to be + replaced with REPLACEMENT CHARACTER). + """ + if isinstance(markup, unicode): + yield (markup, None, None, False) + return + + try_encodings = [user_specified_encoding, document_declared_encoding] + dammit = UnicodeDammit(markup, try_encodings, is_html=True, + exclude_encodings=exclude_encodings) + yield (dammit.markup, dammit.original_encoding, + dammit.declared_html_encoding, + dammit.contains_replacement_characters) + + def feed(self, markup): + args, kwargs = self.parser_args + parser = BeautifulSoupHTMLParser(*args, **kwargs) + parser.soup = self.soup + try: + parser.feed(markup) + except HTMLParseError, e: + warnings.warn(RuntimeWarning( + "Python's built-in HTMLParser cannot parse the given document. This is not a bug in Beautiful Soup. The best solution is to install an external parser (lxml or html5lib), and use Beautiful Soup with that parser. See http://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser for help.")) + raise e + parser.already_closed_empty_element = [] + +# Patch 3.2 versions of HTMLParser earlier than 3.2.3 to use some +# 3.2.3 code. This ensures they don't treat markup like

    as a +# string. +# +# XXX This code can be removed once most Python 3 users are on 3.2.3. +if major == 3 and minor == 2 and not CONSTRUCTOR_TAKES_STRICT: + import re + attrfind_tolerant = re.compile( + r'\s*((?<=[\'"\s])[^\s/>][^\s/=>]*)(\s*=+\s*' + r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?') + HTMLParserTreeBuilder.attrfind_tolerant = attrfind_tolerant + + locatestarttagend = re.compile(r""" + <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name + (?:\s+ # whitespace before attribute name + (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name + (?:\s*=\s* # value indicator + (?:'[^']*' # LITA-enclosed value + |\"[^\"]*\" # LIT-enclosed value + |[^'\">\s]+ # bare value + ) + )? + ) + )* + \s* # trailing whitespace +""", re.VERBOSE) + BeautifulSoupHTMLParser.locatestarttagend = locatestarttagend + + from html.parser import tagfind, attrfind + + def parse_starttag(self, i): + self.__starttag_text = None + endpos = self.check_for_whole_start_tag(i) + if endpos < 0: + return endpos + rawdata = self.rawdata + self.__starttag_text = rawdata[i:endpos] + + # Now parse the data between i+1 and j into a tag and attrs + attrs = [] + match = tagfind.match(rawdata, i+1) + assert match, 'unexpected call to parse_starttag()' + k = match.end() + self.lasttag = tag = rawdata[i+1:k].lower() + while k < endpos: + if self.strict: + m = attrfind.match(rawdata, k) + else: + m = attrfind_tolerant.match(rawdata, k) + if not m: + break + attrname, rest, attrvalue = m.group(1, 2, 3) + if not rest: + attrvalue = None + elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ + attrvalue[:1] == '"' == attrvalue[-1:]: + attrvalue = attrvalue[1:-1] + if attrvalue: + attrvalue = self.unescape(attrvalue) + attrs.append((attrname.lower(), attrvalue)) + k = m.end() + + end = rawdata[k:endpos].strip() + if end not in (">", "/>"): + lineno, offset = self.getpos() + if "\n" in self.__starttag_text: + lineno = lineno + self.__starttag_text.count("\n") + offset = len(self.__starttag_text) \ + - self.__starttag_text.rfind("\n") + else: + offset = offset + len(self.__starttag_text) + if self.strict: + self.error("junk characters in start tag: %r" + % (rawdata[k:endpos][:20],)) + self.handle_data(rawdata[i:endpos]) + return endpos + if end.endswith('/>'): + # XHTML-style empty tag: + self.handle_startendtag(tag, attrs) + else: + self.handle_starttag(tag, attrs) + if tag in self.CDATA_CONTENT_ELEMENTS: + self.set_cdata_mode(tag) + return endpos + + def set_cdata_mode(self, elem): + self.cdata_elem = elem.lower() + self.interesting = re.compile(r'' % self.cdata_elem, re.I) + + BeautifulSoupHTMLParser.parse_starttag = parse_starttag + BeautifulSoupHTMLParser.set_cdata_mode = set_cdata_mode + + CONSTRUCTOR_TAKES_STRICT = True diff --git a/venv/lib/python2.7/site-packages/bs4/builder/_htmlparser.pyc b/venv/lib/python2.7/site-packages/bs4/builder/_htmlparser.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ff76fb8ae06d62b5e7896a618232b62a5b5f16e GIT binary patch literal 10931 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/bs4/builder/_lxml.py b/venv/lib/python2.7/site-packages/bs4/builder/_lxml.py new file mode 100644 index 0000000..d2ca287 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/builder/_lxml.py @@ -0,0 +1,258 @@ +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +__all__ = [ + 'LXMLTreeBuilderForXML', + 'LXMLTreeBuilder', + ] + +from io import BytesIO +from StringIO import StringIO +import collections +from lxml import etree +from bs4.element import ( + Comment, + Doctype, + NamespacedAttribute, + ProcessingInstruction, + XMLProcessingInstruction, +) +from bs4.builder import ( + FAST, + HTML, + HTMLTreeBuilder, + PERMISSIVE, + ParserRejectedMarkup, + TreeBuilder, + XML) +from bs4.dammit import EncodingDetector + +LXML = 'lxml' + +class LXMLTreeBuilderForXML(TreeBuilder): + DEFAULT_PARSER_CLASS = etree.XMLParser + + is_xml = True + processing_instruction_class = XMLProcessingInstruction + + NAME = "lxml-xml" + ALTERNATE_NAMES = ["xml"] + + # Well, it's permissive by XML parser standards. + features = [NAME, LXML, XML, FAST, PERMISSIVE] + + CHUNK_SIZE = 512 + + # This namespace mapping is specified in the XML Namespace + # standard. + DEFAULT_NSMAPS = {'http://www.w3.org/XML/1998/namespace' : "xml"} + + def default_parser(self, encoding): + # This can either return a parser object or a class, which + # will be instantiated with default arguments. + if self._default_parser is not None: + return self._default_parser + return etree.XMLParser( + target=self, strip_cdata=False, recover=True, encoding=encoding) + + def parser_for(self, encoding): + # Use the default parser. + parser = self.default_parser(encoding) + + if isinstance(parser, collections.Callable): + # Instantiate the parser with default arguments + parser = parser(target=self, strip_cdata=False, encoding=encoding) + return parser + + def __init__(self, parser=None, empty_element_tags=None): + # TODO: Issue a warning if parser is present but not a + # callable, since that means there's no way to create new + # parsers for different encodings. + self._default_parser = parser + if empty_element_tags is not None: + self.empty_element_tags = set(empty_element_tags) + self.soup = None + self.nsmaps = [self.DEFAULT_NSMAPS] + + def _getNsTag(self, tag): + # Split the namespace URL out of a fully-qualified lxml tag + # name. Copied from lxml's src/lxml/sax.py. + if tag[0] == '{': + return tuple(tag[1:].split('}', 1)) + else: + return (None, tag) + + def prepare_markup(self, markup, user_specified_encoding=None, + exclude_encodings=None, + document_declared_encoding=None): + """ + :yield: A series of 4-tuples. + (markup, encoding, declared encoding, + has undergone character replacement) + + Each 4-tuple represents a strategy for parsing the document. + """ + # Instead of using UnicodeDammit to convert the bytestring to + # Unicode using different encodings, use EncodingDetector to + # iterate over the encodings, and tell lxml to try to parse + # the document as each one in turn. + is_html = not self.is_xml + if is_html: + self.processing_instruction_class = ProcessingInstruction + else: + self.processing_instruction_class = XMLProcessingInstruction + + if isinstance(markup, unicode): + # We were given Unicode. Maybe lxml can parse Unicode on + # this system? + yield markup, None, document_declared_encoding, False + + if isinstance(markup, unicode): + # No, apparently not. Convert the Unicode to UTF-8 and + # tell lxml to parse it as UTF-8. + yield (markup.encode("utf8"), "utf8", + document_declared_encoding, False) + + try_encodings = [user_specified_encoding, document_declared_encoding] + detector = EncodingDetector( + markup, try_encodings, is_html, exclude_encodings) + for encoding in detector.encodings: + yield (detector.markup, encoding, document_declared_encoding, False) + + def feed(self, markup): + if isinstance(markup, bytes): + markup = BytesIO(markup) + elif isinstance(markup, unicode): + markup = StringIO(markup) + + # Call feed() at least once, even if the markup is empty, + # or the parser won't be initialized. + data = markup.read(self.CHUNK_SIZE) + try: + self.parser = self.parser_for(self.soup.original_encoding) + self.parser.feed(data) + while len(data) != 0: + # Now call feed() on the rest of the data, chunk by chunk. + data = markup.read(self.CHUNK_SIZE) + if len(data) != 0: + self.parser.feed(data) + self.parser.close() + except (UnicodeDecodeError, LookupError, etree.ParserError), e: + raise ParserRejectedMarkup(str(e)) + + def close(self): + self.nsmaps = [self.DEFAULT_NSMAPS] + + def start(self, name, attrs, nsmap={}): + # Make sure attrs is a mutable dict--lxml may send an immutable dictproxy. + attrs = dict(attrs) + nsprefix = None + # Invert each namespace map as it comes in. + if len(self.nsmaps) > 1: + # There are no new namespaces for this tag, but + # non-default namespaces are in play, so we need a + # separate tag stack to know when they end. + self.nsmaps.append(None) + elif len(nsmap) > 0: + # A new namespace mapping has come into play. + inverted_nsmap = dict((value, key) for key, value in nsmap.items()) + self.nsmaps.append(inverted_nsmap) + # Also treat the namespace mapping as a set of attributes on the + # tag, so we can recreate it later. + attrs = attrs.copy() + for prefix, namespace in nsmap.items(): + attribute = NamespacedAttribute( + "xmlns", prefix, "http://www.w3.org/2000/xmlns/") + attrs[attribute] = namespace + + # Namespaces are in play. Find any attributes that came in + # from lxml with namespaces attached to their names, and + # turn then into NamespacedAttribute objects. + new_attrs = {} + for attr, value in attrs.items(): + namespace, attr = self._getNsTag(attr) + if namespace is None: + new_attrs[attr] = value + else: + nsprefix = self._prefix_for_namespace(namespace) + attr = NamespacedAttribute(nsprefix, attr, namespace) + new_attrs[attr] = value + attrs = new_attrs + + namespace, name = self._getNsTag(name) + nsprefix = self._prefix_for_namespace(namespace) + self.soup.handle_starttag(name, namespace, nsprefix, attrs) + + def _prefix_for_namespace(self, namespace): + """Find the currently active prefix for the given namespace.""" + if namespace is None: + return None + for inverted_nsmap in reversed(self.nsmaps): + if inverted_nsmap is not None and namespace in inverted_nsmap: + return inverted_nsmap[namespace] + return None + + def end(self, name): + self.soup.endData() + completed_tag = self.soup.tagStack[-1] + namespace, name = self._getNsTag(name) + nsprefix = None + if namespace is not None: + for inverted_nsmap in reversed(self.nsmaps): + if inverted_nsmap is not None and namespace in inverted_nsmap: + nsprefix = inverted_nsmap[namespace] + break + self.soup.handle_endtag(name, nsprefix) + if len(self.nsmaps) > 1: + # This tag, or one of its parents, introduced a namespace + # mapping, so pop it off the stack. + self.nsmaps.pop() + + def pi(self, target, data): + self.soup.endData() + self.soup.handle_data(target + ' ' + data) + self.soup.endData(self.processing_instruction_class) + + def data(self, content): + self.soup.handle_data(content) + + def doctype(self, name, pubid, system): + self.soup.endData() + doctype = Doctype.for_name_and_ids(name, pubid, system) + self.soup.object_was_parsed(doctype) + + def comment(self, content): + "Handle comments as Comment objects." + self.soup.endData() + self.soup.handle_data(content) + self.soup.endData(Comment) + + def test_fragment_to_document(self, fragment): + """See `TreeBuilder`.""" + return u'\n%s' % fragment + + +class LXMLTreeBuilder(HTMLTreeBuilder, LXMLTreeBuilderForXML): + + NAME = LXML + ALTERNATE_NAMES = ["lxml-html"] + + features = ALTERNATE_NAMES + [NAME, HTML, FAST, PERMISSIVE] + is_xml = False + processing_instruction_class = ProcessingInstruction + + def default_parser(self, encoding): + return etree.HTMLParser + + def feed(self, markup): + encoding = self.soup.original_encoding + try: + self.parser = self.parser_for(encoding) + self.parser.feed(markup) + self.parser.close() + except (UnicodeDecodeError, LookupError, etree.ParserError), e: + raise ParserRejectedMarkup(str(e)) + + + def test_fragment_to_document(self, fragment): + """See `TreeBuilder`.""" + return u'%s' % fragment diff --git a/venv/lib/python2.7/site-packages/bs4/builder/_lxml.pyc b/venv/lib/python2.7/site-packages/bs4/builder/_lxml.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53dd8edae07427e1acd15de405fccfe5103214e4 GIT binary patch literal 9698 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 F{sPnxJ&XVV literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/bs4/dammit.py b/venv/lib/python2.7/site-packages/bs4/dammit.py new file mode 100644 index 0000000..7965565 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/dammit.py @@ -0,0 +1,842 @@ +# -*- coding: utf-8 -*- +"""Beautiful Soup bonus library: Unicode, Dammit + +This library converts a bytestream to Unicode through any means +necessary. It is heavily based on code from Mark Pilgrim's Universal +Feed Parser. It works best on XML and HTML, but it does not rewrite the +XML or HTML to reflect a new encoding; that's the tree builder's job. +""" +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +__license__ = "MIT" + +import codecs +from htmlentitydefs import codepoint2name +import re +import logging +import string + +# Import a library to autodetect character encodings. +chardet_type = None +try: + # First try the fast C implementation. + # PyPI package: cchardet + import cchardet + def chardet_dammit(s): + return cchardet.detect(s)['encoding'] +except ImportError: + try: + # Fall back to the pure Python implementation + # Debian package: python-chardet + # PyPI package: chardet + import chardet + def chardet_dammit(s): + return chardet.detect(s)['encoding'] + #import chardet.constants + #chardet.constants._debug = 1 + except ImportError: + # No chardet available. + def chardet_dammit(s): + return None + +# Available from http://cjkpython.i18n.org/. +try: + import iconv_codec +except ImportError: + pass + +xml_encoding_re = re.compile( + '^<\?.*encoding=[\'"](.*?)[\'"].*\?>'.encode(), re.I) +html_meta_re = re.compile( + '<\s*meta[^>]+charset\s*=\s*["\']?([^>]*?)[ /;\'">]'.encode(), re.I) + +class EntitySubstitution(object): + + """Substitute XML or HTML entities for the corresponding characters.""" + + def _populate_class_variables(): + lookup = {} + reverse_lookup = {} + characters_for_re = [] + for codepoint, name in list(codepoint2name.items()): + character = unichr(codepoint) + if codepoint != 34: + # There's no point in turning the quotation mark into + # ", unless it happens within an attribute value, which + # is handled elsewhere. + characters_for_re.append(character) + lookup[character] = name + # But we do want to turn " into the quotation mark. + reverse_lookup[name] = character + re_definition = "[%s]" % "".join(characters_for_re) + return lookup, reverse_lookup, re.compile(re_definition) + (CHARACTER_TO_HTML_ENTITY, HTML_ENTITY_TO_CHARACTER, + CHARACTER_TO_HTML_ENTITY_RE) = _populate_class_variables() + + CHARACTER_TO_XML_ENTITY = { + "'": "apos", + '"': "quot", + "&": "amp", + "<": "lt", + ">": "gt", + } + + BARE_AMPERSAND_OR_BRACKET = re.compile("([<>]|" + "&(?!#\d+;|#x[0-9a-fA-F]+;|\w+;)" + ")") + + AMPERSAND_OR_BRACKET = re.compile("([<>&])") + + @classmethod + def _substitute_html_entity(cls, matchobj): + entity = cls.CHARACTER_TO_HTML_ENTITY.get(matchobj.group(0)) + return "&%s;" % entity + + @classmethod + def _substitute_xml_entity(cls, matchobj): + """Used with a regular expression to substitute the + appropriate XML entity for an XML special character.""" + entity = cls.CHARACTER_TO_XML_ENTITY[matchobj.group(0)] + return "&%s;" % entity + + @classmethod + def quoted_attribute_value(self, value): + """Make a value into a quoted XML attribute, possibly escaping it. + + Most strings will be quoted using double quotes. + + Bob's Bar -> "Bob's Bar" + + If a string contains double quotes, it will be quoted using + single quotes. + + Welcome to "my bar" -> 'Welcome to "my bar"' + + If a string contains both single and double quotes, the + double quotes will be escaped, and the string will be quoted + using double quotes. + + Welcome to "Bob's Bar" -> "Welcome to "Bob's bar" + """ + quote_with = '"' + if '"' in value: + if "'" in value: + # The string contains both single and double + # quotes. Turn the double quotes into + # entities. We quote the double quotes rather than + # the single quotes because the entity name is + # """ whether this is HTML or XML. If we + # quoted the single quotes, we'd have to decide + # between ' and &squot;. + replace_with = """ + value = value.replace('"', replace_with) + else: + # There are double quotes but no single quotes. + # We can use single quotes to quote the attribute. + quote_with = "'" + return quote_with + value + quote_with + + @classmethod + def substitute_xml(cls, value, make_quoted_attribute=False): + """Substitute XML entities for special XML characters. + + :param value: A string to be substituted. The less-than sign + will become <, the greater-than sign will become >, + and any ampersands will become &. If you want ampersands + that appear to be part of an entity definition to be left + alone, use substitute_xml_containing_entities() instead. + + :param make_quoted_attribute: If True, then the string will be + quoted, as befits an attribute value. + """ + # Escape angle brackets and ampersands. + value = cls.AMPERSAND_OR_BRACKET.sub( + cls._substitute_xml_entity, value) + + if make_quoted_attribute: + value = cls.quoted_attribute_value(value) + return value + + @classmethod + def substitute_xml_containing_entities( + cls, value, make_quoted_attribute=False): + """Substitute XML entities for special XML characters. + + :param value: A string to be substituted. The less-than sign will + become <, the greater-than sign will become >, and any + ampersands that are not part of an entity defition will + become &. + + :param make_quoted_attribute: If True, then the string will be + quoted, as befits an attribute value. + """ + # Escape angle brackets, and ampersands that aren't part of + # entities. + value = cls.BARE_AMPERSAND_OR_BRACKET.sub( + cls._substitute_xml_entity, value) + + if make_quoted_attribute: + value = cls.quoted_attribute_value(value) + return value + + @classmethod + def substitute_html(cls, s): + """Replace certain Unicode characters with named HTML entities. + + This differs from data.encode(encoding, 'xmlcharrefreplace') + in that the goal is to make the result more readable (to those + with ASCII displays) rather than to recover from + errors. There's absolutely nothing wrong with a UTF-8 string + containg a LATIN SMALL LETTER E WITH ACUTE, but replacing that + character with "é" will make it more readable to some + people. + """ + return cls.CHARACTER_TO_HTML_ENTITY_RE.sub( + cls._substitute_html_entity, s) + + +class EncodingDetector: + """Suggests a number of possible encodings for a bytestring. + + Order of precedence: + + 1. Encodings you specifically tell EncodingDetector to try first + (the override_encodings argument to the constructor). + + 2. An encoding declared within the bytestring itself, either in an + XML declaration (if the bytestring is to be interpreted as an XML + document), or in a tag (if the bytestring is to be + interpreted as an HTML document.) + + 3. An encoding detected through textual analysis by chardet, + cchardet, or a similar external library. + + 4. UTF-8. + + 5. Windows-1252. + """ + def __init__(self, markup, override_encodings=None, is_html=False, + exclude_encodings=None): + self.override_encodings = override_encodings or [] + exclude_encodings = exclude_encodings or [] + self.exclude_encodings = set([x.lower() for x in exclude_encodings]) + self.chardet_encoding = None + self.is_html = is_html + self.declared_encoding = None + + # First order of business: strip a byte-order mark. + self.markup, self.sniffed_encoding = self.strip_byte_order_mark(markup) + + def _usable(self, encoding, tried): + if encoding is not None: + encoding = encoding.lower() + if encoding in self.exclude_encodings: + return False + if encoding not in tried: + tried.add(encoding) + return True + return False + + @property + def encodings(self): + """Yield a number of encodings that might work for this markup.""" + tried = set() + for e in self.override_encodings: + if self._usable(e, tried): + yield e + + # Did the document originally start with a byte-order mark + # that indicated its encoding? + if self._usable(self.sniffed_encoding, tried): + yield self.sniffed_encoding + + # Look within the document for an XML or HTML encoding + # declaration. + if self.declared_encoding is None: + self.declared_encoding = self.find_declared_encoding( + self.markup, self.is_html) + if self._usable(self.declared_encoding, tried): + yield self.declared_encoding + + # Use third-party character set detection to guess at the + # encoding. + if self.chardet_encoding is None: + self.chardet_encoding = chardet_dammit(self.markup) + if self._usable(self.chardet_encoding, tried): + yield self.chardet_encoding + + # As a last-ditch effort, try utf-8 and windows-1252. + for e in ('utf-8', 'windows-1252'): + if self._usable(e, tried): + yield e + + @classmethod + def strip_byte_order_mark(cls, data): + """If a byte-order mark is present, strip it and return the encoding it implies.""" + encoding = None + if isinstance(data, unicode): + # Unicode data cannot have a byte-order mark. + return data, encoding + if (len(data) >= 4) and (data[:2] == b'\xfe\xff') \ + and (data[2:4] != '\x00\x00'): + encoding = 'utf-16be' + data = data[2:] + elif (len(data) >= 4) and (data[:2] == b'\xff\xfe') \ + and (data[2:4] != '\x00\x00'): + encoding = 'utf-16le' + data = data[2:] + elif data[:3] == b'\xef\xbb\xbf': + encoding = 'utf-8' + data = data[3:] + elif data[:4] == b'\x00\x00\xfe\xff': + encoding = 'utf-32be' + data = data[4:] + elif data[:4] == b'\xff\xfe\x00\x00': + encoding = 'utf-32le' + data = data[4:] + return data, encoding + + @classmethod + def find_declared_encoding(cls, markup, is_html=False, search_entire_document=False): + """Given a document, tries to find its declared encoding. + + An XML encoding is declared at the beginning of the document. + + An HTML encoding is declared in a tag, hopefully near the + beginning of the document. + """ + if search_entire_document: + xml_endpos = html_endpos = len(markup) + else: + xml_endpos = 1024 + html_endpos = max(2048, int(len(markup) * 0.05)) + + declared_encoding = None + declared_encoding_match = xml_encoding_re.search(markup, endpos=xml_endpos) + if not declared_encoding_match and is_html: + declared_encoding_match = html_meta_re.search(markup, endpos=html_endpos) + if declared_encoding_match is not None: + declared_encoding = declared_encoding_match.groups()[0].decode( + 'ascii', 'replace') + if declared_encoding: + return declared_encoding.lower() + return None + +class UnicodeDammit: + """A class for detecting the encoding of a *ML document and + converting it to a Unicode string. If the source encoding is + windows-1252, can replace MS smart quotes with their HTML or XML + equivalents.""" + + # This dictionary maps commonly seen values for "charset" in HTML + # meta tags to the corresponding Python codec names. It only covers + # values that aren't in Python's aliases and can't be determined + # by the heuristics in find_codec. + CHARSET_ALIASES = {"macintosh": "mac-roman", + "x-sjis": "shift-jis"} + + ENCODINGS_WITH_SMART_QUOTES = [ + "windows-1252", + "iso-8859-1", + "iso-8859-2", + ] + + def __init__(self, markup, override_encodings=[], + smart_quotes_to=None, is_html=False, exclude_encodings=[]): + self.smart_quotes_to = smart_quotes_to + self.tried_encodings = [] + self.contains_replacement_characters = False + self.is_html = is_html + self.log = logging.getLogger(__name__) + self.detector = EncodingDetector( + markup, override_encodings, is_html, exclude_encodings) + + # Short-circuit if the data is in Unicode to begin with. + if isinstance(markup, unicode) or markup == '': + self.markup = markup + self.unicode_markup = unicode(markup) + self.original_encoding = None + return + + # The encoding detector may have stripped a byte-order mark. + # Use the stripped markup from this point on. + self.markup = self.detector.markup + + u = None + for encoding in self.detector.encodings: + markup = self.detector.markup + u = self._convert_from(encoding) + if u is not None: + break + + if not u: + # None of the encodings worked. As an absolute last resort, + # try them again with character replacement. + + for encoding in self.detector.encodings: + if encoding != "ascii": + u = self._convert_from(encoding, "replace") + if u is not None: + self.log.warning( + "Some characters could not be decoded, and were " + "replaced with REPLACEMENT CHARACTER." + ) + self.contains_replacement_characters = True + break + + # If none of that worked, we could at this point force it to + # ASCII, but that would destroy so much data that I think + # giving up is better. + self.unicode_markup = u + if not u: + self.original_encoding = None + + def _sub_ms_char(self, match): + """Changes a MS smart quote character to an XML or HTML + entity, or an ASCII character.""" + orig = match.group(1) + if self.smart_quotes_to == 'ascii': + sub = self.MS_CHARS_TO_ASCII.get(orig).encode() + else: + sub = self.MS_CHARS.get(orig) + if type(sub) == tuple: + if self.smart_quotes_to == 'xml': + sub = '&#x'.encode() + sub[1].encode() + ';'.encode() + else: + sub = '&'.encode() + sub[0].encode() + ';'.encode() + else: + sub = sub.encode() + return sub + + def _convert_from(self, proposed, errors="strict"): + proposed = self.find_codec(proposed) + if not proposed or (proposed, errors) in self.tried_encodings: + return None + self.tried_encodings.append((proposed, errors)) + markup = self.markup + # Convert smart quotes to HTML if coming from an encoding + # that might have them. + if (self.smart_quotes_to is not None + and proposed in self.ENCODINGS_WITH_SMART_QUOTES): + smart_quotes_re = b"([\x80-\x9f])" + smart_quotes_compiled = re.compile(smart_quotes_re) + markup = smart_quotes_compiled.sub(self._sub_ms_char, markup) + + try: + #print "Trying to convert document to %s (errors=%s)" % ( + # proposed, errors) + u = self._to_unicode(markup, proposed, errors) + self.markup = u + self.original_encoding = proposed + except Exception as e: + #print "That didn't work!" + #print e + return None + #print "Correct encoding: %s" % proposed + return self.markup + + def _to_unicode(self, data, encoding, errors="strict"): + '''Given a string and its encoding, decodes the string into Unicode. + %encoding is a string recognized by encodings.aliases''' + return unicode(data, encoding, errors) + + @property + def declared_html_encoding(self): + if not self.is_html: + return None + return self.detector.declared_encoding + + def find_codec(self, charset): + value = (self._codec(self.CHARSET_ALIASES.get(charset, charset)) + or (charset and self._codec(charset.replace("-", ""))) + or (charset and self._codec(charset.replace("-", "_"))) + or (charset and charset.lower()) + or charset + ) + if value: + return value.lower() + return None + + def _codec(self, charset): + if not charset: + return charset + codec = None + try: + codecs.lookup(charset) + codec = charset + except (LookupError, ValueError): + pass + return codec + + + # A partial mapping of ISO-Latin-1 to HTML entities/XML numeric entities. + MS_CHARS = {b'\x80': ('euro', '20AC'), + b'\x81': ' ', + b'\x82': ('sbquo', '201A'), + b'\x83': ('fnof', '192'), + b'\x84': ('bdquo', '201E'), + b'\x85': ('hellip', '2026'), + b'\x86': ('dagger', '2020'), + b'\x87': ('Dagger', '2021'), + b'\x88': ('circ', '2C6'), + b'\x89': ('permil', '2030'), + b'\x8A': ('Scaron', '160'), + b'\x8B': ('lsaquo', '2039'), + b'\x8C': ('OElig', '152'), + b'\x8D': '?', + b'\x8E': ('#x17D', '17D'), + b'\x8F': '?', + b'\x90': '?', + b'\x91': ('lsquo', '2018'), + b'\x92': ('rsquo', '2019'), + b'\x93': ('ldquo', '201C'), + b'\x94': ('rdquo', '201D'), + b'\x95': ('bull', '2022'), + b'\x96': ('ndash', '2013'), + b'\x97': ('mdash', '2014'), + b'\x98': ('tilde', '2DC'), + b'\x99': ('trade', '2122'), + b'\x9a': ('scaron', '161'), + b'\x9b': ('rsaquo', '203A'), + b'\x9c': ('oelig', '153'), + b'\x9d': '?', + b'\x9e': ('#x17E', '17E'), + b'\x9f': ('Yuml', ''),} + + # A parochial partial mapping of ISO-Latin-1 to ASCII. Contains + # horrors like stripping diacritical marks to turn á into a, but also + # contains non-horrors like turning “ into ". + MS_CHARS_TO_ASCII = { + b'\x80' : 'EUR', + b'\x81' : ' ', + b'\x82' : ',', + b'\x83' : 'f', + b'\x84' : ',,', + b'\x85' : '...', + b'\x86' : '+', + b'\x87' : '++', + b'\x88' : '^', + b'\x89' : '%', + b'\x8a' : 'S', + b'\x8b' : '<', + b'\x8c' : 'OE', + b'\x8d' : '?', + b'\x8e' : 'Z', + b'\x8f' : '?', + b'\x90' : '?', + b'\x91' : "'", + b'\x92' : "'", + b'\x93' : '"', + b'\x94' : '"', + b'\x95' : '*', + b'\x96' : '-', + b'\x97' : '--', + b'\x98' : '~', + b'\x99' : '(TM)', + b'\x9a' : 's', + b'\x9b' : '>', + b'\x9c' : 'oe', + b'\x9d' : '?', + b'\x9e' : 'z', + b'\x9f' : 'Y', + b'\xa0' : ' ', + b'\xa1' : '!', + b'\xa2' : 'c', + b'\xa3' : 'GBP', + b'\xa4' : '$', #This approximation is especially parochial--this is the + #generic currency symbol. + b'\xa5' : 'YEN', + b'\xa6' : '|', + b'\xa7' : 'S', + b'\xa8' : '..', + b'\xa9' : '', + b'\xaa' : '(th)', + b'\xab' : '<<', + b'\xac' : '!', + b'\xad' : ' ', + b'\xae' : '(R)', + b'\xaf' : '-', + b'\xb0' : 'o', + b'\xb1' : '+-', + b'\xb2' : '2', + b'\xb3' : '3', + b'\xb4' : ("'", 'acute'), + b'\xb5' : 'u', + b'\xb6' : 'P', + b'\xb7' : '*', + b'\xb8' : ',', + b'\xb9' : '1', + b'\xba' : '(th)', + b'\xbb' : '>>', + b'\xbc' : '1/4', + b'\xbd' : '1/2', + b'\xbe' : '3/4', + b'\xbf' : '?', + b'\xc0' : 'A', + b'\xc1' : 'A', + b'\xc2' : 'A', + b'\xc3' : 'A', + b'\xc4' : 'A', + b'\xc5' : 'A', + b'\xc6' : 'AE', + b'\xc7' : 'C', + b'\xc8' : 'E', + b'\xc9' : 'E', + b'\xca' : 'E', + b'\xcb' : 'E', + b'\xcc' : 'I', + b'\xcd' : 'I', + b'\xce' : 'I', + b'\xcf' : 'I', + b'\xd0' : 'D', + b'\xd1' : 'N', + b'\xd2' : 'O', + b'\xd3' : 'O', + b'\xd4' : 'O', + b'\xd5' : 'O', + b'\xd6' : 'O', + b'\xd7' : '*', + b'\xd8' : 'O', + b'\xd9' : 'U', + b'\xda' : 'U', + b'\xdb' : 'U', + b'\xdc' : 'U', + b'\xdd' : 'Y', + b'\xde' : 'b', + b'\xdf' : 'B', + b'\xe0' : 'a', + b'\xe1' : 'a', + b'\xe2' : 'a', + b'\xe3' : 'a', + b'\xe4' : 'a', + b'\xe5' : 'a', + b'\xe6' : 'ae', + b'\xe7' : 'c', + b'\xe8' : 'e', + b'\xe9' : 'e', + b'\xea' : 'e', + b'\xeb' : 'e', + b'\xec' : 'i', + b'\xed' : 'i', + b'\xee' : 'i', + b'\xef' : 'i', + b'\xf0' : 'o', + b'\xf1' : 'n', + b'\xf2' : 'o', + b'\xf3' : 'o', + b'\xf4' : 'o', + b'\xf5' : 'o', + b'\xf6' : 'o', + b'\xf7' : '/', + b'\xf8' : 'o', + b'\xf9' : 'u', + b'\xfa' : 'u', + b'\xfb' : 'u', + b'\xfc' : 'u', + b'\xfd' : 'y', + b'\xfe' : 'b', + b'\xff' : 'y', + } + + # A map used when removing rogue Windows-1252/ISO-8859-1 + # characters in otherwise UTF-8 documents. + # + # Note that \x81, \x8d, \x8f, \x90, and \x9d are undefined in + # Windows-1252. + WINDOWS_1252_TO_UTF8 = { + 0x80 : b'\xe2\x82\xac', # € + 0x82 : b'\xe2\x80\x9a', # ‚ + 0x83 : b'\xc6\x92', # ƒ + 0x84 : b'\xe2\x80\x9e', # „ + 0x85 : b'\xe2\x80\xa6', # … + 0x86 : b'\xe2\x80\xa0', # † + 0x87 : b'\xe2\x80\xa1', # ‡ + 0x88 : b'\xcb\x86', # ˆ + 0x89 : b'\xe2\x80\xb0', # ‰ + 0x8a : b'\xc5\xa0', # Š + 0x8b : b'\xe2\x80\xb9', # ‹ + 0x8c : b'\xc5\x92', # Œ + 0x8e : b'\xc5\xbd', # Ž + 0x91 : b'\xe2\x80\x98', # ‘ + 0x92 : b'\xe2\x80\x99', # ’ + 0x93 : b'\xe2\x80\x9c', # “ + 0x94 : b'\xe2\x80\x9d', # ” + 0x95 : b'\xe2\x80\xa2', # • + 0x96 : b'\xe2\x80\x93', # – + 0x97 : b'\xe2\x80\x94', # — + 0x98 : b'\xcb\x9c', # ˜ + 0x99 : b'\xe2\x84\xa2', # ™ + 0x9a : b'\xc5\xa1', # š + 0x9b : b'\xe2\x80\xba', # › + 0x9c : b'\xc5\x93', # œ + 0x9e : b'\xc5\xbe', # ž + 0x9f : b'\xc5\xb8', # Ÿ + 0xa0 : b'\xc2\xa0', #   + 0xa1 : b'\xc2\xa1', # ¡ + 0xa2 : b'\xc2\xa2', # ¢ + 0xa3 : b'\xc2\xa3', # £ + 0xa4 : b'\xc2\xa4', # ¤ + 0xa5 : b'\xc2\xa5', # ¥ + 0xa6 : b'\xc2\xa6', # ¦ + 0xa7 : b'\xc2\xa7', # § + 0xa8 : b'\xc2\xa8', # ¨ + 0xa9 : b'\xc2\xa9', # © + 0xaa : b'\xc2\xaa', # ª + 0xab : b'\xc2\xab', # « + 0xac : b'\xc2\xac', # ¬ + 0xad : b'\xc2\xad', # ­ + 0xae : b'\xc2\xae', # ® + 0xaf : b'\xc2\xaf', # ¯ + 0xb0 : b'\xc2\xb0', # ° + 0xb1 : b'\xc2\xb1', # ± + 0xb2 : b'\xc2\xb2', # ² + 0xb3 : b'\xc2\xb3', # ³ + 0xb4 : b'\xc2\xb4', # ´ + 0xb5 : b'\xc2\xb5', # µ + 0xb6 : b'\xc2\xb6', # ¶ + 0xb7 : b'\xc2\xb7', # · + 0xb8 : b'\xc2\xb8', # ¸ + 0xb9 : b'\xc2\xb9', # ¹ + 0xba : b'\xc2\xba', # º + 0xbb : b'\xc2\xbb', # » + 0xbc : b'\xc2\xbc', # ¼ + 0xbd : b'\xc2\xbd', # ½ + 0xbe : b'\xc2\xbe', # ¾ + 0xbf : b'\xc2\xbf', # ¿ + 0xc0 : b'\xc3\x80', # À + 0xc1 : b'\xc3\x81', # Á + 0xc2 : b'\xc3\x82', #  + 0xc3 : b'\xc3\x83', # à + 0xc4 : b'\xc3\x84', # Ä + 0xc5 : b'\xc3\x85', # Å + 0xc6 : b'\xc3\x86', # Æ + 0xc7 : b'\xc3\x87', # Ç + 0xc8 : b'\xc3\x88', # È + 0xc9 : b'\xc3\x89', # É + 0xca : b'\xc3\x8a', # Ê + 0xcb : b'\xc3\x8b', # Ë + 0xcc : b'\xc3\x8c', # Ì + 0xcd : b'\xc3\x8d', # Í + 0xce : b'\xc3\x8e', # Î + 0xcf : b'\xc3\x8f', # Ï + 0xd0 : b'\xc3\x90', # Ð + 0xd1 : b'\xc3\x91', # Ñ + 0xd2 : b'\xc3\x92', # Ò + 0xd3 : b'\xc3\x93', # Ó + 0xd4 : b'\xc3\x94', # Ô + 0xd5 : b'\xc3\x95', # Õ + 0xd6 : b'\xc3\x96', # Ö + 0xd7 : b'\xc3\x97', # × + 0xd8 : b'\xc3\x98', # Ø + 0xd9 : b'\xc3\x99', # Ù + 0xda : b'\xc3\x9a', # Ú + 0xdb : b'\xc3\x9b', # Û + 0xdc : b'\xc3\x9c', # Ü + 0xdd : b'\xc3\x9d', # Ý + 0xde : b'\xc3\x9e', # Þ + 0xdf : b'\xc3\x9f', # ß + 0xe0 : b'\xc3\xa0', # à + 0xe1 : b'\xa1', # á + 0xe2 : b'\xc3\xa2', # â + 0xe3 : b'\xc3\xa3', # ã + 0xe4 : b'\xc3\xa4', # ä + 0xe5 : b'\xc3\xa5', # å + 0xe6 : b'\xc3\xa6', # æ + 0xe7 : b'\xc3\xa7', # ç + 0xe8 : b'\xc3\xa8', # è + 0xe9 : b'\xc3\xa9', # é + 0xea : b'\xc3\xaa', # ê + 0xeb : b'\xc3\xab', # ë + 0xec : b'\xc3\xac', # ì + 0xed : b'\xc3\xad', # í + 0xee : b'\xc3\xae', # î + 0xef : b'\xc3\xaf', # ï + 0xf0 : b'\xc3\xb0', # ð + 0xf1 : b'\xc3\xb1', # ñ + 0xf2 : b'\xc3\xb2', # ò + 0xf3 : b'\xc3\xb3', # ó + 0xf4 : b'\xc3\xb4', # ô + 0xf5 : b'\xc3\xb5', # õ + 0xf6 : b'\xc3\xb6', # ö + 0xf7 : b'\xc3\xb7', # ÷ + 0xf8 : b'\xc3\xb8', # ø + 0xf9 : b'\xc3\xb9', # ù + 0xfa : b'\xc3\xba', # ú + 0xfb : b'\xc3\xbb', # û + 0xfc : b'\xc3\xbc', # ü + 0xfd : b'\xc3\xbd', # ý + 0xfe : b'\xc3\xbe', # þ + } + + MULTIBYTE_MARKERS_AND_SIZES = [ + (0xc2, 0xdf, 2), # 2-byte characters start with a byte C2-DF + (0xe0, 0xef, 3), # 3-byte characters start with E0-EF + (0xf0, 0xf4, 4), # 4-byte characters start with F0-F4 + ] + + FIRST_MULTIBYTE_MARKER = MULTIBYTE_MARKERS_AND_SIZES[0][0] + LAST_MULTIBYTE_MARKER = MULTIBYTE_MARKERS_AND_SIZES[-1][1] + + @classmethod + def detwingle(cls, in_bytes, main_encoding="utf8", + embedded_encoding="windows-1252"): + """Fix characters from one encoding embedded in some other encoding. + + Currently the only situation supported is Windows-1252 (or its + subset ISO-8859-1), embedded in UTF-8. + + The input must be a bytestring. If you've already converted + the document to Unicode, you're too late. + + The output is a bytestring in which `embedded_encoding` + characters have been converted to their `main_encoding` + equivalents. + """ + if embedded_encoding.replace('_', '-').lower() not in ( + 'windows-1252', 'windows_1252'): + raise NotImplementedError( + "Windows-1252 and ISO-8859-1 are the only currently supported " + "embedded encodings.") + + if main_encoding.lower() not in ('utf8', 'utf-8'): + raise NotImplementedError( + "UTF-8 is the only currently supported main encoding.") + + byte_chunks = [] + + chunk_start = 0 + pos = 0 + while pos < len(in_bytes): + byte = in_bytes[pos] + if not isinstance(byte, int): + # Python 2.x + byte = ord(byte) + if (byte >= cls.FIRST_MULTIBYTE_MARKER + and byte <= cls.LAST_MULTIBYTE_MARKER): + # This is the start of a UTF-8 multibyte character. Skip + # to the end. + for start, end, size in cls.MULTIBYTE_MARKERS_AND_SIZES: + if byte >= start and byte <= end: + pos += size + break + elif byte >= 0x80 and byte in cls.WINDOWS_1252_TO_UTF8: + # We found a Windows-1252 character! + # Save the string up to this point as a chunk. + byte_chunks.append(in_bytes[chunk_start:pos]) + + # Now translate the Windows-1252 character into UTF-8 + # and add it as another, one-byte chunk. + byte_chunks.append(cls.WINDOWS_1252_TO_UTF8[byte]) + pos += 1 + chunk_start = pos + else: + # Go on to the next character. + pos += 1 + if chunk_start == 0: + # The string is unchanged. + return in_bytes + else: + # Store the final chunk. + byte_chunks.append(in_bytes[chunk_start:]) + return b''.join(byte_chunks) + diff --git a/venv/lib/python2.7/site-packages/bs4/dammit.pyc b/venv/lib/python2.7/site-packages/bs4/dammit.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0aecdf418931e689a3209c19c9c145ff6f5bf260 GIT binary patch literal 24040 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" % tag_name) + elif choice == 1: + elements.append(rsentence(random.randint(1,4))) + elif choice == 2: + # Close a tag. + tag_name = random.choice(tag_names) + elements.append("" % tag_name) + return "" + "\n".join(elements) + "" + +def benchmark_parsers(num_elements=100000): + """Very basic head-to-head performance benchmark.""" + print "Comparative parser benchmark on Beautiful Soup %s" % __version__ + data = rdoc(num_elements) + print "Generated a large invalid HTML document (%d bytes)." % len(data) + + for parser in ["lxml", ["lxml", "html"], "html5lib", "html.parser"]: + success = False + try: + a = time.time() + soup = BeautifulSoup(data, parser) + b = time.time() + success = True + except Exception, e: + print "%s could not parse the markup." % parser + traceback.print_exc() + if success: + print "BS4+%s parsed the markup in %.2fs." % (parser, b-a) + + from lxml import etree + a = time.time() + etree.HTML(data) + b = time.time() + print "Raw lxml parsed the markup in %.2fs." % (b-a) + + import html5lib + parser = html5lib.HTMLParser() + a = time.time() + parser.parse(data) + b = time.time() + print "Raw html5lib parsed the markup in %.2fs." % (b-a) + +def profile(num_elements=100000, parser="lxml"): + + filehandle = tempfile.NamedTemporaryFile() + filename = filehandle.name + + data = rdoc(num_elements) + vars = dict(bs4=bs4, data=data, parser=parser) + cProfile.runctx('bs4.BeautifulSoup(data, parser)' , vars, vars, filename) + + stats = pstats.Stats(filename) + # stats.strip_dirs() + stats.sort_stats("cumulative") + stats.print_stats('_html5lib|bs4', 50) + +if __name__ == '__main__': + diagnose(sys.stdin.read()) diff --git a/venv/lib/python2.7/site-packages/bs4/diagnose.pyc b/venv/lib/python2.7/site-packages/bs4/diagnose.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00c72b1de1859b53e9c257a42ddc725cf7fe8f22 GIT binary patch literal 10275 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 IPF9@%0pE8r^Z)<= literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/bs4/element.py b/venv/lib/python2.7/site-packages/bs4/element.py new file mode 100644 index 0000000..9ef75f8 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/element.py @@ -0,0 +1,1808 @@ +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +__license__ = "MIT" + +import collections +import re +import shlex +import sys +import warnings +from bs4.dammit import EntitySubstitution + +DEFAULT_OUTPUT_ENCODING = "utf-8" +PY3K = (sys.version_info[0] > 2) + +whitespace_re = re.compile("\s+") + +def _alias(attr): + """Alias one attribute name to another for backward compatibility""" + @property + def alias(self): + return getattr(self, attr) + + @alias.setter + def alias(self): + return setattr(self, attr) + return alias + + +class NamespacedAttribute(unicode): + + def __new__(cls, prefix, name, namespace=None): + if name is None: + obj = unicode.__new__(cls, prefix) + elif prefix is None: + # Not really namespaced. + obj = unicode.__new__(cls, name) + else: + obj = unicode.__new__(cls, prefix + ":" + name) + obj.prefix = prefix + obj.name = name + obj.namespace = namespace + return obj + +class AttributeValueWithCharsetSubstitution(unicode): + """A stand-in object for a character encoding specified in HTML.""" + +class CharsetMetaAttributeValue(AttributeValueWithCharsetSubstitution): + """A generic stand-in for the value of a meta tag's 'charset' attribute. + + When Beautiful Soup parses the markup '', the + value of the 'charset' attribute will be one of these objects. + """ + + def __new__(cls, original_value): + obj = unicode.__new__(cls, original_value) + obj.original_value = original_value + return obj + + def encode(self, encoding): + return encoding + + +class ContentMetaAttributeValue(AttributeValueWithCharsetSubstitution): + """A generic stand-in for the value of a meta tag's 'content' attribute. + + When Beautiful Soup parses the markup: + + + The value of the 'content' attribute will be one of these objects. + """ + + CHARSET_RE = re.compile("((^|;)\s*charset=)([^;]*)", re.M) + + def __new__(cls, original_value): + match = cls.CHARSET_RE.search(original_value) + if match is None: + # No substitution necessary. + return unicode.__new__(unicode, original_value) + + obj = unicode.__new__(cls, original_value) + obj.original_value = original_value + return obj + + def encode(self, encoding): + def rewrite(match): + return match.group(1) + encoding + return self.CHARSET_RE.sub(rewrite, self.original_value) + +class HTMLAwareEntitySubstitution(EntitySubstitution): + + """Entity substitution rules that are aware of some HTML quirks. + + Specifically, the contents of + +Hello, world! + + +''' + soup = self.soup(html) + self.assertEqual("text/javascript", soup.find('script')['type']) + + def test_comment(self): + # Comments are represented as Comment objects. + markup = "

    foobaz

    " + self.assertSoupEquals(markup) + + soup = self.soup(markup) + comment = soup.find(text="foobar") + self.assertEqual(comment.__class__, Comment) + + # The comment is properly integrated into the tree. + foo = soup.find(text="foo") + self.assertEqual(comment, foo.next_element) + baz = soup.find(text="baz") + self.assertEqual(comment, baz.previous_element) + + def test_preserved_whitespace_in_pre_and_textarea(self): + """Whitespace must be preserved in
     and "
    +        self.assertSoupEquals(pre_markup)
    +        self.assertSoupEquals(textarea_markup)
    +
    +        soup = self.soup(pre_markup)
    +        self.assertEqual(soup.pre.prettify(), pre_markup)
    +
    +        soup = self.soup(textarea_markup)
    +        self.assertEqual(soup.textarea.prettify(), textarea_markup)
    +
    +        soup = self.soup("")
    +        self.assertEqual(soup.textarea.prettify(), "")
    +
    +    def test_nested_inline_elements(self):
    +        """Inline elements can be nested indefinitely."""
    +        b_tag = "Inside a B tag"
    +        self.assertSoupEquals(b_tag)
    +
    +        nested_b_tag = "

    A nested tag

    " + self.assertSoupEquals(nested_b_tag) + + double_nested_b_tag = "

    A doubly nested tag

    " + self.assertSoupEquals(nested_b_tag) + + def test_nested_block_level_elements(self): + """Block elements can be nested.""" + soup = self.soup('

    Foo

    ') + blockquote = soup.blockquote + self.assertEqual(blockquote.p.b.string, 'Foo') + self.assertEqual(blockquote.b.string, 'Foo') + + def test_correctly_nested_tables(self): + """One table can go inside another one.""" + markup = ('
    ' + '' + "') + + self.assertSoupEquals( + markup, + '
    Here's another table:" + '' + '' + '
    foo
    Here\'s another table:' + '
    foo
    ' + '
    ') + + self.assertSoupEquals( + "" + "" + "
    Foo
    Bar
    Baz
    ") + + def test_deeply_nested_multivalued_attribute(self): + # html5lib can set the attributes of the same tag many times + # as it rearranges the tree. This has caused problems with + # multivalued attributes. + markup = '
    ' + soup = self.soup(markup) + self.assertEqual(["css"], soup.div.div['class']) + + def test_multivalued_attribute_on_html(self): + # html5lib uses a different API to set the attributes ot the + # tag. This has caused problems with multivalued + # attributes. + markup = '' + soup = self.soup(markup) + self.assertEqual(["a", "b"], soup.html['class']) + + def test_angle_brackets_in_attribute_values_are_escaped(self): + self.assertSoupEquals('', '') + + def test_entities_in_attributes_converted_to_unicode(self): + expect = u'

    ' + self.assertSoupEquals('

    ', expect) + self.assertSoupEquals('

    ', expect) + self.assertSoupEquals('

    ', expect) + self.assertSoupEquals('

    ', expect) + + def test_entities_in_text_converted_to_unicode(self): + expect = u'

    pi\N{LATIN SMALL LETTER N WITH TILDE}ata

    ' + self.assertSoupEquals("

    piñata

    ", expect) + self.assertSoupEquals("

    piñata

    ", expect) + self.assertSoupEquals("

    piñata

    ", expect) + self.assertSoupEquals("

    piñata

    ", expect) + + def test_quot_entity_converted_to_quotation_mark(self): + self.assertSoupEquals("

    I said "good day!"

    ", + '

    I said "good day!"

    ') + + def test_out_of_range_entity(self): + expect = u"\N{REPLACEMENT CHARACTER}" + self.assertSoupEquals("�", expect) + self.assertSoupEquals("�", expect) + self.assertSoupEquals("�", expect) + + def test_multipart_strings(self): + "Mostly to prevent a recurrence of a bug in the html5lib treebuilder." + soup = self.soup("

    \nfoo

    ") + self.assertEqual("p", soup.h2.string.next_element.name) + self.assertEqual("p", soup.p.name) + self.assertConnectedness(soup) + + def test_empty_element_tags(self): + """Verify consistent handling of empty-element tags, + no matter how they come in through the markup. + """ + self.assertSoupEquals('


    ', "


    ") + self.assertSoupEquals('


    ', "


    ") + + def test_head_tag_between_head_and_body(self): + "Prevent recurrence of a bug in the html5lib treebuilder." + content = """ + + foo + +""" + soup = self.soup(content) + self.assertNotEqual(None, soup.html.body) + self.assertConnectedness(soup) + + def test_multiple_copies_of_a_tag(self): + "Prevent recurrence of a bug in the html5lib treebuilder." + content = """ + + + + + +""" + soup = self.soup(content) + self.assertConnectedness(soup.article) + + def test_basic_namespaces(self): + """Parsers don't need to *understand* namespaces, but at the + very least they should not choke on namespaces or lose + data.""" + + markup = b'4' + soup = self.soup(markup) + self.assertEqual(markup, soup.encode()) + html = soup.html + self.assertEqual('http://www.w3.org/1999/xhtml', soup.html['xmlns']) + self.assertEqual( + 'http://www.w3.org/1998/Math/MathML', soup.html['xmlns:mathml']) + self.assertEqual( + 'http://www.w3.org/2000/svg', soup.html['xmlns:svg']) + + def test_multivalued_attribute_value_becomes_list(self): + markup = b'' + soup = self.soup(markup) + self.assertEqual(['foo', 'bar'], soup.a['class']) + + # + # Generally speaking, tests below this point are more tests of + # Beautiful Soup than tests of the tree builders. But parsers are + # weird, so we run these tests separately for every tree builder + # to detect any differences between them. + # + + def test_can_parse_unicode_document(self): + # A seemingly innocuous document... but it's in Unicode! And + # it contains characters that can't be represented in the + # encoding found in the declaration! The horror! + markup = u'Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!' + soup = self.soup(markup) + self.assertEqual(u'Sacr\xe9 bleu!', soup.body.string) + + def test_soupstrainer(self): + """Parsers should be able to work with SoupStrainers.""" + strainer = SoupStrainer("b") + soup = self.soup("A bold statement", + parse_only=strainer) + self.assertEqual(soup.decode(), "bold") + + def test_single_quote_attribute_values_become_double_quotes(self): + self.assertSoupEquals("", + '') + + def test_attribute_values_with_nested_quotes_are_left_alone(self): + text = """a""" + self.assertSoupEquals(text) + + def test_attribute_values_with_double_nested_quotes_get_quoted(self): + text = """a""" + soup = self.soup(text) + soup.foo['attr'] = 'Brawls happen at "Bob\'s Bar"' + self.assertSoupEquals( + soup.foo.decode(), + """a""") + + def test_ampersand_in_attribute_value_gets_escaped(self): + self.assertSoupEquals('', + '') + + self.assertSoupEquals( + 'foo', + 'foo') + + def test_escaped_ampersand_in_attribute_value_is_left_alone(self): + self.assertSoupEquals('') + + def test_entities_in_strings_converted_during_parsing(self): + # Both XML and HTML entities are converted to Unicode characters + # during parsing. + text = "

    <<sacré bleu!>>

    " + expected = u"

    <<sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!>>

    " + self.assertSoupEquals(text, expected) + + def test_smart_quotes_converted_on_the_way_in(self): + # Microsoft smart quotes are converted to Unicode characters during + # parsing. + quote = b"

    \x91Foo\x92

    " + soup = self.soup(quote) + self.assertEqual( + soup.p.string, + u"\N{LEFT SINGLE QUOTATION MARK}Foo\N{RIGHT SINGLE QUOTATION MARK}") + + def test_non_breaking_spaces_converted_on_the_way_in(self): + soup = self.soup("  ") + self.assertEqual(soup.a.string, u"\N{NO-BREAK SPACE}" * 2) + + def test_entities_converted_on_the_way_out(self): + text = "

    <<sacré bleu!>>

    " + expected = u"

    <<sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!>>

    ".encode("utf-8") + soup = self.soup(text) + self.assertEqual(soup.p.encode("utf-8"), expected) + + def test_real_iso_latin_document(self): + # Smoke test of interrelated functionality, using an + # easy-to-understand document. + + # Here it is in Unicode. Note that it claims to be in ISO-Latin-1. + unicode_html = u'

    Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!

    ' + + # That's because we're going to encode it into ISO-Latin-1, and use + # that to test. + iso_latin_html = unicode_html.encode("iso-8859-1") + + # Parse the ISO-Latin-1 HTML. + soup = self.soup(iso_latin_html) + # Encode it to UTF-8. + result = soup.encode("utf-8") + + # What do we expect the result to look like? Well, it would + # look like unicode_html, except that the META tag would say + # UTF-8 instead of ISO-Latin-1. + expected = unicode_html.replace("ISO-Latin-1", "utf-8") + + # And, of course, it would be in UTF-8, not Unicode. + expected = expected.encode("utf-8") + + # Ta-da! + self.assertEqual(result, expected) + + def test_real_shift_jis_document(self): + # Smoke test to make sure the parser can handle a document in + # Shift-JIS encoding, without choking. + shift_jis_html = ( + b'
    '
    +            b'\x82\xb1\x82\xea\x82\xcdShift-JIS\x82\xc5\x83R\x81[\x83f'
    +            b'\x83B\x83\x93\x83O\x82\xb3\x82\xea\x82\xbd\x93\xfa\x96{\x8c'
    +            b'\xea\x82\xcc\x83t\x83@\x83C\x83\x8b\x82\xc5\x82\xb7\x81B'
    +            b'
    ') + unicode_html = shift_jis_html.decode("shift-jis") + soup = self.soup(unicode_html) + + # Make sure the parse tree is correctly encoded to various + # encodings. + self.assertEqual(soup.encode("utf-8"), unicode_html.encode("utf-8")) + self.assertEqual(soup.encode("euc_jp"), unicode_html.encode("euc_jp")) + + def test_real_hebrew_document(self): + # A real-world test to make sure we can convert ISO-8859-9 (a + # Hebrew encoding) to UTF-8. + hebrew_document = b'Hebrew (ISO 8859-8) in Visual Directionality

    Hebrew (ISO 8859-8) in Visual Directionality

    \xed\xe5\xec\xf9' + soup = self.soup( + hebrew_document, from_encoding="iso8859-8") + # Some tree builders call it iso8859-8, others call it iso-8859-9. + # That's not a difference we really care about. + assert soup.original_encoding in ('iso8859-8', 'iso-8859-8') + self.assertEqual( + soup.encode('utf-8'), + hebrew_document.decode("iso8859-8").encode("utf-8")) + + def test_meta_tag_reflects_current_encoding(self): + # Here's the tag saying that a document is + # encoded in Shift-JIS. + meta_tag = ('') + + # Here's a document incorporating that meta tag. + shift_jis_html = ( + '\n%s\n' + '' + 'Shift-JIS markup goes here.') % meta_tag + soup = self.soup(shift_jis_html) + + # Parse the document, and the charset is seemingly unaffected. + parsed_meta = soup.find('meta', {'http-equiv': 'Content-type'}) + content = parsed_meta['content'] + self.assertEqual('text/html; charset=x-sjis', content) + + # But that value is actually a ContentMetaAttributeValue object. + self.assertTrue(isinstance(content, ContentMetaAttributeValue)) + + # And it will take on a value that reflects its current + # encoding. + self.assertEqual('text/html; charset=utf8', content.encode("utf8")) + + # For the rest of the story, see TestSubstitutions in + # test_tree.py. + + def test_html5_style_meta_tag_reflects_current_encoding(self): + # Here's the tag saying that a document is + # encoded in Shift-JIS. + meta_tag = ('') + + # Here's a document incorporating that meta tag. + shift_jis_html = ( + '\n%s\n' + '' + 'Shift-JIS markup goes here.') % meta_tag + soup = self.soup(shift_jis_html) + + # Parse the document, and the charset is seemingly unaffected. + parsed_meta = soup.find('meta', id="encoding") + charset = parsed_meta['charset'] + self.assertEqual('x-sjis', charset) + + # But that value is actually a CharsetMetaAttributeValue object. + self.assertTrue(isinstance(charset, CharsetMetaAttributeValue)) + + # And it will take on a value that reflects its current + # encoding. + self.assertEqual('utf8', charset.encode("utf8")) + + def test_tag_with_no_attributes_can_have_attributes_added(self): + data = self.soup("text") + data.a['foo'] = 'bar' + self.assertEqual('text', data.a.decode()) + +class XMLTreeBuilderSmokeTest(object): + + def test_pickle_and_unpickle_identity(self): + # Pickling a tree, then unpickling it, yields a tree identical + # to the original. + tree = self.soup("foo") + dumped = pickle.dumps(tree, 2) + loaded = pickle.loads(dumped) + self.assertEqual(loaded.__class__, BeautifulSoup) + self.assertEqual(loaded.decode(), tree.decode()) + + def test_docstring_generated(self): + soup = self.soup("") + self.assertEqual( + soup.encode(), b'\n') + + def test_xml_declaration(self): + markup = b"""\n""" + soup = self.soup(markup) + self.assertEqual(markup, soup.encode("utf8")) + + def test_processing_instruction(self): + markup = b"""\n""" + soup = self.soup(markup) + self.assertEqual(markup, soup.encode("utf8")) + + def test_real_xhtml_document(self): + """A real XHTML document should come out *exactly* the same as it went in.""" + markup = b""" + + +Hello. +Goodbye. +""" + soup = self.soup(markup) + self.assertEqual( + soup.encode("utf-8"), markup) + + def test_formatter_processes_script_tag_for_xml_documents(self): + doc = """ + +""" + soup = BeautifulSoup(doc, "lxml-xml") + # lxml would have stripped this while parsing, but we can add + # it later. + soup.script.string = 'console.log("< < hey > > ");' + encoded = soup.encode() + self.assertTrue(b"< < hey > >" in encoded) + + def test_can_parse_unicode_document(self): + markup = u'Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!' + soup = self.soup(markup) + self.assertEqual(u'Sacr\xe9 bleu!', soup.root.string) + + def test_popping_namespaced_tag(self): + markup = 'b2012-07-02T20:33:42Zcd' + soup = self.soup(markup) + self.assertEqual( + unicode(soup.rss), markup) + + def test_docstring_includes_correct_encoding(self): + soup = self.soup("") + self.assertEqual( + soup.encode("latin1"), + b'\n') + + def test_large_xml_document(self): + """A large XML document should come out the same as it went in.""" + markup = (b'\n' + + b'0' * (2**12) + + b'') + soup = self.soup(markup) + self.assertEqual(soup.encode("utf-8"), markup) + + + def test_tags_are_empty_element_if_and_only_if_they_are_empty(self): + self.assertSoupEquals("

    ", "

    ") + self.assertSoupEquals("

    foo

    ") + + def test_namespaces_are_preserved(self): + markup = 'This tag is in the a namespaceThis tag is in the b namespace' + soup = self.soup(markup) + root = soup.root + self.assertEqual("http://example.com/", root['xmlns:a']) + self.assertEqual("http://example.net/", root['xmlns:b']) + + def test_closing_namespaced_tag(self): + markup = '

    20010504

    ' + soup = self.soup(markup) + self.assertEqual(unicode(soup.p), markup) + + def test_namespaced_attributes(self): + markup = '' + soup = self.soup(markup) + self.assertEqual(unicode(soup.foo), markup) + + def test_namespaced_attributes_xml_namespace(self): + markup = 'bar' + soup = self.soup(markup) + self.assertEqual(unicode(soup.foo), markup) + + def test_find_by_prefixed_name(self): + doc = """ +foo + bar + baz + +""" + soup = self.soup(doc) + + # There are three tags. + self.assertEqual(3, len(soup.find_all('tag'))) + + # But two of them are ns1:tag and one of them is ns2:tag. + self.assertEqual(2, len(soup.find_all('ns1:tag'))) + self.assertEqual(1, len(soup.find_all('ns2:tag'))) + + self.assertEqual(1, len(soup.find_all('ns2:tag', key='value'))) + self.assertEqual(3, len(soup.find_all(['ns1:tag', 'ns2:tag']))) + + def test_copy_tag_preserves_namespace(self): + xml = """ +""" + + soup = self.soup(xml) + tag = soup.document + duplicate = copy.copy(tag) + + # The two tags have the same namespace prefix. + self.assertEqual(tag.prefix, duplicate.prefix) + + +class HTML5TreeBuilderSmokeTest(HTMLTreeBuilderSmokeTest): + """Smoke test for a tree builder that supports HTML5.""" + + def test_real_xhtml_document(self): + # Since XHTML is not HTML5, HTML5 parsers are not tested to handle + # XHTML documents in any particular way. + pass + + def test_html_tags_have_namespace(self): + markup = "" + soup = self.soup(markup) + self.assertEqual("http://www.w3.org/1999/xhtml", soup.a.namespace) + + def test_svg_tags_have_namespace(self): + markup = '' + soup = self.soup(markup) + namespace = "http://www.w3.org/2000/svg" + self.assertEqual(namespace, soup.svg.namespace) + self.assertEqual(namespace, soup.circle.namespace) + + + def test_mathml_tags_have_namespace(self): + markup = '5' + soup = self.soup(markup) + namespace = 'http://www.w3.org/1998/Math/MathML' + self.assertEqual(namespace, soup.math.namespace) + self.assertEqual(namespace, soup.msqrt.namespace) + + def test_xml_declaration_becomes_comment(self): + markup = '' + soup = self.soup(markup) + self.assertTrue(isinstance(soup.contents[0], Comment)) + self.assertEqual(soup.contents[0], '?xml version="1.0" encoding="utf-8"?') + self.assertEqual("html", soup.contents[0].next_element.name) + +def skipIf(condition, reason): + def nothing(test, *args, **kwargs): + return None + + def decorator(test_item): + if condition: + return nothing + else: + return test_item + + return decorator diff --git a/venv/lib/python2.7/site-packages/bs4/testing.pyc b/venv/lib/python2.7/site-packages/bs4/testing.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15414d9c8de0408b75f61d06dabc355f2fd2b31a GIT binary patch literal 38579 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 b+`oEa^gwQS@X(_NziWNhy6fP(2ao=L_LP=* literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/bs4/tests/__init__.py b/venv/lib/python2.7/site-packages/bs4/tests/__init__.py new file mode 100644 index 0000000..142c8cc --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/tests/__init__.py @@ -0,0 +1 @@ +"The beautifulsoup tests." diff --git a/venv/lib/python2.7/site-packages/bs4/tests/__init__.pyc b/venv/lib/python2.7/site-packages/bs4/tests/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5450ceb308105205d723201c4d2eb67fbce1d0d GIT binary patch literal 244 zcmY+8KMTSz5XDm+DuTOX$1ZvnLqQO65CjJoom@iGq&Bs-p-Cz(PJUy*fL9U32k&=( z;JDX+jfT&Me@e+$9@aJ53=x8m6VfAxu-EOzh+{4TE)!=}=1NmL9aw3sneM~x)cOd< zM4d7gVoQE76^@`A)h1R#n>3KsrI3w*j6xp84UO7@UgmL>^J)>#&RJgEW~g%oN6<=7 rxKpK=%7<&nHf^e5*jY(e_S&mm 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python2.7/site-packages/bs4/tests/test_docs.py b/venv/lib/python2.7/site-packages/bs4/tests/test_docs.py new file mode 100644 index 0000000..5b9f677 --- /dev/null +++ b/venv/lib/python2.7/site-packages/bs4/tests/test_docs.py @@ -0,0 +1,36 @@ +"Test harness for doctests." + +# pylint: disable-msg=E0611,W0142 + +__metaclass__ = type +__all__ = [ + 'additional_tests', + ] + +import atexit +import doctest +import os +#from pkg_resources import ( +# resource_filename, resource_exists, resource_listdir, cleanup_resources) +import unittest + +DOCTEST_FLAGS = ( + doctest.ELLIPSIS | + doctest.NORMALIZE_WHITESPACE | + doctest.REPORT_NDIFF) + + +# def additional_tests(): +# "Run the doc tests (README.txt and docs/*, if any exist)" +# doctest_files = [ +# os.path.abspath(resource_filename('bs4', 'README.txt'))] +# if resource_exists('bs4', 'docs'): +# for name in resource_listdir('bs4', 'docs'): +# if name.endswith('.txt'): +# doctest_files.append( +# os.path.abspath( +# resource_filename('bs4', 'docs/%s' % name))) +# kwargs = dict(module_relative=False, optionflags=DOCTEST_FLAGS) +# atexit.register(cleanup_resources) +# return unittest.TestSuite(( +# doctest.DocFileSuite(*doctest_files, **kwargs))) diff --git a/venv/lib/python2.7/site-packages/bs4/tests/test_docs.pyc b/venv/lib/python2.7/site-packages/bs4/tests/test_docs.pyc new file mode 100644 index 0000000000000000000000000000000000000000..498f7dea70515517289af650fd84ec3c03dd30a5 GIT binary patch literal 530 zcmYLF!EWL(5S@?^+Ac_Y=&2`;Tv``3LaJ0%OG{`|v4BXVm3&DJb|BPEqS#@V%bxa+ z`vL95E!wgC{AS+B&mQ}&bMo(Ri>}}+8hHM|t)3A$00j^h&<1b|)<|sN$Ze1gQ0Ks# zK${2d0(B3(1+)dC3ELxs$8c9CCvZo<)pvwFr*=9+h=kJJ4J$LDR5!`XF3(pQYwALO zN11V+>NL-oj7>Ft$C&ooDCrhL9AkeR>-s*uFNE%x;;YbXC7DtveYP>>tAI(U z_26=yY_`8IG1eK0NRbxj%PN)p{A$mh9!6v-Sf$gXk}9tXk1Ul(%$y9?vr!kt-u&g} aHRqKSw-)-VdbF tags where other parsers don't.""" + markup = ('' + '' + "') + + self.assertSoupEquals( + markup, + '
    Here's another table:" + '' + '' + '
    foo
    Here\'s another table:' + '
    foo
    ' + '
    ') + + self.assertSoupEquals( + "" + "" + "
    Foo
    Bar
    Baz
    ") + + def test_xml_declaration_followed_by_doctype(self): + markup = ''' + + + + + +

    foo

    + +''' + soup = self.soup(markup) + # Verify that we can reach the

    tag; this means the tree is connected. + self.assertEqual(b"

    foo

    ", soup.p.encode()) + + def test_reparented_markup(self): + markup = '

    foo

    \n

    bar

    ' + soup = self.soup(markup) + self.assertEqual(u"

    foo

    \n

    bar

    ", soup.body.decode()) + self.assertEqual(2, len(soup.find_all('p'))) + + + def test_reparented_markup_ends_with_whitespace(self): + markup = '

    foo

    \n

    bar

    \n' + soup = self.soup(markup) + self.assertEqual(u"

    foo

    \n

    bar

    \n", soup.body.decode()) + self.assertEqual(2, len(soup.find_all('p'))) + + def test_reparented_markup_containing_identical_whitespace_nodes(self): + """Verify that we keep the two whitespace nodes in this + document distinct when reparenting the adjacent tags. + """ + markup = '
    ' + soup = self.soup(markup) + space1, space2 = soup.find_all(string=' ') + tbody1, tbody2 = soup.find_all('tbody') + assert space1.next_element is tbody1 + assert tbody2.next_element is space2 + + def test_reparented_markup_containing_children(self): + markup = '' + soup = self.soup(markup) + noscript = soup.noscript + self.assertEqual("target", noscript.next_element) + target = soup.find(string='target') + + # The 'aftermath' string was duplicated; we want the second one. + final_aftermath = soup.find_all(string='aftermath')[-1] + + # The