From c2361f3a8190189c229b8e4a18e44d998e0ab290 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Tue, 21 Sep 2021 22:33:46 +0300 Subject: [PATCH] .venv update --- .../MarkupSafe-2.0.1.dist-info/LICENSE.rst | 28 - .../MarkupSafe-2.0.1.dist-info/METADATA | 100 - .../MarkupSafe-2.0.1.dist-info/RECORD | 13 - .../MarkupSafe-2.0.1.dist-info/WHEEL | 5 - .../MarkupSafe-2.0.1.dist-info/top_level.txt | 1 - .../__pycache__/bottle.cpython-39.pyc | Bin 145408 -> 145408 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 240386 -> 240386 bytes .../__pycache__/whichcraft.cpython-39.pyc | Bin 1932 -> 1932 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 5099 -> 5099 bytes .../__pycache__/override.cpython-39.pyc | Bin 230 -> 230 bytes .../anyio-3.3.1.dist-info/INSTALLER | 1 - .../anyio-3.3.1.dist-info/LICENSE | 20 - .../anyio-3.3.1.dist-info/METADATA | 102 - .../anyio-3.3.1.dist-info/RECORD | 82 - .../anyio-3.3.1.dist-info/entry_points.txt | 3 - .../anyio-3.3.1.dist-info/top_level.txt | 1 - .../.venv/Lib/site-packages/anyio/__init__.py | 112 - .../anyio/__pycache__/__init__.cpython-39.pyc | Bin 3080 -> 0 bytes .../__pycache__/from_thread.cpython-39.pyc | Bin 15812 -> 0 bytes .../anyio/__pycache__/lowlevel.cpython-39.pyc | Bin 5123 -> 0 bytes .../__pycache__/pytest_plugin.cpython-39.pyc | Bin 4910 -> 0 bytes .../__pycache__/to_process.cpython-39.pyc | Bin 6248 -> 0 bytes .../__pycache__/to_thread.cpython-39.pyc | Bin 2266 -> 0 bytes .../site-packages/anyio/_backends/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 179 -> 0 bytes .../__pycache__/_asyncio.cpython-39.pyc | Bin 56490 -> 0 bytes .../__pycache__/_trio.cpython-39.pyc | Bin 28930 -> 0 bytes .../site-packages/anyio/_backends/_asyncio.py | 1897 --------- .../site-packages/anyio/_backends/_trio.py | 788 ---- .../Lib/site-packages/anyio/_core/__init__.py | 0 .../_core/__pycache__/__init__.cpython-39.pyc | Bin 175 -> 0 bytes .../_core/__pycache__/_compat.cpython-39.pyc | Bin 7711 -> 0 bytes .../__pycache__/_eventloop.cpython-39.pyc | Bin 4372 -> 0 bytes .../__pycache__/_exceptions.cpython-39.pyc | Bin 4795 -> 0 bytes .../_core/__pycache__/_fileio.cpython-39.pyc | Bin 22410 -> 0 bytes .../__pycache__/_resources.cpython-39.pyc | Bin 670 -> 0 bytes .../_core/__pycache__/_signals.cpython-39.pyc | Bin 1042 -> 0 bytes .../_core/__pycache__/_sockets.cpython-39.pyc | Bin 15955 -> 0 bytes .../_core/__pycache__/_streams.cpython-39.pyc | Bin 1514 -> 0 bytes .../__pycache__/_subprocesses.cpython-39.pyc | Bin 4110 -> 0 bytes .../_synchronization.cpython-39.pyc | Bin 18920 -> 0 bytes .../_core/__pycache__/_tasks.cpython-39.pyc | Bin 6256 -> 0 bytes .../_core/__pycache__/_testing.cpython-39.pyc | Bin 2787 -> 0 bytes .../__pycache__/_typedattr.cpython-39.pyc | Bin 3227 -> 0 bytes .../Lib/site-packages/anyio/_core/_compat.py | 175 - .../site-packages/anyio/_core/_eventloop.py | 142 - .../site-packages/anyio/_core/_exceptions.py | 85 - .../Lib/site-packages/anyio/_core/_fileio.py | 527 --- .../site-packages/anyio/_core/_resources.py | 16 - .../Lib/site-packages/anyio/_core/_signals.py | 22 - .../Lib/site-packages/anyio/_core/_sockets.py | 503 --- .../Lib/site-packages/anyio/_core/_streams.py | 42 - .../anyio/_core/_subprocesses.py | 91 - .../anyio/_core/_synchronization.py | 554 --- .../Lib/site-packages/anyio/_core/_tasks.py | 158 - .../Lib/site-packages/anyio/_core/_testing.py | 74 - .../site-packages/anyio/_core/_typedattr.py | 79 - .../Lib/site-packages/anyio/abc/__init__.py | 33 - .../abc/__pycache__/__init__.cpython-39.pyc | Bin 1703 -> 0 bytes .../abc/__pycache__/_resources.cpython-39.pyc | Bin 1336 -> 0 bytes .../abc/__pycache__/_sockets.cpython-39.pyc | Bin 6657 -> 0 bytes .../abc/__pycache__/_streams.cpython-39.pyc | Bin 7466 -> 0 bytes .../__pycache__/_subprocesses.cpython-39.pyc | Bin 2901 -> 0 bytes .../abc/__pycache__/_tasks.cpython-39.pyc | Bin 3727 -> 0 bytes .../abc/__pycache__/_testing.cpython-39.pyc | Bin 1824 -> 0 bytes .../Lib/site-packages/anyio/abc/_resources.py | 26 - .../Lib/site-packages/anyio/abc/_sockets.py | 156 - .../Lib/site-packages/anyio/abc/_streams.py | 187 - .../site-packages/anyio/abc/_subprocesses.py | 77 - .../Lib/site-packages/anyio/abc/_tasks.py | 87 - .../Lib/site-packages/anyio/abc/_testing.py | 37 - .../Lib/site-packages/anyio/from_thread.py | 406 -- .../.venv/Lib/site-packages/anyio/lowlevel.py | 160 - .../.venv/Lib/site-packages/anyio/py.typed | 0 .../Lib/site-packages/anyio/pytest_plugin.py | 152 - .../site-packages/anyio/streams/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 177 -> 0 bytes .../__pycache__/buffered.cpython-39.pyc | Bin 3940 -> 0 bytes .../streams/__pycache__/file.cpython-39.pyc | Bin 5385 -> 0 bytes .../streams/__pycache__/memory.cpython-39.pyc | Bin 8475 -> 0 bytes .../__pycache__/stapled.cpython-39.pyc | Bin 5349 -> 0 bytes .../streams/__pycache__/text.cpython-39.pyc | Bin 6225 -> 0 bytes .../streams/__pycache__/tls.cpython-39.pyc | Bin 10073 -> 0 bytes .../site-packages/anyio/streams/buffered.py | 116 - .../Lib/site-packages/anyio/streams/file.py | 139 - .../Lib/site-packages/anyio/streams/memory.py | 256 -- .../site-packages/anyio/streams/stapled.py | 124 - .../Lib/site-packages/anyio/streams/text.py | 130 - .../Lib/site-packages/anyio/streams/tls.py | 262 -- .../Lib/site-packages/anyio/to_process.py | 230 -- .../Lib/site-packages/anyio/to_thread.py | 54 - .../__pycache__/__init__.cpython-39.pyc | Bin 327 -> 327 bytes .../__pycache__/plugin.cpython-39.pyc | Bin 531 -> 531 bytes .../__pycache__/server.cpython-39.pyc | Bin 955 -> 955 bytes .../bs4/__pycache__/__init__.cpython-39.pyc | Bin 23181 -> 23181 bytes .../bs4/__pycache__/dammit.cpython-39.pyc | Bin 71367 -> 71367 bytes .../bs4/__pycache__/diagnose.cpython-39.pyc | Bin 8458 -> 8458 bytes .../bs4/__pycache__/element.cpython-39.pyc | Bin 65429 -> 65429 bytes .../bs4/__pycache__/formatter.cpython-39.pyc | Bin 6171 -> 6171 bytes .../bs4/__pycache__/testing.cpython-39.pyc | Bin 44336 -> 44336 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 15403 -> 15403 bytes .../__pycache__/_html5lib.cpython-39.pyc | Bin 12493 -> 12493 bytes .../__pycache__/_htmlparser.cpython-39.pyc | Bin 13066 -> 13066 bytes .../builder/__pycache__/_lxml.cpython-39.pyc | Bin 9498 -> 9498 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 255 -> 255 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 420 -> 420 bytes .../certifi/__pycache__/core.cpython-39.pyc | Bin 1146 -> 1146 bytes .../cffi/__pycache__/__init__.cpython-39.pyc | Bin 509 -> 509 bytes .../cffi/__pycache__/api.cpython-39.pyc | Bin 34352 -> 34352 bytes .../__pycache__/backend_ctypes.cpython-39.pyc | Bin 39949 -> 39949 bytes .../__pycache__/cffi_opcode.cpython-39.pyc | Bin 4745 -> 4745 bytes .../__pycache__/commontypes.cpython-39.pyc | Bin 1890 -> 1890 bytes .../cffi/__pycache__/cparser.cpython-39.pyc | Bin 23713 -> 23713 bytes .../cffi/__pycache__/error.cpython-39.pyc | Bin 1510 -> 1510 bytes .../__pycache__/ffiplatform.cpython-39.pyc | Bin 3567 -> 3567 bytes .../cffi/__pycache__/lock.cpython-39.pyc | Bin 407 -> 407 bytes .../cffi/__pycache__/model.cpython-39.pyc | Bin 19749 -> 19749 bytes .../cffi/__pycache__/pkgconfig.cpython-39.pyc | Bin 5145 -> 5145 bytes .../__pycache__/recompiler.cpython-39.pyc | Bin 46944 -> 46944 bytes .../__pycache__/setuptools_ext.cpython-39.pyc | Bin 7284 -> 7284 bytes .../__pycache__/vengine_cpy.cpython-39.pyc | Bin 35470 -> 35470 bytes .../__pycache__/vengine_gen.cpython-39.pyc | Bin 21007 -> 21007 bytes .../cffi/__pycache__/verifier.cpython-39.pyc | Bin 9313 -> 9313 bytes .../INSTALLER | 1 - .../charset_normalizer-2.0.4.dist-info/RECORD | 33 - .../charset_normalizer-2.0.4.dist-info/WHEEL | 5 - .../INSTALLER | 0 .../LICENSE | 0 .../METADATA | 43 +- .../charset_normalizer-2.0.6.dist-info/RECORD | 33 + .../WHEEL | 0 .../entry_points.txt | 0 .../top_level.txt | 0 .../charset_normalizer/__init__.py | 43 +- .../__pycache__/__init__.cpython-39.pyc | Bin 1883 -> 1562 bytes .../__pycache__/api.cpython-39.pyc | Bin 9653 -> 10169 bytes .../__pycache__/cd.cpython-39.pyc | Bin 7146 -> 7172 bytes .../__pycache__/constant.cpython-39.pyc | Bin 12953 -> 13451 bytes .../__pycache__/legacy.cpython-39.pyc | Bin 1447 -> 3032 bytes .../__pycache__/md.cpython-39.pyc | Bin 14076 -> 14330 bytes .../__pycache__/models.cpython-39.pyc | Bin 12463 -> 12948 bytes .../__pycache__/utils.cpython-39.pyc | Bin 7220 -> 7421 bytes .../__pycache__/version.cpython-39.pyc | Bin 266 -> 266 bytes .../site-packages/charset_normalizer/api.py | 371 +- .../charset_normalizer/assets/__init__.py | 1247 +++++- .../__pycache__/__init__.cpython-39.pyc | Bin 7275 -> 7449 bytes .../site-packages/charset_normalizer/cd.py | 112 +- .../cli/__pycache__/__init__.cpython-39.pyc | Bin 186 -> 186 bytes .../cli/__pycache__/normalizer.cpython-39.pyc | Bin 5856 -> 6134 bytes .../charset_normalizer/cli/normalizer.py | 230 +- .../charset_normalizer/constant.py | 662 +-- .../charset_normalizer/legacy.py | 79 +- .../site-packages/charset_normalizer/md.py | 238 +- .../charset_normalizer/models.py | 153 +- .../site-packages/charset_normalizer/utils.py | 88 +- .../charset_normalizer/version.py | 4 +- .../eel/__pycache__/__init__.cpython-39.pyc | Bin 10162 -> 10162 bytes .../eel/__pycache__/__main__.cpython-39.pyc | Bin 1209 -> 1209 bytes .../eel/__pycache__/browsers.cpython-39.pyc | Bin 1908 -> 1908 bytes .../eel/__pycache__/chrome.cpython-39.pyc | Bin 2664 -> 2664 bytes .../eel/__pycache__/edge.cpython-39.pyc | Bin 659 -> 659 bytes .../eel/__pycache__/electron.cpython-39.pyc | Bin 845 -> 845 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 3140 -> 3140 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 637 -> 637 bytes .../__pycache__/_markupbase.cpython-39.pyc | Bin 9464 -> 9464 bytes .../__pycache__/datetime.cpython-39.pyc | Bin 49343 -> 49343 bytes .../backports/__pycache__/misc.cpython-39.pyc | Bin 28773 -> 28773 bytes .../__pycache__/socket.cpython-39.pyc | Bin 14280 -> 14280 bytes .../__pycache__/socketserver.cpython-39.pyc | Bin 22289 -> 22289 bytes .../__pycache__/total_ordering.cpython-39.pyc | Bin 2270 -> 2270 bytes .../email/__pycache__/__init__.cpython-39.pyc | Bin 2043 -> 2043 bytes .../__pycache__/_encoded_words.cpython-39.pyc | Bin 6164 -> 6164 bytes .../_header_value_parser.cpython-39.pyc | Bin 80106 -> 80106 bytes .../__pycache__/_parseaddr.cpython-39.pyc | Bin 12581 -> 12581 bytes .../__pycache__/_policybase.cpython-39.pyc | Bin 14643 -> 14643 bytes .../__pycache__/base64mime.cpython-39.pyc | Bin 3485 -> 3485 bytes .../email/__pycache__/charset.cpython-39.pyc | Bin 11886 -> 11886 bytes .../email/__pycache__/encoders.cpython-39.pyc | Bin 2176 -> 2176 bytes .../email/__pycache__/errors.cpython-39.pyc | Bin 5937 -> 5937 bytes .../__pycache__/feedparser.cpython-39.pyc | Bin 10687 -> 10687 bytes .../__pycache__/generator.cpython-39.pyc | Bin 11773 -> 11773 bytes .../email/__pycache__/header.cpython-39.pyc | Bin 17020 -> 17020 bytes .../__pycache__/headerregistry.cpython-39.pyc | Bin 21198 -> 21198 bytes .../__pycache__/iterators.cpython-39.pyc | Bin 2179 -> 2179 bytes .../email/__pycache__/message.cpython-39.pyc | Bin 28634 -> 28634 bytes .../email/__pycache__/parser.cpython-39.pyc | Bin 6086 -> 6086 bytes .../email/__pycache__/policy.cpython-39.pyc | Bin 8361 -> 8361 bytes .../__pycache__/quoprimime.cpython-39.pyc | Bin 9316 -> 9316 bytes .../email/__pycache__/utils.cpython-39.pyc | Bin 10382 -> 10382 bytes .../mime/__pycache__/__init__.cpython-39.pyc | Bin 191 -> 191 bytes .../__pycache__/application.cpython-39.pyc | Bin 1634 -> 1634 bytes .../mime/__pycache__/audio.cpython-39.pyc | Bin 2799 -> 2799 bytes .../mime/__pycache__/base.cpython-39.pyc | Bin 1123 -> 1123 bytes .../mime/__pycache__/image.cpython-39.pyc | Bin 2079 -> 2079 bytes .../mime/__pycache__/message.cpython-39.pyc | Bin 1465 -> 1465 bytes .../mime/__pycache__/multipart.cpython-39.pyc | Bin 1664 -> 1664 bytes .../__pycache__/nonmultipart.cpython-39.pyc | Bin 975 -> 975 bytes .../mime/__pycache__/text.cpython-39.pyc | Bin 1491 -> 1491 bytes .../html/__pycache__/__init__.cpython-39.pyc | Bin 1043 -> 1043 bytes .../html/__pycache__/entities.cpython-39.pyc | Bin 50750 -> 50750 bytes .../html/__pycache__/parser.cpython-39.pyc | Bin 13632 -> 13632 bytes .../http/__pycache__/__init__.cpython-39.pyc | Bin 185 -> 185 bytes .../http/__pycache__/client.cpython-39.pyc | Bin 30752 -> 30752 bytes .../http/__pycache__/cookiejar.cpython-39.pyc | Bin 53855 -> 53855 bytes .../http/__pycache__/cookies.cpython-39.pyc | Bin 16330 -> 16330 bytes .../http/__pycache__/server.cpython-39.pyc | Bin 34448 -> 34448 bytes .../test/__pycache__/__init__.cpython-39.pyc | Bin 457 -> 457 bytes .../test/__pycache__/pystone.cpython-39.pyc | Bin 6761 -> 6761 bytes .../__pycache__/ssl_servers.cpython-39.pyc | Bin 7093 -> 7093 bytes .../test/__pycache__/support.cpython-39.pyc | Bin 55875 -> 55875 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 187 -> 187 bytes .../urllib/__pycache__/error.cpython-39.pyc | Bin 2683 -> 2683 bytes .../urllib/__pycache__/parse.cpython-39.pyc | Bin 28870 -> 28870 bytes .../urllib/__pycache__/request.cpython-39.pyc | Bin 69753 -> 69753 bytes .../__pycache__/response.cpython-39.pyc | Bin 3926 -> 3926 bytes .../__pycache__/robotparser.cpython-39.pyc | Bin 6127 -> 6127 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 187 -> 187 bytes .../xmlrpc/__pycache__/client.cpython-39.pyc | Bin 33750 -> 33750 bytes .../xmlrpc/__pycache__/server.cpython-39.pyc | Bin 29885 -> 29885 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1247 -> 1247 bytes .../__pycache__/disabled.cpython-39.pyc | Bin 2343 -> 2343 bytes .../__pycache__/iterators.cpython-39.pyc | Bin 1520 -> 1520 bytes .../builtins/__pycache__/misc.cpython-39.pyc | Bin 3071 -> 3071 bytes .../__pycache__/new_min_max.cpython-39.pyc | Bin 1584 -> 1584 bytes .../__pycache__/newnext.cpython-39.pyc | Bin 2038 -> 2038 bytes .../__pycache__/newround.cpython-39.pyc | Bin 2821 -> 2821 bytes .../__pycache__/newsuper.cpython-39.pyc | Bin 2855 -> 2855 bytes .../moves/__pycache__/__init__.cpython-39.pyc | Bin 382 -> 382 bytes .../__pycache__/_dummy_thread.cpython-39.pyc | Bin 359 -> 359 bytes .../__pycache__/_markupbase.cpython-39.pyc | Bin 353 -> 353 bytes .../moves/__pycache__/_thread.cpython-39.pyc | Bin 341 -> 341 bytes .../moves/__pycache__/builtins.cpython-39.pyc | Bin 375 -> 375 bytes .../__pycache__/collections.cpython-39.pyc | Bin 630 -> 630 bytes .../__pycache__/configparser.cpython-39.pyc | Bin 331 -> 331 bytes .../moves/__pycache__/copyreg.cpython-39.pyc | Bin 399 -> 399 bytes .../__pycache__/itertools.cpython-39.pyc | Bin 360 -> 360 bytes .../moves/__pycache__/pickle.cpython-39.pyc | Bin 391 -> 391 bytes .../moves/__pycache__/queue.cpython-39.pyc | Bin 336 -> 336 bytes .../moves/__pycache__/reprlib.cpython-39.pyc | Bin 339 -> 339 bytes .../__pycache__/socketserver.cpython-39.pyc | Bin 357 -> 357 bytes .../__pycache__/subprocess.cpython-39.pyc | Bin 474 -> 474 bytes .../moves/__pycache__/sys.cpython-39.pyc | Bin 329 -> 329 bytes .../moves/__pycache__/winreg.cpython-39.pyc | Bin 340 -> 340 bytes .../dbm/__pycache__/__init__.cpython-39.pyc | Bin 475 -> 475 bytes .../moves/dbm/__pycache__/dumb.cpython-39.pyc | Bin 344 -> 344 bytes .../moves/dbm/__pycache__/gnu.cpython-39.pyc | Bin 339 -> 339 bytes .../moves/dbm/__pycache__/ndbm.cpython-39.pyc | Bin 340 -> 340 bytes .../html/__pycache__/__init__.cpython-39.pyc | Bin 857 -> 857 bytes .../html/__pycache__/entities.cpython-39.pyc | Bin 361 -> 361 bytes .../html/__pycache__/parser.cpython-39.pyc | Bin 353 -> 353 bytes .../http/__pycache__/__init__.cpython-39.pyc | Bin 253 -> 253 bytes .../http/__pycache__/client.cpython-39.pyc | Bin 334 -> 334 bytes .../http/__pycache__/cookiejar.cpython-39.pyc | Bin 358 -> 358 bytes .../http/__pycache__/cookies.cpython-39.pyc | Bin 380 -> 380 bytes .../http/__pycache__/server.cpython-39.pyc | Bin 569 -> 569 bytes .../test/__pycache__/__init__.cpython-39.pyc | Bin 303 -> 303 bytes .../test/__pycache__/support.cpython-39.pyc | Bin 463 -> 463 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 707 -> 707 bytes .../__pycache__/colorchooser.cpython-39.pyc | Bin 483 -> 483 bytes .../__pycache__/commondialog.cpython-39.pyc | Bin 483 -> 483 bytes .../__pycache__/constants.cpython-39.pyc | Bin 471 -> 471 bytes .../tkinter/__pycache__/dialog.cpython-39.pyc | Bin 455 -> 455 bytes .../tkinter/__pycache__/dnd.cpython-39.pyc | Bin 447 -> 447 bytes .../__pycache__/filedialog.cpython-39.pyc | Bin 471 -> 471 bytes .../tkinter/__pycache__/font.cpython-39.pyc | Bin 451 -> 451 bytes .../__pycache__/messagebox.cpython-39.pyc | Bin 475 -> 475 bytes .../__pycache__/scrolledtext.cpython-39.pyc | Bin 479 -> 479 bytes .../__pycache__/simpledialog.cpython-39.pyc | Bin 479 -> 479 bytes .../tkinter/__pycache__/tix.cpython-39.pyc | Bin 443 -> 443 bytes .../tkinter/__pycache__/ttk.cpython-39.pyc | Bin 443 -> 443 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 305 -> 305 bytes .../urllib/__pycache__/error.cpython-39.pyc | Bin 545 -> 545 bytes .../urllib/__pycache__/parse.cpython-39.pyc | Bin 786 -> 786 bytes .../urllib/__pycache__/request.cpython-39.pyc | Bin 1082 -> 1082 bytes .../__pycache__/response.cpython-39.pyc | Bin 493 -> 493 bytes .../__pycache__/robotparser.cpython-39.pyc | Bin 368 -> 368 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 183 -> 183 bytes .../xmlrpc/__pycache__/client.cpython-39.pyc | Bin 330 -> 330 bytes .../xmlrpc/__pycache__/server.cpython-39.pyc | Bin 330 -> 330 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 18411 -> 18411 bytes .../tests/__pycache__/__init__.cpython-39.pyc | Bin 176 -> 176 bytes .../tests/__pycache__/base.cpython-39.pyc | Bin 16680 -> 16680 bytes .../types/__pycache__/__init__.cpython-39.pyc | Bin 6004 -> 6004 bytes .../types/__pycache__/newbytes.cpython-39.pyc | Bin 14337 -> 14337 bytes .../types/__pycache__/newdict.cpython-39.pyc | Bin 3610 -> 3610 bytes .../types/__pycache__/newint.cpython-39.pyc | Bin 12565 -> 12565 bytes .../types/__pycache__/newlist.cpython-39.pyc | Bin 3090 -> 3090 bytes .../__pycache__/newmemoryview.cpython-39.pyc | Bin 995 -> 995 bytes .../__pycache__/newobject.cpython-39.pyc | Bin 2662 -> 2662 bytes .../types/__pycache__/newopen.cpython-39.pyc | Bin 1599 -> 1599 bytes .../types/__pycache__/newrange.cpython-39.pyc | Bin 6127 -> 6127 bytes .../types/__pycache__/newstr.cpython-39.pyc | Bin 14556 -> 14556 bytes .../utils/__pycache__/__init__.cpython-39.pyc | Bin 20282 -> 20282 bytes .../surrogateescape.cpython-39.pyc | Bin 3838 -> 3838 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2457 -> 2457 bytes .../_abstract_linkable.cpython-39.pyc | Bin 10350 -> 10350 bytes .../gevent/__pycache__/_compat.cpython-39.pyc | Bin 5307 -> 5307 bytes .../gevent/__pycache__/_config.cpython-39.pyc | Bin 20424 -> 20424 bytes .../_fileobjectcommon.cpython-39.pyc | Bin 18945 -> 18945 bytes .../_fileobjectposix.cpython-39.pyc | Bin 10451 -> 10451 bytes .../_greenlet_primitives.cpython-39.pyc | Bin 2895 -> 2895 bytes .../__pycache__/_hub_local.cpython-39.pyc | Bin 2809 -> 2809 bytes .../_hub_primitives.cpython-39.pyc | Bin 12046 -> 12046 bytes .../gevent/__pycache__/_ident.cpython-39.pyc | Bin 2111 -> 2111 bytes .../gevent/__pycache__/_imap.cpython-39.pyc | Bin 6249 -> 6249 bytes .../__pycache__/_interfaces.cpython-39.pyc | Bin 11656 -> 11656 bytes .../__pycache__/_monitor.cpython-39.pyc | Bin 8070 -> 8070 bytes .../__pycache__/_patcher.cpython-39.pyc | Bin 7188 -> 7188 bytes .../__pycache__/_semaphore.cpython-39.pyc | Bin 13055 -> 13055 bytes .../__pycache__/_socket2.cpython-39.pyc | Bin 8040 -> 8040 bytes .../__pycache__/_socket3.cpython-39.pyc | Bin 16262 -> 16262 bytes .../__pycache__/_socketcommon.cpython-39.pyc | Bin 16986 -> 16986 bytes .../gevent/__pycache__/_ssl2.cpython-39.pyc | Bin 11356 -> 11356 bytes .../gevent/__pycache__/_ssl3.cpython-39.pyc | Bin 20369 -> 20369 bytes .../__pycache__/_sslgte279.cpython-39.pyc | Bin 18696 -> 18696 bytes .../gevent/__pycache__/_tblib.cpython-39.pyc | Bin 10057 -> 10057 bytes .../__pycache__/_threading.cpython-39.pyc | Bin 4937 -> 4937 bytes .../gevent/__pycache__/_tracer.cpython-39.pyc | Bin 4841 -> 4841 bytes .../gevent/__pycache__/_util.cpython-39.pyc | Bin 9160 -> 9160 bytes .../__pycache__/_util_py2.cpython-39.pyc | Bin 645 -> 645 bytes .../gevent/__pycache__/_waiter.cpython-39.pyc | Bin 6954 -> 6954 bytes .../gevent/__pycache__/ares.cpython-39.pyc | Bin 408 -> 408 bytes .../__pycache__/backdoor.cpython-39.pyc | Bin 7824 -> 7824 bytes .../__pycache__/baseserver.cpython-39.pyc | Bin 13075 -> 13075 bytes .../__pycache__/builtins.cpython-39.pyc | Bin 2742 -> 2742 bytes .../__pycache__/contextvars.cpython-39.pyc | Bin 9756 -> 9756 bytes .../gevent/__pycache__/core.cpython-39.pyc | Bin 561 -> 561 bytes .../gevent/__pycache__/event.cpython-39.pyc | Bin 15255 -> 15255 bytes .../gevent/__pycache__/events.cpython-39.pyc | Bin 15303 -> 15303 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 4675 -> 4675 bytes .../__pycache__/fileobject.cpython-39.pyc | Bin 2884 -> 2884 bytes .../__pycache__/greenlet.cpython-39.pyc | Bin 33212 -> 33212 bytes .../gevent/__pycache__/hub.cpython-39.pyc | Bin 22991 -> 22991 bytes .../gevent/__pycache__/local.cpython-39.pyc | Bin 12984 -> 12984 bytes .../gevent/__pycache__/lock.cpython-39.pyc | Bin 11095 -> 11095 bytes .../gevent/__pycache__/monkey.cpython-39.pyc | Bin 35279 -> 35279 bytes .../gevent/__pycache__/os.cpython-39.pyc | Bin 13953 -> 13953 bytes .../gevent/__pycache__/pool.cpython-39.pyc | Bin 24110 -> 24110 bytes .../gevent/__pycache__/pywsgi.cpython-39.pyc | Bin 39483 -> 39483 bytes .../gevent/__pycache__/queue.cpython-39.pyc | Bin 21182 -> 21182 bytes .../__pycache__/resolver_ares.cpython-39.pyc | Bin 605 -> 605 bytes .../resolver_thread.cpython-39.pyc | Bin 621 -> 621 bytes .../gevent/__pycache__/select.cpython-39.pyc | Bin 7665 -> 7665 bytes .../__pycache__/selectors.cpython-39.pyc | Bin 5619 -> 5619 bytes .../gevent/__pycache__/server.cpython-39.pyc | Bin 8610 -> 8610 bytes .../gevent/__pycache__/signal.cpython-39.pyc | Bin 4075 -> 4075 bytes .../gevent/__pycache__/socket.cpython-39.pyc | Bin 3209 -> 3209 bytes .../gevent/__pycache__/ssl.cpython-39.pyc | Bin 917 -> 917 bytes .../__pycache__/subprocess.cpython-39.pyc | Bin 43435 -> 43435 bytes .../gevent/__pycache__/thread.cpython-39.pyc | Bin 3178 -> 3178 bytes .../__pycache__/threading.cpython-39.pyc | Bin 5661 -> 5661 bytes .../__pycache__/threadpool.cpython-39.pyc | Bin 23165 -> 23165 bytes .../gevent/__pycache__/time.cpython-39.pyc | Bin 565 -> 565 bytes .../gevent/__pycache__/timeout.cpython-39.pyc | Bin 11230 -> 11230 bytes .../gevent/__pycache__/util.cpython-39.pyc | Bin 19517 -> 19517 bytes .../__pycache__/win32util.cpython-39.pyc | Bin 2677 -> 2677 bytes .../_ffi/__pycache__/__init__.cpython-39.pyc | Bin 801 -> 801 bytes .../_ffi/__pycache__/callback.cpython-39.pyc | Bin 1631 -> 1631 bytes .../_ffi/__pycache__/loop.cpython-39.pyc | Bin 19149 -> 19149 bytes .../_ffi/__pycache__/watcher.cpython-39.pyc | Bin 19398 -> 19398 bytes .../libev/__pycache__/__init__.cpython-39.pyc | Bin 309 -> 309 bytes .../_corecffi_build.cpython-39.pyc | Bin 1962 -> 1962 bytes .../libev/__pycache__/corecffi.cpython-39.pyc | Bin 13573 -> 13573 bytes .../libev/__pycache__/watcher.cpython-39.pyc | Bin 9062 -> 9062 bytes .../libuv/__pycache__/__init__.cpython-39.pyc | Bin 309 -> 309 bytes .../_corecffi_build.cpython-39.pyc | Bin 5675 -> 5675 bytes .../libuv/__pycache__/loop.cpython-39.pyc | Bin 12870 -> 12870 bytes .../libuv/__pycache__/watcher.cpython-39.pyc | Bin 19324 -> 19324 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 7109 -> 7109 bytes .../__pycache__/_addresses.cpython-39.pyc | Bin 2988 -> 2988 bytes .../__pycache__/_hostsfile.cpython-39.pyc | Bin 2873 -> 2873 bytes .../resolver/__pycache__/ares.cpython-39.pyc | Bin 9426 -> 9426 bytes .../__pycache__/blocking.cpython-39.pyc | Bin 1544 -> 1544 bytes .../__pycache__/dnspython.cpython-39.pyc | Bin 11418 -> 11418 bytes .../__pycache__/thread.cpython-39.pyc | Bin 2826 -> 2826 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 4164 -> 4164 bytes .../__pycache__/errorhandler.cpython-39.pyc | Bin 1355 -> 1355 bytes .../__pycache__/exception.cpython-39.pyc | Bin 522 -> 522 bytes .../testing/__pycache__/flaky.cpython-39.pyc | Bin 2980 -> 2980 bytes .../testing/__pycache__/hub.cpython-39.pyc | Bin 1940 -> 1940 bytes .../__pycache__/leakcheck.cpython-39.pyc | Bin 5361 -> 5361 bytes .../__pycache__/modules.cpython-39.pyc | Bin 2556 -> 2556 bytes .../__pycache__/monkey_test.cpython-39.pyc | Bin 2150 -> 2150 bytes .../__pycache__/openfiles.cpython-39.pyc | Bin 4970 -> 4970 bytes .../testing/__pycache__/params.cpython-39.pyc | Bin 811 -> 811 bytes .../patched_tests_setup.cpython-39.pyc | Bin 27136 -> 27136 bytes .../__pycache__/resources.cpython-39.pyc | Bin 3186 -> 3186 bytes .../testing/__pycache__/six.cpython-39.pyc | Bin 1039 -> 1039 bytes .../__pycache__/skipping.cpython-39.pyc | Bin 3700 -> 3700 bytes .../__pycache__/sockets.cpython-39.pyc | Bin 1326 -> 1326 bytes .../__pycache__/support.cpython-39.pyc | Bin 3669 -> 3669 bytes .../__pycache__/switching.cpython-39.pyc | Bin 1570 -> 1570 bytes .../__pycache__/sysinfo.cpython-39.pyc | Bin 3713 -> 3713 bytes .../__pycache__/testcase.cpython-39.pyc | Bin 14095 -> 14095 bytes .../__pycache__/testrunner.cpython-39.pyc | Bin 22995 -> 22995 bytes .../testing/__pycache__/timing.cpython-39.pyc | Bin 3970 -> 3970 bytes .../testing/__pycache__/travis.cpython-39.pyc | Bin 1243 -> 1243 bytes .../testing/__pycache__/util.cpython-39.pyc | Bin 16291 -> 16291 bytes .../__pycache__/sitecustomize.cpython-39.pyc | Bin 496 -> 496 bytes .../tests/__pycache__/__init__.cpython-39.pyc | Bin 176 -> 176 bytes .../tests/__pycache__/__main__.cpython-39.pyc | Bin 365 -> 365 bytes .../_blocks_at_top_level.cpython-39.pyc | Bin 258 -> 258 bytes .../_import_import_patch.cpython-39.pyc | Bin 220 -> 220 bytes .../__pycache__/_import_patch.cpython-39.pyc | Bin 245 -> 245 bytes .../__pycache__/_import_wait.cpython-39.pyc | Bin 727 -> 727 bytes .../_imports_at_top_level.cpython-39.pyc | Bin 213 -> 213 bytes ...mports_imports_at_top_level.cpython-39.pyc | Bin 388 -> 388 bytes .../getaddrinfo_module.cpython-39.pyc | Bin 300 -> 300 bytes .../__pycache__/known_failures.cpython-39.pyc | Bin 15206 -> 15206 bytes .../__pycache__/lock_tests.cpython-39.pyc | Bin 23525 -> 23525 bytes .../test__GreenletExit.cpython-39.pyc | Bin 299 -> 299 bytes .../__pycache__/test___config.cpython-39.pyc | Bin 6051 -> 6051 bytes .../__pycache__/test___ident.cpython-39.pyc | Bin 2349 -> 2349 bytes .../__pycache__/test___monitor.cpython-39.pyc | Bin 12632 -> 12632 bytes .../test___monkey_patching.cpython-39.pyc | Bin 2997 -> 2997 bytes .../__pycache__/test__all__.cpython-39.pyc | Bin 7389 -> 7389 bytes .../__pycache__/test__api.cpython-39.pyc | Bin 4095 -> 4095 bytes .../test__api_timeout.cpython-39.pyc | Bin 5725 -> 5725 bytes .../test__ares_host_result.cpython-39.pyc | Bin 1285 -> 1285 bytes .../test__ares_timeout.cpython-39.pyc | Bin 1459 -> 1459 bytes .../__pycache__/test__backdoor.cpython-39.pyc | Bin 6892 -> 6892 bytes .../test__close_backend_fd.cpython-39.pyc | Bin 2678 -> 2678 bytes .../__pycache__/test__compat.cpython-39.pyc | Bin 2637 -> 2637 bytes .../test__contextvars.cpython-39.pyc | Bin 10925 -> 10925 bytes .../__pycache__/test__core.cpython-39.pyc | Bin 5898 -> 5898 bytes .../test__core_async.cpython-39.pyc | Bin 1070 -> 1070 bytes .../test__core_callback.cpython-39.pyc | Bin 996 -> 996 bytes .../test__core_fork.cpython-39.pyc | Bin 1726 -> 1726 bytes .../test__core_loop_run.cpython-39.pyc | Bin 757 -> 757 bytes .../test__core_stat.cpython-39.pyc | Bin 3422 -> 3422 bytes .../test__core_timer.cpython-39.pyc | Bin 4086 -> 4086 bytes .../test__core_watcher.cpython-39.pyc | Bin 3554 -> 3554 bytes .../__pycache__/test__destroy.cpython-39.pyc | Bin 1067 -> 1067 bytes .../test__destroy_default_loop.cpython-39.pyc | Bin 1732 -> 1732 bytes .../__pycache__/test__doctests.cpython-39.pyc | Bin 3748 -> 3748 bytes .../__pycache__/test__environ.cpython-39.pyc | Bin 592 -> 592 bytes .../__pycache__/test__event.cpython-39.pyc | Bin 16069 -> 16069 bytes .../__pycache__/test__events.cpython-39.pyc | Bin 1935 -> 1935 bytes .../test__example_echoserver.cpython-39.pyc | Bin 1489 -> 1489 bytes ...test__example_portforwarder.cpython-39.pyc | Bin 2049 -> 2049 bytes .../test__example_udp_client.cpython-39.pyc | Bin 1172 -> 1172 bytes .../test__example_udp_server.cpython-39.pyc | Bin 886 -> 886 bytes .../test__example_webproxy.cpython-39.pyc | Bin 1241 -> 1241 bytes .../test__example_wsgiserver.cpython-39.pyc | Bin 2650 -> 2650 bytes ...est__example_wsgiserver_ssl.cpython-39.pyc | Bin 858 -> 858 bytes .../__pycache__/test__examples.cpython-39.pyc | Bin 3389 -> 3389 bytes .../__pycache__/test__exc_info.cpython-39.pyc | Bin 1791 -> 1791 bytes .../test__execmodules.cpython-39.pyc | Bin 1579 -> 1579 bytes .../test__fileobject.cpython-39.pyc | Bin 17220 -> 17220 bytes .../test__getaddrinfo_import.cpython-39.pyc | Bin 226 -> 226 bytes .../__pycache__/test__greenio.cpython-39.pyc | Bin 3364 -> 3364 bytes .../__pycache__/test__greenlet.cpython-39.pyc | Bin 36313 -> 36313 bytes .../test__greenletset.cpython-39.pyc | Bin 6337 -> 6337 bytes .../test__greenness.cpython-39.pyc | Bin 2338 -> 2338 bytes .../__pycache__/test__hub.cpython-39.pyc | Bin 12323 -> 12323 bytes .../__pycache__/test__hub_join.cpython-39.pyc | Bin 3778 -> 3778 bytes .../test__hub_join_timeout.cpython-39.pyc | Bin 3978 -> 3978 bytes ...import_blocking_in_greenlet.cpython-39.pyc | Bin 750 -> 750 bytes .../test__import_wait.cpython-39.pyc | Bin 282 -> 282 bytes .../__pycache__/test__issue112.cpython-39.pyc | Bin 751 -> 751 bytes .../test__issue1686.cpython-39.pyc | Bin 1901 -> 1901 bytes .../__pycache__/test__issue230.cpython-39.pyc | Bin 895 -> 895 bytes .../__pycache__/test__issue330.cpython-39.pyc | Bin 2505 -> 2505 bytes .../__pycache__/test__issue467.cpython-39.pyc | Bin 1181 -> 1181 bytes .../__pycache__/test__issue6.cpython-39.pyc | Bin 1144 -> 1144 bytes .../__pycache__/test__issue600.cpython-39.pyc | Bin 1415 -> 1415 bytes .../__pycache__/test__issue607.cpython-39.pyc | Bin 1903 -> 1903 bytes .../__pycache__/test__issue639.cpython-39.pyc | Bin 586 -> 586 bytes .../test__issue_728.cpython-39.pyc | Bin 321 -> 321 bytes .../test__issues461_471.cpython-39.pyc | Bin 2305 -> 2305 bytes .../__pycache__/test__iwait.cpython-39.pyc | Bin 1435 -> 1435 bytes .../__pycache__/test__joinall.cpython-39.pyc | Bin 735 -> 735 bytes .../__pycache__/test__local.cpython-39.pyc | Bin 14157 -> 14157 bytes .../__pycache__/test__lock.cpython-39.pyc | Bin 1008 -> 1008 bytes .../test__loop_callback.cpython-39.pyc | Bin 840 -> 840 bytes .../test__makefile_ref.cpython-39.pyc | Bin 14144 -> 14144 bytes .../__pycache__/test__memleak.cpython-39.pyc | Bin 1227 -> 1227 bytes .../__pycache__/test__monkey.cpython-39.pyc | Bin 5479 -> 5479 bytes ...est__monkey_builtins_future.cpython-39.pyc | Bin 552 -> 552 bytes ...test__monkey_futures_thread.cpython-39.pyc | Bin 1327 -> 1327 bytes .../test__monkey_hub_in_thread.cpython-39.pyc | Bin 712 -> 712 bytes .../test__monkey_logging.cpython-39.pyc | Bin 1379 -> 1379 bytes .../test__monkey_module_run.cpython-39.pyc | Bin 4052 -> 4052 bytes ...st__monkey_multiple_imports.cpython-39.pyc | Bin 236 -> 236 bytes .../test__monkey_queue.cpython-39.pyc | Bin 8880 -> 8880 bytes .../test__monkey_select.cpython-39.pyc | Bin 1000 -> 1000 bytes .../test__monkey_selectors.cpython-39.pyc | Bin 2314 -> 2314 bytes .../test__monkey_sigchld.cpython-39.pyc | Bin 1733 -> 1733 bytes .../test__monkey_sigchld_2.cpython-39.pyc | Bin 961 -> 961 bytes .../test__monkey_sigchld_3.cpython-39.pyc | Bin 1165 -> 1165 bytes .../test__monkey_ssl_warning.cpython-39.pyc | Bin 1238 -> 1238 bytes .../test__monkey_ssl_warning2.cpython-39.pyc | Bin 1552 -> 1552 bytes .../test__monkey_ssl_warning3.cpython-39.pyc | Bin 1575 -> 1575 bytes .../test__nondefaultloop.cpython-39.pyc | Bin 403 -> 403 bytes .../__pycache__/test__order.cpython-39.pyc | Bin 2239 -> 2239 bytes .../tests/__pycache__/test__os.cpython-39.pyc | Bin 10358 -> 10358 bytes .../__pycache__/test__pool.cpython-39.pyc | Bin 22135 -> 22135 bytes .../__pycache__/test__pywsgi.cpython-39.pyc | Bin 64538 -> 64538 bytes .../__pycache__/test__queue.cpython-39.pyc | Bin 16581 -> 16581 bytes .../test__real_greenlet.cpython-39.pyc | Bin 1162 -> 1162 bytes .../__pycache__/test__refcount.cpython-39.pyc | Bin 4385 -> 4385 bytes .../test__refcount_core.cpython-39.pyc | Bin 1148 -> 1148 bytes .../test__resolver_dnspython.cpython-39.pyc | Bin 1655 -> 1655 bytes .../__pycache__/test__select.cpython-39.pyc | Bin 4046 -> 4046 bytes .../test__selectors.cpython-39.pyc | Bin 3174 -> 3174 bytes .../test__semaphore.cpython-39.pyc | Bin 11923 -> 11923 bytes .../__pycache__/test__server.cpython-39.pyc | Bin 19483 -> 19483 bytes .../test__server_pywsgi.cpython-39.pyc | Bin 3727 -> 3727 bytes .../__pycache__/test__signal.cpython-39.pyc | Bin 2662 -> 2662 bytes .../__pycache__/test__sleep0.cpython-39.pyc | Bin 348 -> 348 bytes .../__pycache__/test__socket.cpython-39.pyc | Bin 18778 -> 18778 bytes .../test__socket_close.cpython-39.pyc | Bin 2040 -> 2040 bytes .../test__socket_dns.cpython-39.pyc | Bin 26507 -> 26507 bytes .../test__socket_dns6.cpython-39.pyc | Bin 3044 -> 3044 bytes .../test__socket_errors.cpython-39.pyc | Bin 1195 -> 1195 bytes .../test__socket_ex.cpython-39.pyc | Bin 1341 -> 1341 bytes ...est__socket_send_memoryview.cpython-39.pyc | Bin 1581 -> 1581 bytes .../test__socket_ssl.cpython-39.pyc | Bin 1313 -> 1313 bytes .../test__socket_timeout.cpython-39.pyc | Bin 1794 -> 1794 bytes .../test__socketpair.cpython-39.pyc | Bin 1346 -> 1346 bytes .../__pycache__/test__ssl.cpython-39.pyc | Bin 3306 -> 3306 bytes .../test__subprocess.cpython-39.pyc | Bin 15778 -> 15778 bytes ...est__subprocess_interrupted.cpython-39.pyc | Bin 808 -> 808 bytes .../test__subprocess_poll.cpython-39.pyc | Bin 478 -> 478 bytes .../test__systemerror.cpython-39.pyc | Bin 3657 -> 3657 bytes .../__pycache__/test__thread.cpython-39.pyc | Bin 1104 -> 1104 bytes .../test__threading.cpython-39.pyc | Bin 2786 -> 2786 bytes .../test__threading_2.cpython-39.pyc | Bin 19364 -> 19364 bytes ...st__threading_before_monkey.cpython-39.pyc | Bin 842 -> 842 bytes ...g_holding_lock_while_monkey.cpython-39.pyc | Bin 337 -> 337 bytes ..._threading_monkey_in_thread.cpython-39.pyc | Bin 1994 -> 1994 bytes ...eading_native_before_monkey.cpython-39.pyc | Bin 2050 -> 2050 bytes .../test__threading_no_monkey.cpython-39.pyc | Bin 1043 -> 1043 bytes ...st__threading_patched_local.cpython-39.pyc | Bin 761 -> 761 bytes ...test__threading_vs_settrace.cpython-39.pyc | Bin 4138 -> 4138 bytes .../test__threadpool.cpython-39.pyc | Bin 26447 -> 26447 bytes ...threadpool_executor_patched.cpython-39.pyc | Bin 707 -> 707 bytes .../__pycache__/test__timeout.cpython-39.pyc | Bin 5295 -> 5295 bytes .../__pycache__/test__util.cpython-39.pyc | Bin 9565 -> 9565 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 515 -> 515 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 333 -> 333 bytes .../issue1526_no_monkey.cpython-39.pyc | Bin 652 -> 652 bytes .../issue1526_with_monkey.cpython-39.pyc | Bin 790 -> 790 bytes .../__pycache__/issue302monkey.cpython-39.pyc | Bin 600 -> 600 bytes .../__pycache__/script.cpython-39.pyc | Bin 657 -> 657 bytes .../threadpool_monkey_patches.cpython-39.pyc | Bin 1133 -> 1133 bytes .../threadpool_no_monkey.cpython-39.pyc | Bin 1035 -> 1035 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 646 -> 646 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 727 -> 727 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 868 -> 868 bytes .../__pycache__/handler.cpython-39.pyc | Bin 7601 -> 7601 bytes .../__pycache__/logging.cpython-39.pyc | Bin 1453 -> 1453 bytes .../__pycache__/resource.cpython-39.pyc | Bin 3285 -> 3285 bytes .../__pycache__/server.cpython-39.pyc | Bin 1450 -> 1450 bytes .../__pycache__/utf8validator.cpython-39.pyc | Bin 6115 -> 6115 bytes .../__pycache__/utils.cpython-39.pyc | Bin 1224 -> 1224 bytes .../__pycache__/websocket.cpython-39.pyc | Bin 12954 -> 12954 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 188 -> 188 bytes .../__pycache__/workers.cpython-39.pyc | Bin 511 -> 511 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 189 -> 189 bytes .../protocols/__pycache__/base.cpython-39.pyc | Bin 1501 -> 1501 bytes .../protocols/__pycache__/wamp.cpython-39.pyc | Bin 7393 -> 7393 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 835 -> 835 bytes .../tests/__pycache__/__init__.cpython-39.pyc | Bin 178 -> 178 bytes .../test_contextvars.cpython-39.pyc | Bin 7359 -> 7359 bytes .../tests/__pycache__/test_cpp.cpython-39.pyc | Bin 844 -> 844 bytes .../test_extension_interface.cpython-39.pyc | Bin 3547 -> 3547 bytes .../tests/__pycache__/test_gc.cpython-39.pyc | Bin 2900 -> 2900 bytes .../__pycache__/test_generator.cpython-39.pyc | Bin 2220 -> 2220 bytes .../test_generator_nested.cpython-39.pyc | Bin 5327 -> 5327 bytes .../__pycache__/test_greenlet.cpython-39.pyc | Bin 24922 -> 24922 bytes .../__pycache__/test_leaks.cpython-39.pyc | Bin 3174 -> 3174 bytes .../test_stack_saved.cpython-39.pyc | Bin 856 -> 856 bytes .../__pycache__/test_throw.cpython-39.pyc | Bin 2948 -> 2948 bytes .../__pycache__/test_tracing.cpython-39.pyc | Bin 2233 -> 2233 bytes .../__pycache__/test_version.cpython-39.pyc | Bin 1528 -> 1528 bytes .../__pycache__/test_weakref.cpython-39.pyc | Bin 1847 -> 1847 bytes .../h11-0.12.0.dist-info/INSTALLER | 1 - .../h11-0.12.0.dist-info/LICENSE.txt | 22 - .../h11-0.12.0.dist-info/METADATA | 194 - .../site-packages/h11-0.12.0.dist-info/RECORD | 51 - .../site-packages/h11-0.12.0.dist-info/WHEEL | 5 - .../h11-0.12.0.dist-info/top_level.txt | 1 - .../.venv/Lib/site-packages/h11/__init__.py | 21 - .../h11/__pycache__/__init__.cpython-39.pyc | Bin 485 -> 0 bytes .../h11/__pycache__/_abnf.cpython-39.pyc | Bin 1214 -> 0 bytes .../__pycache__/_connection.cpython-39.pyc | Bin 14438 -> 0 bytes .../h11/__pycache__/_events.cpython-39.pyc | Bin 8972 -> 0 bytes .../h11/__pycache__/_headers.cpython-39.pyc | Bin 4618 -> 0 bytes .../h11/__pycache__/_readers.cpython-39.pyc | Bin 5261 -> 0 bytes .../__pycache__/_receivebuffer.cpython-39.pyc | Bin 2968 -> 0 bytes .../h11/__pycache__/_state.cpython-39.pyc | Bin 3743 -> 0 bytes .../h11/__pycache__/_util.cpython-39.pyc | Bin 3212 -> 0 bytes .../h11/__pycache__/_version.cpython-39.pyc | Bin 189 -> 0 bytes .../h11/__pycache__/_writers.cpython-39.pyc | Bin 3479 -> 0 bytes .../.venv/Lib/site-packages/h11/_abnf.py | 129 - .../Lib/site-packages/h11/_connection.py | 585 --- .../.venv/Lib/site-packages/h11/_events.py | 302 -- .../.venv/Lib/site-packages/h11/_headers.py | 242 -- .../.venv/Lib/site-packages/h11/_readers.py | 222 - .../Lib/site-packages/h11/_receivebuffer.py | 152 - .../.venv/Lib/site-packages/h11/_state.py | 307 -- .../.venv/Lib/site-packages/h11/_util.py | 122 - .../.venv/Lib/site-packages/h11/_version.py | 16 - .../.venv/Lib/site-packages/h11/_writers.py | 123 - .../Lib/site-packages/h11/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-39.pyc | Bin 173 -> 0 bytes .../tests/__pycache__/helpers.cpython-39.pyc | Bin 1969 -> 0 bytes .../test_against_stdlib_http.cpython-39.pyc | Bin 3586 -> 0 bytes .../test_connection.cpython-39.pyc | Bin 32093 -> 0 bytes .../__pycache__/test_events.cpython-39.pyc | Bin 3895 -> 0 bytes .../__pycache__/test_headers.cpython-39.pyc | Bin 3517 -> 0 bytes .../__pycache__/test_helpers.cpython-39.pyc | Bin 648 -> 0 bytes .../tests/__pycache__/test_io.cpython-39.pyc | Bin 11687 -> 0 bytes .../test_receivebuffer.cpython-39.pyc | Bin 2241 -> 0 bytes .../__pycache__/test_state.cpython-39.pyc | Bin 5084 -> 0 bytes .../__pycache__/test_util.cpython-39.pyc | Bin 3061 -> 0 bytes .../site-packages/h11/tests/data/test-file | 1 - .../Lib/site-packages/h11/tests/helpers.py | 77 - .../h11/tests/test_against_stdlib_http.py | 111 - .../h11/tests/test_connection.py | 1078 ----- .../site-packages/h11/tests/test_events.py | 179 - .../site-packages/h11/tests/test_headers.py | 151 - .../site-packages/h11/tests/test_helpers.py | 23 - .../Lib/site-packages/h11/tests/test_io.py | 544 --- .../h11/tests/test_receivebuffer.py | 134 - .../Lib/site-packages/h11/tests/test_state.py | 250 -- .../Lib/site-packages/h11/tests/test_util.py | 99 - .../httpcore-0.13.7.dist-info/INSTALLER | 1 - .../httpcore-0.13.7.dist-info/LICENSE.md | 27 - .../httpcore-0.13.7.dist-info/METADATA | 422 -- .../httpcore-0.13.7.dist-info/RECORD | 67 - .../httpcore-0.13.7.dist-info/WHEEL | 5 - .../httpcore-0.13.7.dist-info/top_level.txt | 4 - .../Lib/site-packages/httpcore/__init__.py | 63 - .../__pycache__/__init__.cpython-39.pyc | Bin 1407 -> 0 bytes .../__pycache__/_bytestreams.cpython-39.pyc | Bin 3568 -> 0 bytes .../__pycache__/_exceptions.cpython-39.pyc | Bin 2568 -> 0 bytes .../__pycache__/_threadlock.cpython-39.pyc | Bin 1436 -> 0 bytes .../__pycache__/_types.cpython-39.pyc | Bin 532 -> 0 bytes .../__pycache__/_utils.cpython-39.pyc | Bin 3212 -> 0 bytes .../site-packages/httpcore/_async/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 179 -> 0 bytes .../_async/__pycache__/base.cpython-39.pyc | Bin 4398 -> 0 bytes .../__pycache__/connection.cpython-39.pyc | Bin 7180 -> 0 bytes .../connection_pool.cpython-39.pyc | Bin 10892 -> 0 bytes .../_async/__pycache__/http.cpython-39.pyc | Bin 1938 -> 0 bytes .../_async/__pycache__/http11.cpython-39.pyc | Bin 8721 -> 0 bytes .../_async/__pycache__/http2.cpython-39.pyc | Bin 14369 -> 0 bytes .../__pycache__/http_proxy.cpython-39.pyc | Bin 6253 -> 0 bytes .../Lib/site-packages/httpcore/_async/base.py | 122 - .../httpcore/_async/connection.py | 220 - .../httpcore/_async/connection_pool.py | 362 -- .../Lib/site-packages/httpcore/_async/http.py | 42 - .../site-packages/httpcore/_async/http11.py | 269 -- .../site-packages/httpcore/_async/http2.py | 446 -- .../httpcore/_async/http_proxy.py | 290 -- .../httpcore/_backends/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 182 -> 0 bytes .../__pycache__/anyio.cpython-39.pyc | Bin 7045 -> 0 bytes .../__pycache__/asyncio.cpython-39.pyc | Bin 9058 -> 0 bytes .../_backends/__pycache__/auto.cpython-39.pyc | Bin 2523 -> 0 bytes .../_backends/__pycache__/base.cpython-39.pyc | Bin 5284 -> 0 bytes .../__pycache__/curio.cpython-39.pyc | Bin 6937 -> 0 bytes .../_backends/__pycache__/sync.cpython-39.pyc | Bin 6729 -> 0 bytes .../_backends/__pycache__/trio.cpython-39.pyc | Bin 7260 -> 0 bytes .../site-packages/httpcore/_backends/anyio.py | 201 - .../httpcore/_backends/asyncio.py | 303 -- .../site-packages/httpcore/_backends/auto.py | 67 - .../site-packages/httpcore/_backends/base.py | 137 - .../site-packages/httpcore/_backends/curio.py | 206 - .../site-packages/httpcore/_backends/sync.py | 178 - .../site-packages/httpcore/_backends/trio.py | 212 - .../site-packages/httpcore/_bytestreams.py | 96 - .../Lib/site-packages/httpcore/_exceptions.py | 79 - .../site-packages/httpcore/_sync/__init__.py | 0 .../_sync/__pycache__/__init__.cpython-39.pyc | Bin 178 -> 0 bytes .../_sync/__pycache__/base.cpython-39.pyc | Bin 4315 -> 0 bytes .../__pycache__/connection.cpython-39.pyc | Bin 7041 -> 0 bytes .../connection_pool.cpython-39.pyc | Bin 10644 -> 0 bytes .../_sync/__pycache__/http.cpython-39.pyc | Bin 1928 -> 0 bytes .../_sync/__pycache__/http11.cpython-39.pyc | Bin 8579 -> 0 bytes .../_sync/__pycache__/http2.cpython-39.pyc | Bin 14059 -> 0 bytes .../__pycache__/http_proxy.cpython-39.pyc | Bin 6147 -> 0 bytes .../Lib/site-packages/httpcore/_sync/base.py | 122 - .../httpcore/_sync/connection.py | 220 - .../httpcore/_sync/connection_pool.py | 362 -- .../Lib/site-packages/httpcore/_sync/http.py | 42 - .../site-packages/httpcore/_sync/http11.py | 269 -- .../Lib/site-packages/httpcore/_sync/http2.py | 446 -- .../httpcore/_sync/http_proxy.py | 290 -- .../Lib/site-packages/httpcore/_threadlock.py | 35 - .../Lib/site-packages/httpcore/_types.py | 12 - .../Lib/site-packages/httpcore/_utils.py | 105 - .../.venv/Lib/site-packages/httpcore/py.typed | 0 .../httpx-0.19.0.dist-info/INSTALLER | 1 - .../httpx-0.19.0.dist-info/LICENSE.md | 12 - .../httpx-0.19.0.dist-info/METADATA | 990 ----- .../httpx-0.19.0.dist-info/RECORD | 50 - .../httpx-0.19.0.dist-info/REQUESTED | 0 .../httpx-0.19.0.dist-info/WHEEL | 5 - .../httpx-0.19.0.dist-info/top_level.txt | 2 - .../.venv/Lib/site-packages/httpx/__init__.py | 124 - .../httpx/__pycache__/__init__.cpython-39.pyc | Bin 2452 -> 0 bytes .../__pycache__/__version__.cpython-39.pyc | Bin 287 -> 0 bytes .../httpx/__pycache__/_api.cpython-39.pyc | Bin 7875 -> 0 bytes .../httpx/__pycache__/_auth.cpython-39.pyc | Bin 9281 -> 0 bytes .../httpx/__pycache__/_client.cpython-39.pyc | Bin 41263 -> 0 bytes .../httpx/__pycache__/_compat.cpython-39.pyc | Bin 1164 -> 0 bytes .../httpx/__pycache__/_config.cpython-39.pyc | Bin 9484 -> 0 bytes .../httpx/__pycache__/_content.cpython-39.pyc | Bin 6764 -> 0 bytes .../__pycache__/_decoders.cpython-39.pyc | Bin 10199 -> 0 bytes .../__pycache__/_exceptions.cpython-39.pyc | Bin 10584 -> 0 bytes .../httpx/__pycache__/_models.cpython-39.pyc | Bin 56051 -> 0 bytes .../__pycache__/_multipart.cpython-39.pyc | Bin 6496 -> 0 bytes .../__pycache__/_status_codes.cpython-39.pyc | Bin 5612 -> 0 bytes .../httpx/__pycache__/_types.cpython-39.pyc | Bin 1709 -> 0 bytes .../httpx/__pycache__/_utils.cpython-39.pyc | Bin 14604 -> 0 bytes .../Lib/site-packages/httpx/__version__.py | 3 - .../.venv/Lib/site-packages/httpx/_api.py | 445 -- .../.venv/Lib/site-packages/httpx/_auth.py | 304 -- .../.venv/Lib/site-packages/httpx/_client.py | 2007 --------- .../.venv/Lib/site-packages/httpx/_compat.py | 48 - .../.venv/Lib/site-packages/httpx/_config.py | 349 -- .../.venv/Lib/site-packages/httpx/_content.py | 207 - .../Lib/site-packages/httpx/_decoders.py | 333 -- .../Lib/site-packages/httpx/_exceptions.py | 339 -- .../.venv/Lib/site-packages/httpx/_models.py | 1862 --------- .../Lib/site-packages/httpx/_multipart.py | 209 - .../Lib/site-packages/httpx/_status_codes.py | 143 - .../httpx/_transports/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 181 -> 0 bytes .../__pycache__/asgi.cpython-39.pyc | Bin 4877 -> 0 bytes .../__pycache__/base.cpython-39.pyc | Bin 8143 -> 0 bytes .../__pycache__/default.cpython-39.pyc | Bin 7781 -> 0 bytes .../__pycache__/mock.cpython-39.pyc | Bin 1660 -> 0 bytes .../__pycache__/wsgi.cpython-39.pyc | Bin 4469 -> 0 bytes .../site-packages/httpx/_transports/asgi.py | 169 - .../site-packages/httpx/_transports/base.py | 183 - .../httpx/_transports/default.py | 294 -- .../site-packages/httpx/_transports/mock.py | 70 - .../site-packages/httpx/_transports/wsgi.py | 138 - .../.venv/Lib/site-packages/httpx/_types.py | 91 - .../.venv/Lib/site-packages/httpx/_utils.py | 508 --- .../.venv/Lib/site-packages/httpx/py.typed | 0 .../idna/__pycache__/__init__.cpython-39.pyc | Bin 827 -> 827 bytes .../idna/__pycache__/codec.cpython-39.pyc | Bin 2858 -> 2858 bytes .../idna/__pycache__/compat.cpython-39.pyc | Bin 664 -> 664 bytes .../idna/__pycache__/core.cpython-39.pyc | Bin 9132 -> 9132 bytes .../idna/__pycache__/idnadata.cpython-39.pyc | Bin 22118 -> 22118 bytes .../idna/__pycache__/intranges.cpython-39.pyc | Bin 1840 -> 1840 bytes .../__pycache__/package_data.cpython-39.pyc | Bin 191 -> 191 bytes .../idna/__pycache__/uts46data.cpython-39.pyc | Bin 146151 -> 146151 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 175 -> 175 bytes .../__pycache__/fixer_util.cpython-39.pyc | Bin 11962 -> 11962 bytes .../__pycache__/main.cpython-39.pyc | Bin 9553 -> 9553 bytes .../fixes/__pycache__/__init__.cpython-39.pyc | Bin 1983 -> 1983 bytes .../__pycache__/fix_UserDict.cpython-39.pyc | Bin 2224 -> 2224 bytes .../fix_absolute_import.cpython-39.pyc | Bin 2494 -> 2494 bytes ...rts_except_unicode_literals.cpython-39.pyc | Bin 1087 -> 1087 bytes .../__pycache__/fix_basestring.cpython-39.pyc | Bin 812 -> 812 bytes .../__pycache__/fix_bytes.cpython-39.pyc | Bin 1052 -> 1052 bytes .../fixes/__pycache__/fix_cmp.cpython-39.pyc | Bin 1097 -> 1097 bytes .../__pycache__/fix_division.cpython-39.pyc | Bin 433 -> 433 bytes .../fix_division_safe.cpython-39.pyc | Bin 3048 -> 3048 bytes .../__pycache__/fix_execfile.cpython-39.pyc | Bin 1330 -> 1330 bytes .../fix_future_builtins.cpython-39.pyc | Bin 1744 -> 1744 bytes ...fix_future_standard_library.cpython-39.pyc | Bin 1086 -> 1086 bytes ...ure_standard_library_urllib.cpython-39.pyc | Bin 1152 -> 1152 bytes .../__pycache__/fix_input.cpython-39.pyc | Bin 1090 -> 1090 bytes .../__pycache__/fix_metaclass.cpython-39.pyc | Bin 5805 -> 5805 bytes .../__pycache__/fix_next_call.cpython-39.pyc | Bin 3045 -> 3045 bytes .../__pycache__/fix_object.cpython-39.pyc | Bin 819 -> 819 bytes .../fix_oldstr_wrap.cpython-39.pyc | Bin 1400 -> 1400 bytes ...fix_order___future__imports.cpython-39.pyc | Bin 1047 -> 1047 bytes .../__pycache__/fix_print.cpython-39.pyc | Bin 2413 -> 2413 bytes .../fix_print_with_import.cpython-39.pyc | Bin 966 -> 966 bytes .../__pycache__/fix_raise.cpython-39.pyc | Bin 2506 -> 2506 bytes ...remove_old__future__imports.cpython-39.pyc | Bin 1252 -> 1252 bytes .../fix_unicode_keep_u.cpython-39.pyc | Bin 1175 -> 1175 bytes ...fix_unicode_literals_import.cpython-39.pyc | Bin 818 -> 818 bytes .../fix_xrange_with_import.cpython-39.pyc | Bin 897 -> 897 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 177 -> 177 bytes .../__pycache__/main.cpython-39.pyc | Bin 5904 -> 5904 bytes .../fixes/__pycache__/__init__.cpython-39.pyc | Bin 846 -> 846 bytes .../__pycache__/feature_base.cpython-39.pyc | Bin 2646 -> 2646 bytes ...ix_add_all__future__imports.cpython-39.pyc | Bin 1072 -> 1072 bytes ...fix_add_all_future_builtins.cpython-39.pyc | Bin 1200 -> 1200 bytes ...ure_standard_library_import.cpython-39.pyc | Bin 1001 -> 1001 bytes .../fix_annotations.cpython-39.pyc | Bin 1693 -> 1693 bytes .../__pycache__/fix_division.cpython-39.pyc | Bin 1359 -> 1359 bytes .../__pycache__/fix_features.cpython-39.pyc | Bin 2266 -> 2266 bytes .../fix_fullargspec.cpython-39.pyc | Bin 864 -> 864 bytes .../fix_future_builtins.cpython-39.pyc | Bin 1541 -> 1541 bytes .../__pycache__/fix_getcwd.cpython-39.pyc | Bin 1126 -> 1126 bytes .../__pycache__/fix_imports.cpython-39.pyc | Bin 3611 -> 3611 bytes .../__pycache__/fix_imports2.cpython-39.pyc | Bin 6023 -> 6023 bytes .../__pycache__/fix_kwargs.cpython-39.pyc | Bin 3771 -> 3771 bytes .../__pycache__/fix_memoryview.cpython-39.pyc | Bin 933 -> 933 bytes .../__pycache__/fix_metaclass.cpython-39.pyc | Bin 2025 -> 2025 bytes .../__pycache__/fix_newstyle.cpython-39.pyc | Bin 1218 -> 1218 bytes .../fixes/__pycache__/fix_next.cpython-39.pyc | Bin 1547 -> 1547 bytes .../fix_printfunction.cpython-39.pyc | Bin 806 -> 806 bytes .../__pycache__/fix_raise.cpython-39.pyc | Bin 1348 -> 1348 bytes .../__pycache__/fix_raise_.cpython-39.pyc | Bin 1474 -> 1474 bytes .../__pycache__/fix_throw.cpython-39.pyc | Bin 1207 -> 1207 bytes .../__pycache__/fix_unpacking.cpython-39.pyc | Bin 5667 -> 5667 bytes .../Lib/site-packages/markupsafe/__init__.py | 288 -- .../__pycache__/__init__.cpython-39.pyc | Bin 10679 -> 0 bytes .../__pycache__/_native.cpython-39.pyc | Bin 2326 -> 0 bytes .../Lib/site-packages/markupsafe/_native.py | 75 - .../markupsafe/_speedups.cp39-win_amd64.pyd | Bin 16384 -> 0 bytes .../site-packages/markupsafe/_speedups.pyi | 9 - .../Lib/site-packages/markupsafe/py.typed | 0 .../past/__pycache__/__init__.cpython-39.pyc | Bin 3111 -> 3111 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1626 -> 1626 bytes .../builtins/__pycache__/misc.cpython-39.pyc | Bin 2368 -> 2368 bytes .../__pycache__/noniterators.cpython-39.pyc | Bin 3275 -> 3275 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 11157 -> 11157 bytes .../types/__pycache__/__init__.cpython-39.pyc | Bin 889 -> 889 bytes .../__pycache__/basestring.cpython-39.pyc | Bin 1318 -> 1318 bytes .../types/__pycache__/olddict.cpython-39.pyc | Bin 2375 -> 2375 bytes .../types/__pycache__/oldstr.cpython-39.pyc | Bin 2918 -> 2918 bytes .../utils/__pycache__/__init__.cpython-39.pyc | Bin 3056 -> 3056 bytes .../site-packages/pip-21.2.4.dist-info/RECORD | 6 +- .../pip/__pycache__/__init__.cpython-39.pyc | Bin 623 -> 623 bytes .../pip/__pycache__/__main__.cpython-39.pyc | Bin 579 -> 579 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 744 -> 744 bytes .../__pycache__/build_env.cpython-39.pyc | Bin 9083 -> 9083 bytes .../__pycache__/cache.cpython-39.pyc | Bin 7834 -> 7834 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 10686 -> 10686 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 15635 -> 15635 bytes .../_internal/__pycache__/main.cpython-39.pyc | Bin 568 -> 568 bytes .../__pycache__/pyproject.cpython-39.pyc | Bin 3447 -> 3447 bytes .../self_outdated_check.cpython-39.pyc | Bin 4331 -> 4331 bytes .../__pycache__/wheel_builder.cpython-39.pyc | Bin 8269 -> 8269 bytes .../cli/__pycache__/__init__.cpython-39.pyc | Bin 264 -> 264 bytes .../__pycache__/autocompletion.cpython-39.pyc | Bin 5121 -> 5121 bytes .../__pycache__/base_command.cpython-39.pyc | Bin 6025 -> 6025 bytes .../cli/__pycache__/cmdoptions.cpython-39.pyc | Bin 22481 -> 22481 bytes .../command_context.cpython-39.pyc | Bin 1279 -> 1279 bytes .../cli/__pycache__/main.cpython-39.pyc | Bin 1354 -> 1354 bytes .../__pycache__/main_parser.cpython-39.pyc | Bin 2151 -> 2151 bytes .../cli/__pycache__/parser.cpython-39.pyc | Bin 9935 -> 9935 bytes .../__pycache__/progress_bars.cpython-39.pyc | Bin 7611 -> 7611 bytes .../__pycache__/req_command.cpython-39.pyc | Bin 12046 -> 12046 bytes .../cli/__pycache__/spinners.cpython-39.pyc | Bin 4934 -> 4934 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 343 -> 343 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 3097 -> 3097 bytes .../commands/__pycache__/cache.cpython-39.pyc | Bin 6030 -> 6030 bytes .../commands/__pycache__/check.cpython-39.pyc | Bin 1559 -> 1559 bytes .../__pycache__/completion.cpython-39.pyc | Bin 3128 -> 3128 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 8335 -> 8335 bytes .../commands/__pycache__/debug.cpython-39.pyc | Bin 6656 -> 6656 bytes .../__pycache__/download.cpython-39.pyc | Bin 3979 -> 3979 bytes .../__pycache__/freeze.cpython-39.pyc | Bin 2623 -> 2623 bytes .../commands/__pycache__/hash.cpython-39.pyc | Bin 2121 -> 2121 bytes .../commands/__pycache__/help.cpython-39.pyc | Bin 1295 -> 1295 bytes .../commands/__pycache__/index.cpython-39.pyc | Bin 4514 -> 4514 bytes .../__pycache__/install.cpython-39.pyc | Bin 17648 -> 17648 bytes .../commands/__pycache__/list.cpython-39.pyc | Bin 9950 -> 9950 bytes .../__pycache__/search.cpython-39.pyc | Bin 5307 -> 5307 bytes .../commands/__pycache__/show.cpython-39.pyc | Bin 8370 -> 8370 bytes .../__pycache__/uninstall.cpython-39.pyc | Bin 3089 -> 3089 bytes .../commands/__pycache__/wheel.cpython-39.pyc | Bin 4852 -> 4852 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 787 -> 787 bytes .../__pycache__/base.cpython-39.pyc | Bin 1914 -> 1914 bytes .../__pycache__/installed.cpython-39.pyc | Bin 1233 -> 1233 bytes .../__pycache__/sdist.cpython-39.pyc | Bin 3567 -> 3567 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 1568 -> 1568 bytes .../index/__pycache__/__init__.cpython-39.pyc | Bin 218 -> 218 bytes .../__pycache__/collector.cpython-39.pyc | Bin 15942 -> 15942 bytes .../__pycache__/package_finder.cpython-39.pyc | Bin 28096 -> 28096 bytes .../index/__pycache__/sources.cpython-39.pyc | Bin 7183 -> 7183 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 10044 -> 10044 bytes .../__pycache__/_distutils.cpython-39.pyc | Bin 4657 -> 4657 bytes .../__pycache__/_sysconfig.cpython-39.pyc | Bin 6248 -> 6248 bytes .../locations/__pycache__/base.cpython-39.pyc | Bin 1526 -> 1526 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1839 -> 1839 bytes .../metadata/__pycache__/base.cpython-39.pyc | Bin 9452 -> 9452 bytes .../__pycache__/pkg_resources.cpython-39.pyc | Bin 6153 -> 6153 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 252 -> 252 bytes .../__pycache__/candidate.cpython-39.pyc | Bin 1432 -> 1432 bytes .../__pycache__/direct_url.cpython-39.pyc | Bin 7047 -> 7047 bytes .../__pycache__/format_control.cpython-39.pyc | Bin 2719 -> 2719 bytes .../models/__pycache__/index.cpython-39.pyc | Bin 1231 -> 1231 bytes .../models/__pycache__/link.cpython-39.pyc | Bin 10251 -> 10251 bytes .../models/__pycache__/scheme.cpython-39.pyc | Bin 998 -> 998 bytes .../__pycache__/search_scope.cpython-39.pyc | Bin 3471 -> 3471 bytes .../selection_prefs.cpython-39.pyc | Bin 1654 -> 1654 bytes .../__pycache__/target_python.cpython-39.pyc | Bin 3404 -> 3404 bytes .../models/__pycache__/wheel.cpython-39.pyc | Bin 4332 -> 4332 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 240 -> 240 bytes .../network/__pycache__/auth.cpython-39.pyc | Bin 7437 -> 7437 bytes .../network/__pycache__/cache.cpython-39.pyc | Bin 2882 -> 2882 bytes .../__pycache__/download.cpython-39.pyc | Bin 5471 -> 5471 bytes .../__pycache__/lazy_wheel.cpython-39.pyc | Bin 8337 -> 8337 bytes .../__pycache__/session.cpython-39.pyc | Bin 10536 -> 10536 bytes .../network/__pycache__/utils.cpython-39.pyc | Bin 1418 -> 1418 bytes .../network/__pycache__/xmlrpc.cpython-39.pyc | Bin 2039 -> 2039 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 188 -> 188 bytes .../__pycache__/check.cpython-39.pyc | Bin 3933 -> 3933 bytes .../__pycache__/freeze.cpython-39.pyc | Bin 6274 -> 6274 bytes .../__pycache__/prepare.cpython-39.pyc | Bin 14214 -> 14214 bytes .../build/__pycache__/__init__.cpython-39.pyc | Bin 194 -> 194 bytes .../build/__pycache__/metadata.cpython-39.pyc | Bin 1140 -> 1140 bytes .../metadata_legacy.cpython-39.pyc | Bin 1914 -> 1914 bytes .../build/__pycache__/wheel.cpython-39.pyc | Bin 1119 -> 1119 bytes .../__pycache__/wheel_legacy.cpython-39.pyc | Bin 2513 -> 2513 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 252 -> 252 bytes .../editable_legacy.cpython-39.pyc | Bin 1295 -> 1295 bytes .../install/__pycache__/legacy.cpython-39.pyc | Bin 3456 -> 3456 bytes .../install/__pycache__/wheel.cpython-39.pyc | Bin 20295 -> 20295 bytes .../req/__pycache__/__init__.cpython-39.pyc | Bin 2551 -> 2551 bytes .../__pycache__/constructors.cpython-39.pyc | Bin 11667 -> 11667 bytes .../req/__pycache__/req_file.cpython-39.pyc | Bin 13361 -> 13361 bytes .../__pycache__/req_install.cpython-39.pyc | Bin 21362 -> 21362 bytes .../req/__pycache__/req_set.cpython-39.pyc | Bin 5888 -> 5888 bytes .../__pycache__/req_tracker.cpython-39.pyc | Bin 4271 -> 4271 bytes .../__pycache__/req_uninstall.cpython-39.pyc | Bin 18754 -> 18754 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 188 -> 188 bytes .../__pycache__/base.cpython-39.pyc | Bin 1018 -> 1018 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 195 -> 195 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 11986 -> 11986 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 199 -> 199 bytes .../__pycache__/base.cpython-39.pyc | Bin 6735 -> 6735 bytes .../__pycache__/candidates.cpython-39.pyc | Bin 19026 -> 19026 bytes .../__pycache__/factory.cpython-39.pyc | Bin 18443 -> 18443 bytes .../found_candidates.cpython-39.pyc | Bin 4788 -> 4788 bytes .../__pycache__/provider.cpython-39.pyc | Bin 6745 -> 6745 bytes .../__pycache__/reporter.cpython-39.pyc | Bin 3318 -> 3318 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 7569 -> 7569 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 7764 -> 7764 bytes .../utils/__pycache__/__init__.cpython-39.pyc | Bin 183 -> 183 bytes .../utils/__pycache__/_log.cpython-39.pyc | Bin 1508 -> 1508 bytes .../utils/__pycache__/appdirs.cpython-39.pyc | Bin 1321 -> 1321 bytes .../utils/__pycache__/compat.cpython-39.pyc | Bin 1502 -> 1502 bytes .../compatibility_tags.cpython-39.pyc | Bin 4101 -> 4101 bytes .../utils/__pycache__/datetime.cpython-39.pyc | Bin 502 -> 502 bytes .../__pycache__/deprecation.cpython-39.pyc | Bin 2965 -> 2965 bytes .../direct_url_helpers.cpython-39.pyc | Bin 1812 -> 1812 bytes .../__pycache__/distutils_args.cpython-39.pyc | Bin 1088 -> 1088 bytes .../utils/__pycache__/encoding.cpython-39.pyc | Bin 1292 -> 1292 bytes .../__pycache__/entrypoints.cpython-39.pyc | Bin 1293 -> 1293 bytes .../__pycache__/filesystem.cpython-39.pyc | Bin 5129 -> 5129 bytes .../__pycache__/filetypes.cpython-39.pyc | Bin 795 -> 795 bytes .../utils/__pycache__/glibc.cpython-39.pyc | Bin 1605 -> 1605 bytes .../utils/__pycache__/hashes.cpython-39.pyc | Bin 4987 -> 4987 bytes .../inject_securetransport.cpython-39.pyc | Bin 956 -> 956 bytes .../utils/__pycache__/logging.cpython-39.pyc | Bin 9036 -> 9036 bytes .../utils/__pycache__/misc.cpython-39.pyc | Bin 21656 -> 21656 bytes .../utils/__pycache__/models.cpython-39.pyc | Bin 1887 -> 1887 bytes .../__pycache__/packaging.cpython-39.pyc | Bin 2511 -> 2511 bytes .../utils/__pycache__/parallel.cpython-39.pyc | Bin 3028 -> 3028 bytes .../__pycache__/pkg_resources.cpython-39.pyc | Bin 1709 -> 1709 bytes .../setuptools_build.cpython-39.pyc | Bin 2953 -> 2953 bytes .../__pycache__/subprocess.cpython-39.pyc | Bin 5690 -> 5690 bytes .../utils/__pycache__/temp_dir.cpython-39.pyc | Bin 6827 -> 6827 bytes .../__pycache__/unpacking.cpython-39.pyc | Bin 6471 -> 6471 bytes .../utils/__pycache__/urls.cpython-39.pyc | Bin 1527 -> 1527 bytes .../__pycache__/virtualenv.cpython-39.pyc | Bin 3206 -> 3206 bytes .../utils/__pycache__/wheel.cpython-39.pyc | Bin 5957 -> 5957 bytes .../vcs/__pycache__/__init__.cpython-39.pyc | Bin 506 -> 506 bytes .../vcs/__pycache__/bazaar.cpython-39.pyc | Bin 2992 -> 2992 bytes .../vcs/__pycache__/git.cpython-39.pyc | Bin 11707 -> 11707 bytes .../vcs/__pycache__/mercurial.cpython-39.pyc | Bin 4639 -> 4639 bytes .../vcs/__pycache__/subversion.cpython-39.pyc | Bin 7953 -> 7953 bytes .../__pycache__/versioncontrol.cpython-39.pyc | Bin 19476 -> 19476 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2891 -> 2891 bytes .../__pycache__/appdirs.cpython-39.pyc | Bin 21391 -> 21391 bytes .../_vendor/__pycache__/distro.cpython-39.pyc | Bin 36870 -> 36870 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 240427 -> 240427 bytes .../_vendor/__pycache__/six.cpython-39.pyc | Bin 27500 -> 27500 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 541 -> 541 bytes .../__pycache__/_cmd.cpython-39.pyc | Bin 1562 -> 1562 bytes .../__pycache__/adapter.cpython-39.pyc | Bin 3067 -> 3067 bytes .../__pycache__/cache.cpython-39.pyc | Bin 1814 -> 1814 bytes .../__pycache__/compat.cpython-39.pyc | Bin 738 -> 738 bytes .../__pycache__/controller.cpython-39.pyc | Bin 7755 -> 7755 bytes .../__pycache__/filewrapper.cpython-39.pyc | Bin 2163 -> 2163 bytes .../__pycache__/heuristics.cpython-39.pyc | Bin 4695 -> 4695 bytes .../__pycache__/serialize.cpython-39.pyc | Bin 4214 -> 4214 bytes .../__pycache__/wrapper.cpython-39.pyc | Bin 665 -> 665 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 285 -> 285 bytes .../__pycache__/file_cache.cpython-39.pyc | Bin 3301 -> 3301 bytes .../__pycache__/redis_cache.cpython-39.pyc | Bin 1557 -> 1557 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 267 -> 267 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 444 -> 444 bytes .../certifi/__pycache__/core.cpython-39.pyc | Bin 1535 -> 1535 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1891 -> 1891 bytes .../__pycache__/big5freq.cpython-39.pyc | Bin 27170 -> 27170 bytes .../__pycache__/big5prober.cpython-39.pyc | Bin 1125 -> 1125 bytes .../chardistribution.cpython-39.pyc | Bin 6211 -> 6211 bytes .../charsetgroupprober.cpython-39.pyc | Bin 2252 -> 2252 bytes .../__pycache__/charsetprober.cpython-39.pyc | Bin 3474 -> 3474 bytes .../codingstatemachine.cpython-39.pyc | Bin 2901 -> 2901 bytes .../chardet/__pycache__/compat.cpython-39.pyc | Bin 390 -> 390 bytes .../__pycache__/cp949prober.cpython-39.pyc | Bin 1132 -> 1132 bytes .../chardet/__pycache__/enums.cpython-39.pyc | Bin 2639 -> 2639 bytes .../__pycache__/escprober.cpython-39.pyc | Bin 2624 -> 2624 bytes .../chardet/__pycache__/escsm.cpython-39.pyc | Bin 7073 -> 7073 bytes .../__pycache__/eucjpprober.cpython-39.pyc | Bin 2438 -> 2438 bytes .../__pycache__/euckrfreq.cpython-39.pyc | Bin 12054 -> 12054 bytes .../__pycache__/euckrprober.cpython-39.pyc | Bin 1133 -> 1133 bytes .../__pycache__/euctwfreq.cpython-39.pyc | Bin 27174 -> 27174 bytes .../__pycache__/euctwprober.cpython-39.pyc | Bin 1133 -> 1133 bytes .../__pycache__/gb2312freq.cpython-39.pyc | Bin 19098 -> 19098 bytes .../__pycache__/gb2312prober.cpython-39.pyc | Bin 1141 -> 1141 bytes .../__pycache__/hebrewprober.cpython-39.pyc | Bin 3010 -> 3010 bytes .../__pycache__/jisfreq.cpython-39.pyc | Bin 22126 -> 22126 bytes .../chardet/__pycache__/jpcntx.cpython-39.pyc | Bin 37599 -> 37599 bytes .../langbulgarianmodel.cpython-39.pyc | Bin 21801 -> 21801 bytes .../__pycache__/langgreekmodel.cpython-39.pyc | Bin 20477 -> 20477 bytes .../langhebrewmodel.cpython-39.pyc | Bin 20545 -> 20545 bytes .../langhungarianmodel.cpython-39.pyc | Bin 21746 -> 21746 bytes .../langrussianmodel.cpython-39.pyc | Bin 26349 -> 26349 bytes .../__pycache__/langthaimodel.cpython-39.pyc | Bin 20721 -> 20721 bytes .../langturkishmodel.cpython-39.pyc | Bin 20561 -> 20561 bytes .../__pycache__/latin1prober.cpython-39.pyc | Bin 2946 -> 2946 bytes .../mbcharsetprober.cpython-39.pyc | Bin 2253 -> 2253 bytes .../mbcsgroupprober.cpython-39.pyc | Bin 1122 -> 1122 bytes .../chardet/__pycache__/mbcssm.cpython-39.pyc | Bin 15709 -> 15709 bytes .../sbcharsetprober.cpython-39.pyc | Bin 3106 -> 3106 bytes .../sbcsgroupprober.cpython-39.pyc | Bin 1691 -> 1691 bytes .../__pycache__/sjisprober.cpython-39.pyc | Bin 2474 -> 2474 bytes .../universaldetector.cpython-39.pyc | Bin 5822 -> 5822 bytes .../__pycache__/utf8prober.cpython-39.pyc | Bin 1983 -> 1983 bytes .../__pycache__/version.cpython-39.pyc | Bin 430 -> 430 bytes .../cli/__pycache__/__init__.cpython-39.pyc | Bin 187 -> 187 bytes .../cli/__pycache__/chardetect.cpython-39.pyc | Bin 2681 -> 2681 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 192 -> 192 bytes .../__pycache__/languages.cpython-39.pyc | Bin 7923 -> 7923 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 435 -> 435 bytes .../colorama/__pycache__/ansi.cpython-39.pyc | Bin 3220 -> 3220 bytes .../__pycache__/ansitowin32.cpython-39.pyc | Bin 7686 -> 7686 bytes .../__pycache__/initialise.cpython-39.pyc | Bin 1702 -> 1702 bytes .../colorama/__pycache__/win32.cpython-39.pyc | Bin 3934 -> 3934 bytes .../__pycache__/winterm.cpython-39.pyc | Bin 4656 -> 4656 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1048 -> 1048 bytes .../distlib/__pycache__/compat.cpython-39.pyc | Bin 32150 -> 32150 bytes .../__pycache__/database.cpython-39.pyc | Bin 42472 -> 42472 bytes .../distlib/__pycache__/index.cpython-39.pyc | Bin 17281 -> 17281 bytes .../__pycache__/locators.cpython-39.pyc | Bin 38245 -> 38245 bytes .../__pycache__/manifest.cpython-39.pyc | Bin 10184 -> 10184 bytes .../__pycache__/markers.cpython-39.pyc | Bin 4428 -> 4428 bytes .../__pycache__/metadata.cpython-39.pyc | Bin 26579 -> 26579 bytes .../__pycache__/resources.cpython-39.pyc | Bin 11002 -> 11002 bytes .../__pycache__/scripts.cpython-39.pyc | Bin 11085 -> 11085 bytes .../distlib/__pycache__/util.cpython-39.pyc | Bin 52587 -> 52587 bytes .../__pycache__/version.cpython-39.pyc | Bin 20339 -> 20339 bytes .../distlib/__pycache__/wheel.cpython-39.pyc | Bin 27212 -> 27212 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 475 -> 475 bytes .../_backport/__pycache__/misc.cpython-39.pyc | Bin 1095 -> 1095 bytes .../__pycache__/shutil.cpython-39.pyc | Bin 21669 -> 21669 bytes .../__pycache__/sysconfig.cpython-39.pyc | Bin 15959 -> 15959 bytes .../__pycache__/tarfile.cpython-39.pyc | Bin 62723 -> 62723 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1294 -> 1294 bytes .../__pycache__/_ihatexml.cpython-39.pyc | Bin 13763 -> 13763 bytes .../__pycache__/_inputstream.cpython-39.pyc | Bin 21622 -> 21622 bytes .../__pycache__/_tokenizer.cpython-39.pyc | Bin 39717 -> 39717 bytes .../__pycache__/_utils.cpython-39.pyc | Bin 4794 -> 4794 bytes .../__pycache__/constants.cpython-39.pyc | Bin 66332 -> 66332 bytes .../__pycache__/html5parser.cpython-39.pyc | Bin 91003 -> 91003 bytes .../__pycache__/serializer.cpython-39.pyc | Bin 10805 -> 10805 bytes .../_trie/__pycache__/__init__.cpython-39.pyc | Bin 344 -> 344 bytes .../_trie/__pycache__/_base.cpython-39.pyc | Bin 1588 -> 1588 bytes .../_trie/__pycache__/py.cpython-39.pyc | Bin 2249 -> 2249 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 192 -> 192 bytes .../alphabeticalattributes.cpython-39.pyc | Bin 1314 -> 1314 bytes .../filters/__pycache__/base.cpython-39.pyc | Bin 862 -> 862 bytes .../inject_meta_charset.cpython-39.pyc | Bin 1868 -> 1868 bytes .../filters/__pycache__/lint.cpython-39.pyc | Bin 2610 -> 2610 bytes .../__pycache__/optionaltags.cpython-39.pyc | Bin 2755 -> 2755 bytes .../__pycache__/sanitizer.cpython-39.pyc | Bin 16878 -> 16878 bytes .../__pycache__/whitespace.cpython-39.pyc | Bin 1360 -> 1360 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 929 -> 929 bytes .../__pycache__/genshi.cpython-39.pyc | Bin 1537 -> 1537 bytes .../__pycache__/sax.cpython-39.pyc | Bin 1456 -> 1456 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 3324 -> 3324 bytes .../__pycache__/base.cpython-39.pyc | Bin 11308 -> 11308 bytes .../__pycache__/dom.cpython-39.pyc | Bin 9445 -> 9445 bytes .../__pycache__/etree.cpython-39.pyc | Bin 11813 -> 11813 bytes .../__pycache__/etree_lxml.cpython-39.pyc | Bin 12996 -> 12996 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 3990 -> 3990 bytes .../__pycache__/base.cpython-39.pyc | Bin 6989 -> 6989 bytes .../__pycache__/dom.cpython-39.pyc | Bin 1724 -> 1724 bytes .../__pycache__/etree.cpython-39.pyc | Bin 3486 -> 3486 bytes .../__pycache__/etree_lxml.cpython-39.pyc | Bin 6623 -> 6623 bytes .../__pycache__/genshi.cpython-39.pyc | Bin 1880 -> 1880 bytes .../idna/__pycache__/__init__.cpython-39.pyc | Bin 839 -> 839 bytes .../idna/__pycache__/codec.cpython-39.pyc | Bin 2870 -> 2870 bytes .../idna/__pycache__/compat.cpython-39.pyc | Bin 676 -> 676 bytes .../idna/__pycache__/core.cpython-39.pyc | Bin 9144 -> 9144 bytes .../idna/__pycache__/idnadata.cpython-39.pyc | Bin 22130 -> 22130 bytes .../idna/__pycache__/intranges.cpython-39.pyc | Bin 1852 -> 1852 bytes .../__pycache__/package_data.cpython-39.pyc | Bin 203 -> 203 bytes .../idna/__pycache__/uts46data.cpython-39.pyc | Bin 146163 -> 146163 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1406 -> 1406 bytes .../__pycache__/_version.cpython-39.pyc | Bin 210 -> 210 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 1844 -> 1844 bytes .../msgpack/__pycache__/ext.cpython-39.pyc | Bin 6272 -> 6272 bytes .../__pycache__/fallback.cpython-39.pyc | Bin 26718 -> 26718 bytes .../__pycache__/__about__.cpython-39.pyc | Bin 582 -> 582 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 438 -> 438 bytes .../__pycache__/_manylinux.cpython-39.pyc | Bin 7286 -> 7286 bytes .../__pycache__/_musllinux.cpython-39.pyc | Bin 4601 -> 4601 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 3074 -> 3074 bytes .../__pycache__/markers.cpython-39.pyc | Bin 9445 -> 9445 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 3966 -> 3966 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 22202 -> 22202 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 12281 -> 12281 bytes .../__pycache__/utils.cpython-39.pyc | Bin 3603 -> 3603 bytes .../__pycache__/version.cpython-39.pyc | Bin 13144 -> 13144 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 305 -> 305 bytes .../pep517/__pycache__/build.cpython-39.pyc | Bin 3570 -> 3570 bytes .../pep517/__pycache__/check.cpython-39.pyc | Bin 5117 -> 5117 bytes .../__pycache__/colorlog.cpython-39.pyc | Bin 2930 -> 2930 bytes .../pep517/__pycache__/compat.cpython-39.pyc | Bin 1285 -> 1285 bytes .../__pycache__/dirtools.cpython-39.pyc | Bin 1339 -> 1339 bytes .../__pycache__/envbuild.cpython-39.pyc | Bin 4516 -> 4516 bytes .../pep517/__pycache__/meta.cpython-39.pyc | Bin 2912 -> 2912 bytes .../__pycache__/wrappers.cpython-39.pyc | Bin 12262 -> 12262 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 907 -> 907 bytes .../__pycache__/_in_process.cpython-39.pyc | Bin 9923 -> 9923 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 100323 -> 100323 bytes .../__pycache__/py31compat.cpython-39.pyc | Bin 642 -> 642 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 5649 -> 5649 bytes .../progress/__pycache__/bar.cpython-39.pyc | Bin 2631 -> 2631 bytes .../__pycache__/counter.cpython-39.pyc | Bin 1465 -> 1465 bytes .../__pycache__/spinner.cpython-39.pyc | Bin 1382 -> 1382 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 3994 -> 3994 bytes .../__pycache__/__version__.cpython-39.pyc | Bin 547 -> 547 bytes .../_internal_utils.cpython-39.pyc | Bin 1294 -> 1294 bytes .../__pycache__/adapters.cpython-39.pyc | Bin 16965 -> 16965 bytes .../requests/__pycache__/api.cpython-39.pyc | Bin 6711 -> 6711 bytes .../requests/__pycache__/auth.cpython-39.pyc | Bin 8323 -> 8323 bytes .../requests/__pycache__/certs.cpython-39.pyc | Bin 625 -> 625 bytes .../__pycache__/compat.cpython-39.pyc | Bin 1604 -> 1604 bytes .../__pycache__/cookies.cpython-39.pyc | Bin 18814 -> 18814 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 5397 -> 5397 bytes .../requests/__pycache__/help.cpython-39.pyc | Bin 2885 -> 2885 bytes .../requests/__pycache__/hooks.cpython-39.pyc | Bin 982 -> 982 bytes .../__pycache__/models.cpython-39.pyc | Bin 24462 -> 24462 bytes .../__pycache__/packages.cpython-39.pyc | Bin 494 -> 494 bytes .../__pycache__/sessions.cpython-39.pyc | Bin 19849 -> 19849 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 4231 -> 4231 bytes .../__pycache__/structures.cpython-39.pyc | Bin 4452 -> 4452 bytes .../requests/__pycache__/utils.cpython-39.pyc | Bin 23316 -> 23316 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 598 -> 598 bytes .../__pycache__/providers.cpython-39.pyc | Bin 6518 -> 6518 bytes .../__pycache__/reporters.cpython-39.pyc | Bin 2294 -> 2294 bytes .../__pycache__/resolvers.cpython-39.pyc | Bin 15145 -> 15145 bytes .../__pycache__/structs.cpython-39.pyc | Bin 7271 -> 7271 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 193 -> 193 bytes .../collections_abc.cpython-39.pyc | Bin 367 -> 367 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 16271 -> 16271 bytes .../__pycache__/_asyncio.cpython-39.pyc | Bin 2586 -> 2586 bytes .../__pycache__/_utils.cpython-39.pyc | Bin 1223 -> 1223 bytes .../tenacity/__pycache__/after.cpython-39.pyc | Bin 1202 -> 1202 bytes .../__pycache__/before.cpython-39.pyc | Bin 1090 -> 1090 bytes .../__pycache__/before_sleep.cpython-39.pyc | Bin 1382 -> 1382 bytes .../tenacity/__pycache__/nap.cpython-39.pyc | Bin 1184 -> 1184 bytes .../tenacity/__pycache__/retry.cpython-39.pyc | Bin 8772 -> 8772 bytes .../tenacity/__pycache__/stop.cpython-39.pyc | Bin 4236 -> 4236 bytes .../__pycache__/tornadoweb.cpython-39.pyc | Bin 1736 -> 1736 bytes .../tenacity/__pycache__/wait.cpython-39.pyc | Bin 7948 -> 7948 bytes .../tomli/__pycache__/__init__.cpython-39.pyc | Bin 371 -> 371 bytes .../tomli/__pycache__/_parser.cpython-39.pyc | Bin 16346 -> 16346 bytes .../tomli/__pycache__/_re.cpython-39.pyc | Bin 2421 -> 2421 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2181 -> 2181 bytes .../__pycache__/_collections.cpython-39.pyc | Bin 10776 -> 10776 bytes .../__pycache__/_version.cpython-39.pyc | Bin 205 -> 205 bytes .../__pycache__/connection.cpython-39.pyc | Bin 13362 -> 13362 bytes .../__pycache__/connectionpool.cpython-39.pyc | Bin 24458 -> 24458 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 11638 -> 11638 bytes .../urllib3/__pycache__/fields.cpython-39.pyc | Bin 8153 -> 8153 bytes .../__pycache__/filepost.cpython-39.pyc | Bin 2754 -> 2754 bytes .../__pycache__/poolmanager.cpython-39.pyc | Bin 15156 -> 15156 bytes .../__pycache__/request.cpython-39.pyc | Bin 5617 -> 5617 bytes .../__pycache__/response.cpython-39.pyc | Bin 20828 -> 20828 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 191 -> 191 bytes .../_appengine_environ.cpython-39.pyc | Bin 1411 -> 1411 bytes .../__pycache__/appengine.cpython-39.pyc | Bin 8264 -> 8264 bytes .../__pycache__/ntlmpool.cpython-39.pyc | Bin 3618 -> 3618 bytes .../__pycache__/pyopenssl.cpython-39.pyc | Bin 15586 -> 15586 bytes .../securetransport.cpython-39.pyc | Bin 21902 -> 21902 bytes .../contrib/__pycache__/socks.cpython-39.pyc | Bin 5627 -> 5627 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 208 -> 208 bytes .../__pycache__/bindings.cpython-39.pyc | Bin 10715 -> 10715 bytes .../__pycache__/low_level.cpython-39.pyc | Bin 9164 -> 9164 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 305 -> 305 bytes .../packages/__pycache__/six.cpython-39.pyc | Bin 27575 -> 27575 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 202 -> 202 bytes .../__pycache__/makefile.cpython-39.pyc | Bin 1300 -> 1300 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 564 -> 564 bytes .../_implementation.cpython-39.pyc | Bin 3295 -> 3295 bytes .../util/__pycache__/__init__.cpython-39.pyc | Bin 1101 -> 1101 bytes .../__pycache__/connection.cpython-39.pyc | Bin 3453 -> 3453 bytes .../util/__pycache__/proxy.cpython-39.pyc | Bin 1337 -> 1337 bytes .../util/__pycache__/queue.cpython-39.pyc | Bin 1056 -> 1056 bytes .../util/__pycache__/request.cpython-39.pyc | Bin 3444 -> 3444 bytes .../util/__pycache__/response.cpython-39.pyc | Bin 2341 -> 2341 bytes .../util/__pycache__/retry.cpython-39.pyc | Bin 15828 -> 15828 bytes .../util/__pycache__/ssl_.cpython-39.pyc | Bin 11325 -> 11325 bytes .../__pycache__/ssltransport.cpython-39.pyc | Bin 7506 -> 7506 bytes .../util/__pycache__/timeout.cpython-39.pyc | Bin 8939 -> 8939 bytes .../util/__pycache__/url.cpython-39.pyc | Bin 10664 -> 10664 bytes .../util/__pycache__/wait.cpython-39.pyc | Bin 3124 -> 3124 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 9715 -> 9715 bytes .../__pycache__/labels.cpython-39.pyc | Bin 3829 -> 3829 bytes .../__pycache__/mklabels.cpython-39.pyc | Bin 1899 -> 1899 bytes .../__pycache__/tests.cpython-39.pyc | Bin 5063 -> 5063 bytes .../__pycache__/x_user_defined.cpython-39.pyc | Bin 2659 -> 2659 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 100431 -> 100431 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 185 -> 185 bytes .../__pycache__/appdirs.cpython-39.pyc | Bin 20502 -> 20502 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 201339 -> 201339 bytes .../__pycache__/__about__.cpython-39.pyc | Bin 701 -> 701 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 547 -> 547 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 1145 -> 1145 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 2899 -> 2899 bytes .../__pycache__/_typing.cpython-39.pyc | Bin 1490 -> 1490 bytes .../__pycache__/markers.cpython-39.pyc | Bin 9306 -> 9306 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 4083 -> 4083 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 20582 -> 20582 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 17261 -> 17261 bytes .../__pycache__/utils.cpython-39.pyc | Bin 1652 -> 1652 bytes .../__pycache__/version.cpython-39.pyc | Bin 13319 -> 13319 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2874 -> 2874 bytes .../__pycache__/setup.cpython-39.pyc | Bin 313 -> 313 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2516 -> 2516 bytes .../__pycache__/_ast_gen.cpython-39.pyc | Bin 10215 -> 10215 bytes .../__pycache__/_build_tables.cpython-39.pyc | Bin 529 -> 529 bytes .../__pycache__/ast_transforms.cpython-39.pyc | Bin 2529 -> 2529 bytes .../__pycache__/c_ast.cpython-39.pyc | Bin 35181 -> 35181 bytes .../__pycache__/c_generator.cpython-39.pyc | Bin 16721 -> 16721 bytes .../__pycache__/c_lexer.cpython-39.pyc | Bin 11895 -> 11895 bytes .../__pycache__/c_parser.cpython-39.pyc | Bin 60499 -> 60499 bytes .../__pycache__/lextab.cpython-39.pyc | Bin 5411 -> 5411 bytes .../__pycache__/plyparser.cpython-39.pyc | Bin 4676 -> 4676 bytes .../__pycache__/yacctab.cpython-39.pyc | Bin 146784 -> 146784 bytes .../ply/__pycache__/__init__.cpython-39.pyc | Bin 226 -> 226 bytes .../ply/__pycache__/cpp.cpython-39.pyc | Bin 16043 -> 16043 bytes .../ply/__pycache__/ctokens.cpython-39.pyc | Bin 2079 -> 2079 bytes .../ply/__pycache__/lex.cpython-39.pyc | Bin 21420 -> 21420 bytes .../ply/__pycache__/yacc.cpython-39.pyc | Bin 52975 -> 52975 bytes .../ply/__pycache__/ygen.cpython-39.pyc | Bin 1789 -> 1789 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 3857 -> 3857 bytes .../__pycache__/__version__.cpython-39.pyc | Bin 535 -> 535 bytes .../_internal_utils.cpython-39.pyc | Bin 1282 -> 1282 bytes .../__pycache__/adapters.cpython-39.pyc | Bin 16881 -> 16881 bytes .../requests/__pycache__/api.cpython-39.pyc | Bin 6699 -> 6699 bytes .../requests/__pycache__/auth.cpython-39.pyc | Bin 8311 -> 8311 bytes .../requests/__pycache__/certs.cpython-39.pyc | Bin 601 -> 601 bytes .../__pycache__/compat.cpython-39.pyc | Bin 1691 -> 1691 bytes .../__pycache__/cookies.cpython-39.pyc | Bin 18802 -> 18802 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 5373 -> 5373 bytes .../requests/__pycache__/help.cpython-39.pyc | Bin 2853 -> 2853 bytes .../requests/__pycache__/hooks.cpython-39.pyc | Bin 970 -> 970 bytes .../__pycache__/models.cpython-39.pyc | Bin 24378 -> 24378 bytes .../__pycache__/packages.cpython-39.pyc | Bin 677 -> 677 bytes .../__pycache__/sessions.cpython-39.pyc | Bin 19837 -> 19837 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 4219 -> 4219 bytes .../__pycache__/structures.cpython-39.pyc | Bin 4440 -> 4440 bytes .../requests/__pycache__/utils.cpython-39.pyc | Bin 23292 -> 23292 bytes .../rfc3986-1.5.0.dist-info/AUTHORS.rst | 14 - .../rfc3986-1.5.0.dist-info/INSTALLER | 1 - .../rfc3986-1.5.0.dist-info/LICENSE | 13 - .../rfc3986-1.5.0.dist-info/METADATA | 230 -- .../rfc3986-1.5.0.dist-info/RECORD | 33 - .../rfc3986-1.5.0.dist-info/WHEEL | 6 - .../rfc3986-1.5.0.dist-info/top_level.txt | 1 - .../Lib/site-packages/rfc3986/__init__.py | 56 - .../__pycache__/__init__.cpython-39.pyc | Bin 1039 -> 0 bytes .../rfc3986/__pycache__/_mixin.cpython-39.pyc | Bin 10623 -> 0 bytes .../__pycache__/abnf_regexp.cpython-39.pyc | Bin 4131 -> 0 bytes .../rfc3986/__pycache__/api.cpython-39.pyc | Bin 3679 -> 0 bytes .../__pycache__/builder.cpython-39.pyc | Bin 11159 -> 0 bytes .../rfc3986/__pycache__/compat.cpython-39.pyc | Bin 1197 -> 0 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 4751 -> 0 bytes .../rfc3986/__pycache__/iri.cpython-39.pyc | Bin 4430 -> 0 bytes .../rfc3986/__pycache__/misc.cpython-39.pyc | Bin 2238 -> 0 bytes .../__pycache__/normalizers.cpython-39.pyc | Bin 3550 -> 0 bytes .../__pycache__/parseresult.cpython-39.pyc | Bin 9930 -> 0 bytes .../rfc3986/__pycache__/uri.cpython-39.pyc | Bin 4239 -> 0 bytes .../__pycache__/validators.cpython-39.pyc | Bin 12923 -> 0 bytes .../.venv/Lib/site-packages/rfc3986/_mixin.py | 373 -- .../Lib/site-packages/rfc3986/abnf_regexp.py | 282 -- .../.venv/Lib/site-packages/rfc3986/api.py | 106 - .../Lib/site-packages/rfc3986/builder.py | 389 -- .../.venv/Lib/site-packages/rfc3986/compat.py | 60 - .../Lib/site-packages/rfc3986/exceptions.py | 124 - .../.venv/Lib/site-packages/rfc3986/iri.py | 162 - .../.venv/Lib/site-packages/rfc3986/misc.py | 135 - .../Lib/site-packages/rfc3986/normalizers.py | 172 - .../Lib/site-packages/rfc3986/parseresult.py | 479 --- .../.venv/Lib/site-packages/rfc3986/uri.py | 161 - .../Lib/site-packages/rfc3986/validators.py | 447 -- .../__pycache__/__init__.cpython-39.pyc | Bin 8618 -> 8618 bytes .../_deprecation_warning.cpython-39.pyc | Bin 544 -> 544 bytes .../__pycache__/_imp.cpython-39.pyc | Bin 2079 -> 2079 bytes .../__pycache__/archive_util.cpython-39.pyc | Bin 5808 -> 5808 bytes .../__pycache__/build_meta.cpython-39.pyc | Bin 9067 -> 9067 bytes .../__pycache__/config.cpython-39.pyc | Bin 19957 -> 19957 bytes .../__pycache__/dep_util.cpython-39.pyc | Bin 851 -> 851 bytes .../__pycache__/depends.cpython-39.pyc | Bin 5243 -> 5243 bytes .../__pycache__/dist.cpython-39.pyc | Bin 36238 -> 36238 bytes .../__pycache__/errors.cpython-39.pyc | Bin 844 -> 844 bytes .../__pycache__/extension.cpython-39.pyc | Bin 1938 -> 1938 bytes .../__pycache__/glob.cpython-39.pyc | Bin 3688 -> 3688 bytes .../__pycache__/installer.cpython-39.pyc | Bin 2765 -> 2765 bytes .../__pycache__/launch.cpython-39.pyc | Bin 895 -> 895 bytes .../__pycache__/lib2to3_ex.cpython-39.pyc | Bin 2697 -> 2697 bytes .../__pycache__/monkey.cpython-39.pyc | Bin 4607 -> 4607 bytes .../__pycache__/msvc.cpython-39.pyc | Bin 42833 -> 42833 bytes .../__pycache__/namespaces.cpython-39.pyc | Bin 3594 -> 3594 bytes .../__pycache__/package_index.cpython-39.pyc | Bin 32630 -> 32630 bytes .../__pycache__/py34compat.cpython-39.pyc | Bin 474 -> 474 bytes .../__pycache__/sandbox.cpython-39.pyc | Bin 15768 -> 15768 bytes .../__pycache__/unicode_utils.cpython-39.pyc | Bin 1108 -> 1108 bytes .../__pycache__/version.cpython-39.pyc | Bin 318 -> 318 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 7274 -> 7274 bytes .../windows_support.cpython-39.pyc | Bin 1017 -> 1017 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 452 -> 452 bytes .../__pycache__/_msvccompiler.cpython-39.pyc | Bin 13807 -> 13807 bytes .../__pycache__/archive_util.cpython-39.pyc | Bin 6639 -> 6639 bytes .../__pycache__/bcppcompiler.cpython-39.pyc | Bin 6550 -> 6550 bytes .../__pycache__/ccompiler.cpython-39.pyc | Bin 33418 -> 33418 bytes .../_distutils/__pycache__/cmd.cpython-39.pyc | Bin 13978 -> 13978 bytes .../__pycache__/config.cpython-39.pyc | Bin 3581 -> 3581 bytes .../__pycache__/core.cpython-39.pyc | Bin 6706 -> 6706 bytes .../cygwinccompiler.cpython-39.pyc | Bin 8786 -> 8786 bytes .../__pycache__/debug.cpython-39.pyc | Bin 248 -> 248 bytes .../__pycache__/dep_util.cpython-39.pyc | Bin 2768 -> 2768 bytes .../__pycache__/dir_util.cpython-39.pyc | Bin 5869 -> 5869 bytes .../__pycache__/dist.cpython-39.pyc | Bin 34439 -> 34439 bytes .../__pycache__/errors.cpython-39.pyc | Bin 5304 -> 5304 bytes .../__pycache__/extension.cpython-39.pyc | Bin 6969 -> 6969 bytes .../__pycache__/fancy_getopt.cpython-39.pyc | Bin 10677 -> 10677 bytes .../__pycache__/file_util.cpython-39.pyc | Bin 6035 -> 6035 bytes .../__pycache__/filelist.cpython-39.pyc | Bin 10827 -> 10827 bytes .../_distutils/__pycache__/log.cpython-39.pyc | Bin 2367 -> 2367 bytes .../__pycache__/msvc9compiler.cpython-39.pyc | Bin 17564 -> 17564 bytes .../__pycache__/msvccompiler.cpython-39.pyc | Bin 14759 -> 14759 bytes .../__pycache__/py35compat.cpython-39.pyc | Bin 624 -> 624 bytes .../__pycache__/py38compat.cpython-39.pyc | Bin 419 -> 419 bytes .../__pycache__/spawn.cpython-39.pyc | Bin 2895 -> 2895 bytes .../__pycache__/sysconfig.cpython-39.pyc | Bin 12401 -> 12401 bytes .../__pycache__/text_file.cpython-39.pyc | Bin 8493 -> 8493 bytes .../__pycache__/unixccompiler.cpython-39.pyc | Bin 6832 -> 6832 bytes .../__pycache__/util.cpython-39.pyc | Bin 17331 -> 17331 bytes .../__pycache__/version.cpython-39.pyc | Bin 7393 -> 7393 bytes .../versionpredicate.cpython-39.pyc | Bin 5177 -> 5177 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 527 -> 527 bytes .../command/__pycache__/bdist.cpython-39.pyc | Bin 3657 -> 3657 bytes .../__pycache__/bdist_dumb.cpython-39.pyc | Bin 3640 -> 3640 bytes .../__pycache__/bdist_msi.cpython-39.pyc | Bin 19822 -> 19822 bytes .../__pycache__/bdist_rpm.cpython-39.pyc | Bin 12277 -> 12277 bytes .../__pycache__/bdist_wininst.cpython-39.pyc | Bin 8597 -> 8597 bytes .../command/__pycache__/build.cpython-39.pyc | Bin 3929 -> 3929 bytes .../__pycache__/build_clib.cpython-39.pyc | Bin 4852 -> 4852 bytes .../__pycache__/build_ext.cpython-39.pyc | Bin 16311 -> 16311 bytes .../__pycache__/build_py.cpython-39.pyc | Bin 10485 -> 10485 bytes .../__pycache__/build_scripts.cpython-39.pyc | Bin 4382 -> 4382 bytes .../command/__pycache__/check.cpython-39.pyc | Bin 4961 -> 4961 bytes .../command/__pycache__/clean.cpython-39.pyc | Bin 2134 -> 2134 bytes .../command/__pycache__/config.cpython-39.pyc | Bin 10264 -> 10264 bytes .../__pycache__/install.cpython-39.pyc | Bin 13845 -> 13845 bytes .../__pycache__/install_data.cpython-39.pyc | Bin 2337 -> 2337 bytes .../install_egg_info.cpython-39.pyc | Bin 3072 -> 3072 bytes .../install_headers.cpython-39.pyc | Bin 1762 -> 1762 bytes .../__pycache__/install_lib.cpython-39.pyc | Bin 5134 -> 5134 bytes .../install_scripts.cpython-39.pyc | Bin 2185 -> 2185 bytes .../__pycache__/py37compat.cpython-39.pyc | Bin 1028 -> 1028 bytes .../__pycache__/register.cpython-39.pyc | Bin 8505 -> 8505 bytes .../command/__pycache__/sdist.cpython-39.pyc | Bin 14532 -> 14532 bytes .../command/__pycache__/upload.cpython-39.pyc | Bin 5255 -> 5255 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 182 -> 182 bytes .../__pycache__/ordered_set.cpython-39.pyc | Bin 16376 -> 16376 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 201336 -> 201336 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 263 -> 263 bytes .../__pycache__/more.cpython-39.pyc | Bin 110008 -> 110008 bytes .../__pycache__/recipes.cpython-39.pyc | Bin 17928 -> 17928 bytes .../__pycache__/__about__.cpython-39.pyc | Bin 698 -> 698 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 544 -> 544 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 1142 -> 1142 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 2896 -> 2896 bytes .../__pycache__/_typing.cpython-39.pyc | Bin 1487 -> 1487 bytes .../__pycache__/markers.cpython-39.pyc | Bin 9300 -> 9300 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 4077 -> 4077 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 20579 -> 20579 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 17258 -> 17258 bytes .../__pycache__/utils.cpython-39.pyc | Bin 1649 -> 1649 bytes .../__pycache__/version.cpython-39.pyc | Bin 13316 -> 13316 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 371 -> 371 bytes .../command/__pycache__/alias.cpython-39.pyc | Bin 2365 -> 2365 bytes .../__pycache__/bdist_egg.cpython-39.pyc | Bin 13031 -> 13031 bytes .../__pycache__/bdist_rpm.cpython-39.pyc | Bin 1351 -> 1351 bytes .../__pycache__/build_clib.cpython-39.pyc | Bin 2462 -> 2462 bytes .../__pycache__/build_ext.cpython-39.pyc | Bin 9821 -> 9821 bytes .../__pycache__/build_py.cpython-39.pyc | Bin 8376 -> 8376 bytes .../__pycache__/develop.cpython-39.pyc | Bin 6450 -> 6450 bytes .../__pycache__/dist_info.cpython-39.pyc | Bin 1389 -> 1389 bytes .../__pycache__/easy_install.cpython-39.pyc | Bin 63546 -> 63546 bytes .../__pycache__/egg_info.cpython-39.pyc | Bin 21972 -> 21972 bytes .../__pycache__/install.cpython-39.pyc | Bin 4030 -> 4030 bytes .../install_egg_info.cpython-39.pyc | Bin 2421 -> 2421 bytes .../__pycache__/install_lib.cpython-39.pyc | Bin 4128 -> 4128 bytes .../install_scripts.cpython-39.pyc | Bin 2416 -> 2416 bytes .../__pycache__/py36compat.cpython-39.pyc | Bin 4583 -> 4583 bytes .../__pycache__/register.cpython-39.pyc | Bin 839 -> 839 bytes .../command/__pycache__/rotate.cpython-39.pyc | Bin 2498 -> 2498 bytes .../__pycache__/saveopts.cpython-39.pyc | Bin 917 -> 917 bytes .../command/__pycache__/sdist.cpython-39.pyc | Bin 6458 -> 6458 bytes .../command/__pycache__/setopt.cpython-39.pyc | Bin 4529 -> 4529 bytes .../command/__pycache__/test.cpython-39.pyc | Bin 8515 -> 8515 bytes .../command/__pycache__/upload.cpython-39.pyc | Bin 812 -> 812 bytes .../__pycache__/upload_docs.cpython-39.pyc | Bin 6155 -> 6155 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2913 -> 2913 bytes .../snakeviz-2.1.0.dist-info/INSTALLER | 1 - .../snakeviz-2.1.0.dist-info/LICENSE.txt | 26 - .../snakeviz-2.1.0.dist-info/METADATA | 54 - .../snakeviz-2.1.0.dist-info/RECORD | 42 - .../snakeviz-2.1.0.dist-info/REQUESTED | 0 .../snakeviz-2.1.0.dist-info/WHEEL | 6 - .../snakeviz-2.1.0.dist-info/entry_points.txt | 3 - .../snakeviz-2.1.0.dist-info/top_level.txt | 1 - .../Lib/site-packages/snakeviz/__init__.py | 2 - .../Lib/site-packages/snakeviz/__main__.py | 7 - .../__pycache__/__init__.cpython-39.pyc | Bin 240 -> 0 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 302 -> 0 bytes .../snakeviz/__pycache__/cli.cpython-39.pyc | Bin 4668 -> 0 bytes .../__pycache__/ipymagic.cpython-39.pyc | Bin 4520 -> 0 bytes .../snakeviz/__pycache__/main.cpython-39.pyc | Bin 1962 -> 0 bytes .../snakeviz/__pycache__/stats.cpython-39.pyc | Bin 2735 -> 0 bytes .../__pycache__/version.cpython-39.pyc | Bin 205 -> 0 bytes .../.venv/Lib/site-packages/snakeviz/cli.py | 169 - .../Lib/site-packages/snakeviz/ipymagic.py | 172 - .../.venv/Lib/site-packages/snakeviz/main.py | 73 - .../site-packages/snakeviz/static/drawsvg.js | 363 -- .../site-packages/snakeviz/static/favicon.ico | Bin 1406 -> 0 bytes .../snakeviz/static/images/sort_asc.png | Bin 1118 -> 0 bytes .../snakeviz/static/images/sort_both.png | Bin 1136 -> 0 bytes .../snakeviz/static/images/sort_desc.png | Bin 1127 -> 0 bytes .../snakeviz/static/snakeviz.css | 228 -- .../site-packages/snakeviz/static/snakeviz.js | 228 -- .../site-packages/snakeviz/static/sunburst.js | 233 -- .../snakeviz/static/vendor/d3.min.js | 5 - .../snakeviz/static/vendor/d3.v3.min.js | 5 - .../snakeviz/static/vendor/immutable.min.js | 36 - .../static/vendor/jquery-1.11.1.min.js | 4 - .../static/vendor/jquery-3.2.1.min.js | 4 - .../static/vendor/jquery.dataTables.min.css | 1 - .../static/vendor/jquery.dataTables.min.js | 167 - .../static/vendor/lodash.compat.min.js | 61 - .../snakeviz/static/vendor/lodash.min.js | 4 - .../.venv/Lib/site-packages/snakeviz/stats.py | 80 - .../site-packages/snakeviz/templates/dir.html | 61 - .../site-packages/snakeviz/templates/viz.html | 306 -- .../Lib/site-packages/snakeviz/version.py | 1 - .../sniffio-1.2.0.dist-info/INSTALLER | 1 - .../sniffio-1.2.0.dist-info/LICENSE | 3 - .../sniffio-1.2.0.dist-info/LICENSE.APACHE2 | 202 - .../sniffio-1.2.0.dist-info/LICENSE.MIT | 20 - .../sniffio-1.2.0.dist-info/METADATA | 103 - .../sniffio-1.2.0.dist-info/RECORD | 19 - .../sniffio-1.2.0.dist-info/WHEEL | 5 - .../sniffio-1.2.0.dist-info/top_level.txt | 1 - .../Lib/site-packages/sniffio/__init__.py | 14 - .../__pycache__/__init__.cpython-39.pyc | Bin 405 -> 0 bytes .../sniffio/__pycache__/_impl.cpython-39.pyc | Bin 2486 -> 0 bytes .../__pycache__/_version.cpython-39.pyc | Bin 192 -> 0 bytes .../.venv/Lib/site-packages/sniffio/_impl.py | 83 - .../site-packages/sniffio/_tests/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 178 -> 0 bytes .../__pycache__/test_sniffio.cpython-39.pyc | Bin 1800 -> 0 bytes .../sniffio/_tests/test_sniffio.py | 67 - .../Lib/site-packages/sniffio/_version.py | 3 - .../.venv/Lib/site-packages/sniffio/py.typed | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 3666 -> 3666 bytes .../__pycache__/__meta__.cpython-39.pyc | Bin 5775 -> 5775 bytes .../__pycache__/css_match.cpython-39.pyc | Bin 34026 -> 34026 bytes .../__pycache__/css_parser.cpython-39.pyc | Bin 26864 -> 26864 bytes .../__pycache__/css_types.cpython-39.pyc | Bin 10620 -> 10620 bytes .../soupsieve/__pycache__/util.cpython-39.pyc | Bin 2863 -> 2863 bytes .../tornado-6.1.dist-info/INSTALLER | 1 - .../tornado-6.1.dist-info/LICENSE | 202 - .../tornado-6.1.dist-info/METADATA | 70 - .../tornado-6.1.dist-info/RECORD | 165 - .../site-packages/tornado-6.1.dist-info/WHEEL | 5 - .../tornado-6.1.dist-info/top_level.txt | 1 - .../Lib/site-packages/tornado/__init__.py | 26 - .../__pycache__/__init__.cpython-39.pyc | Bin 278 -> 0 bytes .../__pycache__/_locale_data.cpython-39.pyc | Bin 2894 -> 0 bytes .../tornado/__pycache__/auth.cpython-39.pyc | Bin 38671 -> 0 bytes .../__pycache__/autoreload.cpython-39.pyc | Bin 7681 -> 0 bytes .../__pycache__/concurrent.cpython-39.pyc | Bin 7951 -> 0 bytes .../curl_httpclient.cpython-39.pyc | Bin 13743 -> 0 bytes .../tornado/__pycache__/escape.cpython-39.pyc | Bin 10673 -> 0 bytes .../tornado/__pycache__/gen.cpython-39.pyc | Bin 26147 -> 0 bytes .../http1connection.cpython-39.pyc | Bin 22448 -> 0 bytes .../__pycache__/httpclient.cpython-39.pyc | Bin 28383 -> 0 bytes .../__pycache__/httpserver.cpython-39.pyc | Bin 13568 -> 0 bytes .../__pycache__/httputil.cpython-39.pyc | Bin 32058 -> 0 bytes .../tornado/__pycache__/ioloop.cpython-39.pyc | Bin 31290 -> 0 bytes .../__pycache__/iostream.cpython-39.pyc | Bin 45856 -> 0 bytes .../tornado/__pycache__/locale.cpython-39.pyc | Bin 16213 -> 0 bytes .../tornado/__pycache__/locks.cpython-39.pyc | Bin 18506 -> 0 bytes .../tornado/__pycache__/log.cpython-39.pyc | Bin 8383 -> 0 bytes .../__pycache__/netutil.cpython-39.pyc | Bin 17475 -> 0 bytes .../__pycache__/options.cpython-39.pyc | Bin 23327 -> 0 bytes .../__pycache__/process.cpython-39.pyc | Bin 10334 -> 0 bytes .../tornado/__pycache__/queues.cpython-39.pyc | Bin 13272 -> 0 bytes .../__pycache__/routing.cpython-39.pyc | Bin 24240 -> 0 bytes .../simple_httpclient.cpython-39.pyc | Bin 18825 -> 0 bytes .../__pycache__/tcpclient.cpython-39.pyc | Bin 9121 -> 0 bytes .../__pycache__/tcpserver.cpython-39.pyc | Bin 10964 -> 0 bytes .../__pycache__/template.cpython-39.pyc | Bin 34229 -> 0 bytes .../__pycache__/testing.cpython-39.pyc | Bin 26885 -> 0 bytes .../tornado/__pycache__/util.cpython-39.pyc | Bin 14542 -> 0 bytes .../tornado/__pycache__/web.cpython-39.pyc | Bin 113452 -> 0 bytes .../__pycache__/websocket.cpython-39.pyc | Bin 51318 -> 0 bytes .../tornado/__pycache__/wsgi.cpython-39.pyc | Bin 6450 -> 0 bytes .../Lib/site-packages/tornado/_locale_data.py | 80 - .../.venv/Lib/site-packages/tornado/auth.py | 1187 ------ .../Lib/site-packages/tornado/autoreload.py | 363 -- .../Lib/site-packages/tornado/concurrent.py | 263 -- .../site-packages/tornado/curl_httpclient.py | 583 --- .../.venv/Lib/site-packages/tornado/escape.py | 402 -- .../.venv/Lib/site-packages/tornado/gen.py | 872 ---- .../site-packages/tornado/http1connection.py | 842 ---- .../Lib/site-packages/tornado/httpclient.py | 790 ---- .../Lib/site-packages/tornado/httpserver.py | 398 -- .../Lib/site-packages/tornado/httputil.py | 1133 ------ .../.venv/Lib/site-packages/tornado/ioloop.py | 944 ----- .../Lib/site-packages/tornado/iostream.py | 1660 -------- .../.venv/Lib/site-packages/tornado/locale.py | 581 --- .../.venv/Lib/site-packages/tornado/locks.py | 571 --- .../.venv/Lib/site-packages/tornado/log.py | 339 -- .../Lib/site-packages/tornado/netutil.py | 617 --- .../Lib/site-packages/tornado/options.py | 735 ---- .../tornado/platform/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 180 -> 0 bytes .../__pycache__/asyncio.cpython-39.pyc | Bin 17283 -> 0 bytes .../__pycache__/caresresolver.cpython-39.pyc | Bin 3287 -> 0 bytes .../__pycache__/twisted.cpython-39.pyc | Bin 4453 -> 0 bytes .../site-packages/tornado/platform/asyncio.py | 611 --- .../tornado/platform/caresresolver.py | 89 - .../site-packages/tornado/platform/twisted.py | 146 - .../Lib/site-packages/tornado/process.py | 373 -- .../.venv/Lib/site-packages/tornado/py.typed | 0 .../.venv/Lib/site-packages/tornado/queues.py | 414 -- .../Lib/site-packages/tornado/routing.py | 717 ---- .../tornado/simple_httpclient.py | 699 ---- .../tornado/speedups.cp39-win_amd64.pyd | Bin 10240 -> 0 bytes .../Lib/site-packages/tornado/tcpclient.py | 328 -- .../Lib/site-packages/tornado/tcpserver.py | 334 -- .../Lib/site-packages/tornado/template.py | 1048 ----- .../site-packages/tornado/test/__main__.py | 12 - .../test/__pycache__/__main__.cpython-39.pyc | Bin 342 -> 0 bytes .../__pycache__/asyncio_test.cpython-39.pyc | Bin 6801 -> 0 bytes .../test/__pycache__/auth_test.cpython-39.pyc | Bin 21399 -> 0 bytes .../autoreload_test.cpython-39.pyc | Bin 3235 -> 0 bytes .../concurrent_test.cpython-39.pyc | Bin 8460 -> 0 bytes .../curl_httpclient_test.cpython-39.pyc | Bin 4843 -> 0 bytes .../__pycache__/escape_test.cpython-39.pyc | Bin 9541 -> 0 bytes .../test/__pycache__/gen_test.cpython-39.pyc | Bin 38035 -> 0 bytes .../http1connection_test.cpython-39.pyc | Bin 2905 -> 0 bytes .../httpclient_test.cpython-39.pyc | Bin 30106 -> 0 bytes .../httpserver_test.cpython-39.pyc | Bin 56078 -> 0 bytes .../__pycache__/httputil_test.cpython-39.pyc | Bin 17187 -> 0 bytes .../__pycache__/import_test.cpython-39.pyc | Bin 2044 -> 0 bytes .../__pycache__/ioloop_test.cpython-39.pyc | Bin 27964 -> 0 bytes .../__pycache__/iostream_test.cpython-39.pyc | Bin 43294 -> 0 bytes .../__pycache__/locale_test.cpython-39.pyc | Bin 5398 -> 0 bytes .../__pycache__/locks_test.cpython-39.pyc | Bin 17737 -> 0 bytes .../test/__pycache__/log_test.cpython-39.pyc | Bin 8575 -> 0 bytes .../__pycache__/netutil_test.cpython-39.pyc | Bin 8670 -> 0 bytes .../__pycache__/options_test.cpython-39.pyc | Bin 10864 -> 0 bytes .../__pycache__/process_test.cpython-39.pyc | Bin 8125 -> 0 bytes .../__pycache__/queues_test.cpython-39.pyc | Bin 14337 -> 0 bytes .../resolve_test_helper.cpython-39.pyc | Bin 466 -> 0 bytes .../__pycache__/routing_test.cpython-39.pyc | Bin 10469 -> 0 bytes .../test/__pycache__/runtests.cpython-39.pyc | Bin 6905 -> 0 bytes .../simple_httpclient_test.cpython-39.pyc | Bin 38536 -> 0 bytes .../__pycache__/tcpclient_test.cpython-39.pyc | Bin 16486 -> 0 bytes .../__pycache__/tcpserver_test.cpython-39.pyc | Bin 6862 -> 0 bytes .../__pycache__/template_test.cpython-39.pyc | Bin 18088 -> 0 bytes .../__pycache__/testing_test.cpython-39.pyc | Bin 15189 -> 0 bytes .../__pycache__/twisted_test.cpython-39.pyc | Bin 8861 -> 0 bytes .../test/__pycache__/util.cpython-39.pyc | Bin 2964 -> 0 bytes .../test/__pycache__/util_test.cpython-39.pyc | Bin 11380 -> 0 bytes .../test/__pycache__/web_test.cpython-39.pyc | Bin 125629 -> 0 bytes .../__pycache__/websocket_test.cpython-39.pyc | Bin 33989 -> 0 bytes .../test/__pycache__/wsgi_test.cpython-39.pyc | Bin 1108 -> 0 bytes .../tornado/test/asyncio_test.py | 190 - .../site-packages/tornado/test/auth_test.py | 609 --- .../tornado/test/autoreload_test.py | 127 - .../tornado/test/concurrent_test.py | 212 - .../tornado/test/csv_translations/fr_FR.csv | 1 - .../tornado/test/curl_httpclient_test.py | 129 - .../site-packages/tornado/test/escape_test.py | 322 -- .../site-packages/tornado/test/gen_test.py | 1119 ----- .../fr_FR/LC_MESSAGES/tornado_test.mo | Bin 665 -> 0 bytes .../fr_FR/LC_MESSAGES/tornado_test.po | 47 - .../tornado/test/http1connection_test.py | 61 - .../tornado/test/httpclient_test.py | 898 ----- .../tornado/test/httpserver_test.py | 1339 ------ .../tornado/test/httputil_test.py | 521 --- .../site-packages/tornado/test/import_test.py | 66 - .../site-packages/tornado/test/ioloop_test.py | 725 ---- .../tornado/test/iostream_test.py | 1282 ------ .../site-packages/tornado/test/locale_test.py | 151 - .../site-packages/tornado/test/locks_test.py | 535 --- .../site-packages/tornado/test/log_test.py | 245 -- .../tornado/test/netutil_test.py | 233 -- .../tornado/test/options_test.cfg | 7 - .../tornado/test/options_test.py | 328 -- .../tornado/test/options_test_types.cfg | 11 - .../tornado/test/options_test_types_str.cfg | 8 - .../tornado/test/process_test.py | 274 -- .../site-packages/tornado/test/queues_test.py | 431 -- .../tornado/test/resolve_test_helper.py | 10 - .../tornado/test/routing_test.py | 276 -- .../site-packages/tornado/test/runtests.py | 241 -- .../tornado/test/simple_httpclient_test.py | 834 ---- .../tornado/test/static/dir/index.html | 1 - .../tornado/test/static/robots.txt | 2 - .../tornado/test/static/sample.xml | 23 - .../tornado/test/static/sample.xml.bz2 | Bin 285 -> 0 bytes .../tornado/test/static/sample.xml.gz | Bin 264 -> 0 bytes .../site-packages/tornado/test/static_foo.txt | 2 - .../tornado/test/tcpclient_test.py | 438 -- .../tornado/test/tcpserver_test.py | 192 - .../tornado/test/template_test.py | 536 --- .../tornado/test/templates/utf8.html | 1 - .../Lib/site-packages/tornado/test/test.crt | 20 - .../Lib/site-packages/tornado/test/test.key | 28 - .../tornado/test/testing_test.py | 353 -- .../tornado/test/twisted_test.py | 247 -- .../Lib/site-packages/tornado/test/util.py | 114 - .../site-packages/tornado/test/util_test.py | 308 -- .../site-packages/tornado/test/web_test.py | 3156 --------------- .../tornado/test/websocket_test.py | 840 ---- .../site-packages/tornado/test/wsgi_test.py | 20 - .../Lib/site-packages/tornado/testing.py | 818 ---- .../.venv/Lib/site-packages/tornado/util.py | 474 --- .../.venv/Lib/site-packages/tornado/web.py | 3588 ----------------- .../Lib/site-packages/tornado/websocket.py | 1666 -------- .../.venv/Lib/site-packages/tornado/wsgi.py | 199 - .../__pycache__/__init__.cpython-39.pyc | Bin 2169 -> 2169 bytes .../__pycache__/_collections.cpython-39.pyc | Bin 10764 -> 10764 bytes .../__pycache__/_version.cpython-39.pyc | Bin 193 -> 193 bytes .../__pycache__/connection.cpython-39.pyc | Bin 13350 -> 13350 bytes .../__pycache__/connectionpool.cpython-39.pyc | Bin 24446 -> 24446 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 11626 -> 11626 bytes .../urllib3/__pycache__/fields.cpython-39.pyc | Bin 8141 -> 8141 bytes .../__pycache__/filepost.cpython-39.pyc | Bin 2742 -> 2742 bytes .../__pycache__/poolmanager.cpython-39.pyc | Bin 15144 -> 15144 bytes .../__pycache__/request.cpython-39.pyc | Bin 5605 -> 5605 bytes .../__pycache__/response.cpython-39.pyc | Bin 20816 -> 20816 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 179 -> 179 bytes .../_appengine_environ.cpython-39.pyc | Bin 1399 -> 1399 bytes .../__pycache__/appengine.cpython-39.pyc | Bin 8228 -> 8228 bytes .../__pycache__/ntlmpool.cpython-39.pyc | Bin 3606 -> 3606 bytes .../__pycache__/pyopenssl.cpython-39.pyc | Bin 15550 -> 15550 bytes .../securetransport.cpython-39.pyc | Bin 21866 -> 21866 bytes .../contrib/__pycache__/socks.cpython-39.pyc | Bin 5615 -> 5615 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 196 -> 196 bytes .../__pycache__/bindings.cpython-39.pyc | Bin 10691 -> 10691 bytes .../__pycache__/low_level.cpython-39.pyc | Bin 9152 -> 9152 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 293 -> 293 bytes .../packages/__pycache__/six.cpython-39.pyc | Bin 27563 -> 27563 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 190 -> 190 bytes .../__pycache__/makefile.cpython-39.pyc | Bin 1288 -> 1288 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 552 -> 552 bytes .../_implementation.cpython-39.pyc | Bin 3283 -> 3283 bytes .../util/__pycache__/__init__.cpython-39.pyc | Bin 1089 -> 1089 bytes .../__pycache__/connection.cpython-39.pyc | Bin 3429 -> 3429 bytes .../util/__pycache__/proxy.cpython-39.pyc | Bin 1325 -> 1325 bytes .../util/__pycache__/queue.cpython-39.pyc | Bin 1044 -> 1044 bytes .../util/__pycache__/request.cpython-39.pyc | Bin 3432 -> 3432 bytes .../util/__pycache__/response.cpython-39.pyc | Bin 2329 -> 2329 bytes .../util/__pycache__/retry.cpython-39.pyc | Bin 15816 -> 15816 bytes .../util/__pycache__/ssl_.cpython-39.pyc | Bin 11301 -> 11301 bytes .../__pycache__/ssltransport.cpython-39.pyc | Bin 7470 -> 7470 bytes .../util/__pycache__/timeout.cpython-39.pyc | Bin 8927 -> 8927 bytes .../util/__pycache__/url.cpython-39.pyc | Bin 10628 -> 10628 bytes .../util/__pycache__/wait.cpython-39.pyc | Bin 3112 -> 3112 bytes .../event/__pycache__/__init__.cpython-39.pyc | Bin 423 -> 423 bytes .../__pycache__/classhandler.cpython-39.pyc | Bin 2049 -> 2049 bytes .../event/__pycache__/tests.cpython-39.pyc | Bin 1990 -> 1990 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2673 -> 2673 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 4581 -> 4581 bytes .../__pycache__/_flatten.cpython-39.pyc | Bin 588 -> 588 bytes .../__pycache__/adapter.cpython-39.pyc | Bin 26361 -> 26361 bytes .../__pycache__/advice.cpython-39.pyc | Bin 4968 -> 4968 bytes .../__pycache__/declarations.cpython-39.pyc | Bin 30992 -> 30992 bytes .../__pycache__/document.cpython-39.pyc | Bin 3185 -> 3185 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 7262 -> 7262 bytes .../__pycache__/interface.cpython-39.pyc | Bin 25243 -> 25243 bytes .../__pycache__/interfaces.cpython-39.pyc | Bin 60678 -> 60678 bytes .../__pycache__/registry.cpython-39.pyc | Bin 22612 -> 22612 bytes .../interface/__pycache__/ro.cpython-39.pyc | Bin 19707 -> 19707 bytes .../__pycache__/verify.cpython-39.pyc | Bin 4484 -> 4484 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 8721 -> 8721 bytes .../__pycache__/builtins.cpython-39.pyc | Bin 3544 -> 3544 bytes .../__pycache__/collections.cpython-39.pyc | Bin 8114 -> 8114 bytes .../__pycache__/idatetime.cpython-39.pyc | Bin 24679 -> 24679 bytes .../__pycache__/interfaces.cpython-39.pyc | Bin 7733 -> 7733 bytes .../common/__pycache__/io.cpython-39.pyc | Bin 1379 -> 1379 bytes .../common/__pycache__/mapping.cpython-39.pyc | Bin 7373 -> 7373 bytes .../common/__pycache__/numbers.cpython-39.pyc | Bin 2180 -> 2180 bytes .../__pycache__/sequence.cpython-39.pyc | Bin 8993 -> 8993 bytes .../tests/__pycache__/__init__.cpython-39.pyc | Bin 3679 -> 3679 bytes .../__pycache__/basemapping.cpython-39.pyc | Bin 3665 -> 3665 bytes .../__pycache__/test_builtins.cpython-39.pyc | Bin 1259 -> 1259 bytes .../test_collections.cpython-39.pyc | Bin 5317 -> 5317 bytes .../__pycache__/test_idatetime.cpython-39.pyc | Bin 1307 -> 1307 bytes .../test_import_interfaces.cpython-39.pyc | Bin 663 -> 663 bytes .../tests/__pycache__/test_io.cpython-39.pyc | Bin 1873 -> 1873 bytes .../__pycache__/test_numbers.cpython-39.pyc | Bin 1221 -> 1221 bytes .../tests/__pycache__/__init__.cpython-39.pyc | Bin 3737 -> 3737 bytes .../advisory_testing.cpython-39.pyc | Bin 1156 -> 1156 bytes .../tests/__pycache__/dummy.cpython-39.pyc | Bin 463 -> 463 bytes .../tests/__pycache__/idummy.cpython-39.pyc | Bin 661 -> 661 bytes .../tests/__pycache__/m1.cpython-39.pyc | Bin 584 -> 584 bytes .../tests/__pycache__/odd.cpython-39.pyc | Bin 3494 -> 3494 bytes .../__pycache__/test_adapter.cpython-39.pyc | Bin 75793 -> 75793 bytes .../__pycache__/test_advice.cpython-39.pyc | Bin 15854 -> 15854 bytes .../test_declarations.cpython-39.pyc | Bin 113992 -> 113992 bytes .../__pycache__/test_document.cpython-39.pyc | Bin 21231 -> 21231 bytes .../__pycache__/test_element.cpython-39.pyc | Bin 854 -> 854 bytes .../test_exceptions.cpython-39.pyc | Bin 7140 -> 7140 bytes .../__pycache__/test_interface.cpython-39.pyc | Bin 114966 -> 114966 bytes .../test_interfaces.cpython-39.pyc | Bin 6604 -> 6604 bytes .../test_odd_declarations.cpython-39.pyc | Bin 10326 -> 10326 bytes .../__pycache__/test_registry.cpython-39.pyc | Bin 125190 -> 125190 bytes .../tests/__pycache__/test_ro.cpython-39.pyc | Bin 18895 -> 18895 bytes .../__pycache__/test_sorting.cpython-39.pyc | Bin 2481 -> 2481 bytes .../__pycache__/test_verify.cpython-39.pyc | Bin 33994 -> 33994 bytes .../Scripts/__pycache__/bottle.cpython-39.pyc | Bin 145422 -> 145422 bytes IKEA_scraper/.venv/Scripts/activate | 2 +- IKEA_scraper/.venv/Scripts/activate.bat | 2 +- IKEA_scraper/.venv/Scripts/bottle.py | 2 +- IKEA_scraper/.venv/Scripts/futurize-script.py | 2 +- IKEA_scraper/.venv/Scripts/normalizer.exe | Bin 106395 -> 106395 bytes .../.venv/Scripts/pasteurize-script.py | 2 +- IKEA_scraper/.venv/Scripts/pip.exe | Bin 106372 -> 106372 bytes IKEA_scraper/.venv/Scripts/pip3.9.exe | Bin 106372 -> 106372 bytes IKEA_scraper/.venv/Scripts/pip3.exe | Bin 106372 -> 106372 bytes IKEA_scraper/.venv/Scripts/snakeviz.exe | Bin 106362 -> 0 bytes IKEA_scraper/__pycache__/ikea.cpython-39.pyc | Bin 5205 -> 5205 bytes 1753 files changed, 2543 insertions(+), 77157 deletions(-) delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/LICENSE.rst delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/WHEEL delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/LICENSE delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/entry_points.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/from_thread.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/lowlevel.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/pytest_plugin.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/to_process.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/to_thread.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/_trio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/_asyncio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/_trio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_compat.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_eventloop.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_exceptions.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_fileio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_resources.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_signals.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_sockets.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_streams.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_subprocesses.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_synchronization.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_tasks.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_testing.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_typedattr.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_compat.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_eventloop.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_exceptions.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_fileio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_resources.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_signals.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_sockets.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_streams.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_subprocesses.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_synchronization.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_tasks.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_testing.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_typedattr.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_resources.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_sockets.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_streams.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_tasks.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_testing.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_resources.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_sockets.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_streams.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_subprocesses.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_tasks.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_testing.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/from_thread.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/lowlevel.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/py.typed delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/pytest_plugin.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/buffered.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/file.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/memory.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/stapled.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/text.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/tls.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/buffered.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/file.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/memory.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/stapled.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/text.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/streams/tls.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/to_process.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/anyio/to_thread.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/WHEEL rename IKEA_scraper/.venv/Lib/site-packages/{MarkupSafe-2.0.1.dist-info => charset_normalizer-2.0.6.dist-info}/INSTALLER (100%) rename IKEA_scraper/.venv/Lib/site-packages/{charset_normalizer-2.0.4.dist-info => charset_normalizer-2.0.6.dist-info}/LICENSE (100%) rename IKEA_scraper/.venv/Lib/site-packages/{charset_normalizer-2.0.4.dist-info => charset_normalizer-2.0.6.dist-info}/METADATA (89%) create mode 100644 IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/RECORD rename IKEA_scraper/.venv/Lib/site-packages/{anyio-3.3.1.dist-info => charset_normalizer-2.0.6.dist-info}/WHEEL (100%) rename IKEA_scraper/.venv/Lib/site-packages/{charset_normalizer-2.0.4.dist-info => charset_normalizer-2.0.6.dist-info}/entry_points.txt (100%) rename IKEA_scraper/.venv/Lib/site-packages/{charset_normalizer-2.0.4.dist-info => charset_normalizer-2.0.6.dist-info}/top_level.txt (100%) delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/LICENSE.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/WHEEL delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_abnf.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_connection.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_events.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_headers.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_readers.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_receivebuffer.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_state.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_util.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_version.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_writers.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_abnf.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_connection.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_events.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_headers.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_readers.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_receivebuffer.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_state.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_util.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_version.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/_writers.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/helpers.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_against_stdlib_http.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_connection.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_events.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_headers.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_helpers.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_io.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_state.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_util.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/data/test-file delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/helpers.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_against_stdlib_http.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_connection.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_events.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_headers.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_helpers.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_io.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_receivebuffer.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_state.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_util.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/LICENSE.md delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/WHEEL delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_bytestreams.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_exceptions.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_threadlock.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_types.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_utils.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/base.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/connection.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/connection_pool.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/http.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/http11.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/http2.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/http_proxy.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/base.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/connection.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/connection_pool.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http11.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http2.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http_proxy.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/anyio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/asyncio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/auto.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/base.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/curio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/sync.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/trio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/anyio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/asyncio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/auto.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/base.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/curio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/sync.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/trio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_bytestreams.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_exceptions.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/base.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/connection.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/connection_pool.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http11.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http2.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http_proxy.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/base.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/connection.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/connection_pool.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http11.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http2.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http_proxy.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_threadlock.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_types.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/_utils.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpcore/py.typed delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/LICENSE.md delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/REQUESTED delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/WHEEL delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/__version__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_api.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_auth.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_client.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_compat.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_config.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_content.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_decoders.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_exceptions.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_models.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_multipart.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_status_codes.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_types.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_utils.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/__version__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_api.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_auth.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_client.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_compat.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_config.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_content.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_decoders.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_exceptions.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_models.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_multipart.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_status_codes.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/asgi.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/base.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/default.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/mock.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/wsgi.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/asgi.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/base.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/default.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/mock.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/wsgi.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_types.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/_utils.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/httpx/py.typed delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/markupsafe/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/markupsafe/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/markupsafe/__pycache__/_native.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/markupsafe/_native.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/markupsafe/_speedups.cp39-win_amd64.pyd delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/markupsafe/_speedups.pyi delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/markupsafe/py.typed delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/AUTHORS.rst delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/LICENSE delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/WHEEL delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/_mixin.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/abnf_regexp.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/api.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/builder.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/compat.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/exceptions.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/iri.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/misc.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/normalizers.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/parseresult.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/uri.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/validators.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/_mixin.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/abnf_regexp.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/api.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/builder.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/compat.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/exceptions.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/iri.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/misc.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/normalizers.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/parseresult.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/uri.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/rfc3986/validators.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/LICENSE.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/REQUESTED delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/WHEEL delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/entry_points.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__main__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/__main__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/cli.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/ipymagic.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/main.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/stats.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/version.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/cli.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/ipymagic.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/main.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/drawsvg.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/favicon.ico delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/images/sort_asc.png delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/images/sort_both.png delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/images/sort_desc.png delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/snakeviz.css delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/snakeviz.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/sunburst.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/d3.min.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/d3.v3.min.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/immutable.min.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/jquery-1.11.1.min.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/jquery-3.2.1.min.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/jquery.dataTables.min.css delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/jquery.dataTables.min.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/lodash.compat.min.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/lodash.min.js delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/stats.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/templates/dir.html delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/templates/viz.html delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/snakeviz/version.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio-1.2.0.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio-1.2.0.dist-info/LICENSE delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio-1.2.0.dist-info/LICENSE.APACHE2 delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio-1.2.0.dist-info/LICENSE.MIT delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio-1.2.0.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio-1.2.0.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio-1.2.0.dist-info/WHEEL delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio-1.2.0.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/__pycache__/_impl.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/__pycache__/_version.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/_impl.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/_tests/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/_tests/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/_tests/__pycache__/test_sniffio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/_tests/test_sniffio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/_version.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/sniffio/py.typed delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado-6.1.dist-info/INSTALLER delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado-6.1.dist-info/LICENSE delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado-6.1.dist-info/METADATA delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado-6.1.dist-info/RECORD delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado-6.1.dist-info/WHEEL delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado-6.1.dist-info/top_level.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/_locale_data.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/auth.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/autoreload.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/concurrent.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/curl_httpclient.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/escape.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/gen.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/http1connection.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/httpclient.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/httpserver.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/httputil.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/ioloop.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/iostream.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/locale.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/locks.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/log.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/netutil.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/options.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/process.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/queues.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/routing.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/simple_httpclient.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/tcpclient.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/tcpserver.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/template.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/testing.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/util.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/web.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/websocket.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/__pycache__/wsgi.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/_locale_data.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/auth.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/autoreload.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/concurrent.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/curl_httpclient.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/escape.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/gen.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/http1connection.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/httpclient.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/httpserver.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/httputil.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/ioloop.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/iostream.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/locale.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/locks.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/log.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/netutil.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/options.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/platform/__init__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/platform/__pycache__/__init__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/platform/__pycache__/asyncio.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/platform/__pycache__/caresresolver.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/platform/__pycache__/twisted.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/platform/asyncio.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/platform/caresresolver.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/platform/twisted.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/process.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/py.typed delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/queues.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/routing.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/simple_httpclient.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/speedups.cp39-win_amd64.pyd delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/tcpclient.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/tcpserver.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/template.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__main__.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/__main__.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/asyncio_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/auth_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/autoreload_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/concurrent_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/curl_httpclient_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/escape_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/gen_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/http1connection_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/httpclient_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/httpserver_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/httputil_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/import_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/ioloop_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/iostream_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/locale_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/locks_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/log_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/netutil_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/options_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/process_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/queues_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/resolve_test_helper.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/routing_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/runtests.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/simple_httpclient_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/tcpclient_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/tcpserver_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/template_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/testing_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/twisted_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/util.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/util_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/web_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/websocket_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/__pycache__/wsgi_test.cpython-39.pyc delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/asyncio_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/auth_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/autoreload_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/concurrent_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/csv_translations/fr_FR.csv delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/curl_httpclient_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/escape_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/gen_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.mo delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/http1connection_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/httpclient_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/httpserver_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/httputil_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/import_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/ioloop_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/iostream_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/locale_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/locks_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/log_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/netutil_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/options_test.cfg delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/options_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/options_test_types.cfg delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/options_test_types_str.cfg delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/process_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/queues_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/resolve_test_helper.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/routing_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/runtests.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/simple_httpclient_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/static/dir/index.html delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/static/robots.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/static/sample.xml delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/static/sample.xml.bz2 delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/static/sample.xml.gz delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/static_foo.txt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/tcpclient_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/tcpserver_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/template_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/templates/utf8.html delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/test.crt delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/test.key delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/testing_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/twisted_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/util.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/util_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/web_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/websocket_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/test/wsgi_test.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/testing.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/util.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/web.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/websocket.py delete mode 100644 IKEA_scraper/.venv/Lib/site-packages/tornado/wsgi.py delete mode 100644 IKEA_scraper/.venv/Scripts/snakeviz.exe diff --git a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/LICENSE.rst b/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/LICENSE.rst deleted file mode 100644 index 9d227a0c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/LICENSE.rst +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2010 Pallets - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. 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. - -3. Neither the name of the copyright holder nor the names of its - contributors may 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 -HOLDER 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/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/METADATA b/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/METADATA deleted file mode 100644 index ef44e2b3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/METADATA +++ /dev/null @@ -1,100 +0,0 @@ -Metadata-Version: 2.1 -Name: MarkupSafe -Version: 2.0.1 -Summary: Safely add untrusted strings to HTML/XML markup. -Home-page: https://palletsprojects.com/p/markupsafe/ -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -Maintainer: Pallets -Maintainer-email: contact@palletsprojects.com -License: BSD-3-Clause -Project-URL: Donate, https://palletsprojects.com/donate -Project-URL: Documentation, https://markupsafe.palletsprojects.com/ -Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ -Project-URL: Source Code, https://github.com/pallets/markupsafe/ -Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/ -Project-URL: Twitter, https://twitter.com/PalletsTeam -Project-URL: Chat, https://discord.gg/pallets -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: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Text Processing :: Markup :: HTML -Requires-Python: >=3.6 -Description-Content-Type: text/x-rst - -MarkupSafe -========== - -MarkupSafe implements a text object that escapes characters so it is -safe to use in HTML and XML. Characters that have special meanings are -replaced so that they display as the actual characters. This mitigates -injection attacks, meaning untrusted user input can safely be displayed -on a page. - - -Installing ----------- - -Install and update using `pip`_: - -.. code-block:: text - - pip install -U MarkupSafe - -.. _pip: https://pip.pypa.io/en/stable/quickstart/ - - -Examples --------- - -.. code-block:: pycon - - >>> from markupsafe import Markup, escape - - >>> # escape replaces special characters and wraps in Markup - >>> escape("") - Markup('<script>alert(document.cookie);</script>') - - >>> # wrap in Markup to mark text "safe" and prevent escaping - >>> Markup("Hello") - Markup('hello') - - >>> escape(Markup("Hello")) - Markup('hello') - - >>> # Markup is a str subclass - >>> # methods and operators escape their arguments - >>> template = Markup("Hello {name}") - >>> template.format(name='"World"') - Markup('Hello "World"') - - -Donate ------- - -The Pallets organization develops and supports MarkupSafe and other -popular packages. In order to grow the community of contributors and -users, and allow the maintainers to devote more time to the projects, -`please donate today`_. - -.. _please donate today: https://palletsprojects.com/donate - - -Links ------ - -- Documentation: https://markupsafe.palletsprojects.com/ -- Changes: https://markupsafe.palletsprojects.com/changes/ -- PyPI Releases: https://pypi.org/project/MarkupSafe/ -- Source Code: https://github.com/pallets/markupsafe/ -- Issue Tracker: https://github.com/pallets/markupsafe/issues/ -- Website: https://palletsprojects.com/p/markupsafe/ -- Twitter: https://twitter.com/PalletsTeam -- Chat: https://discord.gg/pallets - - diff --git a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/RECORD deleted file mode 100644 index c5acda27..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/RECORD +++ /dev/null @@ -1,13 +0,0 @@ -MarkupSafe-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -MarkupSafe-2.0.1.dist-info/LICENSE.rst,sha256=RjHsDbX9kKVH4zaBcmTGeYIUM4FG-KyUtKV_lu6MnsQ,1503 -MarkupSafe-2.0.1.dist-info/METADATA,sha256=FmPpxBdaqCCjF-XKqoxeEzqAzhetQnrkkSsd3V3X-Jc,3211 -MarkupSafe-2.0.1.dist-info/RECORD,, -MarkupSafe-2.0.1.dist-info/WHEEL,sha256=jr7ubY0Lkz_yXH9FfFe9PTtLhGOsf62dZkNvTYrJINE,100 -MarkupSafe-2.0.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 -markupsafe/__init__.py,sha256=s08KbuFRV3zh4Wh7xjsIphXgp1xf0EUB79wlPj-4scc,9211 -markupsafe/__pycache__/__init__.cpython-39.pyc,, -markupsafe/__pycache__/_native.cpython-39.pyc,, -markupsafe/_native.py,sha256=JMXegJtk1ZcnRKrgyCA-CEXmRnOpaIXLyDAM98GbshY,2061 -markupsafe/_speedups.cp39-win_amd64.pyd,sha256=hPTsANj9bt7hLYxWLuZcC7E3-EnJQ4GlvIf9Vx0p1p0,16384 -markupsafe/_speedups.pyi,sha256=f5QtwIOP0eLrxh2v5p6SmaYmlcHIGIfmz0DovaqL0OU,238 -markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/WHEEL b/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/WHEEL deleted file mode 100644 index d1267fcc..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.36.2) -Root-Is-Purelib: false -Tag: cp39-cp39-win_amd64 - diff --git a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/top_level.txt b/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/top_level.txt deleted file mode 100644 index 75bf7292..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -markupsafe diff --git a/IKEA_scraper/.venv/Lib/site-packages/__pycache__/bottle.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/__pycache__/bottle.cpython-39.pyc index 1d8dfb851f8f83ef85cb688bd39388f3b28fcaaf..59ba49d3d7cd9080795bf77a8027ea0b0c743e49 100644 GIT binary patch delta 37 rcmZqpz|ru5gFBIzmx}=ibd0<GYVk2{fk2{fG0YjJs(*OVf delta 27 hcmeC-@8Rc87S|k(ZZ?0SLH_ye4uNFuF~w$pQdGyaliT delta 24 ecmaFH_>7S|k(ZZ?0SNdmJ51y*V04*SlLY`u#Rf=3.6.2 -License-File: LICENSE -Requires-Dist: idna (>=2.8) -Requires-Dist: sniffio (>=1.1) -Requires-Dist: dataclasses ; python_version < "3.7" -Requires-Dist: typing-extensions ; python_version < "3.8" -Provides-Extra: doc -Requires-Dist: sphinx-rtd-theme ; extra == 'doc' -Requires-Dist: sphinx-autodoc-typehints (>=1.2.0) ; extra == 'doc' -Provides-Extra: test -Requires-Dist: coverage[toml] (>=4.5) ; extra == 'test' -Requires-Dist: hypothesis (>=4.0) ; extra == 'test' -Requires-Dist: pytest (>=6.0) ; extra == 'test' -Requires-Dist: pytest-mock (>=3.6.1) ; extra == 'test' -Requires-Dist: trustme ; extra == 'test' -Requires-Dist: uvloop (<0.15) ; (python_version < "3.7" and (platform_python_implementation == "CPython" and platform_system != "Windows")) and extra == 'test' -Requires-Dist: mock (>=4) ; (python_version < "3.8") and extra == 'test' -Requires-Dist: uvloop (>=0.15) ; (python_version >= "3.7" and (platform_python_implementation == "CPython" and platform_system != "Windows")) and extra == 'test' -Provides-Extra: trio -Requires-Dist: trio (>=0.16) ; extra == 'trio' - -.. image:: https://github.com/agronholm/anyio/workflows/Python%20codeqa/test/badge.svg?branch=master - :target: https://github.com/agronholm/anyio/actions?query=workflow%3A%22Python+codeqa%2Ftest%22+branch%3Amaster - :alt: Build Status -.. image:: https://coveralls.io/repos/github/agronholm/anyio/badge.svg?branch=master - :target: https://coveralls.io/github/agronholm/anyio?branch=master - :alt: Code Coverage -.. image:: https://readthedocs.org/projects/anyio/badge/?version=latest - :target: https://anyio.readthedocs.io/en/latest/?badge=latest - :alt: Documentation -.. image:: https://badges.gitter.im/gitterHQ/gitter.svg - :target: https://gitter.im/python-trio/AnyIO - :alt: Gitter chat - -AnyIO is an asynchronous networking and concurrency library that works on top of either asyncio_ or -trio_. It implements trio-like `structured concurrency`_ (SC) on top of asyncio, and works in harmony -with the native SC of trio itself. - -Applications and libraries written against AnyIO's API will run unmodified on either asyncio_ or -trio_. AnyIO can also be adopted into a library or application incrementally – bit by bit, no full -refactoring necessary. It will blend in with native libraries of your chosen backend. - -Documentation -------------- - -View full documentation at: https://anyio.readthedocs.io/ - -Features --------- - -AnyIO offers the following functionality: - -* Task groups (nurseries_ in trio terminology) -* High level networking (TCP, UDP and UNIX sockets) - - * `Happy eyeballs`_ algorithm for TCP connections (more robust than that of asyncio on Python - 3.8) - * async/await style UDP sockets (unlike asyncio where you still have to use Transports and - Protocols) - -* A versatile API for byte streams and object streams -* Inter-task synchronization and communication (locks, conditions, events, semaphores, object - streams) -* Worker threads -* Subprocesses -* Asynchronous file I/O (using worker threads) -* Signal handling - -AnyIO also comes with its own pytest_ plugin which also supports asynchronous fixtures. -It even works with the popular Hypothesis_ library. - -.. _asyncio: https://docs.python.org/3/library/asyncio.html -.. _trio: https://github.com/python-trio/trio -.. _structured concurrency: https://en.wikipedia.org/wiki/Structured_concurrency -.. _nurseries: https://trio.readthedocs.io/en/stable/reference-core.html#nurseries-and-spawning -.. _Happy eyeballs: https://en.wikipedia.org/wiki/Happy_Eyeballs -.. _pytest: https://docs.pytest.org/en/latest/ -.. _Hypothesis: https://hypothesis.works/ - - diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/RECORD deleted file mode 100644 index 2626710e..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/RECORD +++ /dev/null @@ -1,82 +0,0 @@ -anyio-3.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -anyio-3.3.1.dist-info/LICENSE,sha256=U2GsncWPLvX9LpsJxoKXwX8ElQkJu8gCO9uC6s8iwrA,1081 -anyio-3.3.1.dist-info/METADATA,sha256=oGrmmbL9vyZq73qvft4Wp14jiWJ8Gri92iEVYgTVyJI,4553 -anyio-3.3.1.dist-info/RECORD,, -anyio-3.3.1.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 -anyio-3.3.1.dist-info/entry_points.txt,sha256=z1bvtbND76CfYuqdNZxiaibWP2IOqSVa8FQKIk4lVQk,40 -anyio-3.3.1.dist-info/top_level.txt,sha256=QglSMiWX8_5dpoVAEIHdEYzvqFMdSYWmCj6tYw2ITkQ,6 -anyio/__init__.py,sha256=bsBPHK2CO_8TfnoTiFbh5eZVO189rdD8uF5OgY2gp54,3799 -anyio/__pycache__/__init__.cpython-39.pyc,, -anyio/__pycache__/from_thread.cpython-39.pyc,, -anyio/__pycache__/lowlevel.cpython-39.pyc,, -anyio/__pycache__/pytest_plugin.cpython-39.pyc,, -anyio/__pycache__/to_process.cpython-39.pyc,, -anyio/__pycache__/to_thread.cpython-39.pyc,, -anyio/_backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -anyio/_backends/__pycache__/__init__.cpython-39.pyc,, -anyio/_backends/__pycache__/_asyncio.cpython-39.pyc,, -anyio/_backends/__pycache__/_trio.cpython-39.pyc,, -anyio/_backends/_asyncio.py,sha256=topgvYOZYrRW4cSyAOcAn6xP_YZ9CXIwsBhz0IFw_LQ,65171 -anyio/_backends/_trio.py,sha256=kFm2dDSPLCRQaIZJcD5fX1RHddEaYXwwj2DvIHEEWDg,25713 -anyio/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -anyio/_core/__pycache__/__init__.cpython-39.pyc,, -anyio/_core/__pycache__/_compat.cpython-39.pyc,, -anyio/_core/__pycache__/_eventloop.cpython-39.pyc,, -anyio/_core/__pycache__/_exceptions.cpython-39.pyc,, -anyio/_core/__pycache__/_fileio.cpython-39.pyc,, -anyio/_core/__pycache__/_resources.cpython-39.pyc,, -anyio/_core/__pycache__/_signals.cpython-39.pyc,, -anyio/_core/__pycache__/_sockets.cpython-39.pyc,, -anyio/_core/__pycache__/_streams.cpython-39.pyc,, -anyio/_core/__pycache__/_subprocesses.cpython-39.pyc,, -anyio/_core/__pycache__/_synchronization.cpython-39.pyc,, -anyio/_core/__pycache__/_tasks.cpython-39.pyc,, -anyio/_core/__pycache__/_testing.cpython-39.pyc,, -anyio/_core/__pycache__/_typedattr.cpython-39.pyc,, -anyio/_core/_compat.py,sha256=egvqvJXQWs2vhpi-yl1oTmOdXUtYUOGUMoudV03xz5c,5635 -anyio/_core/_eventloop.py,sha256=NHXj_qMJlJNSD3YtKc2wVbbOujDXPxM46s1Ayik9tHA,4187 -anyio/_core/_exceptions.py,sha256=t0cTxVckJ6YZjFkDOuWPt6ymSpEq1bmTGEPz4LVTcHc,2838 -anyio/_core/_fileio.py,sha256=mYG_lon4iaBXz3mXF9JjEMEu0s_lMQnBaA8BTQDej8o,17974 -anyio/_core/_resources.py,sha256=M_uN-90N8eSsWuvo-0xluWU_OG2BTyccAgsQ7XtHxzs,399 -anyio/_core/_signals.py,sha256=ub6LfvBz-z3O1qj8-WkWi46t_dpcPTefSfC27NBs-lU,820 -anyio/_core/_sockets.py,sha256=9IvIGk2W_1bDvfZ4GBnhs7g4vRl1uyQ4JDg6vkpgXB4,19695 -anyio/_core/_streams.py,sha256=MP1w-dvGutT0a8vFWQDvaDfVPRsAF0im_LkTqG6OAOk,1458 -anyio/_core/_subprocesses.py,sha256=yY40OdWoOJATJNU1Phpz2u6e-AYmcqjOaPJS8UXYeB8,4252 -anyio/_core/_synchronization.py,sha256=HdvdWg5WqnQbMypUBq2DL0NgyZ09G6SnnIL-e0HJnXw,16365 -anyio/_core/_tasks.py,sha256=rEt3dhdZKsfEcif4QDk4ROWLKaPlkfuNkzFPegVbQi4,5186 -anyio/_core/_testing.py,sha256=uMRNkDr91G92OtYIqIo__sMOJi27zYEaUjgBtyYImus,2045 -anyio/_core/_typedattr.py,sha256=0hYrxkAFHCEBkcIC1-goHLd5bXth5VbNkCLTojvNbaM,2496 -anyio/abc/__init__.py,sha256=PKJiaWuoOQZNhO3peq4y4i5Xlbmv5dJVX-ckboH5h4k,1936 -anyio/abc/__pycache__/__init__.cpython-39.pyc,, -anyio/abc/__pycache__/_resources.cpython-39.pyc,, -anyio/abc/__pycache__/_sockets.cpython-39.pyc,, -anyio/abc/__pycache__/_streams.cpython-39.pyc,, -anyio/abc/__pycache__/_subprocesses.cpython-39.pyc,, -anyio/abc/__pycache__/_tasks.cpython-39.pyc,, -anyio/abc/__pycache__/_testing.cpython-39.pyc,, -anyio/abc/_resources.py,sha256=VC7Gzy8xwOGrPtfjNuSjGaKVXmBy0IS4sVpEwq2vZa0,761 -anyio/abc/_sockets.py,sha256=uFgijTGLAHbrfK8JA3arScbiN0o88bf0uUSlq4MjnEg,5605 -anyio/abc/_streams.py,sha256=h_EXlQsbpwt63gd2jSjaGBLprBfzG7vcSQYIZuDI5LY,6516 -anyio/abc/_subprocesses.py,sha256=krC7Bai9F3KII75Czkww88xCdTPvnb-fYoF-IPupHeo,2040 -anyio/abc/_tasks.py,sha256=bl96jRwdaSfTFV4b9GfGRdFZs-dtikHU4IFLKRiYLQY,3001 -anyio/abc/_testing.py,sha256=LfRDpPw4FQrja9dkhzV_RovBmV4sxqvzxHX5YrV6lYc,1147 -anyio/from_thread.py,sha256=w_ntrTMLfj9OHV3h3QgxC9qQKmUly6GrXOswAK7_jDA,15510 -anyio/lowlevel.py,sha256=iHitP45bE-pH67spwNI3qBqtITPygKp90q_pU4Gz7E8,4609 -anyio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -anyio/pytest_plugin.py,sha256=bguloPM9UfdxIGlteWnctgT2PXbs1zFRdZ_JHtIGSJc,5544 -anyio/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -anyio/streams/__pycache__/__init__.cpython-39.pyc,, -anyio/streams/__pycache__/buffered.cpython-39.pyc,, -anyio/streams/__pycache__/file.cpython-39.pyc,, -anyio/streams/__pycache__/memory.cpython-39.pyc,, -anyio/streams/__pycache__/stapled.cpython-39.pyc,, -anyio/streams/__pycache__/text.cpython-39.pyc,, -anyio/streams/__pycache__/tls.cpython-39.pyc,, -anyio/streams/buffered.py,sha256=32jQEEkqefrmPgAXKAQoGnNSdm5l0zzaa0V_nYkwpbM,4435 -anyio/streams/file.py,sha256=fMaiJwdCwrNUxtg7gk3BaDsfUaHBj6GLmDoQQfNmqz4,4331 -anyio/streams/memory.py,sha256=WAwgrD_oIa-IVSVU3YmtTbxlI1UmxrthF_UW3e1rnCo,9145 -anyio/streams/stapled.py,sha256=euIt3fnuvs3rE7Xn5QsDYhebP5neXAoyCVcAPcM6vpE,4168 -anyio/streams/text.py,sha256=iTrT7auMl2SGvFxGf-UA0DJAdTx2ZOW663q1ucMihzs,4966 -anyio/streams/tls.py,sha256=xzcpIUfaMR_GcBNYwNttdqmaGcsdDLd1bD0u1LVtyyc,10921 -anyio/to_process.py,sha256=--L0kbI0eb2gjiQTCJeBA7-e9iWIYkKq6ymAMu8uYQ4,9067 -anyio/to_thread.py,sha256=f-SIvh1-VSg78_R5k6JfP7sXJ5epx3eBa3cDPh1s8lk,2139 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/entry_points.txt b/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/entry_points.txt deleted file mode 100644 index 1740df03..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[pytest11] -anyio = anyio.pytest_plugin - diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/top_level.txt b/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/top_level.txt deleted file mode 100644 index c77c069e..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -anyio diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/__init__.py deleted file mode 100644 index 11673a43..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/__init__.py +++ /dev/null @@ -1,112 +0,0 @@ -__all__ = ( - 'maybe_async', - 'maybe_async_cm', - 'run', - 'sleep', - 'sleep_forever', - 'sleep_until', - 'current_time', - 'get_all_backends', - 'get_cancelled_exc_class', - 'BrokenResourceError', - 'BrokenWorkerProcess', - 'BusyResourceError', - 'ClosedResourceError', - 'DelimiterNotFound', - 'EndOfStream', - 'ExceptionGroup', - 'IncompleteRead', - 'TypedAttributeLookupError', - 'WouldBlock', - 'AsyncFile', - 'Path', - 'open_file', - 'wrap_file', - 'aclose_forcefully', - 'open_signal_receiver', - 'connect_tcp', - 'connect_unix', - 'create_tcp_listener', - 'create_unix_listener', - 'create_udp_socket', - 'create_connected_udp_socket', - 'getaddrinfo', - 'getnameinfo', - 'wait_socket_readable', - 'wait_socket_writable', - 'create_memory_object_stream', - 'run_process', - 'open_process', - 'create_lock', - 'CapacityLimiter', - 'CapacityLimiterStatistics', - 'Condition', - 'ConditionStatistics', - 'Event', - 'EventStatistics', - 'Lock', - 'LockStatistics', - 'Semaphore', - 'SemaphoreStatistics', - 'create_condition', - 'create_event', - 'create_semaphore', - 'create_capacity_limiter', - 'open_cancel_scope', - 'fail_after', - 'move_on_after', - 'current_effective_deadline', - 'TASK_STATUS_IGNORED', - 'CancelScope', - 'create_task_group', - 'TaskInfo', - 'get_current_task', - 'get_running_tasks', - 'wait_all_tasks_blocked', - 'run_sync_in_worker_thread', - 'run_async_from_thread', - 'run_sync_from_thread', - 'current_default_worker_thread_limiter', - 'create_blocking_portal', - 'start_blocking_portal', - 'typed_attribute', - 'TypedAttributeSet', - 'TypedAttributeProvider' -) - -from ._core._compat import maybe_async, maybe_async_cm -from ._core._eventloop import ( - current_time, get_all_backends, get_cancelled_exc_class, run, sleep, sleep_forever, - sleep_until) -from ._core._exceptions import ( - BrokenResourceError, BrokenWorkerProcess, BusyResourceError, ClosedResourceError, - DelimiterNotFound, EndOfStream, ExceptionGroup, IncompleteRead, TypedAttributeLookupError, - WouldBlock) -from ._core._fileio import AsyncFile, Path, open_file, wrap_file -from ._core._resources import aclose_forcefully -from ._core._signals import open_signal_receiver -from ._core._sockets import ( - connect_tcp, connect_unix, create_connected_udp_socket, create_tcp_listener, create_udp_socket, - create_unix_listener, getaddrinfo, getnameinfo, wait_socket_readable, wait_socket_writable) -from ._core._streams import create_memory_object_stream -from ._core._subprocesses import open_process, run_process -from ._core._synchronization import ( - CapacityLimiter, CapacityLimiterStatistics, Condition, ConditionStatistics, Event, - EventStatistics, Lock, LockStatistics, Semaphore, SemaphoreStatistics, create_capacity_limiter, - create_condition, create_event, create_lock, create_semaphore) -from ._core._tasks import ( - TASK_STATUS_IGNORED, CancelScope, create_task_group, current_effective_deadline, fail_after, - move_on_after, open_cancel_scope) -from ._core._testing import TaskInfo, get_current_task, get_running_tasks, wait_all_tasks_blocked -from ._core._typedattr import TypedAttributeProvider, TypedAttributeSet, typed_attribute - -# Re-exported here, for backwards compatibility -# isort: off -from .to_thread import current_default_worker_thread_limiter, run_sync_in_worker_thread -from .from_thread import ( - create_blocking_portal, run_async_from_thread, run_sync_from_thread, start_blocking_portal) - -# Re-export imports so they look like they live directly in this package -for key, value in list(locals().items()): - if getattr(value, '__module__', '').startswith('anyio.'): - value.__module__ = __name__ diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index b5bb81524ab08034c379e5d69dbbedfad64182b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3080 zcmb_eSyvlJ7M74$Bq5M2fx(XB*v5+-8}Iun)({xXARLk#d1{L867*2FOH9yaHG7DqO{Da1AR^!Rv6{&Ckd$ z@dn&*a#r5NS(wFJaLegAc^mJ*9lQ&7@gCg6`*0s0zyo{;5AhK^!pHC!pTHA*3QzGF zJj3Vk9ACf-dwa*YGv2 z!YZ!8n&ZdhpKu-4@eRDe4cKtpxcoD2!Y0F4B+N&SoXt9ZxwkIBFP;+JcQ%0y+w zb0~MVa(zHg(>Wc zm~koD4)^v&=tt%>F&+;+A*Jw{c<(V!@+dN;Ij!uJO%bV<_QayrO83ZZrT2y2(8?2b zW^t|+wLh9SFI6P`lVov0$N+;_=yeq@saEKl++ygzY1CpZIGVA=_nv6RfeM$kYBkN+ zO6VzUN)d}q!F@Bm)ou#E8pk@=X~kkqsr^>7bFS>RYDs@iDsSIps${UGKnj!I;PIZx zsHO;6gNV$b=FN^+yNOY-8*<6C@I>Iu>8UUjp0%LYwC3z8tuT0R zN}fGu4}%{la};2Vp}QQbLZx zDdj^R#N9RQDY?&g?9EQFhdPKI+uH&KD&1yk=Wle8sAKP(4I$R-I&sw9y{F~6M{@=p zpXW{P1#x?=<2^I|5mAeIY;PZUk;%-f&=1ImrqmaYjSns!*kCl{?s1GyuaWD<2#>Lu znn2#%vvF-oeeu|M;mCsBO-H+oO$575Z#?QRbGr9N_e$15E+S3Q-M^CvEb^>ovJDdlV#Qf`(izVGXUYN0<9=9A_{04&aLhZ^`)NT79EUcCG2Qr_(i+j=3}w zQOtGRIn^LXQ&^2#N%!2ucLk3xW#-7YQy|uq({aV?bXa>N3gW`WndFvP=lpk~)AJ7$=<2E!oFJe#<)7O~0WBhNvh zJK%CuD%JcQo`hoWrCyJS{mOkdy(@yjCHr~G>1r26daMRo=1N? zCXQBc6*+Pd0;S$wt(|T?7SU1Az+`XOrum*$Veo^kzAF4bh7yc+w{XSfcZ5~{9BO`zAK`-ON3j@)?eGC*=)0IMxJ*PNA2J3)M&DhTu9HPrjq4!Avu+vOqP@X14p8xWB>pF diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/from_thread.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/from_thread.cpython-39.pyc deleted file mode 100644 index 066a35879eaf04a3a3f47983b869199d56140b83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15812 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 Riqn<_di8TW*rTMjVmBC#VTijlA%OtB z0Buv1`%w9zFYO;lGPNK5*8k9dfwxYd{MyG%C+T-~N$Q$52{~BqIeQknd(L+*OMh~* zY~b_HuaO zLm2%70|ukRnA`s@JNR7hh}M?Vj-}J`qm~FmpZ4SU5qJDBjGsDbM>t8VBX~a)(n(_{ zc^agx4)y#f#weJ6vehiB*R4G62T%M^L@5be+UTcFHJ->O19Z_py!0N$|141=)Bjw ztcO+`rmR3CS$S{TYeSv@OEq7v-dJ4!c+g4XXk9`Dad-W0s}slJ`iHkxmc67U{hpBP z%_kyyvVJ?*SWjS&cY1zn%YP)2bw3&e@w-r3D4vM0*&9ewKitts$RI{V(cjBhf7jZL zV1CEnrz|IED+>w0B~F6q(a?-AS=FYmAU(4SG!482H*zUymRhuSt z9`=lH#(6JJp`HLWqK)KjylPay{$gcuUWaj!XY+R0X55&}K-vSSZ0k1buHy(xb)CDGZW zw??bqhx5XFvzngoJ=JuwhM=2o%Xk|;1n~nO3)B*xWC4vZC{em5(kF8*VI%37SCA}m zc3YA_!_4yf<=KSiJw=33@bmz6!Q8&gC@zv6k1`+hhaDS2KJ z#%Y3qyjB-B?D-MgR7GYC9D8zFe+5rsqbZv@STF5YhMUtl0oz`U z@A+Y0Ab(-U@;pSPLk)RlW{arb&1}D)##v?cBk$hw?N3&`yDMwQZs~`Zatn_#Mv+OP zkL+q(m^3ju+7;=So1|f+_QGay-k{{pt7 z0WwfuWF=1uE<{)GEDt$kVi?FGiJTH>k#$EO>XU}9<4GtM?XVrgGj>e0j8os_2IbAw z-^w3jxPjFY5w_*KAmn9g#%V;-e6n^B1*zxV0hQ#@7%Y$Pc75Nbn6NKci-EN!3#^w1I(-@F*k{nQcnq98o-NXoc6@;p=O>?V-uL8YCw#g6m?PKBweMdP;qFbDrO9KL~{%yP>2feJ3#em_jL6;ES5pwcGq z&kDn#Zw4j-;Q%lJ$=7UEzDKXI2r6)a;={0fP|p5RU?eVFHOY?G|GYN~%>_ zREUl~7CHpM>v)m}Xei)6XWQkJ?XY>{KGwI5)EwYiLEqHcVY}=(+-1{#ncHEn7&AUK z9_JyGAKcS20cJcmY5o`@FB`T#?q>QBsw35`8 zS*Y)_B8q4=Fg$*iQ`x~Sj^-ZH0=oo@>7_(d0+yP zk<#rfrnD$vj6T#S%_&V$5FVdL?clYkt#gcFG7HJCj~O~^LAgV-fPKIi^!op`1k+0# zGW!x{J==Txkxh@y`w&9gRhZ7ev){NMXv6KW)Y`QBOg49zHXGz}L*5PQYwo8;WL}2B zDQa%A&v3Q;!rEnjLhgi%S*zPs9M6IB1AikF&c*Eu7ge1a#b6?CtGfq?p))v%NP&oJ z*qr=1HI(0#pK1^K1;}jTb{uc@dm16XA%SC*@CWb{@*u-9Srry8vm)9l6E;-={D@7- zj1(u8O)2W*KpMM1?n|VGO)IrGbFa)@^Er@D$zl_6at9@WMsi;7n*y+0qDGy7f{fZc z>IUVqw7Of_k4t%#WDXu8v!IGUgP)MeD4CqZ5yoi2Al+}LsmbdC+(0kOl#%rNFm ziu6Y20msB$j&a`G$)8~VSy|O7 z+Tv8R%D1W6%Z~>E1H~v!AE(xw6wuvYF0! zP*O!l0pIw{B;aevPhQcp9g6c;zhu`MOhaLrHhsv*5dNzeNmZArzL{h?ZqH5Lw) z3t7SQc-+F=i}cPtMX0*rE#lDzRp^uiY86R=sZ{POGAKu6#h%2SM5Y5t4xk}iqTVz$ zOVlVtuTbwMHG3yeJ(X?<<-f<1kYUQqMkP`=XDst;n@xRP$(d}fX0inY-6`;phvFoM(0*IPzMgRZ+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/pytest_plugin.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/__pycache__/pytest_plugin.cpython-39.pyc deleted file mode 100644 index b7eab1d00861499e6e22e2f38ae0c437c1e75a5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4910 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index a225bd66760ee18a1c62438d391cd524cfed5551..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179 zcmYe~<>g`kf`|Vc6G8N25P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_Si&acOWkyMU zUQAJ9UP^v$OmK2Wetu4jr?;zPd~tG7VnJ$Aj9yu4URjJ!W>QRXW=X1UL1J=tVtQ(E vOk!STX1;!W5|E#omr|@BAD@|*SrQ+wS5SG2!zMRBr8Fni4rJqJAZ7pnuO~0D diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-39.pyc deleted file mode 100644 index 74015af90aa3cf302132cf57108d84d0918002a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56490 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 AQvd(} diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/_trio.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/__pycache__/_trio.cpython-39.pyc deleted file mode 100644 index 6a22a81cd44958793f56a8bfd0e43514bec97c8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28930 zcmchA36vbidERtS&$+X+Cl(731eYKLaVc^Mf)pi@6bWDff*`>KgkA7xLK+UHdx2TZ zv8bK}u&Y@}0w__IMN)E{IFaCZ;VVJn*p6c-PMpXGoj7@s9a(m+j`L#K@}W5IInVZc zv1NW$F0o?4x z<-MGU#hjR9RARRNHEcufP20q;S&3II+cNkpUP)Awc2e?IB~?w^X~`!lnQGR~Nmn%6V=W3=IW$9S>0l9 zscyBmR&TR!t8TNmRd2U%uWq-uSMRXzs7~2a)jRDwt2^u+(xy?l%iamNGL?5!ciFqD z@3h}pz1zN9o@Fc3)qCuBNq(SmZ}mR=KIC)GU}dIyzkPpox4paifc-#qkG)6A^OXmy z57`e@-)+CU`mp`5lnqthQ+==fUdazv-dBCZex&-S{b=ZgexmYJ^|1Z46VRK=rtNygF~s8?hH-wb9+W zbfI19-s#+S#jsD{cbog1`^=TN{k*$#=>_`*q|YwBXxsAplKm2XPueFB#hlxn?XSd~ z?e5d4dl;o3v_B+u3U)z$U$$SC-=bZ_?^*VTmcPUr4dlJ*&tl>zCJ z{N87uMQhW}J!tJ7v{pfD6*r0Y-u0S+C-*w{;mLh?QoRz#h-;B&GtT{Zc0Zog<=JxN z*>2|nJbM7o&dIZLfX{ID0Ky%>*X{0eTVev`X;;ZVmU?c^F%~VryUpE-`{!5#cjuf3 zucn=coOc8I24H&Fc@Nrt58&Ukv;ug~BlqmaOU`?*8TJKtyL)a6_|JLYRnvLIdGr;_ zzSvRrnDc&=t)iXBohQ)F6Yiw@{FWHnSwq=gXCKP;xod#@!@%{2QMTWiMcJ(TVU#sd z)=OD@sO1*WIT|(KD&LNZ?YL$HiWluSWQFa(*&tN2bmOhHQA4U1o&NC=~rd9qi zlz+^rW7G;=$P{XK!3$GmtG0#>Ds4(*N?g%BgUNL z_}25z0_uGnm@$_=VShq?U$tMwdnRym0xdn~JdYZmjFi0Kyoi$T0CcwV5}6YL(oF+=m69pT<}|?KtSm zbrwlv?DW7G2 za6uJI?x|ww?854@J3Z#d_tjSY%)Sf7a-(>v;`-^?Vx=Ov>}$Qe^ zvGHuNRs`w#nc2FkuQbXv*H0X9&#kz=b)Z~o_^Cr~%~j=+ZyhOnxP7*`yj-rG_S19q z<1PTM`RSv}Y_VAJ)AM|>R&xFLyxZ^-3oFa$-y&Rois^GjZ$IEJE4Nf^xXwN{+J%L&$m13QjfLxm zKZXxdt`;uT)mc{+8fTPSbO6lQepNr~){eVgeMOaAJ*1KSE8c2n(b#OI?zv89;lRO~ zb98aOfwrm`cmCkTk}J48gio=Il1-(0?YyfRh4S+GhYKFiQgj@J2SZ&rKv6=*j?7@# z$)S~^a!@cZTf{f1%$Mq*57W;dK1KxZLrd~y22UI~b`0dx#(1TEq2iu*h33u_*Q&(^ zUK=Dn3LLi3lD@s5LLyrzfE><)2(k->u=x^cJNgHULfaO;QUa19 z>A4-Zh^~RiWskaGl>XJ>) zgp^FU6L@nlcyn`DDjdF5J&3{1f%ejMRX$xNqa@E>D5}$*pH#v^B~o_y7e|KIGq^mO zYK_>2(TrV#w771}T{rz?{nQee*iRJ-HTOcHfR^K>il-h!UG;t>*JJ7ce!hO zwbgR{{sIMyTXVeo3k_AS&n&O1{b-w)Cs3PfV-fP231I3Ok%bpzL|c(*8q1@N*pjgr zE61AV4;rsydRfi>2~BaH!AUE#W+9!H&$fh7E6o&%i4<>iqyV@voD*I;BdTY#GC5T5v%LIGk2 zVxfSRo>85Uu zvT?lHMp?r|-nar94!*EPT(TsRN$p~XN0@X0F^{t2xY~#tjUrCJ-U9@`o!}&m41rh* zJH8&`!hsyCK-u-}^#opfj=csH-a$0so8ZI*zRrrPzl&7GJN#q5MLRj%;EMo?0>oW_ z0JVTp03*cmJo4QGCkQsK0EBO1h||Fk2Q_jEC1`)w={wFB(ZPq>ovcB#wiLxo$Lrrj z{~?N#-kGvn>EH27==4;iCF@mwPMvR z6#Q(VP^~*F73On=!nu`VML$s_Vny*GqDbvyZa)(;vv9SVM9v?iUDndxD#bGE6hy6X zktT1FvY%d7P{OLQ>L(T}^BV&-!2t!hh5CZRRBxwi{>qgGn z8qZrHfRofp7Mc%kEu46+xON8)VhVcMgnnn4k?l{$%E^+6^i zk-iYI>IGavq-jH5?ddCt3VT`U(@5HVL7N+*=Pf%fTHkP}+u>1g6K>K?i8fF07x!sN zGtlNKXmhRgv(UELtA;z^<~ZAO2Ji&4c+9M*hvkWrck?ngLk-kn4eI)&JtUfW#Lv(? z6k}^nJq_@B$ee^Hl7wo@p_+;{j1BV|q)Gu`BelrW*Uh;nrxVb~MHtsG*hn&d4qv)f zsI4f^RjdARm@8BRi#r!^m`A&;FMpECnz%gTFov%T#WC6fxuw4PLj5M+y9bGen&Ovm zABF?qDS^IWp)9_XxWZ8-sMDs+xrOPZTEt803=%R%G0;q4mtZ8C70RsCPhv0O!N+iU zl)Z#`)W}2aMxhSdR8%h|i}iv(Dl?iq0(=FTwGXXLQFOur3Y3~2!1M5Z$iU2bXu(E& z$y!}7V(aimtxYx(O=~H61;X~S`F!j}40zqTWYx0zcXw=e>)l#fw?VH61hb0{r&D_9 zQ0Yaj;xsubZeD3CDSuohQpn2OPOROiq{r|uzJ6P>(hn0WUhA^N<015S%8#%1au zb1B|5P8-em_Z!DyZa2*`3^2NjK*#a9wMQ4ul)b427-Q-*ry*0gtJND*nzSE9ehOx% zRPd%i!c(W*DX)P^s_V=MOw*R2%+DQPsWr+~JttCU0g9iMikQgMYoQUMP_BpKF(=|q z5<%5@lzkRgiv!YTl$P4f&9wAI6bZk?S1G059uhQdff5>cB^ZWUL0&_jknR*EUN@W< zQT9E!G@NGA0GvbZPbn`>4|mH{(IR9Rt!Su9RDlT*d@@iF*{vz_M&3x?P^|ML4445eg0y!aRnhb58IZDk75N}*sH)gr zr-@9#NN(jNv`nSc08d^uUX8tKESiq##9zs+TMeUWk#`;IwRni%=|muI@lMAdWyTmT z?;#{??TYcnq!Ih1@yXch;93(zYT@6NxB+5)Am;7bEnZLhHZ=i5glTic6cd#@a+@XW{g5uCGdCrydn?BX%X2iZvk2HY`!ciI#Ca zo%9pl3O=qj((8d3I*}J6$%=3ftq~!lepT1 zvbhItJ(Gm`Y_ksM;v(AoOnjcLQqa<;6;F`d@N$H1bhR|7Ydkf$P%+XDp(_JRm@MPULR z&j~_-dPQAfb4jho`V2#T0?)g?sK2@3Ef+7;bi0vGe;ReQ4FG94X(ZoT+trP;{x44F zyTv4lMt@3Do1bXVt*C~Wk9!TJC^fWrq*PMh!3TrEcZA=o5`IhJ!dF;DzUoJi`*B=C z!w{75QA>m)%i%RM-E$@6I{t{my|_HO3qsyI0e=%e7Q9!+V_0)?Q(~`XoH)ElmXmM)=*0 zMo~Ahy4;X8tJ)$~G)IKPiYp!_ zTZ#m)?n4q9161|CMfbO=^O<}xNknd@f+j_+kD@}%FpUWqPTO#8H!Z_5*S7UT>P+xr ze_=+d5iD}Lr*Rk>%37<4Sc4+rxcnqs^Kj+%HGXLV{5q~syxrCp7~KG8p}B5S7g@Cv zE!gnlMu@{7f<0P;83tE(z2*UTgw>CiYjCq`0{Po0Py`@?wHE5s>v$kzq{PXZIdfuA z%6dpVj^}%EdGAHipTu2ApcZjkaK=W7J0rxM@ki$2HSC~lK_98wf}gS4OVI4OMbMN@ zy#y^wo>77}1A;aq1Z`e2g`n}0`MoUYN3U>D)|}tKQ<-N+iFIwF2R$>a{8u4R^>+xz5hk5{BUJHKfJ;k05|57k*H+{=nzN76}k zZh~T!E`cR+12|@I2X_FT#XIgS2w=DoTB4SQ4(~Ef7J@eyJk!eogTb9%4#=Zs!Wn|d z9(G1hcgP(M-W_$u#K}K`k|dWGq{VS(la!81slX=X6V7HS9}CLqv>*hN&K4;j?<(Kw z+$QCloCK7@Ha~St)l07DVZsexk>rxl2u`^sn!&*uozB3#xrNi>O(Jsv3FVmzG(%ge zq106OGNnsfYYRHIm*Q$a)6P;_SYe&Em6cH6kM{M){{iNH5Q%Sbndqie_=l*Xr@inD z42PGwmJdcfqv^1(`6ojfMgss)%)f9tp>tZ$vt6 zjg)UpV*$x4pT;UwuLLHLaa=O+Hl}G%^cng91y(_~1#~=x7u7#x(j|SaqYSdQg@dsW z2a)%Cu)tZofI;Jq_;0!JL(IpQ%l)0p{|Ij+TK$=817Ux7;alh@8?4dQo&KNrAEUcW zq`T3uyY_oG@0Hq^qYKwX49!!0zAC0P6as^ho(9979tBE$)qG%u5KWZluOjuzcx0RDW!ut;ENz16e$2UYg zkSi6rM3FXCkqN0r@ms1NVe(Iy{3w$)HA{|$sM8S2^Vxiy|FrYn zG{)hCp9n5_2h0~QU2xzPteu}u`zgddz#Ht~+n&KZrMqWNl+{l#;dG;gc+$)OF3ua@ z#O0kq!g*s826;0s?v_Lolabd_!89P%OhMew!0^ZK6{Ciw*7Y>qMrl+ss(L01=arVWv#^YE7biOwX{byem9Vt z9#H>`1=3JgowAnpotXOm*;f6K{X0>oh-E;Zp78W}gs zH9#2gd1nas1G3IHjK#MFc*t~E*|X(~QF5Us>dSDQdio3qDxUvxQ8@dyd#@d!{_*!dwH=hs+U{h$G_Jhhc zg2kPU_%#4|Hm0^UEbW!S;-n%`fW!YSp}CjIFCu|kvRrX%b?t{a!s4zEJyyhEI72Jx( z+U6cG14q&r8iP;}2ZAVi85auq$9x=@VC`vS8VDv4X=ti(MAaCV&DtJ-EM9Q=?z?f9 zP`evY@_05O^^;djsQQ%D#%fI9t)m+aR!Fw&m7$#|vm#!OuEC~`&L3pBrgnS;#NE&5 zv8fQoENYG@Ko{55i$sQ~T!T_;TqGFQ$aeK0rSI!Kjxs;rW@rX6YWMJez<|V>gB`2c z`aiPddzciMe2Gb$#wAC=t9~BILBg0rCT$E``J{hN|V(ME%wtl{fp?F{4`M-G}3IUT4FpZhu-vqj7#PEXNW|Me_GICeqf zE&6%Hduk`{X~vTJ0|lA0$&LDVsG(kA(#GRq+`4VT&q=6TbRaFk_BCoM^%>Of7!@(w z(*B>q4cYMx_@l)c2tC&2-JYQxu!@}#;@gIwW5Yt|8>Xwl%0Io^ogQna39oqPN@62% z+32wVno$d&tu>R14lOM|Enw$-gtF+$R)33$V5E%}`ev7i7Ale$h@WojyfFor^{BZv z-hrS1uAeykY6hTv0 zfCT3ePVD0d!CyDe4ZnTV{C9xpXRB_tu2#>N-3wY|ijT0xe^5hDp_-!C)VEm6&WZ<{ zwAJY6M-?aI`6&9*hSfsh+DHfbNTB_dCK=^TTw)Z7lsC9A(&^jKQr=I8c9{Ay!A#9R zbz-6L{PDheN&AT1`r^k3q6lxqclH2PKn>VaKH9@{r_0vQ&SBS7s*tUT(cJKWVrh@u;?!|3E{|WJEw>nDEm2o-y_W^6$8oy& zVL_!BedS7owcf+R6)il~78zENA*<5<@QJy@FGNR-=-g!0I}Pgszr~A-PGIQs8-#xp zwJmzaex*RQK~;@55v>9fW~&xnmklT}vti)Ly-k3HClBEXX03P<--tVjYsPxKVO?oC zDX9YAXhLYv#hKiI;%lTgGNkII>^MTHubFx(anf41))VW=^;Ezk1FJs*9>L}{^3g`F znU3&C`cnGban77Cr5Qxjw7f4g6W$jZgO`nSUpRNXhfBU36(G$7CMYkTjIU?bv+D!R zOe4LNKO6sy;hD`W@IbgY;IcQ0%Jy7E^F`5A7ZMy;x!noQ$z?)?Y^3O8f!`C-6<>~ zVSknS8a_a5?N0r%B6XMR2n&zY^NsS_OyFH{rdDe1#bpGeyUrBs2e=oDYITb1caKh0 z;lwVUcBkGywKjC`R0%*7WK#hP@<9RPoN+%ru6`N4E7HE7m2DtmZ1{}FINN4qgi25J3agC{Gq~;gL8hG%S&E)4YOo6DmtH%8T(3(9x2Qpoqguu0`jxZ z7LFf2^wh$!r7@K{DDC57tjM{wK0zxIEL`KG%xs=U^rp=2e@CRMmoL==5RMJhKrwUn1P-DmxG}rUQc?WESW-SizWXEH%-IK={Ova zpy^E_4{PGGaT@xzX@aEp=m?*N3FdqRL<;wlkm3~Me!!BZn$o2kiECgy5b0DSxsi0R z27S$3Pc%{;Oq+hA0@k|+OqWG?KPaJ-ax!-3(RjI9r6jfG8$LbGQ{(qRXs23~hLWQjl zXQ%YU&GXGg2RDweNk7#IMMft*fc`;})ZJ(|2Hi>hnTGK}KLTyEVfYe4@*2I71!-Y& zx21=W!nS(Map7FGnNW-B8e#5_nUI>)Rwjak|HoXL@Y@#BSMcED1kpk!ZEWAJSW?2( z@yDn96Xs|uuqC(+0)HIUmIORG7R+iLQk)dCnlUpee`H}+wm-QI?q}oPHbnhoBNIkZ z;JO#Fu?aVML?(>d#@10sv_wg34J=TKg^k@y5(>PwwOEp{P*~NN4Au0GJ5TKG>#2y1 z{Un;z(rZ*AXW+=JlurdyTqPFxAVP}SRzYm;(5vuuzW550HU?>We<8$R3{$MNtvy3+ zS>L@D5;5Ci{ZHbC7SbEA7}q9|i^L9}G}mEk2Kq9-3dQ~QOz$4nbE2#Vhg_nOTuR}> zl;~O;b;L^ z@CT3-=8hgXcx2y;Vj6`JCvT!jJ5gxK?FexmWN$Z+`~tD6C$F^JC&3(#o1<7p@5QeM z3m)(;`;HK4`;K;*w0d)c?oUzW--KTh2A!o?@;AT>qiqfknL+&-yZS5gfckR|@-LXY z#iS3V{z^DLq14-Y0eQQm%0Q8CFR5aALNa_pya5;YZ29#i2$0w zdOE0yDk^isFM=g;lKQP^>MKMtDfQ+wWud!YW|!o1p(&Q!oTlh%YRgwRDa@;8)UhGc zg_La4ZaZi(Q9#W!oEtjcA}ext06aY4XRymu&k+8)d>QK3IpY7yH`W;_Z?bXI(;G@B*&U(FREf`4lWgXjzEa1&kqD-Q1SY=~|F^_nC-{L_l4{KmqXjV1 zMps~*_If3#8e4i}88?Eh=d?M-Sk|WTdTUM-Hpib~5FsQw4Pd5iVbf8uQy$&o<*lsIUU+z#^D);@UnRv9kp zAth6Z>rZ<~|E3sDlY4vUH{-S&okOPwbZv8=p$pq(x=pAy+jV)zD54{n7Gpy=oKZP{ z#6GD3$Y=SKVj1^QovGt63u_r$9Q;Aq*&!w%To%2P;soEu^(HQlt#b|Vd`#uJuv)W_ zn(#iw5tA09Y+tvU)&@%xxRQ=ZTNa+#CsCSedu2g|lPF0eW&?U7)F<-6wn1lPR@Z`s zZEGXTwW!P3;=)Df#y}H(FYq!P`NkvKFwSX%H@)x4!r{4t3lICLAg7me@ODgr>|+W9 z0GI2jG9pe8dLn{AQ|uQpDlv;e(OK3UV3K3?>XurRBnvCQ?Jw5i6>7**zI zL=T><)yD%oVgAs8C+wJLZ#PeAOvt=|$f3EZ7~~Wg{#Vc|mf^-(+HbJAaIh=2^2JGx zR!<4?m=bWrGRg^#GNDGDUFvcQMfs7M?h@i`2e5aZMZ zE~R}H9b>Z9nw-*aHv3HBz@g*&o>f9je}EcTpE_DNe(=Qn!DB~{FQ{RTSTITs6Ll8F zgWAkeY~|{Y+mRC1q=2OrXE~Vt-bDnDqMulDR8~nyPPj-)+t3V2iPOFQq(u2DNL)f@ z4QEX>V;#{W$H8Ji>FQH3L#Pn8!G9G4fdQ%4qWeav7IwjZBx*t4Nvy)v&VPE=&o$Oa zbO@%Z{~0|ZLh8NvX|JaG`3vR783YOhC-rc9O6vx}{O>|-%c9Q?_%9kC@9V&a+Rl;Q!GuFsQ_LM;P7)C= z9b*p9nK{^Z%sV({yxs8^$K76B-pfcr;|V*>;V25$HiCU}fs+U;Ao5J_(Me*RgEjR; z20MD>P6v)N%7oAKnyp>~8B!0Rn_jmHAZxGRlPvpfmQx?)yPe~ga|Y%)Tz)_V?GMWN zKCqAE(3k!@og!oQWcrnsnPWPwZ=-b}9bTvq$p44sPVWhVSK8j(AA%aQ1w*lL7!TMR4= zah%;zMsa^#_)ngcP}uQD#kUui#|A@w#mXcWqQPz9dZZ=mj|R#SSFwcCA#k6>Q*vz* z(O?#0D{%Tl5Dk`SoePzabDyzhxllQr1`%%kz-AA5FFXlq#2s0}#tyU=Jqc>W z9dgH{UU(AJI7;-J;Ym=N+zF|%*_p)Z>1Mz=;cS6JM7DX@lL36&oZImfr(5BkPq#aF z;C^fHbjrCCcek~k?r`qH{WkY@X?dsf4%}^*mDgQrH!y}Z9S=Wp_EWDujN=inqqt<^ z(N6-Q2~t_4oj%g&3_m6=N~6tP2avVo5;p!mh8iJE%y+_suPgAdp+mSlp=@Ir>r60p z%-8!%EsoRQild-9j(%&)FZ3s_4(U&@(KP^4^4Z7$CcB!t#l({k6WTX%-BQ>fz%-_) zV*9cmAJifcZ0&{M<|kv2Wm~4<1a7pz>pT^sEoudl3L!bpqze~(aIOVOoag>@pcS|X z4!`J;N5lmwMS=|oLu+3K>=*Xx=Nj0hSkb$Yy}pRJ2i4BEy2pxTclRAFJcr(T9Mb$8 z0tRIZkN`lUrz=hKL%e`T-6Ln$YwfPTiQ&OUmf;PZLJ(a2g6rIBgg9L`cB$RX+8x~^ z>}up&fMd9LzF3xn8*T;2y#VBL1dyq2K)PG$fux1$zf1uMcJjs2xs|eV3$?oJ1G}j% z!kN3VPY^H?w&3P$Sbh`mYhf5zPGPuv+k^{fFcm=F zm%APSWUmu4!A~Da9lYGbQ^cRZ(22jBLNVSCe`izE5I{S7er zricltxHyZeFJ>MD7~dTMqeq7YFZaca^eoawz7A*Fo#NIX4_+@sKX_k!JOn_#Cjv+h zKKixvt>8nOX-Dv3yXlwq+vg%6^eCgYO*(x?w`sVK4en<`p`fP~RM6U76a_fRTX6|8 zrbL^NR67!$t4=XTS*%LTG44lEW-7`nZB|l1C~}!1K`WAw;s;bjp1PB7hz;6SZIa{E zQH-L~9NfLQL-4{EM#~Bh*1yg!0+@%cIBG<1=WuuPow&pNRCmrMK_k%r%vCWLz>~}H6 z#`;}y;vRB{)ixRl-XUy=b&|MJ++C?1HEDlPwkCzgF#EZXxp{bxoyUpbJj5tGS#Th@ z=R@Dbrs%r>g+6!4D&bIXx=Q86Oi&S3+FyeL(;tSADMUN@MGl&DjfGLTUGqlHR0q3< zp2Xt}E}_FFGU3o0vfGR&@L^y)W-xKZI*mbds1l}ru@yh~IG0P7QW8msxQdOmyo*B# zv7~M-Wq_arT1c=3k(F`81tyjx#_!x?=k_$?2vFbEY^mY_h5v8?+u6dgsCpfzJpnNq zDf{tIA2v73YD1+n<%$y^vg~^HfG*$*p86AvNbN&C9>9x8F=skyXIc&7&?VHuIbn-+ z&(7#?!6pXjo@?Kx!c!9uu zWax!cJOa$c+2LBZcY>{+LWlpW%@x>$$dV3_&|6zkd=fWpMWJI!ZnnYCNkcURVdzvD zsGWhMMmuz}aEWlcjM;L%>dk-Rwy|^ATEn;D+>t}h;5x#Q+@aN#4& z59mX>qy%dR%JsOpR^MVzPNTkDaC!2*KBq8U2!<5Ke>{ygq)}AqyN{2{!?+Z)Hck74;&QO`cPvyBNqoSihy0jS_4i;aK1t4*e(pU?a{B*TlMBMrF-!@@Xqbw!5o|BH`Z2T zD~6QGHp(kl-a9uO#k5eEIJ$+xjuPgFne-tu^+f_12efHsz(v@rZLAGPV3v)e9o8%@ z2vU+bX+Me#;ggN*PjaCWC$>V7E>eL)`60!Y_N(-2q)B5khM+cUY-FzCfJBU826r(i z%-GTZX%f*1mekF8wT^l=?s6N0*KklSR*dspv*9@prajp@sFFvv26GLsxaj(WPQB)e zRN{XSFg>JMPk8cSfNu|B{)qp#;`9n+tsGV`PjnG+etdbQp%5SjtCWf0@jTuUB2=Vj zRH-lf$(0(XU06o$L(Qrm-B_g1BvC(w_F~vG0R?)4dnT;6EYo@`iAi7{;R#8k_#{Ko zPl7iw3JR~t5eWNuD;BPRPv%e*bm~(`a8MoogA@(542K_Hp9lI92i7KP$@vJ<8B7^y7QcfRa4IT~mUF!Gv!oOznWh6MfvR(_!ni+kZq^HOa*yJAm zcQH675QE3Okf%8|aBzSpr#`|ctV{U4Z`M6UGQ$~)Sn2olLFGy0VGZbG6lHWW&H>a@ zIVOWls2t?XMa3D18euZZWQ>W}{+pPi^GNRmkg32H-qN74hsE@eICnia)e>C3qlm6; ztV;Q1%g+26z1*#~v-nq8oY%%nIOmmPE&ae3u!FVkVzQG}v2new+!>@*1e~aM@WC!7 z@8r|r;Hl`$O1-|Urdd1^7Pk&{R`>9ocQLt_3AYic86@^-$BFN9gt(m#-q(P85{zk2 zgoXIeX3nU3t-K~j_=%^%9%CzA&M?twc1GG4oxX?t<$`9kY5E|GhV;v=6Z_RegihiQ z$%0}D`vZroj5X1ogZJcTy67+kuFcyr<(LVl9GZ;3lg&Je#E+}oV>F=Y^-rU~7RVXh)ZV+l5kYR7tSsWX||11Dr^>#%( z3yy1b7ZN`w=pRh7LvOoU@!X6_P`SCQD8D8-8W-+l@a^0UWV!Yxv& zKEl_2oXP7CO^mI=b8K(ldmAL^YaqH z5k_`PSigcu*6}hDn#eJBP( zh}%e9H!{7I8LQ0QWa1#Ex`?5E^2tv>rvE1dPIF@(3DBW%I~CX z9txi`=xdl0Mq|Ppj^oV~4#PImsbp&S9?5CbGBs|EPMe1L7AKe4w{jWOiI0w<<#Aj? zxE{pQZ-}fmhQE=^jVF@a= (3, 8): - get_coro = asyncio.Task.get_coro -else: - def get_coro(task: asyncio.Task) -> Union[Coroutine, Generator]: - return task._coro - -if sys.version_info >= (3, 7): - from asyncio import all_tasks, create_task, current_task, get_running_loop - from asyncio import run as native_run - - def _get_task_callbacks(task: asyncio.Task) -> Iterable[Callable]: - return [cb for cb, context in task._callbacks] # type: ignore -else: - _T = TypeVar('_T') - - def _get_task_callbacks(task: asyncio.Task) -> Iterable[Callable]: - return task._callbacks - - def native_run(main, *, debug=False): - # Snatched from Python 3.7 - from asyncio import coroutines, events, tasks - - def _cancel_all_tasks(loop): - to_cancel = all_tasks(loop) - if not to_cancel: - return - - for task in to_cancel: - task.cancel() - - loop.run_until_complete( - tasks.gather(*to_cancel, loop=loop, return_exceptions=True)) - - for task in to_cancel: - if task.cancelled(): - continue - if task.exception() is not None: - loop.call_exception_handler({ - 'message': 'unhandled exception during asyncio.run() shutdown', - 'exception': task.exception(), - 'task': task, - }) - - if events._get_running_loop() is not None: - raise RuntimeError( - "asyncio.run() cannot be called from a running event loop") - - if not coroutines.iscoroutine(main): - raise ValueError("a coroutine was expected, got {!r}".format(main)) - - loop = events.new_event_loop() - try: - events.set_event_loop(loop) - loop.set_debug(debug) - return loop.run_until_complete(main) - finally: - try: - _cancel_all_tasks(loop) - loop.run_until_complete(loop.shutdown_asyncgens()) - finally: - events.set_event_loop(None) - loop.close() - - def create_task(coro: Union[Generator[Any, None, _T], Awaitable[_T]], *, - name: object = None) -> asyncio.Task: - return get_running_loop().create_task(coro) - - def get_running_loop() -> asyncio.AbstractEventLoop: - loop = asyncio._get_running_loop() - if loop is not None: - return loop - else: - raise RuntimeError('no running event loop') - - def all_tasks(loop: Optional[asyncio.AbstractEventLoop] = None) -> Set[asyncio.Task]: - """Return a set of all tasks for the loop.""" - from asyncio import Task - - if loop is None: - loop = get_running_loop() - - return {t for t in Task.all_tasks(loop) if not t.done()} - - def current_task(loop: Optional[asyncio.AbstractEventLoop] = None) -> Optional[asyncio.Task]: - if loop is None: - loop = get_running_loop() - - return asyncio.Task.current_task(loop) - -T_Retval = TypeVar('T_Retval') - -# Check whether there is native support for task names in asyncio (3.8+) -_native_task_names = hasattr(asyncio.Task, 'get_name') - - -_root_task: RunVar[Optional[asyncio.Task]] = RunVar('_root_task') - - -def find_root_task() -> asyncio.Task: - root_task = _root_task.get(None) - if root_task is not None and not root_task.done(): - return root_task - - # Look for a task that has been started via run_until_complete() - for task in all_tasks(): - if task._callbacks and not task.done(): - for cb in _get_task_callbacks(task): - if (cb is _run_until_complete_cb - or getattr(cb, '__module__', None) == 'uvloop.loop'): - _root_task.set(task) - return task - - # Look up the topmost task in the AnyIO task tree, if possible - task = cast(asyncio.Task, current_task()) - state = _task_states.get(task) - if state: - cancel_scope = state.cancel_scope - while cancel_scope and cancel_scope._parent_scope is not None: - cancel_scope = cancel_scope._parent_scope - - if cancel_scope is not None: - return cast(asyncio.Task, cancel_scope._host_task) - - return task - - -def get_callable_name(func: Callable) -> str: - module = getattr(func, '__module__', None) - qualname = getattr(func, '__qualname__', None) - return '.'.join([x for x in (module, qualname) if x]) - - -# -# Event loop -# - -_run_vars = WeakKeyDictionary() # type: WeakKeyDictionary[asyncio.AbstractEventLoop, Any] - -current_token = get_running_loop - - -def _task_started(task: asyncio.Task) -> bool: - """Return ``True`` if the task has been started and has not finished.""" - coro = get_coro(task) - try: - return getcoroutinestate(coro) in (CORO_RUNNING, CORO_SUSPENDED) - except AttributeError: - try: - return getgeneratorstate(coro) in (GEN_RUNNING, GEN_SUSPENDED) - except AttributeError: - # task coro is async_genenerator_asend https://bugs.python.org/issue37771 - raise Exception(f"Cannot determine if task {task} has started or not") - - -def _maybe_set_event_loop_policy(policy: Optional[asyncio.AbstractEventLoopPolicy], - use_uvloop: bool) -> None: - # On CPython, use uvloop when possible if no other policy has been given and if not - # explicitly disabled - if policy is None and use_uvloop and sys.implementation.name == 'cpython': - try: - import uvloop - except ImportError: - pass - else: - # Test for missing shutdown_default_executor() (uvloop 0.14.0 and earlier) - if (not hasattr(asyncio.AbstractEventLoop, 'shutdown_default_executor') - or hasattr(uvloop.loop.Loop, 'shutdown_default_executor')): - policy = uvloop.EventLoopPolicy() - - if policy is not None: - asyncio.set_event_loop_policy(policy) - - -def run(func: Callable[..., Awaitable[T_Retval]], *args: object, - debug: bool = False, use_uvloop: bool = False, - policy: Optional[asyncio.AbstractEventLoopPolicy] = None) -> T_Retval: - @wraps(func) - async def wrapper() -> T_Retval: - task = cast(asyncio.Task, current_task()) - task_state = TaskState(None, get_callable_name(func), None) - _task_states[task] = task_state - if _native_task_names: - task.set_name(task_state.name) - - try: - return await func(*args) - finally: - del _task_states[task] - - _maybe_set_event_loop_policy(policy, use_uvloop) - return native_run(wrapper(), debug=debug) - - -# -# Miscellaneous -# - -sleep = asyncio.sleep - - -# -# Timeouts and cancellation -# - -CancelledError = asyncio.CancelledError - - -class CancelScope(BaseCancelScope): - def __new__(cls, *, deadline: float = math.inf, shield: bool = False) -> "CancelScope": - return object.__new__(cls) - - def __init__(self, deadline: float = math.inf, shield: bool = False): - self._deadline = deadline - self._shield = shield - self._parent_scope: Optional[CancelScope] = None - self._cancel_called = False - self._active = False - self._timeout_handle: Optional[asyncio.TimerHandle] = None - self._cancel_handle: Optional[asyncio.Handle] = None - self._tasks: Set[asyncio.Task] = set() - self._host_task: Optional[asyncio.Task] = None - self._timeout_expired = False - - def __enter__(self) -> "CancelScope": - if self._active: - raise RuntimeError( - "Each CancelScope may only be used for a single 'with' block" - ) - - self._host_task = host_task = cast(asyncio.Task, current_task()) - self._tasks.add(host_task) - try: - task_state = _task_states[host_task] - except KeyError: - task_name = host_task.get_name() if _native_task_names else None - task_state = TaskState(None, task_name, self) - _task_states[host_task] = task_state - else: - self._parent_scope = task_state.cancel_scope - task_state.cancel_scope = self - - self._timeout() - self._active = True - return self - - def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - if not self._active: - raise RuntimeError('This cancel scope is not active') - if current_task() is not self._host_task: - raise RuntimeError('Attempted to exit cancel scope in a different task than it was ' - 'entered in') - - assert self._host_task is not None - host_task_state = _task_states.get(self._host_task) - if host_task_state is None or host_task_state.cancel_scope is not self: - raise RuntimeError("Attempted to exit a cancel scope that isn't the current tasks's " - "current cancel scope") - - self._active = False - if self._timeout_handle: - self._timeout_handle.cancel() - self._timeout_handle = None - - self._tasks.remove(self._host_task) - - host_task_state.cancel_scope = self._parent_scope - - # Restart the cancellation effort in the nearest directly cancelled parent scope if this - # one was shielded - if self._shield: - self._deliver_cancellation_to_parent() - - if exc_val is not None: - exceptions = exc_val.exceptions if isinstance(exc_val, ExceptionGroup) else [exc_val] - if all(isinstance(exc, CancelledError) for exc in exceptions): - if self._timeout_expired: - return True - elif not self._cancel_called: - # Task was cancelled natively - return None - elif not self._parent_cancelled(): - # This scope was directly cancelled - return True - - return None - - def _timeout(self) -> None: - if self._deadline != math.inf: - loop = get_running_loop() - if loop.time() >= self._deadline: - self._timeout_expired = True - self.cancel() - else: - self._timeout_handle = loop.call_at(self._deadline, self._timeout) - - def _deliver_cancellation(self) -> None: - """ - Deliver cancellation to directly contained tasks and nested cancel scopes. - - Schedule another run at the end if we still have tasks eligible for cancellation. - """ - should_retry = False - current = current_task() - for task in self._tasks: - if task._must_cancel: # type: ignore - continue - - # The task is eligible for cancellation if it has started and is not in a cancel - # scope shielded from this one - cancel_scope = _task_states[task].cancel_scope - while cancel_scope is not self: - if cancel_scope is None or cancel_scope._shield: - break - else: - cancel_scope = cancel_scope._parent_scope - else: - should_retry = True - if task is not current and (task is self._host_task or _task_started(task)): - task.cancel() - - # Schedule another callback if there are still tasks left - if should_retry: - self._cancel_handle = get_running_loop().call_soon(self._deliver_cancellation) - else: - self._cancel_handle = None - - def _deliver_cancellation_to_parent(self) -> None: - """Start cancellation effort in the nearest directly cancelled parent scope""" - scope = self._parent_scope - while scope is not None: - if scope._cancel_called and scope._cancel_handle is None: - scope._deliver_cancellation() - break - - # No point in looking beyond any shielded scope - if scope._shield: - break - - scope = scope._parent_scope - - def _parent_cancelled(self) -> bool: - # Check whether any parent has been cancelled - cancel_scope = self._parent_scope - while cancel_scope is not None and not cancel_scope._shield: - if cancel_scope._cancel_called: - return True - else: - cancel_scope = cancel_scope._parent_scope - - return False - - def cancel(self) -> DeprecatedAwaitable: - if not self._cancel_called: - if self._timeout_handle: - self._timeout_handle.cancel() - self._timeout_handle = None - - self._cancel_called = True - self._deliver_cancellation() - - return DeprecatedAwaitable(self.cancel) - - @property - def deadline(self) -> float: - return self._deadline - - @deadline.setter - def deadline(self, value: float) -> None: - self._deadline = float(value) - if self._timeout_handle is not None: - self._timeout_handle.cancel() - self._timeout_handle = None - - if self._active and not self._cancel_called: - self._timeout() - - @property - def cancel_called(self) -> bool: - return self._cancel_called - - @property - def shield(self) -> bool: - return self._shield - - @shield.setter - def shield(self, value: bool) -> None: - if self._shield != value: - self._shield = value - if not value: - self._deliver_cancellation_to_parent() - - -async def checkpoint() -> None: - await sleep(0) - - -async def checkpoint_if_cancelled() -> None: - task = current_task() - if task is None: - return - - try: - cancel_scope = _task_states[task].cancel_scope - except KeyError: - return - - while cancel_scope: - if cancel_scope.cancel_called: - await sleep(0) - elif cancel_scope.shield: - break - else: - cancel_scope = cancel_scope._parent_scope - - -async def cancel_shielded_checkpoint() -> None: - with CancelScope(shield=True): - await sleep(0) - - -def current_effective_deadline() -> float: - try: - cancel_scope = _task_states[current_task()].cancel_scope # type: ignore[index] - except KeyError: - return math.inf - - deadline = math.inf - while cancel_scope: - deadline = min(deadline, cancel_scope.deadline) - if cancel_scope.shield: - break - else: - cancel_scope = cancel_scope._parent_scope - - return deadline - - -def current_time() -> float: - return get_running_loop().time() - - -# -# Task states -# - -class TaskState: - """ - Encapsulates auxiliary task information that cannot be added to the Task instance itself - because there are no guarantees about its implementation. - """ - - __slots__ = 'parent_id', 'name', 'cancel_scope' - - def __init__(self, parent_id: Optional[int], name: Optional[str], - cancel_scope: Optional[CancelScope]): - self.parent_id = parent_id - self.name = name - self.cancel_scope = cancel_scope - - -_task_states = WeakKeyDictionary() # type: WeakKeyDictionary[asyncio.Task, TaskState] - - -# -# Task groups -# - -class ExceptionGroup(BaseExceptionGroup): - def __init__(self, exceptions: Sequence[BaseException]): - super().__init__() - self.exceptions = exceptions - - -class _AsyncioTaskStatus(abc.TaskStatus): - def __init__(self, future: asyncio.Future): - self._future = future - - def started(self, value: object = None) -> None: - try: - self._future.set_result(value) - except asyncio.InvalidStateError: - raise RuntimeError("called 'started' twice on the same task status") from None - - -class TaskGroup(abc.TaskGroup): - def __init__(self) -> None: - self.cancel_scope: CancelScope = CancelScope() - self._active = False - self._exceptions: List[BaseException] = [] - - async def __aenter__(self) -> "TaskGroup": - self.cancel_scope.__enter__() - self._active = True - return self - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - ignore_exception = self.cancel_scope.__exit__(exc_type, exc_val, exc_tb) - if exc_val is not None: - self.cancel_scope.cancel() - self._exceptions.append(exc_val) - - while self.cancel_scope._tasks: - try: - await asyncio.wait(self.cancel_scope._tasks) - except asyncio.CancelledError: - self.cancel_scope.cancel() - - self._active = False - if not self.cancel_scope._parent_cancelled(): - exceptions = self._filter_cancellation_errors(self._exceptions) - else: - exceptions = self._exceptions - - try: - if len(exceptions) > 1: - if all(isinstance(e, CancelledError) and not e.args for e in exceptions): - # Tasks were cancelled natively, without a cancellation message - raise CancelledError - else: - raise ExceptionGroup(exceptions) - elif exceptions and exceptions[0] is not exc_val: - raise exceptions[0] - except BaseException as exc: - # Clear the context here, as it can only be done in-flight. - # If the context is not cleared, it can result in recursive tracebacks (see #145). - exc.__context__ = None - raise - - return ignore_exception - - @staticmethod - def _filter_cancellation_errors(exceptions: Sequence[BaseException]) -> List[BaseException]: - filtered_exceptions: List[BaseException] = [] - for exc in exceptions: - if isinstance(exc, ExceptionGroup): - new_exceptions = TaskGroup._filter_cancellation_errors(exc.exceptions) - if len(new_exceptions) > 1: - filtered_exceptions.append(exc) - elif len(new_exceptions) == 1: - filtered_exceptions.append(new_exceptions[0]) - elif new_exceptions: - new_exc = ExceptionGroup(new_exceptions) - new_exc.__cause__ = exc.__cause__ - new_exc.__context__ = exc.__context__ - new_exc.__traceback__ = exc.__traceback__ - filtered_exceptions.append(new_exc) - elif not isinstance(exc, CancelledError) or exc.args: - filtered_exceptions.append(exc) - - return filtered_exceptions - - async def _run_wrapped_task( - self, coro: Coroutine, task_status_future: Optional[asyncio.Future]) -> None: - # This is the code path for Python 3.6 and 3.7 on which asyncio freaks out if a task raises - # a BaseException. - __traceback_hide__ = __tracebackhide__ = True # noqa: F841 - task = cast(asyncio.Task, current_task()) - try: - await coro - except BaseException as exc: - if task_status_future is None or task_status_future.done(): - self._exceptions.append(exc) - self.cancel_scope.cancel() - else: - task_status_future.set_exception(exc) - else: - if task_status_future is not None and not task_status_future.done(): - task_status_future.set_exception( - RuntimeError('Child exited without calling task_status.started()')) - finally: - if task in self.cancel_scope._tasks: - self.cancel_scope._tasks.remove(task) - del _task_states[task] - - def _spawn(self, func: Callable[..., Coroutine], args: tuple, name: object, - task_status_future: Optional[asyncio.Future] = None) -> asyncio.Task: - def task_done(_task: asyncio.Task) -> None: - # This is the code path for Python 3.8+ - assert _task in self.cancel_scope._tasks - self.cancel_scope._tasks.remove(_task) - del _task_states[_task] - - try: - exc = _task.exception() - except CancelledError as e: - while isinstance(e.__context__, CancelledError): - e = e.__context__ - - exc = e - - if exc is not None: - if task_status_future is None or task_status_future.done(): - self._exceptions.append(exc) - self.cancel_scope.cancel() - else: - task_status_future.set_exception(exc) - elif task_status_future is not None and not task_status_future.done(): - task_status_future.set_exception( - RuntimeError('Child exited without calling task_status.started()')) - - if not self._active: - raise RuntimeError('This task group is not active; no new tasks can be started.') - - options = {} - name = get_callable_name(func) if name is None else str(name) - if _native_task_names: - options['name'] = name - - kwargs = {} - if task_status_future: - kwargs['task_status'] = _AsyncioTaskStatus(task_status_future) - - coro = func(*args, **kwargs) - if not asyncio.iscoroutine(coro): - raise TypeError(f'Expected an async function, but {func} appears to be synchronous') - - foreign_coro = not hasattr(coro, 'cr_frame') and not hasattr(coro, 'gi_frame') - if foreign_coro or sys.version_info < (3, 8): - coro = self._run_wrapped_task(coro, task_status_future) - - task = create_task(coro, **options) - if not foreign_coro and sys.version_info >= (3, 8): - task.add_done_callback(task_done) - - # Make the spawned task inherit the task group's cancel scope - _task_states[task] = TaskState(parent_id=id(current_task()), name=name, - cancel_scope=self.cancel_scope) - self.cancel_scope._tasks.add(task) - return task - - def start_soon(self, func: Callable[..., Coroutine], *args: object, - name: object = None) -> None: - self._spawn(func, args, name) - - async def start(self, func: Callable[..., Coroutine], *args: object, - name: object = None) -> None: - future: asyncio.Future = asyncio.Future() - task = self._spawn(func, args, name, future) - - # If the task raises an exception after sending a start value without a switch point - # between, the task group is cancelled and this method never proceeds to process the - # completed future. That's why we have to have a shielded cancel scope here. - with CancelScope(shield=True): - try: - return await future - except CancelledError: - task.cancel() - raise - - -# -# Threads -# - -_Retval_Queue_Type = Tuple[Optional[T_Retval], Optional[BaseException]] - - -class WorkerThread(Thread): - MAX_IDLE_TIME = 10 # seconds - - def __init__(self, root_task: asyncio.Task, workers: Set['WorkerThread'], - idle_workers: Deque['WorkerThread']): - super().__init__(name='AnyIO worker thread') - self.root_task = root_task - self.workers = workers - self.idle_workers = idle_workers - self.loop = root_task._loop - self.queue: Queue[Union[Tuple[Callable, tuple, asyncio.Future], None]] = Queue(2) - self.idle_since = current_time() - self.stopping = False - - def _report_result(self, future: asyncio.Future, result: Any, - exc: Optional[BaseException]) -> None: - self.idle_since = current_time() - if not self.stopping: - self.idle_workers.append(self) - - if not future.cancelled(): - if exc is not None: - future.set_exception(exc) - else: - future.set_result(result) - - def run(self) -> None: - with claim_worker_thread('asyncio'): - threadlocals.loop = self.loop - while True: - item = self.queue.get() - if item is None: - # Shutdown command received - return - - func, args, future = item - if not future.cancelled(): - result = None - exception: Optional[BaseException] = None - try: - result = func(*args) - except BaseException as exc: - exception = exc - - if not self.loop.is_closed(): - self.loop.call_soon_threadsafe( - self._report_result, future, result, exception) - - self.queue.task_done() - - def stop(self, f: Optional[asyncio.Task] = None) -> None: - self.stopping = True - self.queue.put_nowait(None) - self.workers.discard(self) - try: - self.idle_workers.remove(self) - except ValueError: - pass - - -_threadpool_idle_workers: RunVar[Deque[WorkerThread]] = RunVar('_threadpool_idle_workers') -_threadpool_workers: RunVar[Set[WorkerThread]] = RunVar('_threadpool_workers') - - -async def run_sync_in_worker_thread( - func: Callable[..., T_Retval], *args: object, cancellable: bool = False, - limiter: Optional['CapacityLimiter'] = None) -> T_Retval: - await checkpoint() - - # If this is the first run in this event loop thread, set up the necessary variables - try: - idle_workers = _threadpool_idle_workers.get() - workers = _threadpool_workers.get() - except LookupError: - idle_workers = deque() - workers = set() - _threadpool_idle_workers.set(idle_workers) - _threadpool_workers.set(workers) - - async with (limiter or current_default_thread_limiter()): - with CancelScope(shield=not cancellable): - future: asyncio.Future = asyncio.Future() - root_task = find_root_task() - if not idle_workers: - worker = WorkerThread(root_task, workers, idle_workers) - worker.start() - workers.add(worker) - root_task.add_done_callback(worker.stop) - else: - worker = idle_workers.pop() - - # Prune any other workers that have been idle for MAX_IDLE_TIME seconds or longer - now = current_time() - while idle_workers: - if now - idle_workers[0].idle_since < WorkerThread.MAX_IDLE_TIME: - break - - expired_worker = idle_workers.popleft() - expired_worker.root_task.remove_done_callback(expired_worker.stop) - expired_worker.stop() - - worker.queue.put_nowait((func, args, future)) - return await future - - -def run_sync_from_thread(func: Callable[..., T_Retval], *args: object, - loop: Optional[asyncio.AbstractEventLoop] = None) -> T_Retval: - @wraps(func) - def wrapper() -> None: - try: - f.set_result(func(*args)) - except BaseException as exc: - f.set_exception(exc) - if not isinstance(exc, Exception): - raise - - f: concurrent.futures.Future[T_Retval] = Future() - loop = loop or threadlocals.loop - loop.call_soon_threadsafe(wrapper) - return f.result() - - -def run_async_from_thread( - func: Callable[..., Coroutine[Any, Any, T_Retval]], *args: object -) -> T_Retval: - f: concurrent.futures.Future[T_Retval] = asyncio.run_coroutine_threadsafe( - func(*args), threadlocals.loop) - return f.result() - - -class BlockingPortal(abc.BlockingPortal): - def __new__(cls) -> "BlockingPortal": - return object.__new__(cls) - - def __init__(self) -> None: - super().__init__() - self._loop = get_running_loop() - - def _spawn_task_from_thread(self, func: Callable, args: tuple, kwargs: Dict[str, Any], - name: object, future: Future) -> None: - run_sync_from_thread( - partial(self._task_group.start_soon, name=name), self._call_func, func, args, kwargs, - future, loop=self._loop) - - -# -# Subprocesses -# - -@dataclass(eq=False) -class StreamReaderWrapper(abc.ByteReceiveStream): - _stream: asyncio.StreamReader - - async def receive(self, max_bytes: int = 65536) -> bytes: - data = await self._stream.read(max_bytes) - if data: - return data - else: - raise EndOfStream - - async def aclose(self) -> None: - self._stream.feed_eof() - - -@dataclass(eq=False) -class StreamWriterWrapper(abc.ByteSendStream): - _stream: asyncio.StreamWriter - - async def send(self, item: bytes) -> None: - self._stream.write(item) - await self._stream.drain() - - async def aclose(self) -> None: - self._stream.close() - - -@dataclass(eq=False) -class Process(abc.Process): - _process: asyncio.subprocess.Process - _stdin: Optional[StreamWriterWrapper] - _stdout: Optional[StreamReaderWrapper] - _stderr: Optional[StreamReaderWrapper] - - async def aclose(self) -> None: - if self._stdin: - await self._stdin.aclose() - if self._stdout: - await self._stdout.aclose() - if self._stderr: - await self._stderr.aclose() - - await self.wait() - - async def wait(self) -> int: - return await self._process.wait() - - def terminate(self) -> None: - self._process.terminate() - - def kill(self) -> None: - self._process.kill() - - def send_signal(self, signal: int) -> None: - self._process.send_signal(signal) - - @property - def pid(self) -> int: - return self._process.pid - - @property - def returncode(self) -> Optional[int]: - return self._process.returncode - - @property - def stdin(self) -> Optional[abc.ByteSendStream]: - return self._stdin - - @property - def stdout(self) -> Optional[abc.ByteReceiveStream]: - return self._stdout - - @property - def stderr(self) -> Optional[abc.ByteReceiveStream]: - return self._stderr - - -async def open_process(command: Union[str, Sequence[str]], *, shell: bool, - stdin: int, stdout: int, stderr: int, - cwd: Union[str, bytes, PathLike, None] = None, - env: Optional[Mapping[str, str]] = None) -> Process: - await checkpoint() - if shell: - process = await asyncio.create_subprocess_shell( - command, stdin=stdin, stdout=stdout, # type: ignore[arg-type] - stderr=stderr, cwd=cwd, env=env, - ) - else: - process = await asyncio.create_subprocess_exec(*command, stdin=stdin, stdout=stdout, - stderr=stderr, cwd=cwd, env=env) - - stdin_stream = StreamWriterWrapper(process.stdin) if process.stdin else None - stdout_stream = StreamReaderWrapper(process.stdout) if process.stdout else None - stderr_stream = StreamReaderWrapper(process.stderr) if process.stderr else None - return Process(process, stdin_stream, stdout_stream, stderr_stream) - - -def _forcibly_shutdown_process_pool_on_exit(workers: Set[Process], _task: object) -> None: - """ - Forcibly shuts down worker processes belonging to this event loop.""" - child_watcher: Optional[asyncio.AbstractChildWatcher] - try: - child_watcher = asyncio.get_event_loop_policy().get_child_watcher() - except NotImplementedError: - child_watcher = None - - # Close as much as possible (w/o async/await) to avoid warnings - for process in workers: - if process.returncode is None: - continue - - process._stdin._stream._transport.close() # type: ignore - process._stdout._stream._transport.close() # type: ignore - process._stderr._stream._transport.close() # type: ignore - process.kill() - if child_watcher: - child_watcher.remove_child_handler(process.pid) - - -async def _shutdown_process_pool_on_exit(workers: Set[Process]) -> None: - """ - Shuts down worker processes belonging to this event loop. - - NOTE: this only works when the event loop was started using asyncio.run() or anyio.run(). - - """ - process: Process - try: - await sleep(math.inf) - except asyncio.CancelledError: - for process in workers: - if process.returncode is None: - process.kill() - - for process in workers: - await process.aclose() - - -def setup_process_pool_exit_at_shutdown(workers: Set[Process]) -> None: - kwargs = {'name': 'AnyIO process pool shutdown task'} if _native_task_names else {} - create_task(_shutdown_process_pool_on_exit(workers), **kwargs) - find_root_task().add_done_callback(partial(_forcibly_shutdown_process_pool_on_exit, workers)) - - -# -# Sockets and networking -# - - -class StreamProtocol(asyncio.Protocol): - read_queue: Deque[bytes] - read_event: asyncio.Event - write_event: asyncio.Event - exception: Optional[Exception] = None - - def connection_made(self, transport: asyncio.BaseTransport) -> None: - self.read_queue = deque() - self.read_event = asyncio.Event() - self.write_event = asyncio.Event() - self.write_event.set() - cast(asyncio.Transport, transport).set_write_buffer_limits(0) - - def connection_lost(self, exc: Optional[Exception]) -> None: - if exc: - self.exception = BrokenResourceError() - self.exception.__cause__ = exc - - self.read_event.set() - self.write_event.set() - - def data_received(self, data: bytes) -> None: - self.read_queue.append(data) - self.read_event.set() - - def eof_received(self) -> Optional[bool]: - self.read_event.set() - return True - - def pause_writing(self) -> None: - self.write_event = asyncio.Event() - - def resume_writing(self) -> None: - self.write_event.set() - - -class DatagramProtocol(asyncio.DatagramProtocol): - read_queue: Deque[Tuple[bytes, IPSockAddrType]] - read_event: asyncio.Event - write_event: asyncio.Event - exception: Optional[Exception] = None - - def connection_made(self, transport: asyncio.BaseTransport) -> None: - self.read_queue = deque(maxlen=100) # arbitrary value - self.read_event = asyncio.Event() - self.write_event = asyncio.Event() - self.write_event.set() - - def connection_lost(self, exc: Optional[Exception]) -> None: - self.read_event.set() - self.write_event.set() - - def datagram_received(self, data: bytes, addr: IPSockAddrType) -> None: - addr = convert_ipv6_sockaddr(addr) - self.read_queue.append((data, addr)) - self.read_event.set() - - def error_received(self, exc: Exception) -> None: - self.exception = exc - - def pause_writing(self) -> None: - self.write_event.clear() - - def resume_writing(self) -> None: - self.write_event.set() - - -class SocketStream(abc.SocketStream): - def __init__(self, transport: asyncio.Transport, protocol: StreamProtocol): - self._transport = transport - self._protocol = protocol - self._receive_guard = ResourceGuard('reading from') - self._send_guard = ResourceGuard('writing to') - self._closed = False - - @property - def _raw_socket(self) -> socket.socket: - return self._transport.get_extra_info('socket') - - async def receive(self, max_bytes: int = 65536) -> bytes: - with self._receive_guard: - await checkpoint() - - if not self._protocol.read_event.is_set() and not self._transport.is_closing(): - self._transport.resume_reading() - await self._protocol.read_event.wait() - self._transport.pause_reading() - - try: - chunk = self._protocol.read_queue.popleft() - except IndexError: - if self._closed: - raise ClosedResourceError from None - elif self._protocol.exception: - raise self._protocol.exception - else: - raise EndOfStream from None - - if len(chunk) > max_bytes: - # Split the oversized chunk - chunk, leftover = chunk[:max_bytes], chunk[max_bytes:] - self._protocol.read_queue.appendleft(leftover) - - # If the read queue is empty, clear the flag so that the next call will block until - # data is available - if not self._protocol.read_queue: - self._protocol.read_event.clear() - - return chunk - - async def send(self, item: bytes) -> None: - with self._send_guard: - await checkpoint() - - if self._closed: - raise ClosedResourceError - elif self._protocol.exception is not None: - raise self._protocol.exception - - try: - self._transport.write(item) - except RuntimeError as exc: - if self._transport.is_closing(): - raise BrokenResourceError from exc - else: - raise - - await self._protocol.write_event.wait() - - async def send_eof(self) -> None: - try: - self._transport.write_eof() - except OSError: - pass - - async def aclose(self) -> None: - if not self._transport.is_closing(): - self._closed = True - try: - self._transport.write_eof() - except OSError: - pass - - self._transport.close() - await sleep(0) - self._transport.abort() - - -class UNIXSocketStream(abc.SocketStream): - _receive_future: Optional[asyncio.Future] = None - _send_future: Optional[asyncio.Future] = None - _closing = False - - def __init__(self, raw_socket: socket.socket): - self.__raw_socket = raw_socket - self._loop = get_running_loop() - self._receive_guard = ResourceGuard('reading from') - self._send_guard = ResourceGuard('writing to') - - @property - def _raw_socket(self) -> socket.socket: - return self.__raw_socket - - def _wait_until_readable(self, loop: asyncio.AbstractEventLoop) -> asyncio.Future: - def callback(f: object) -> None: - del self._receive_future - loop.remove_reader(self.__raw_socket) - - f = self._receive_future = asyncio.Future() - self._loop.add_reader(self.__raw_socket, f.set_result, None) - f.add_done_callback(callback) - return f - - def _wait_until_writable(self, loop: asyncio.AbstractEventLoop) -> asyncio.Future: - def callback(f: object) -> None: - del self._send_future - loop.remove_writer(self.__raw_socket) - - f = self._send_future = asyncio.Future() - self._loop.add_writer(self.__raw_socket, f.set_result, None) - f.add_done_callback(callback) - return f - - async def send_eof(self) -> None: - with self._send_guard: - self._raw_socket.shutdown(socket.SHUT_WR) - - async def receive(self, max_bytes: int = 65536) -> bytes: - loop = get_running_loop() - await checkpoint() - with self._receive_guard: - while True: - try: - data = self.__raw_socket.recv(max_bytes) - except BlockingIOError: - await self._wait_until_readable(loop) - except OSError as exc: - if self._closing: - raise ClosedResourceError from None - else: - raise BrokenResourceError from exc - else: - if not data: - raise EndOfStream - - return data - - async def send(self, item: bytes) -> None: - loop = get_running_loop() - await checkpoint() - with self._send_guard: - view = memoryview(item) - while view: - try: - bytes_sent = self.__raw_socket.send(item) - except BlockingIOError: - await self._wait_until_writable(loop) - except OSError as exc: - if self._closing: - raise ClosedResourceError from None - else: - raise BrokenResourceError from exc - else: - view = view[bytes_sent:] - - async def receive_fds(self, msglen: int, maxfds: int) -> Tuple[bytes, List[int]]: - if not isinstance(msglen, int) or msglen < 0: - raise ValueError('msglen must be a non-negative integer') - if not isinstance(maxfds, int) or maxfds < 1: - raise ValueError('maxfds must be a positive integer') - - loop = get_running_loop() - fds = array.array("i") - await checkpoint() - with self._receive_guard: - while True: - try: - message, ancdata, flags, addr = self.__raw_socket.recvmsg( - msglen, socket.CMSG_LEN(maxfds * fds.itemsize)) - except BlockingIOError: - await self._wait_until_readable(loop) - except OSError as exc: - if self._closing: - raise ClosedResourceError from None - else: - raise BrokenResourceError from exc - else: - if not message and not ancdata: - raise EndOfStream - - break - - for cmsg_level, cmsg_type, cmsg_data in ancdata: - if cmsg_level != socket.SOL_SOCKET or cmsg_type != socket.SCM_RIGHTS: - raise RuntimeError(f'Received unexpected ancillary data; message = {message!r}, ' - f'cmsg_level = {cmsg_level}, cmsg_type = {cmsg_type}') - - fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) - - return message, list(fds) - - async def send_fds(self, message: bytes, fds: Collection[Union[int, IOBase]]) -> None: - if not message: - raise ValueError('message must not be empty') - if not fds: - raise ValueError('fds must not be empty') - - loop = get_running_loop() - filenos: List[int] = [] - for fd in fds: - if isinstance(fd, int): - filenos.append(fd) - elif isinstance(fd, IOBase): - filenos.append(fd.fileno()) - - fdarray = array.array("i", filenos) - await checkpoint() - with self._send_guard: - while True: - try: - # The ignore can be removed after mypy picks up - # https://github.com/python/typeshed/pull/5545 - self.__raw_socket.sendmsg( - [message], - [(socket.SOL_SOCKET, socket.SCM_RIGHTS, fdarray)] # type: ignore - ) - break - except BlockingIOError: - await self._wait_until_writable(loop) - except OSError as exc: - if self._closing: - raise ClosedResourceError from None - else: - raise BrokenResourceError from exc - - async def aclose(self) -> None: - if not self._closing: - self._closing = True - if self.__raw_socket.fileno() != -1: - self.__raw_socket.close() - - if self._receive_future: - self._receive_future.set_result(None) - if self._send_future: - self._send_future.set_result(None) - - -class TCPSocketListener(abc.SocketListener): - _accept_scope: Optional[CancelScope] = None - _closed = False - - def __init__(self, raw_socket: socket.socket): - self.__raw_socket = raw_socket - self._loop = cast(asyncio.BaseEventLoop, get_running_loop()) - self._accept_guard = ResourceGuard('accepting connections from') - - @property - def _raw_socket(self) -> socket.socket: - return self.__raw_socket - - async def accept(self) -> abc.SocketStream: - if self._closed: - raise ClosedResourceError - - with self._accept_guard: - await checkpoint() - with CancelScope() as self._accept_scope: - try: - client_sock, _addr = await self._loop.sock_accept(self._raw_socket) - except asyncio.CancelledError: - # Workaround for https://bugs.python.org/issue41317 - try: - self._loop.remove_reader(self._raw_socket) - except (ValueError, NotImplementedError): - pass - - if self._closed: - raise ClosedResourceError from None - - raise - finally: - self._accept_scope = None - - client_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - transport, protocol = await self._loop.connect_accepted_socket(StreamProtocol, client_sock) - return SocketStream(cast(asyncio.Transport, transport), cast(StreamProtocol, protocol)) - - async def aclose(self) -> None: - if self._closed: - return - - self._closed = True - if self._accept_scope: - # Workaround for https://bugs.python.org/issue41317 - try: - self._loop.remove_reader(self._raw_socket) - except (ValueError, NotImplementedError): - pass - - self._accept_scope.cancel() - await sleep(0) - - self._raw_socket.close() - - -class UNIXSocketListener(abc.SocketListener): - def __init__(self, raw_socket: socket.socket): - self.__raw_socket = raw_socket - self._loop = get_running_loop() - self._accept_guard = ResourceGuard('accepting connections from') - self._closed = False - - async def accept(self) -> abc.SocketStream: - await checkpoint() - with self._accept_guard: - while True: - try: - client_sock, _ = self.__raw_socket.accept() - return UNIXSocketStream(client_sock) - except BlockingIOError: - f: asyncio.Future = asyncio.Future() - self._loop.add_reader(self.__raw_socket, f.set_result, None) - f.add_done_callback(lambda _: self._loop.remove_reader(self.__raw_socket)) - await f - except OSError as exc: - if self._closed: - raise ClosedResourceError from None - else: - raise BrokenResourceError from exc - - async def aclose(self) -> None: - self._closed = True - self.__raw_socket.close() - - @property - def _raw_socket(self) -> socket.socket: - return self.__raw_socket - - -class UDPSocket(abc.UDPSocket): - def __init__(self, transport: asyncio.DatagramTransport, protocol: DatagramProtocol): - self._transport = transport - self._protocol = protocol - self._receive_guard = ResourceGuard('reading from') - self._send_guard = ResourceGuard('writing to') - self._closed = False - - @property - def _raw_socket(self) -> socket.socket: - return self._transport.get_extra_info('socket') - - async def aclose(self) -> None: - if not self._transport.is_closing(): - self._closed = True - self._transport.close() - - async def receive(self) -> Tuple[bytes, IPSockAddrType]: - with self._receive_guard: - await checkpoint() - - # If the buffer is empty, ask for more data - if not self._protocol.read_queue and not self._transport.is_closing(): - self._protocol.read_event.clear() - await self._protocol.read_event.wait() - - try: - return self._protocol.read_queue.popleft() - except IndexError: - if self._closed: - raise ClosedResourceError from None - else: - raise BrokenResourceError from None - - async def send(self, item: UDPPacketType) -> None: - with self._send_guard: - await checkpoint() - await self._protocol.write_event.wait() - if self._closed: - raise ClosedResourceError - elif self._transport.is_closing(): - raise BrokenResourceError - else: - self._transport.sendto(*item) - - -class ConnectedUDPSocket(abc.ConnectedUDPSocket): - def __init__(self, transport: asyncio.DatagramTransport, protocol: DatagramProtocol): - self._transport = transport - self._protocol = protocol - self._receive_guard = ResourceGuard('reading from') - self._send_guard = ResourceGuard('writing to') - self._closed = False - - @property - def _raw_socket(self) -> socket.socket: - return self._transport.get_extra_info('socket') - - async def aclose(self) -> None: - if not self._transport.is_closing(): - self._closed = True - self._transport.close() - - async def receive(self) -> bytes: - with self._receive_guard: - await checkpoint() - - # If the buffer is empty, ask for more data - if not self._protocol.read_queue and not self._transport.is_closing(): - self._protocol.read_event.clear() - await self._protocol.read_event.wait() - - try: - packet = self._protocol.read_queue.popleft() - except IndexError: - if self._closed: - raise ClosedResourceError from None - else: - raise BrokenResourceError from None - - return packet[0] - - async def send(self, item: bytes) -> None: - with self._send_guard: - await checkpoint() - await self._protocol.write_event.wait() - if self._closed: - raise ClosedResourceError - elif self._transport.is_closing(): - raise BrokenResourceError - else: - self._transport.sendto(item) - - -async def connect_tcp(host: str, port: int, - local_addr: Optional[Tuple[str, int]] = None) -> SocketStream: - transport, protocol = cast( - Tuple[asyncio.Transport, StreamProtocol], - await get_running_loop().create_connection(StreamProtocol, host, port, - local_addr=local_addr) - ) - transport.pause_reading() - return SocketStream(transport, protocol) - - -async def connect_unix(path: str) -> UNIXSocketStream: - await checkpoint() - loop = get_running_loop() - raw_socket = socket.socket(socket.AF_UNIX) - raw_socket.setblocking(False) - while True: - try: - raw_socket.connect(path) - except BlockingIOError: - f: asyncio.Future = asyncio.Future() - loop.add_writer(raw_socket, f.set_result, None) - f.add_done_callback(lambda _: loop.remove_writer(raw_socket)) - await f - except BaseException: - raw_socket.close() - raise - else: - return UNIXSocketStream(raw_socket) - - -async def create_udp_socket( - family: socket.AddressFamily, - local_address: Optional[IPSockAddrType], - remote_address: Optional[IPSockAddrType], - reuse_port: bool -) -> Union[UDPSocket, ConnectedUDPSocket]: - result = await get_running_loop().create_datagram_endpoint( - DatagramProtocol, local_addr=local_address, remote_addr=remote_address, family=family, - reuse_port=reuse_port) - transport = cast(asyncio.DatagramTransport, result[0]) - protocol = cast(DatagramProtocol, result[1]) - if protocol.exception: - transport.close() - raise protocol.exception - - if not remote_address: - return UDPSocket(transport, protocol) - else: - return ConnectedUDPSocket(transport, protocol) - - -async def getaddrinfo(host: Union[bytearray, bytes, str], port: Union[str, int, None], *, - family: Union[int, AddressFamily] = 0, type: Union[int, SocketKind] = 0, - proto: int = 0, flags: int = 0) -> GetAddrInfoReturnType: - # https://github.com/python/typeshed/pull/4304 - result = await get_running_loop().getaddrinfo( - host, port, family=family, type=type, proto=proto, flags=flags) # type: ignore[arg-type] - return cast(GetAddrInfoReturnType, result) - - -async def getnameinfo(sockaddr: IPSockAddrType, flags: int = 0) -> Tuple[str, str]: - return await get_running_loop().getnameinfo(sockaddr, flags) - - -_read_events: RunVar[Dict[Any, asyncio.Event]] = RunVar('read_events') -_write_events: RunVar[Dict[Any, asyncio.Event]] = RunVar('write_events') - - -async def wait_socket_readable(sock: socket.socket) -> None: - await checkpoint() - try: - read_events = _read_events.get() - except LookupError: - read_events = {} - _read_events.set(read_events) - - if read_events.get(sock): - raise BusyResourceError('reading from') from None - - loop = get_running_loop() - event = read_events[sock] = asyncio.Event() - loop.add_reader(sock, event.set) - try: - await event.wait() - finally: - if read_events.pop(sock, None) is not None: - loop.remove_reader(sock) - readable = True - else: - readable = False - - if not readable: - raise ClosedResourceError - - -async def wait_socket_writable(sock: socket.socket) -> None: - await checkpoint() - try: - write_events = _write_events.get() - except LookupError: - write_events = {} - _write_events.set(write_events) - - if write_events.get(sock): - raise BusyResourceError('writing to') from None - - loop = get_running_loop() - event = write_events[sock] = asyncio.Event() - loop.add_writer(sock.fileno(), event.set) - try: - await event.wait() - finally: - if write_events.pop(sock, None) is not None: - loop.remove_writer(sock) - writable = True - else: - writable = False - - if not writable: - raise ClosedResourceError - - -# -# Synchronization -# - -class Event(BaseEvent): - def __new__(cls) -> "Event": - return object.__new__(cls) - - def __init__(self) -> None: - self._event = asyncio.Event() - - def set(self) -> DeprecatedAwaitable: - self._event.set() - return DeprecatedAwaitable(self.set) - - def is_set(self) -> bool: - return self._event.is_set() - - async def wait(self) -> None: - if await self._event.wait(): - await checkpoint() - - def statistics(self) -> EventStatistics: - return EventStatistics(len(self._event._waiters)) # type: ignore[attr-defined] - - -class CapacityLimiter(BaseCapacityLimiter): - _total_tokens: float = 0 - - def __new__(cls, total_tokens: float) -> "CapacityLimiter": - return object.__new__(cls) - - def __init__(self, total_tokens: float): - self._borrowers: Set[Any] = set() - self._wait_queue: Dict[Any, asyncio.Event] = OrderedDict() - self.total_tokens = total_tokens - - async def __aenter__(self) -> None: - await self.acquire() - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> None: - self.release() - - @property - def total_tokens(self) -> float: - return self._total_tokens - - @total_tokens.setter - def total_tokens(self, value: float) -> None: - if not isinstance(value, int) and not math.isinf(value): - raise TypeError('total_tokens must be an int or math.inf') - if value < 1: - raise ValueError('total_tokens must be >= 1') - - old_value = self._total_tokens - self._total_tokens = value - events = [] - for event in self._wait_queue.values(): - if value <= old_value: - break - - if not event.is_set(): - events.append(event) - old_value += 1 - - for event in events: - event.set() - - @property - def borrowed_tokens(self) -> int: - return len(self._borrowers) - - @property - def available_tokens(self) -> float: - return self._total_tokens - len(self._borrowers) - - def acquire_nowait(self) -> DeprecatedAwaitable: - self.acquire_on_behalf_of_nowait(current_task()) - return DeprecatedAwaitable(self.acquire_nowait) - - def acquire_on_behalf_of_nowait(self, borrower: object) -> DeprecatedAwaitable: - if borrower in self._borrowers: - raise RuntimeError("this borrower is already holding one of this CapacityLimiter's " - "tokens") - - if self._wait_queue or len(self._borrowers) >= self._total_tokens: - raise WouldBlock - - self._borrowers.add(borrower) - return DeprecatedAwaitable(self.acquire_on_behalf_of_nowait) - - async def acquire(self) -> None: - return await self.acquire_on_behalf_of(current_task()) - - async def acquire_on_behalf_of(self, borrower: object) -> None: - await checkpoint_if_cancelled() - try: - self.acquire_on_behalf_of_nowait(borrower) - except WouldBlock: - event = asyncio.Event() - self._wait_queue[borrower] = event - try: - await event.wait() - except BaseException: - self._wait_queue.pop(borrower, None) - raise - - self._borrowers.add(borrower) - else: - await cancel_shielded_checkpoint() - - def release(self) -> None: - self.release_on_behalf_of(current_task()) - - def release_on_behalf_of(self, borrower: object) -> None: - try: - self._borrowers.remove(borrower) - except KeyError: - raise RuntimeError("this borrower isn't holding any of this CapacityLimiter's " - "tokens") from None - - # Notify the next task in line if this limiter has free capacity now - if self._wait_queue and len(self._borrowers) < self._total_tokens: - event = self._wait_queue.popitem()[1] - event.set() - - def statistics(self) -> CapacityLimiterStatistics: - return CapacityLimiterStatistics(self.borrowed_tokens, self.total_tokens, - tuple(self._borrowers), len(self._wait_queue)) - - -_default_thread_limiter: RunVar[CapacityLimiter] = RunVar('_default_thread_limiter') - - -def current_default_thread_limiter() -> CapacityLimiter: - try: - return _default_thread_limiter.get() - except LookupError: - limiter = CapacityLimiter(40) - _default_thread_limiter.set(limiter) - return limiter - - -# -# Operating system signals -# - -class _SignalReceiver(DeprecatedAsyncContextManager["_SignalReceiver"]): - def __init__(self, signals: Tuple[int, ...]): - self._signals = signals - self._loop = get_running_loop() - self._signal_queue: Deque[int] = deque() - self._future: asyncio.Future = asyncio.Future() - self._handled_signals: Set[int] = set() - - def _deliver(self, signum: int) -> None: - self._signal_queue.append(signum) - if not self._future.done(): - self._future.set_result(None) - - def __enter__(self) -> "_SignalReceiver": - for sig in set(self._signals): - self._loop.add_signal_handler(sig, self._deliver, sig) - self._handled_signals.add(sig) - - return self - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - for sig in self._handled_signals: - self._loop.remove_signal_handler(sig) - return None - - def __aiter__(self) -> "_SignalReceiver": - return self - - async def __anext__(self) -> int: - await checkpoint() - if not self._signal_queue: - self._future = asyncio.Future() - await self._future - - return self._signal_queue.popleft() - - -def open_signal_receiver(*signals: int) -> _SignalReceiver: - return _SignalReceiver(signals) - - -# -# Testing and debugging -# - -def _create_task_info(task: asyncio.Task) -> TaskInfo: - task_state = _task_states.get(task) - if task_state is None: - name = task.get_name() if _native_task_names else None - parent_id = None - else: - name = task_state.name - parent_id = task_state.parent_id - - return TaskInfo(id(task), parent_id, name, get_coro(task)) - - -def get_current_task() -> TaskInfo: - return _create_task_info(current_task()) # type: ignore - - -def get_running_tasks() -> List[TaskInfo]: - return [_create_task_info(task) for task in all_tasks() if not task.done()] - - -async def wait_all_tasks_blocked() -> None: - await checkpoint() - this_task = current_task() - while True: - for task in all_tasks(): - if task is this_task: - continue - - if task._fut_waiter is None or task._fut_waiter.done(): # type: ignore[attr-defined] - await sleep(0.1) - break - else: - return - - -class TestRunner(abc.TestRunner): - def __init__(self, debug: bool = False, use_uvloop: bool = False, - policy: Optional[asyncio.AbstractEventLoopPolicy] = None): - _maybe_set_event_loop_policy(policy, use_uvloop) - self._loop = asyncio.new_event_loop() - self._loop.set_debug(debug) - asyncio.set_event_loop(self._loop) - - def _cancel_all_tasks(self) -> None: - to_cancel = all_tasks(self._loop) - if not to_cancel: - return - - for task in to_cancel: - task.cancel() - - self._loop.run_until_complete(asyncio.gather(*to_cancel, return_exceptions=True)) - - for task in to_cancel: - if task.cancelled(): - continue - if task.exception() is not None: - raise cast(BaseException, task.exception()) - - def close(self) -> None: - try: - self._cancel_all_tasks() - self._loop.run_until_complete(self._loop.shutdown_asyncgens()) - finally: - asyncio.set_event_loop(None) - self._loop.close() - - def call(self, func: Callable[..., Awaitable[T_Retval]], - *args: object, **kwargs: object) -> T_Retval: - def exception_handler(loop: asyncio.AbstractEventLoop, context: Dict[str, Any]) -> None: - exceptions.append(context['exception']) - - exceptions: List[Exception] = [] - self._loop.set_exception_handler(exception_handler) - try: - retval: T_Retval = self._loop.run_until_complete(func(*args, **kwargs)) - except Exception as exc: - retval = None # type: ignore[assignment] - exceptions.append(exc) - finally: - self._loop.set_exception_handler(None) - - if len(exceptions) == 1: - raise exceptions[0] - elif exceptions: - raise ExceptionGroup(exceptions) - - return retval diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/_trio.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/_trio.py deleted file mode 100644 index aa4e0e28..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_backends/_trio.py +++ /dev/null @@ -1,788 +0,0 @@ -import array -import math -import socket -from concurrent.futures import Future -from dataclasses import dataclass -from functools import partial -from io import IOBase -from os import PathLike -from types import TracebackType -from typing import ( - Any, Awaitable, Callable, Collection, ContextManager, Coroutine, Deque, Dict, Generic, List, - Mapping, NoReturn, Optional, Sequence, Set, Tuple, Type, TypeVar, Union) - -import trio.from_thread -from outcome import Error, Outcome, Value -from trio.socket import SocketType as TrioSocketType -from trio.to_thread import run_sync - -from .. import CapacityLimiterStatistics, EventStatistics, TaskInfo, abc -from .._core._compat import DeprecatedAsyncContextManager, DeprecatedAwaitable, T -from .._core._eventloop import claim_worker_thread -from .._core._exceptions import ( - BrokenResourceError, BusyResourceError, ClosedResourceError, EndOfStream) -from .._core._exceptions import ExceptionGroup as BaseExceptionGroup -from .._core._sockets import convert_ipv6_sockaddr -from .._core._synchronization import CapacityLimiter as BaseCapacityLimiter -from .._core._synchronization import Event as BaseEvent -from .._core._synchronization import ResourceGuard -from .._core._tasks import CancelScope as BaseCancelScope -from ..abc import IPSockAddrType, UDPPacketType - -try: - from trio import lowlevel as trio_lowlevel -except ImportError: - from trio import hazmat as trio_lowlevel - from trio.hazmat import wait_readable, wait_writable -else: - from trio.lowlevel import wait_readable, wait_writable - - -T_Retval = TypeVar('T_Retval') -T_SockAddr = TypeVar('T_SockAddr', str, IPSockAddrType) - - -# -# Event loop -# - -run = trio.run -current_token = trio.lowlevel.current_trio_token -RunVar = trio.lowlevel.RunVar - - -# -# Miscellaneous -# - -sleep = trio.sleep - - -# -# Timeouts and cancellation -# - -class CancelScope(BaseCancelScope): - def __new__(cls, original: Optional[trio.CancelScope] = None, - **kwargs: object) -> 'CancelScope': - return object.__new__(cls) - - def __init__(self, original: Optional[trio.CancelScope] = None, **kwargs: object) -> None: - self.__original = original or trio.CancelScope(**kwargs) - - def __enter__(self) -> 'CancelScope': - self.__original.__enter__() - return self - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - return self.__original.__exit__(exc_type, exc_val, exc_tb) - - def cancel(self) -> DeprecatedAwaitable: - self.__original.cancel() - return DeprecatedAwaitable(self.cancel) - - @property - def deadline(self) -> float: - return self.__original.deadline - - @deadline.setter - def deadline(self, value: float) -> None: - self.__original.deadline = value - - @property - def cancel_called(self) -> bool: - return self.__original.cancel_called - - @property - def shield(self) -> bool: - return self.__original.shield - - @shield.setter - def shield(self, value: bool) -> None: - self.__original.shield = value - - -CancelledError = trio.Cancelled -checkpoint = trio.lowlevel.checkpoint -checkpoint_if_cancelled = trio.lowlevel.checkpoint_if_cancelled -cancel_shielded_checkpoint = trio.lowlevel.cancel_shielded_checkpoint -current_effective_deadline = trio.current_effective_deadline -current_time = trio.current_time - - -# -# Task groups -# - -class ExceptionGroup(BaseExceptionGroup, trio.MultiError): - pass - - -class TaskGroup(abc.TaskGroup): - def __init__(self) -> None: - self._active = False - self._nursery_manager = trio.open_nursery() - self.cancel_scope = None # type: ignore[assignment] - - async def __aenter__(self) -> 'TaskGroup': - self._active = True - self._nursery = await self._nursery_manager.__aenter__() - self.cancel_scope = CancelScope(self._nursery.cancel_scope) - return self - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - try: - return await self._nursery_manager.__aexit__(exc_type, exc_val, exc_tb) - except trio.MultiError as exc: - raise ExceptionGroup(exc.exceptions) from None - finally: - self._active = False - - def start_soon(self, func: Callable, *args: object, name: object = None) -> None: - if not self._active: - raise RuntimeError('This task group is not active; no new tasks can be started.') - - self._nursery.start_soon(func, *args, name=name) - - async def start(self, func: Callable[..., Coroutine], - *args: object, name: object = None) -> object: - if not self._active: - raise RuntimeError('This task group is not active; no new tasks can be started.') - - return await self._nursery.start(func, *args, name=name) - -# -# Threads -# - - -async def run_sync_in_worker_thread( - func: Callable[..., T_Retval], *args: object, cancellable: bool = False, - limiter: Optional[trio.CapacityLimiter] = None) -> T_Retval: - def wrapper() -> T_Retval: - with claim_worker_thread('trio'): - return func(*args) - - return await run_sync(wrapper, cancellable=cancellable, limiter=limiter) - -run_async_from_thread = trio.from_thread.run -run_sync_from_thread = trio.from_thread.run_sync - - -class BlockingPortal(abc.BlockingPortal): - def __new__(cls) -> 'BlockingPortal': - return object.__new__(cls) - - def __init__(self) -> None: - super().__init__() - self._token = trio.lowlevel.current_trio_token() - - def _spawn_task_from_thread(self, func: Callable, args: tuple, kwargs: Dict[str, Any], - name: object, future: Future) -> None: - return trio.from_thread.run_sync( - partial(self._task_group.start_soon, name=name), self._call_func, func, args, kwargs, - future, trio_token=self._token) - - -# -# Subprocesses -# - -@dataclass(eq=False) -class ReceiveStreamWrapper(abc.ByteReceiveStream): - _stream: trio.abc.ReceiveStream - - async def receive(self, max_bytes: Optional[int] = None) -> bytes: - try: - data = await self._stream.receive_some(max_bytes) - except trio.ClosedResourceError as exc: - raise ClosedResourceError from exc.__cause__ - except trio.BrokenResourceError as exc: - raise BrokenResourceError from exc.__cause__ - - if data: - return data - else: - raise EndOfStream - - async def aclose(self) -> None: - await self._stream.aclose() - - -@dataclass(eq=False) -class SendStreamWrapper(abc.ByteSendStream): - _stream: trio.abc.SendStream - - async def send(self, item: bytes) -> None: - try: - await self._stream.send_all(item) - except trio.ClosedResourceError as exc: - raise ClosedResourceError from exc.__cause__ - except trio.BrokenResourceError as exc: - raise BrokenResourceError from exc.__cause__ - - async def aclose(self) -> None: - await self._stream.aclose() - - -@dataclass(eq=False) -class Process(abc.Process): - _process: trio.Process - _stdin: Optional[abc.ByteSendStream] - _stdout: Optional[abc.ByteReceiveStream] - _stderr: Optional[abc.ByteReceiveStream] - - async def aclose(self) -> None: - if self._stdin: - await self._stdin.aclose() - if self._stdout: - await self._stdout.aclose() - if self._stderr: - await self._stderr.aclose() - - await self.wait() - - async def wait(self) -> int: - return await self._process.wait() - - def terminate(self) -> None: - self._process.terminate() - - def kill(self) -> None: - self._process.kill() - - def send_signal(self, signal: int) -> None: - self._process.send_signal(signal) - - @property - def pid(self) -> int: - return self._process.pid - - @property - def returncode(self) -> Optional[int]: - return self._process.returncode - - @property - def stdin(self) -> Optional[abc.ByteSendStream]: - return self._stdin - - @property - def stdout(self) -> Optional[abc.ByteReceiveStream]: - return self._stdout - - @property - def stderr(self) -> Optional[abc.ByteReceiveStream]: - return self._stderr - - -async def open_process(command: Union[str, Sequence[str]], *, shell: bool, - stdin: int, stdout: int, stderr: int, - cwd: Union[str, bytes, PathLike, None] = None, - env: Optional[Mapping[str, str]] = None) -> Process: - process = await trio.open_process(command, stdin=stdin, stdout=stdout, stderr=stderr, - shell=shell, cwd=cwd, env=env) - stdin_stream = SendStreamWrapper(process.stdin) if process.stdin else None - stdout_stream = ReceiveStreamWrapper(process.stdout) if process.stdout else None - stderr_stream = ReceiveStreamWrapper(process.stderr) if process.stderr else None - return Process(process, stdin_stream, stdout_stream, stderr_stream) - - -class _ProcessPoolShutdownInstrument(trio.abc.Instrument): - def after_run(self) -> None: - super().after_run() - - -current_default_worker_process_limiter = trio.lowlevel.RunVar( - 'current_default_worker_process_limiter') - - -async def _shutdown_process_pool(workers: Set[Process]) -> None: - process: Process - try: - await sleep(math.inf) - except trio.Cancelled: - for process in workers: - if process.returncode is None: - process.kill() - - with CancelScope(shield=True): - for process in workers: - await process.aclose() - - -def setup_process_pool_exit_at_shutdown(workers: Set[Process]) -> None: - trio.lowlevel.spawn_system_task(_shutdown_process_pool, workers) - - -# -# Sockets and networking -# - -class _TrioSocketMixin(Generic[T_SockAddr]): - def __init__(self, trio_socket: TrioSocketType) -> None: - self._trio_socket = trio_socket - self._closed = False - - def _check_closed(self) -> None: - if self._closed: - raise ClosedResourceError - if self._trio_socket.fileno() < 0: - raise BrokenResourceError - - @property - def _raw_socket(self) -> socket.socket: - return self._trio_socket._sock - - async def aclose(self) -> None: - if self._trio_socket.fileno() >= 0: - self._closed = True - self._trio_socket.close() - - def _convert_socket_error(self, exc: BaseException) -> 'NoReturn': - if isinstance(exc, trio.ClosedResourceError): - raise ClosedResourceError from exc - elif self._trio_socket.fileno() < 0 and self._closed: - raise ClosedResourceError from None - elif isinstance(exc, OSError): - raise BrokenResourceError from exc - else: - raise exc - - -class SocketStream(_TrioSocketMixin, abc.SocketStream): - def __init__(self, trio_socket: TrioSocketType) -> None: - super().__init__(trio_socket) - self._receive_guard = ResourceGuard('reading from') - self._send_guard = ResourceGuard('writing to') - - async def receive(self, max_bytes: int = 65536) -> bytes: - with self._receive_guard: - try: - data = await self._trio_socket.recv(max_bytes) - except BaseException as exc: - self._convert_socket_error(exc) - - if data: - return data - else: - raise EndOfStream - - async def send(self, item: bytes) -> None: - with self._send_guard: - view = memoryview(item) - while view: - try: - bytes_sent = await self._trio_socket.send(view) - except BaseException as exc: - self._convert_socket_error(exc) - - view = view[bytes_sent:] - - async def send_eof(self) -> None: - self._trio_socket.shutdown(socket.SHUT_WR) - - -class UNIXSocketStream(SocketStream, abc.UNIXSocketStream): - async def receive_fds(self, msglen: int, maxfds: int) -> Tuple[bytes, List[int]]: - if not isinstance(msglen, int) or msglen < 0: - raise ValueError('msglen must be a non-negative integer') - if not isinstance(maxfds, int) or maxfds < 1: - raise ValueError('maxfds must be a positive integer') - - fds = array.array("i") - await checkpoint() - with self._receive_guard: - while True: - try: - message, ancdata, flags, addr = await self._trio_socket.recvmsg( - msglen, socket.CMSG_LEN(maxfds * fds.itemsize)) - except BaseException as exc: - self._convert_socket_error(exc) - else: - if not message and not ancdata: - raise EndOfStream - - break - - for cmsg_level, cmsg_type, cmsg_data in ancdata: - if cmsg_level != socket.SOL_SOCKET or cmsg_type != socket.SCM_RIGHTS: - raise RuntimeError(f'Received unexpected ancillary data; message = {message}, ' - f'cmsg_level = {cmsg_level}, cmsg_type = {cmsg_type}') - - fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) - - return message, list(fds) - - async def send_fds(self, message: bytes, fds: Collection[Union[int, IOBase]]) -> None: - if not message: - raise ValueError('message must not be empty') - if not fds: - raise ValueError('fds must not be empty') - - filenos: List[int] = [] - for fd in fds: - if isinstance(fd, int): - filenos.append(fd) - elif isinstance(fd, IOBase): - filenos.append(fd.fileno()) - - fdarray = array.array("i", filenos) - await checkpoint() - with self._send_guard: - while True: - try: - await self._trio_socket.sendmsg( - [message], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, fdarray)]) - break - except BaseException as exc: - self._convert_socket_error(exc) - - -class TCPSocketListener(_TrioSocketMixin, abc.SocketListener): - def __init__(self, raw_socket: socket.socket): - super().__init__(trio.socket.from_stdlib_socket(raw_socket)) - self._accept_guard = ResourceGuard('accepting connections from') - - async def accept(self) -> SocketStream: - with self._accept_guard: - try: - trio_socket, _addr = await self._trio_socket.accept() - except BaseException as exc: - self._convert_socket_error(exc) - - trio_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - return SocketStream(trio_socket) - - -class UNIXSocketListener(_TrioSocketMixin, abc.SocketListener): - def __init__(self, raw_socket: socket.socket): - super().__init__(trio.socket.from_stdlib_socket(raw_socket)) - self._accept_guard = ResourceGuard('accepting connections from') - - async def accept(self) -> UNIXSocketStream: - with self._accept_guard: - try: - trio_socket, _addr = await self._trio_socket.accept() - except BaseException as exc: - self._convert_socket_error(exc) - - return UNIXSocketStream(trio_socket) - - -class UDPSocket(_TrioSocketMixin[IPSockAddrType], abc.UDPSocket): - def __init__(self, trio_socket: TrioSocketType) -> None: - super().__init__(trio_socket) - self._receive_guard = ResourceGuard('reading from') - self._send_guard = ResourceGuard('writing to') - - async def receive(self) -> Tuple[bytes, IPSockAddrType]: - with self._receive_guard: - try: - data, addr = await self._trio_socket.recvfrom(65536) - return data, convert_ipv6_sockaddr(addr) - except BaseException as exc: - self._convert_socket_error(exc) - - async def send(self, item: UDPPacketType) -> None: - with self._send_guard: - try: - await self._trio_socket.sendto(*item) - except BaseException as exc: - self._convert_socket_error(exc) - - -class ConnectedUDPSocket(_TrioSocketMixin[IPSockAddrType], abc.ConnectedUDPSocket): - def __init__(self, trio_socket: TrioSocketType) -> None: - super().__init__(trio_socket) - self._receive_guard = ResourceGuard('reading from') - self._send_guard = ResourceGuard('writing to') - - async def receive(self) -> bytes: - with self._receive_guard: - try: - return await self._trio_socket.recv(65536) - except BaseException as exc: - self._convert_socket_error(exc) - - async def send(self, item: bytes) -> None: - with self._send_guard: - try: - await self._trio_socket.send(item) - except BaseException as exc: - self._convert_socket_error(exc) - - -async def connect_tcp(host: str, port: int, - local_address: Optional[IPSockAddrType] = None) -> SocketStream: - family = socket.AF_INET6 if ':' in host else socket.AF_INET - trio_socket = trio.socket.socket(family) - trio_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - if local_address: - await trio_socket.bind(local_address) - - try: - await trio_socket.connect((host, port)) - except BaseException: - trio_socket.close() - raise - - return SocketStream(trio_socket) - - -async def connect_unix(path: str) -> UNIXSocketStream: - trio_socket = trio.socket.socket(socket.AF_UNIX) - try: - await trio_socket.connect(path) - except BaseException: - trio_socket.close() - raise - - return UNIXSocketStream(trio_socket) - - -async def create_udp_socket( - family: socket.AddressFamily, - local_address: Optional[IPSockAddrType], - remote_address: Optional[IPSockAddrType], - reuse_port: bool -) -> Union[UDPSocket, ConnectedUDPSocket]: - trio_socket = trio.socket.socket(family=family, type=socket.SOCK_DGRAM) - - if reuse_port: - trio_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - - if local_address: - await trio_socket.bind(local_address) - - if remote_address: - await trio_socket.connect(remote_address) - return ConnectedUDPSocket(trio_socket) - else: - return UDPSocket(trio_socket) - - -getaddrinfo = trio.socket.getaddrinfo -getnameinfo = trio.socket.getnameinfo - - -async def wait_socket_readable(sock: socket.socket) -> None: - try: - await wait_readable(sock) - except trio.ClosedResourceError as exc: - raise ClosedResourceError().with_traceback(exc.__traceback__) from None - except trio.BusyResourceError: - raise BusyResourceError('reading from') from None - - -async def wait_socket_writable(sock: socket.socket) -> None: - try: - await wait_writable(sock) - except trio.ClosedResourceError as exc: - raise ClosedResourceError().with_traceback(exc.__traceback__) from None - except trio.BusyResourceError: - raise BusyResourceError('writing to') from None - - -# -# Synchronization -# - -class Event(BaseEvent): - def __new__(cls) -> 'Event': - return object.__new__(cls) - - def __init__(self) -> None: - self.__original = trio.Event() - - def is_set(self) -> bool: - return self.__original.is_set() - - async def wait(self) -> None: - return await self.__original.wait() - - def statistics(self) -> EventStatistics: - return self.__original.statistics() - - def set(self) -> DeprecatedAwaitable: - self.__original.set() - return DeprecatedAwaitable(self.set) - - -class CapacityLimiter(BaseCapacityLimiter): - def __new__(cls, *args: object, **kwargs: object) -> "CapacityLimiter": - return object.__new__(cls) - - def __init__(self, *args: object, original: Optional[trio.CapacityLimiter] = None) -> None: - self.__original = original or trio.CapacityLimiter(*args) - - async def __aenter__(self) -> None: - return await self.__original.__aenter__() - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - return await self.__original.__aexit__(exc_type, exc_val, exc_tb) - - @property - def total_tokens(self) -> float: - return self.__original.total_tokens - - @total_tokens.setter - def total_tokens(self, value: float) -> None: - self.__original.total_tokens = value - - @property - def borrowed_tokens(self) -> int: - return self.__original.borrowed_tokens - - @property - def available_tokens(self) -> float: - return self.__original.available_tokens - - def acquire_nowait(self) -> DeprecatedAwaitable: - self.__original.acquire_nowait() - return DeprecatedAwaitable(self.acquire_nowait) - - def acquire_on_behalf_of_nowait(self, borrower: object) -> DeprecatedAwaitable: - self.__original.acquire_on_behalf_of_nowait(borrower) - return DeprecatedAwaitable(self.acquire_on_behalf_of_nowait) - - async def acquire(self) -> None: - await self.__original.acquire() - - async def acquire_on_behalf_of(self, borrower: object) -> None: - await self.__original.acquire_on_behalf_of(borrower) - - def release(self) -> None: - return self.__original.release() - - def release_on_behalf_of(self, borrower: object) -> None: - return self.__original.release_on_behalf_of(borrower) - - def statistics(self) -> CapacityLimiterStatistics: - return self.__original.statistics() - - -_capacity_limiter_wrapper = RunVar('_capacity_limiter_wrapper') - - -def current_default_thread_limiter() -> CapacityLimiter: - try: - return _capacity_limiter_wrapper.get() - except LookupError: - limiter = CapacityLimiter(original=trio.to_thread.current_default_thread_limiter()) - _capacity_limiter_wrapper.set(limiter) - return limiter - - -# -# Signal handling -# - -class _SignalReceiver(DeprecatedAsyncContextManager[T]): - def __init__(self, cm: ContextManager[T]): - self._cm = cm - - def __enter__(self) -> T: - return self._cm.__enter__() - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - return self._cm.__exit__(exc_type, exc_val, exc_tb) - - -def open_signal_receiver(*signals: int) -> _SignalReceiver: - cm = trio.open_signal_receiver(*signals) - return _SignalReceiver(cm) - -# -# Testing and debugging -# - - -def get_current_task() -> TaskInfo: - task = trio_lowlevel.current_task() - - parent_id = None - if task.parent_nursery and task.parent_nursery.parent_task: - parent_id = id(task.parent_nursery.parent_task) - - return TaskInfo(id(task), parent_id, task.name, task.coro) - - -def get_running_tasks() -> List[TaskInfo]: - root_task = trio_lowlevel.current_root_task() - task_infos = [TaskInfo(id(root_task), None, root_task.name, root_task.coro)] - nurseries = root_task.child_nurseries - while nurseries: - new_nurseries: List[trio.Nursery] = [] - for nursery in nurseries: - for task in nursery.child_tasks: - task_infos.append( - TaskInfo(id(task), id(nursery.parent_task), task.name, task.coro)) - new_nurseries.extend(task.child_nurseries) - - nurseries = new_nurseries - - return task_infos - - -def wait_all_tasks_blocked() -> Awaitable[None]: - import trio.testing - return trio.testing.wait_all_tasks_blocked() - - -class TestRunner(abc.TestRunner): - def __init__(self, **options: object) -> None: - from collections import deque - from queue import Queue - - self._call_queue: "Queue[Callable[..., object]]" = Queue() - self._result_queue: Deque[Outcome] = deque() - self._stop_event: Optional[trio.Event] = None - self._nursery: Optional[trio.Nursery] = None - self._options = options - - async def _trio_main(self) -> None: - self._stop_event = trio.Event() - async with trio.open_nursery() as self._nursery: - await self._stop_event.wait() - - async def _call_func(self, func: Callable[..., Awaitable[object]], - args: tuple, kwargs: dict) -> None: - try: - retval = await func(*args, **kwargs) - except BaseException as exc: - self._result_queue.append(Error(exc)) - else: - self._result_queue.append(Value(retval)) - - def _main_task_finished(self, outcome: object) -> None: - self._nursery = None - - def close(self) -> None: - if self._stop_event: - self._stop_event.set() - while self._nursery is not None: - self._call_queue.get()() - - def call(self, func: Callable[..., Awaitable[T_Retval]], - *args: object, **kwargs: object) -> T_Retval: - if self._nursery is None: - trio.lowlevel.start_guest_run( - self._trio_main, run_sync_soon_threadsafe=self._call_queue.put, - done_callback=self._main_task_finished, **self._options) - while self._nursery is None: - self._call_queue.get()() - - self._nursery.start_soon(self._call_func, func, args, kwargs) - while not self._result_queue: - self._call_queue.get()() - - outcome = self._result_queue.pop() - return outcome.unwrap() diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 5e2e376f00228501d4af3a054a62fc962f432bcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmYe~<>g`kf`|Vc6G8N25P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_Wi&acOWkyMU zUQAJ9UP^v$OmK2Wetu4jr?;zPd~tG7VnJ$Aj9yu4URjJ!W>QRXW=X1UL1J=tVtQ(E sOk!STX1;!Wa(+>&etdjpUS>&ryk0@&Ee@O9{FKt1R6CGupMjVG0OkuW8vpTXP)66`tGPFOnr$wrtrR%f@&OED7X76hb6q$2fo>vB+hj)MPZ>E3Mht+4Rg> z)|PT9Xbf53s z)~i&C8lHcCw(6Pln)Wa1j6PX(R#2k9>zc+irnj^}cl5w;44wK$%M2{Xl5Mk<39?RB zwyjn!$UFI<;1q(QQw&N@DJVPTpyE`5s#6W7oT*^inGTLQ$ATGWCYW_*gE?m|IPM&m z?`K-`!3pPtuJOEhmt|S5buw6R7Idv`@l(zMpJn+2-8s$YSb-H;i7zy)1|kt>&tcWG{2ZI1UF7T> z%{phUYwS3izpJtN1H-XFSE4m}f$D~lw%7^qbCNCKjq~gRU*t>J#o&#@BvCB-quE@8}O=P`DkSLBX5TYBGeo@6sOwc5o` z=mu*>l3RUw?R6e|N!8nmV&VC5z~h~e)%0Y3wLh{Jwqt%Le%)((+gxC#vH?QA<@s-K z>~(mpih-ZMdCgsW<=Wb-H`cEwv#Zfw+duqTl3(*$EpMyElj_(^;W}?~;l-gyaxuR! zkVy@l{Dv33eWTq76MZ9@y~;a+`(Di1>aN#}W?`^-)87fh z*5-{@udTX~FT4&HoAukgeS7n@=GJD^jQKMioIfrk+Vt9c&G1>*4+W<>=y-9xvzL?t zZ*Pmc9^J((F=3$63~?Uy<2e;)K&DtcH)u(YZR*k@CsF!~_D((IjDE54%dccF;-(N2UYs;gtuYIK5$JNzz?@zeTqK!vNjUBe_c!%5DP27tOG2nh|Hyd`F z`#g#~u~#oj;*FhVWH-8Pp9I)Oy9qe88E1AJ+FPQ@wz*oz>)2a7-sM@9Pw5|ZL-^pxLUtnxA9pKDFKGVTVBTTJg26B z@0{Ch?*b;`VZ!?4;J&LqnuneYdMhZ=1}d&OI@273o18SceotoxGohC=++r4b8J0ya z%X2)>3kw=Fc#eKi7iC?-Te*7{%R^sVPMH-UJEdgaJ*@S93T6T72YO=ofiIzn&FP^w zl{J)zOz*zFuenlvNKoQyP1g^geJnaB@dQYQxm@dmqVtYo;>v4{XuIu$FUL4`+{6l$4sUKKL zp5O7^Sn7Lf-G&v&%AqaAFlpEHp*G#8#P2j3`;uXtp|Nk?H^Izn1>AKLoJ0_^Zj0Jw*Zpa_9A}mj?bkf6!ejawFN67o+p|it3xe)0TVBvL}gTYea5Vs zMLnyRKNB=lGnDL1ymS);YxL?VR54C5)(?zmCN`LUpueNX=Dv2IL$VD|q*{?g+V%!| z1$v0w20KuGgYA*NLJe~SWx)S0ROOD>-d2iOX|IPdPf9zAxyPhROFtp%Ys}@2Cp>7{ zV0q;8NmWY1v2&0Ld!Q@_Co)bY$sVEedY7&rvOAFtl}!gcwouJVip_|)_u4)e1dpUZ zUeh%pLLucqT*Tmr{MbZO9q}HZZLVP~B2Qnd6!p9zzKd4PObSxHOaG~e9sIXj{5EeX zRF3O3dRs~q33m+53S{aZAU^2-njdCjV_#?135{jmH_69`d}Y^rWod5vHl+9LOD42cNfR7(4#_E<_+@}#j1;El$-wPy#-Z8)*SCRSGl{Q0Nq;y9g@F1{xZOw8d2 zULyfMnMr*n*tDO*SH-J+`Ic|5U7C%ttx& znCPvbMD)hcz%d=B%795TnFUj2@eIpgB#V(8%cn+;N#jPLikv|xg_!~?$X=OM&?~Y6 zuBs}?Bdi&9^$QQ2yq+VrjhK;gK-ByCEe$fD;}^2)jms(x3^krjT@tHbp`_++F+JW9FMnX`YUcX-x~PGCqPg>F9a5U4`3`g?i+$@W zk61i~$uSPd2udk*UHQH=O8`sn%w$gbv`78ff%R7$FmS;1hC$kPUG51Nz#@A%kqg)t z!CBXbec7SUkT}$PXD2g}k{&q*Xmxc>^ci#|BN4%bj~7cIdwXQR(-ZeoURtdrz5&va z%gs}lZcvbuAxPbbDXPfyiR)C+1|ugvv~nazE=oj;kd>RsoHFSK4n6WVFcQ6kYKQ?i zb%X-Kf%%@+P*^C#*@OEhXEF%Pkz7z{fK!*}X2ZlA1)xM>0d62Ka*W{@wL}WdDr}Uv zDQT;03Tu?#(=5%Y;3}uZ0vI8*$X_$j?+7W@(j1#3yi=RFr{9SDfml0$54I2R+=o!~ z{jekhjm8l|!_nZot_$sK`mIR3f*0h%a5W*Ie#?s@NXYQ`eh7jNEiDBF?#zUXlYub6 zqgFPCi~8e?Qh$wBljt`3=r#_cTf7VkaTQg~RDd3EIda1`5s^%EQBpBJ{|N4s%lkN3 zlSHMkj&X|Q#-zUN3g(hbgTnqv*phO2hq#f_r01>P(j)jul>tF1eW*P+BXyaInTABT zWCSksI>;t+Kv4J{N_rj_921X`syo8B&P|}SbAtrs0SI0pv zKZ>>#By(Q??n$LDus(0KQlXWS`x-4^Q$^?rQ6w_*MqW2Qo6gLcCv#_y>HzYY>4|=e zD%An3szN{Knp)^B9 zjUyaPwLw+le+u}Y669Gcbq*y!9fWjwWOiiUOG0*FJ5#A4$)OTmMAcUV`hD1^edCrP z?Wl3f?AuXGDs4hqEhBE=M;-W>LG9!3M>H?hk389-b|Cz{hoU6jDC-mT1Es?Tw)IN` z&}w11i9$$r;SU3D2!E6GL7$s10lyz(kBJNr{QgJ`5QH>+BK-T?|1apfiA5*wOX&ME zO1kg439wiD_Q9ts$(kO=Ah{GO#*{#$>s2PVLai~oE01AleBUGzDH>xKB;kD*r5|VJ z_3Y=P|#=FX6EkE`>{22f{Twx_(u$+v#W)!Wh9m;i2b`S}SQhSmS_yV5M6_9;^qVCS< zJvnlBNB0Db`gs!Z3|{i3r9p!pYCmfC=P*BVK{j>2j_R){YIm!5>9M=ZoW&7;koNwV z)}gyk!#AmPj1SG&JiwnlNR?VLRcfyHvTq^i+_roFITZJg1*ZtcBIG=g@MK5AIT<_e zHW8d1iRloJUPdS<`m6O53^m%R5r)fy0PRbKdbIzNN}(>PK%STxto?<8KPX-b_{8f} zNspKEMuG%lBFdk}#NSY)C#&hxrtzs|^)5f|#?n;T5m_O7C-00L4N7E>r@?e79%7Q* zP*Uk1#EaB)=HsQdpBY<69609Olf_axM}9dmqx|}BQ;V1sFHl9IsUiOW1lkBVFaRs+nr8pWPxV#7G6?#XafpA^?|h_~pd(wtPXKB#5h|*q5PJb4%q$ zG89)uD!Z0N8$v8dX^9+FQfJCEU6Hyas-#Ah+EaemFlsqQvolo9qDt}&0i9_fRTOHco!lK;9W*HCKa3$!+6ViFS>eX&Aaa=WEZq}&TS ziAe{URI Hb94U%{B5s} diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_eventloop.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_eventloop.cpython-39.pyc deleted file mode 100644 index f4c1f5b3a2924203a7eb6c84a75d6df801df90b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4372 zcmai1TW=f372a7c$t6YIeUoFyW5-U!)>fP*>4go9D7F&^4%EOhY;-GtTJ4OimG;8U z4sDa5iXt-l*1q&HPGA*9f&7j3z3B74_41PbgaWPmomoDfCXU_TNJLk;! zKfWvi?qugO7{Ghj_CUW?8}#EV8`fKl7Mr+n$a8c2tTT&tdef6qVzO zS21-bs>ZJ8#x<`N*S&f?=8eS-uMv-XtlLYzeVbvbLko)U9tos$!C zPK=RM(|cOHhF&fw<@sUH8F3ap7o>yL8`6brMtX_YA@Q8xPaIhBhPVj*=Af4=&ZGZ= zc;iXgyC~SQ)x7jA;l9*l`9zQ=T0YjXpZE`?LeF>@cT%O>aVolzY}WG9V$#dq>wXmZ zYmv-r*He{tb(qN9xe*3BuYDpDseGNP-2F*MhiT$RdHHU)gTc<-UPtCtD)0H~TkNZa zB~IOt9VG)_OR@OK4>igCI7)rpwDYQ;^^zb=Jx8lB&E320J5oRNBQ;5L@qNt?wqzpm z$zi3Pnl-b9W;u7(yGf8czIu?UX^dAhDDsMux~r0aR;S0tOI#y1eu6jqCyIVUThG|8 zwe8%ul4FjgtxdbfnMJ>!TFJ~+OP2&2IA4N)UzK*)7p#9mJEAmTUs_+;x-6Vu+uLQ# zeGhXhy#cef!OH#_T@~eG%nln=zOe5@ny747eo;y4#s90;RqCl?MfX`vRCbxDbS?F@ zY1apAmu*-3?+xtEA3|%}9+Wr72G#>MDE*Gzu|jKL|DOGZ-M0o+^%pavF{th`W-UW! z^!?*tAFYGkuXg_k2SQhU5>zhce;8XlFU$NIS{Hg!}lTJ=sucl6EsLF;w#? zO*;#9Bjhdw1YM=5TW=`o3m$hf&68B~HOaAe=<0FRO_DHqK=KZWXmxz$$7b0U_m5D- zEHoTN+uP!uGz$x|addQJte$b5^3_#Res%TWj3HH8Jn>`6({*F>|1gS!|B)ndzCqw` zzx?gUx~Rux2)LAyP57;@4(YnO%2S0Vk@m>7M>K8mE!lgND)FM$0o==IHB=R%fY*Ez za$nNt5j5Cae_o`4Fy8iT1%Cl~;F4U4j%d{FFlYtFJ)AK4tZHg)SIrFh4B3dr;gED<3>^FX_oZdQ8O>e$3b4! zDZ=JAmb!$o|GIahweopyL#N4#@)ME9E6c$~nno+1-oClm&I09kq*_^kr$1bQtt)Uf zd1VM(w&EwfFnzlXvdFjF#+OYr==2naaMCTijKZ3+S%Xcmiall9>;!6W+76qt8)&)g z6zYwC+qT8*=MFP75#Gx}Mt)Bn$Lzg$O`<4v6QX~@n^9EP)(+zJz}jV>;-qj3@vdq2 zL&K@h{ca`=#rL9;pKXCT%5-KO8HDR0s3p2cTZnSQI5rF~MuWmdMguMrtul#RDYAll zOVG7}%_-Oc(DQN@N!e*K^%k@O<>)NG=-hBu?!V^vKXLyei#bMT=d#!T8(ZE3b? z?+lH^F@@5%-QRhYq2#0y5A|Ca5BwyMQ6$A)sD>MnXYyw^qpk*_Fpv_=BY#WsZioAt&-($KKu}i02a*}$G^KC=;xUpX+$#)t z5T(Hul8#Y|k_L_2&w$MW%~t@ei2O^t`DX(?INMC{f?`07r5%;6T>$h(%-B>HY0kr-ouA=QY#Z$IiR+_C zU^38=YM&&v_aa6cqS{8t&ktz-KI)KZ4%df*G_j|Km$1+7pupi1SCfHt64#?`Hh|Z* zOWN5iKdVsS-nRRvg>?^pd*3p>)qzb%S8cDBl9`u#aCpV0ePb{6r%nEOA+5VelD#ai z7MGSRZxlxic%C0+-m#J280dyK8+8&2s*R>8GmnJyA2)%R)1N@3tBTK5N3{18R%-j=UwFs#nsrO^N$yDbvavFY@v_T{2DJG`Yvbz#^=WSLWj%`I)>q@*qWAH``Z) zpM4&fnhCG&2L*E23qVA12LRzm@LaatQp0utm+LssPqUfljqgs?CmK@|6ZI42nVQYc GjQtlvGl0eb diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_exceptions.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_exceptions.cpython-39.pyc deleted file mode 100644 index f307637146a206000276412cc448589df81a59e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4795 zcmb_g&2JmW72jDdDUtf3KO);f(r$sGFjI#~ztBKX1xv9T7)=;ga_g2=uo~_RrL~s3 z^vtd#5=t&IkaL0FVgvS3KySVFFWFnsQ_sEm5cl_HNs2UO8*Q_~4(ILeyqS6L_ul)B z_`*WP!u5}D*ZK0CW&M+c@ymg56Sw|58es_*S{>G8jQVzHcM8n{vp%szK{$^r;YjDC z&@4hOiW20KkxP(g#4O}lBhNrCiwfk5k!K;#iFwHLMlM5M5Q~r(ja-4eB&v|Bat`|E zAzu&|Azw7_7a(5}mmy!4i+H~T`7N;wdD*G4#xDlpCT?9tBdsPAR?`-&Sr9gq7P3nlD&CjTrqpq&e0f``SoI%Q zTwI$x&{DXEdopqp)eE9sH;LU;OP9N9@V%St@xGLczq!5cXaCtba@XkW~q5J zbPxAR{i(f@LFm#yLNg9L=?MEV``T(V6Ls^=;@6gAHA{eFF}tvl>fR(6|2Toe!`Mx@ z-p5W9a5X|Dup`{IiaWHiLj|u9=*SitI5~qWz~rY2Fog~32%Hl4DTI9T+VG-2?Y)3o zUqzExC)QIY*fIMCS>s9JnaLj%K8^m>^~l)KtjZ0ru8`K!bNh>!9`Z0!PVKCyQ=p5$ z8$?0kc{Mw8v<%y75tE#q9;?{ePderI7A$aNl&g!cyi>s z*Jc#o=&3hejm9fj-`lj}LFADKgz9!07sFRpZCvbVDHl}QlwJeBEsD{Z$a8`d`losC{1H>EFw1G#0=U0vmp zmqtkt4&yhEM}8D^(vBOYofeW|+;&?St;cgMAb%JndvTf=q>JHFk&9_jZCdUim;tqN zhaY)HM^;iYN!9;>`WyEUS!eSdBL5={@)=#;iK$fJi*}%N;`U4V($x}dU$fOk{HSZx z7}yyA8tf59e~5bo^(o`O5$Zvd7^o`>nX%+`25<`K@6jX!fEN`#nF7q406up+5}&to zFZO?XKCsV{5+9bg$#R*4JI`BWuRN2W8omzi?_jxv;vwEio?3nZ4{y>(YiNde{~h=b z75=6pi?Vdhk~5;PYROsQJZ6URIL-1vBEI7^E24}nSIHJ{54pxCDo(rozmA81;Rl^G zOoA@T{fLziQV-;S7UWDKh+LlM$z4)YuNXBe2VA*dCA}^%TOab6KW%U=N3(u0rgkOI z>I1$*aWOWf$|p+VUBshQMt}d^_g`~WvdY=`Q>G}B_~iWIMOlTi>c_bCPtgb_>_^tI z^}xDiov<%i!l-{jwV{BX{SCddpB9eUGdz3Zz=BR=N+qS|EmBE<-^GwG-uV*T?5UNo z#6D&xC^pCJLE!|&=Fj#+Qo=GQ%A5yr5Gh(z=D=o>a(be;FIylfAUk$u*FVe(*wYyL zDY~-CY8dFmk2~G9k7#1Te~H;I`tObGY`lvYLjv=>`f3>aJk)FG3Kk}XUGZnorkJVI&U#IlIkyhUHWN6m-SjF@@eGiBgi zydY0$dRbvk$+73{#gd}uKJJN&P)yep%_JWWXl7p49YZt8tEFu5PDFtaN~*_Pa0d}T zp3}aovM!InFT>srSZSW?zI&c9I3B^g#6AZVr6qAlL^L8I6=h0|;}g|o(2Q3wi6QC# zK5RLGcglt2S%Y~B!yy|Uv0%H=-?)dF5Uu6}2QqNpGQd`1&|iZD*N@Xspg5qDyFuja zfaUDKl+XUyBFEAs zE+5W9E=P13{f6$jIMm_^xLKQ{B)bPZ#QA%4J~v8+u72hD?&sL%XS7u+GdRnV{9oIn za-Uqhff};k|7gIEu=kyvKX_4m$b)2O$EB03Nepyw#hdFjJUq;yK?7e$gMNWU-5XmZ z$&K2DtURhHd6g`|WMCF~b}EnZnmM4GldL)5C^|J5Ca8!{sh?0o3CDmTn;UbdF^8h* k&dXle>}vl1h&2L?DG>8)zEGVpe@?Yhb*jtNx$4Y+0Q2Of=Kufz diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_fileio.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_fileio.cpython-39.pyc deleted file mode 100644 index 528c9b1ae757e96dfd3ed67b277657e132bbc953..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22410 zcmch9d2k%(b?5Y47#svZ5F$Z}$AE`KNEAf+&_TY`n%qH-}~Noy!XDD(yCQG34H$Z&-Rt>IG9NM7bc>gRY=^2 z$GIz+NT`Ies)>U6Zxt*_CksjZPgYa4bRliAELF|avW2X?r>lutSD{PZGu2$JyU<MX^T)UxgLv3wgZEam) zU2UW=0z6sORb5}(P}m^vx$2FzjfIU?!cNX^Qr#yq`kUaO2b4A!Hd~2$pQN^!l-;9$ zjC5}`UmGoq*0vV5*0vS4)wUP5qvoK!Bb_L0!!wF!Yhn9?3Du`oolB@y_C|Za?pvQY zn=agBkEp!8*1p;9vUg6U)+g*yd#Am|z8P;(IEGX|YVDj(qF!=+0_8W^x2#X7feYPg zP^~_fIcpVe1-8)^Y+GLkHqaDoLjg9mwFMWbxA0{6i{(u4tR)`s)XlzvTR^q$LQ;*W z_2<%sU3OY+P&dA4K`tBBCdg%zy-IC{R8r{4ZOGlCHY0cQ*<@kd?z(upJ$}i;7+FUW zW7}S(PECwiUbiZ_rE<08I7oEOm9$$aRq>j8wB*h_QaNFd4SLB#hrLxtpL+B_asNXH z_CI`R;z2L9ufE`A0gkxZTeZ(wsFx49wl291?dA5Ds@2kD)%Lm`wClF6l)ao3GRwTN zTKbWS<9fNnb8e+kFIBzV5&Pu4T`${S=IHz!s%9Rqqr^*>ORU#8W$S9Aq+W&IC&;+l zD7rJ+E-54o2anlKV_ui-vE-{MRC+aMYGw{rfPXCQ^&g(I>-Qs}7v9xSw%5n>QTvQ5 zss6`+i)`ONKQ(1*Z{SH?aqVVC8Q5Ar8KmyR<9yFbBq|{oq4tYbU!8S%s*4V=#PN)m8+<+Eq(PAT7Y=VlU3+o~| zTT~u7BlddaZLkNV)~MPl{N0G$ZRm-~-5%y{M9nTvDwOO1Z#S`|z}mz1CVPX(;$~3W zsm27)X2G+`?g~q82}?Gb7Jw)vPDtQZ;M~O;h0W?Ndy73FlqiMU)Hr&aw?}8UPFavc zPM*Ho)Jl~?;iqsC3#ALYJ>lOt*SgG2jzk+)8Y(bydD|TH~7xGYQ2TJbb8&i3A#?DVQs@2BnN_|==OjaA^6G-H1wmZ{MPJZX<8C%== z(y3BKW>~&amu3xJnWmCQ>5lC+Y~GURBoTb(bx-8ITB+M@Nhgx7)ZIo~GH898v%@cw zccKc~x_Z7|E`{ZeZJ+R~x^}hdzfM)>of*U9zG^k!K>u~v(-OL=DjL#;l;*HJ*$O?? zjrr-BPVqbQb8`*tIwFgfQ7bpg^R+X-;F{cCx~lG@cksddaCdFRN{L zUf0W9LW2+A`RvEz@a(Z2akoKDXfIip5I3;uec{gM=fDT8l&bIBPgR$AjX_;HX}z*?JW9 zIy%JVUpmx>7dNq#n6;LyvzY99D>BfVu4&sXxvtjRk-nVNJMd56Lcp#Wa5LV#-eS?O zS}fj!jDV#ZqAZ0qE?b5lYzX0p?|g)xEMCA3gga&}jvR&Fap{XK!648|?3*PDF1WVy%vj2(g&-S6%MRtgc5X8yxkvAf;qz_Cdo04|Kr5en-q?^fC8qa~c+6Nz z!Q&AQB8x(xq}PiHuRFl##InML;5`vmB03&6^vB7wCgYc=Yab<4Ygg4tHxH#Ng1ez6ImsIz664MVLuhygjsR~QiS*oO>mm@#dB;V1U zH!yL7V{z;Xdw?{Xbfbr!pxs!?%QmK_9NYD>umoT$n^8`oS@7X|2G1*aoDqQNezlam zl)BoE#lw2A$s9y`{UAZx^70V!PT`5!w%Gog_u~=)U`6}Q0ip7)jrK(@jRV=DTxmeU3 zN6pie-U;BPuxLR6#0J&3F((Im28V2SLGNa*Zh|)x+`-Zm7FIc6co{i6Xl~+WgYD-V zw=un$fV+jhkAMd-y@`OUiyk82AzEgo9^e}l)k`)Ucx(Rs>nM9OD z)P@IXy#-)B9*3;utn`-Q)L<%U4X1~4{i&hUaEg$B$V>7W!P^MlMw0o|+SEpr3y$%z zZZFNlvX_SVY_EG#+%>S<{9%ddmJ=Kk4+T9BM? zBK0gS3U{;xF_oehk1Pl~@xlecO)k;UOD?6B(o318>{8dIZY&HI?17w{TFRZJmoT~b zNiiP}LuC1qu~148pGb8fw1DB0(9`oZyAC6qrn`NnB$hiZYX|x+mMn}`rYGksRTqZq z-YGZ<_8zBrj{AuA8UuANd?v=yjq$!1kHN&4F$U!1=%tB7)MKpsHIGvsvWS!DuOQ#p zFnvQ-`btj{JCKaM=nQov`0$-(#eO`}f~Ka3&RTp)ME4}DJ9frC17~O8Tc9xFIv5B6 zUf5Di#4UnoX?t50K3U%nB@|w}$gmD^65^lqrd>^GIf@~EiM@qdq;L69=q@&%5qgA~ug8I{ zW%VX2Sv;@ck=4V6IZp+iO)03XO1_vjdm2qym6*qB>84fU`J|h1vu+m+e~!uJ)Wp%t z@UfOl*f))XdMqafrLRMEIEu6lBHqvuw=pMY8^a~MHhKyLdJO>&08oh?_*cLJbH+VY zsh@FO!Y=gqDdW6`J6mcR=k+SPUs8;HX^;&UI%3$KI76J3Dd@*y&f*= z8^PVE^oRU!RolcFP3N`g(RQ^%a^SM|b8b>M`wr_MCvahJL7lw9jwXG&Mcpd(M(qvY zg4lPd+azaeh-+NkE;-x696G4!_TP@29d_2oC5~$3-W1joXEkze_Ho~#?nIAw`aIsH z?nY|NPwiE2L+Tcc+-h|Xr15rjFVeR*$I_SbJJfy1-=+4c`!86CjICBFwI5FN2h@Rc z*}`r1xKHb#dQf=09W~gmhtwgo+wGUWQ$38-9#DIe$l?)De3zO)-kW`X4y#9zdW+D1 z>+BsW!5AHAy&E+jQ%6vCXGrU)dR%DT<-S78|eV!Py5zW?DH&Kcs$#at8L4I&~qfPOCErPaLw} zslH`DjFLyF0WI)d67gHOkX4K77bHG8f!g1;4=+=j8pPU5L2dONj7%(MsrMY~6(;C z1;N*c9ve+V5Dqv#4h+ApK7sP5eQjSYBlAh*e@eX!Z9k^I?{nhor;O1B^z_r}Gobv8 z`d#4UxLrivCG}b4y;uF7|mPa@dYufBrxSJl^$E~_7)hn-r`ufBdEqrRcO2^vbJu!a6m7W2}p*c9amu&?c~ z*kTdn;|k`r zE!cPAfaeNdh-WZD)~JDc1%cJP1Uh&G46rsF;fQhO1whgK`y3@f6!>L|F4`SQ$)DCX-|?X&n+UxS!UJtJos*L_M=%qbP)>wX_Vpr)*2^Z`4ncc%TKAn}9vFU1Ka>ag=&eg_1H?bfV1 zT{@xdsbZ0V?KC_OzPCGSo6~CKL+_NBo&!&K z1Md+NOROu}y8i=D;P_niC|ZY6=}zOd#YNDAhK&ARv@V4VBsEFW8#v{V6PR{!(Jzfk z|0_awz^5BDYO$DKD^WNa;Zj_NB7M>SCql8$rzkBt$kEu`&)Rf3vyZdZ%P`InX--~B zyqr|YPp5HmNlpC3+W8Y}432DA$Z|FTbsD{1uH+Qw8cyX*T=(fV)!4C%#s5nh99M*L z1KFFB4whI;SXx2s;6j$KWn@4H^FQGUDE9j@@Y`GyNpxkV!~=EIxj9E znjlUN(Z_7DXrC+=FZtd?eZu^vY7G+oPh{GXa4O@%7zL zTe+*kx1!(2?4}b$X6XBom%gplcwX>bjsa;7CNd&KqXV<2{SgqS%>1Wm4iT-tH%S}dtw z1F5%1NErdLdJCCA-Csd=skY0X81-q?iJHSxc`;lXFunGETY0K~kknW+k4)dU+&~PPogq5^&TUx?MS%j#%yv4Uj}(G`E1HfT}&g+o|w%* zyy5kmvE+pQ4C;<$H8&1@6aZIQ>DX&ic|^JyYix3W`wxhmw-3Wb)OnnJG}_*8`TM+} z>=+2rY?+2G?%U3$o70f@1LCLQ9GRh|;HAo^6-Fght~&bHncJorpGDqNAxlYE2J*F{ zaWrdTC=jABWbQ1%R+lTl65nm!vYiITXyo6l30dRKjGZT+LyPy42dW>AcxIlM1|3Ww z3L2G)j3UC!v*{=sA{AjIWA-s_+~x+WG3A?%(^!r^kLsleN5+(IHiAUylZcG>(@r<#24-Xi%Dm*Q_Y;9ZAw0Bdy4M@=ai1XfS@OkYCg~d$kqRxM3|3+hWw0k+%VbQ` zeGU=*1_&3rnGk{^18Cc%_tI&h~?^Q;A$ztRk%Av8eUhXvS126 z*jQ%14rZQoq1V_dk9YevX6vk04=*nwr#bMt<-~9BvK?hTpUwg4q}ih=Odh%6K+t_AtA0d zvUTtvWVVhDS2QQIM$A&5vQ->m{cW`UaD-+!p@UW(WZ%ey?gl#!z6S}%W8Bbu2h4mV z!i;gzhHb7ZD{z$tN5WWMz6)Mnitu7~_GY6NW;hh#aPXdOFdW#f;H+()y;8n;?ng{y zD-X`&m(i|$h5sJ%K1MDmb?!ln{;V+(7vnZ($lZJi0yV==uo*pw96x9Ru6UNkAw9~` z6e{@k*leRx$8lvwpJZO^zNo*CyiY_VV$?Hef?mk6dK9%fJZ+)QY(Qz#P;7qbD!PG3 zE`$07)8eL2FLS>a5(mXV@_LT;|%c$$%DZLG%p9#DTK!h<>ONc~r@ zApal^yTUvDFSy{$Yox`-33CLJ@kKsAeCL@%juD&j5|tS5`CjrbNv z##RX!J|D7`@=rI6b-x~}`VWAny~jlTr4V&mA7`CA0a`G3A%kYFj0Bl$9|_*LzLfQ^ ztY+cv$TnwIySqb^rn$D;brm_}Su;i$UnR$)D#^{(_0?;+AP}q9e+XuNClpm+ic0+s z7E-7y!lF6T6jor0250n+Dc;k(eGtn7aegPlgISH6jbPL_b#oMz%j6{Z@IBnf&7=>$ zmdcCsffcbVck-3EB7^auvjfN?#M(ybk5Kyk2%}~T6Gqv-MPRRgh1M^V_&I_$x-9rX zgs$1gBQBE;%2Xp6s_l5;Q1N7g9U>ik5f*z_%cW~$iAJtj8$U=|Zq?>Zn5HX_vD)pi-X0CN(Y5eqz{?}-6RL=kgJ}~iDfMeW%Lxf4R zBJ`~Uvxu$qC4x3>{x`_`o2G^g2FD&BU5nJoIiLM_UYi#sBX?2c?4`emR_)aP6nTH& zqz>1K*~+C^%RE9Qq5TSJw=OKflDG06t$BATcE$U*K>6><1Xl_8x_lN`ALG~~HwTPU zU=-yo5@CyQxr=w9hy^24Cf%?kh{|Q z)!d7sYO})X)#H1$;X@DlMBemY5VVcTUn1|nvrjTAN%3cyeYA<>)o-B!Fv&UfheR?8 zu>58kIJsm2PDMAlZy|CK^DwZr~*YgNh)RQJyVfMWClbn||H~qZT{2h~t zhI=Sj`zFY=bT^2H3er1nY`$Vpcou5#&Vniqtw7 z5zX^&Iu`3Qy9;r0yMj5PjpJa;St0!CirxqF>*>Xkm5C~Cl%Aa7+%{{slp zf(!J}9Ijd#dujgo+VWh99&!V0YGKp*UH0JF8@VnTF!+z`eH()w@{$;yHU{~#PUcSB zSVl{`<{`Ohz;U?^K3Tl*Ig7_JTZghPST7`AuwF>Mka{6KB@6GlzGpKo2R;*Qb8-+c zS0)2o{12hYG~|KMxgX$sn%4=Hb>2FkJddxYy_o*x4bS4JaWQ!w%JU@Vt%CiV#t+|F z@aXSJIB(evBqoMvmK4MfJ?k{qj@G^)L$<0Ch{*SyaVp8<{c?QIcd(jB@n*bv1NM`4D?)1Bf{Zk9IhU$iv?6OR!w2U?;?I1LGO>dF@eS%?v8wmyowh)LGb92>yNWj%Y{}BQ0 zJpCg8{Hmk>Egk*G%=;4po}2Zb67cw_c@EP&%ILo&_-lf{CHOmnzbD|*rn!9R9}~!o zXo8!WM_I6A&VK{IxBcIg#`pRA!@t3F_$R*t!0-C=*8qZNIPxyP5+LdRG%*aOM!H7Q zs4J;qz>V1;)udqFhSDRbKbXQ|a3zcHa`&Mf-}|hgEB)r(O8ksh0s4N{pD`uWp*Q^XP2AzZ+{J8SXy3(DaLly;P9$8sU6{k6#rz&bmN>fzcvdl* z*u%G8f{#}z_dwMbN;3b7K1C{pCw?k1{ZN4C={sGQ2Z zFTkNaBJmcyMQ(^wUx5Q+ob5uHXeJ(eem-YHCzCM(`SE*BFEK(ty>nMWaCSlMLogh1 zEK!X!j1dobD1$o8LW~6F5g&aCc+Bs8jk3pUiEi*jr(BYnZr!E`E1& zk18hQg6T#ara_;W+kiec!nH;*AGj7@DgpftYIngnbb&4(e8T7W3ST3P&e2tHjSc|t zC3x@Q9ia$a0Gzu21lgyLVb?z&Ksg4y;N!P30ojw<3PKg3p0YGr>DH1p45{FNumM#H zPOQhBj)%;BU8yB;Wn~HTMJ%kvzs$4BmAZB0j8@JEYN(_-2v^J70<(r1TK~`+*;iyX!29)Xf0n=LN~cwBsN%ZL7p&A;<_E7{ z%nQp5ZG_3Er$U|PudAcnR!%%>C_AA`VROK&^iILF5j(~DOW0}C_1mka#j%D-9=B3< zzPXLTpp674*lfZo9rYnSV#W_Giwj5Xi5=jF(}D1g@&8|+JgYTtrFia#Zv92K@K*Q- DN>{I| diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_signals.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_signals.cpython-39.pyc deleted file mode 100644 index 37031f8db6c6b4bc739288e4465bb15b2b185252..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_streams.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_streams.cpython-39.pyc deleted file mode 100644 index ae5f325a0ce3ddfe8a69c69bafd4530c7231713e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1514 zcmZWp&2Hm15GJV~%TDZVw~Mwxb0CTyA|TD4dNGQki`_j0ZL>uk>_IT#(9+n}MwASS za_bCB5>m}43k}s91gJK0HD^&7U;EB+w z4}Jh$nDvY4D~Rn+5JS3xku{)n{qfzc5#-5s{ge0B8{3gp7Ha=|a%w@N*9ThtGMQGh z8JJ0#UP0YWabsc$i*LYICXWfgu942MKgC|UC=xbeZ}{0877DYEbJHjB!A|^h{%kn@ zalNobJ~k>(3Oydhi=xQJr{6t)GAU!DmSDywE67*l@6+kH#QVQos`ygPp&YAxofeNL zabe)`q--K6PnPTYvls)nFwsp;CPkB!tpV|;Y%sg#A?iC|1Jq-}zH6laFBbCvR~!5x zZv%Q4i}{eY$R#P;E8feFgX`3r>^wu|npyUWUpnT{3e=sAC=ach@D2ZsUn6NRnK{O} zLv!n0vkm`MSpQmVxb2Xf2_%iHP7!8LVtd+zEtPBomu=v(&CE%!u^BFvQCi-6*rCiT zJq06+nWQH!v677dky zA!Zt?S%W`TW_%RUU{_Qvp&A@5q6XU@+SJ|*|3kJR{vA9`Sx_O=!PmM-stmrNtIID? e1pH7uaso#nvWGVVUkLWE;DYyV1|8D&QTq>P5{EYc diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_subprocesses.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_subprocesses.cpython-39.pyc deleted file mode 100644 index 41ee4551ecc7c2762e53924f802a53420911dbbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4110 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 C1t*69 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_tasks.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_tasks.cpython-39.pyc deleted file mode 100644 index d8cbfbde63bed3c9013d3478e4ca7a465a68bbc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6256 zcmc&&NpmE{6|SupwYsI&G8$S%?X6Lm&}E6mpbGm8t2{)Y8tX z9*q=&12ZQ_aPq;IIlzI#{0RREj&*bR#L+(bfc?G9u2!`cVj{rdimvS3^W|H<_g;Ce zRzt({_is16x0W^SAJiy66*S(&n`*kIF^%b==Fq

XG3XI@Qh4j4a2BDo#bVt*{!^ zoEqvCRt@XXj58B8oCex8Ru5;RrqhgCPAi&o=49VYI3Km0wywRcu?Cxcq_J7vcxXBc zeBq(yETXr`TIg+Y{I6*kSz>c+{;|%N`4VeCHrN7Nd{lKVVdfHB#>{2j#H-qP#4u`yB@fFTMA+NJhiF zLDkL7%SP!pV5-(J^Jj1Jq2Rukakh~j#{P{Y&iI4u4_@rusB7Nknd{L`VX*5H&E>~J<4wHjb11mx=uC4AR^cYonE`H^%mOzodE;un=-#;- zCxWvRvinbrymH?QM?9|zo{dE8(>05S>U6OicvCuzX`9*;z5hhRIxFSjo@k?2EEUDS zKe*Z3e*bWgCGocKVwObPoBkk4!tFcn+}dzcUwA_)Y=5*3m>{piZsyL89XI(olT$?L8gdl7ftyy3c0 z!bTz0o38t(kr$3fs>$v?_cL+1AphhdVukwVP|Oym)^*uFBZP@zeT|tDA?S|Dt^Epv z5FQ)6%4;w$3yKRvf`Zri468vw>ud%p+2FIhD%)f<)p`^V)oYFY=`|4FkA*?Zd-m3V+gT8C`rKnSnhZm%3d$X%&Tgbjw#6K#Pd`vpzz61=phX?@shnr!yyyNw1?Wherz1; zO#j>fSB-whP>X3B)LZxy>r^*$(+|_q_7n4xTAA0N+Wf$EpTXq99+pZX>W;^s=+lH@ zy0qqrMc2`hX`g{4BIxKjwZ{~%qlmLWO0e61qUTHfB)bz0LmqM98oMP#B5=$lY;?+Y z@~RRN-A)l{94(fKRKpXlVcK^R_ZKM&QoZl3CS(1RY8-?iY3t6;9s%yPt3kYXwF7Ml z_Ut&3+L(+od*G#*1vN~0R$AQ`Kcb8OgoWXxD)vR zb;Tl`BF}?&Kli+sC+8VY&DNJD_JJGsBAyL;J4!M;C$}c!;;eh|b@P^5JWP(}$rxY(9Ug8OI?gxvN{0Hs*|vJE&pAfR1X}euk;yB`QeC zPZ=Bedj25DT=zBxmBpFU7FSH@tcX?GV2z3^C{3|5)5){7lDg- zfu>RrAbv{o>q7x2B(g(k;_wDM19!w#njn3_HL96Z(Eak(TVBdaG#l0NR(EP&-^;o+F%qcJ_$^vK-l=C2RlbkzBC4do9#I@(NG>oB8bcl#DmXWyVm7K9rIhI6#KgO~7rTK|P?R`V6XXa=6u{HMR&?!lp z1O$SRyt#z{7|umTR-MXu=qEEZ0P87!N>tg!9w~(ln%UL?AjZ*mFjQe?ztcR0i4s)A z>)1r`%%mD!R*(}@5cUhIU5I0^Vf16XDWz<6ea@WV6^$UktuP*XhYBzyT#*2ahmN9G z^72=x0G{-bE>ef2X=sj1ag{&M0uqi_I?mV zqsT_glpG)+Q5g+Zq#Vbyw1Y@;4+*Y37T_V%5x7X@AYQf;foQa!#42Ygzz$fHQtl*Y z)0WT?IX2Fs{zrIxieECpJEX*l*ri}X1yPC?xWyq7xq^?MqKO-Jrx9jn`{T(3necbL zUB6pG-kt3~D)8@%XCeJgRpKjPX(R*;(535(S1=+d&{Wzg^~w?y{V1)H$=P|Z)7S&> zxgH^3h}mfsg*Lmcw{@|B+7#ZI=$L3CMIKMDiR4VZn`bppI-zmkc@Sg+@Uch-AY0_m z{J{|J3;ZPtrMT}R28}Tb7W4fyjtsugxWW{6Db=3Rx{1mmWB&hWU5Q6iicnFG_Du-l zl>Cv6pA!8^cqM&sD@yKjH;I+tkFkUDzm0WWyhZ!Hh{DG^^^p8;;7wHukB~|G!uXPc zCQ9M;qklsk$O=A69*Q^;j+b~Hs9Mrm_i8#@IZ|#4Y%pjS0U~Y)t?7OADQN9*y~eFTI8Q{OHO}|B9(9KBl}hAX8@ z!d042-y@x+t&Poh+|8|xtq(WdJ8$>j`{3411%lEkQ#2_E4#m%@AWTylE*VYqpL^~4 p>*^!v?*UordvaZG0u-A@TVK|jX1h`~mtR|%Z!fI2SLfzh{{_6C->U!s diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_testing.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_testing.cpython-39.pyc deleted file mode 100644 index 5d89db80d3f16f362521234e54c1a3a5fcc1be5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2787 zcmZuzTW=gS6t?HKm+WpX4J}0l4TwueDqAGrC8DTRi`s~4K}`kHvdD7A-e!{7nXT<@ zm1xUL`pPe8E5T!b2miuvh^PLAN+8bh>?WIwqdBpCe08?KH&_>@10vTeU?8RxQ!mBFXX_&`J{DHg1=yoS3YT zwsBV$QgKr%TmNBfva;a$8;Zv~d+ClGE17a5#jU42GkiOj_cLwmDtpRR!NiOWLJ764 zN768^_lq>owo}x!I6_$5gilX_NYbZ*^gTiQzVP}1SRcvoG67lxS{MGyKm;NL%Nw#O zmqhf^6E#ssPh=<>;CJO^Th`pFCECF2$Ys$16p+6xR$ylZFviuYScBE7xBw`u+xkPU z_cn`R$v45%W(?y2x}s%abj*v`d9kC)qMYd1z~OGwo!ZEra202Ti8HYgn;jWXitO=3 z!V*NYVJ1~v4jluf7G%a;!3j1OJA1x5;FMj9vmscqUx|Z8vp<&c!VU8{{Q{Q!x}ZcG z6&HLYE7OG3smfeP7mbRqR<|b$g1@C@p34-Yue*FZ?H=VvoI<8l_ukM#`*O`$T3iMHTyl?A_ zWkqHfTSrI`Izj`wP9yhsusToY?))6oZdgKkDjO+jCaOq16q*g39|8OxEDV`aLk~T5 zaY}Z*Dc$wfB9*EE=N%5V(<{y9Xq?LtWVRHEr!FAxT_gxb zMJ~e3MvTeFj9r1b#_$r_q%H4YdBJexzozOkFjH(l^MP|T*kuC-2#h7W^pI{5g|>sM z!4B6u&L+6P*>Fld;D<*T`v?TIgMywwt>T{1i>5lgAHW2(f?k({0MZLjK;G^8@ZWzG zLB0jOgWzf=ZXDFExf;CjmL>pQgRwN{T0^dZ6|+2Z72uLThKo;w1?LoWBgQ@f=6Tju z+{EwoTr|#@jSi+Li)dJ=QqJ3hZ1rCfVV-Lw6^iS+c^x!AgDj&G2bPvU>H=TH9s-oS9 zd5p1k?-Ix6Ja4&+GS$lj)mI0d3hg}C6J&e|Uj=o|9Xw$+#t$KMW~1|lRAxUT22$Nn zL4Sv?ka!2hq6<9E;THiKrY1!J4a+&A;gLMyorIQW;=C-!^QZLK$N2>Yx--ZP%h>~? zXRc9&eJ}ByhjtYk`b-x?5v{OJ;Ri@qt&Zd9Lf8f74fv{Tt~IH`o!$xGVZ$|*Wl3@jk$49xccrl rnZq0*uTsNxZkHbjfV=QK&9?qc^*nxy8R2@!y0=1Ge&<@JxwiB_Bh-pb diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_typedattr.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/__pycache__/_typedattr.cpython-39.pyc deleted file mode 100644 index d3a013d9a50aa5ee61cf7d918ec9cef63968750e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3227 zcmaJ@ZI9c=5#C+Ch|)>A7heJxFj}I`i`6=^Q4~dRaEe^cL6Igs7_pNg#1+hnyE@Uw z7kQUFM}p!HkIQDw3R1RY8wd9)>*Ge_NrFJ1Vu8+0kjy5^}@KS@`#mNe+YzX$)@a%V|`UCBiIITanT z^~?_T{y;=m^qvvXTe9F9JoUvkJZ;0%zMv1tVCNN}B*%kRWgTX-$~)po!bgd$?0a!k zRINYp=`_wxtJcHWRDR7><$RUJc~*J(xl~Ec#VZQm4`_8A7l^~6Q1PfNJ`8bj)qWV>lVe^c#Y{XdUpy}h$O0-QCQIvkTF?bq(tG4D?|sh}>;)6-C#v@sY(dYd+Al0&E!f|fu>Wo? z=@0breqk@k3+E>S6@+==99P?6xB;QVu%h9-gV|_0aRI(w#tq?Y zol5Wl^3xKrsye#hs?bm3Vgd;Zi%nuzj>gzlyI~k-aS^V95rzY+vZ6#+TNhwd9_q_@ zDk0I^VQAtOhIIz+Lk!fHvi?7tsP#q=vH1BqIPh%6NYIn$^^&V zFnnC{q?u`jp~xe!ingj=gCdeivO;1C;ui?VV0s%yn57!C(xbMk@XeK+#k%|$Zv7O* z#hjJ4bfha=r$oAAcAelY7!VYY-7_0#%ad)GcZKtu2_Q7{u4CS9$u7)nnJ>KOmT0eM zd$K>K5(rQ32%PD_j03uW^dJGc)!UZ?c3=a*aODqNEf+qj6?*)X3m@<zt&xYG%d3!p^^00RT7W=EN>iv&NI%z<+>Sz ze`{D91B%BQXz8grR17cUx^S>M@If(#NK3Awi9hCXf=3-t4(1wsjoBw$uk~YqO&~Y% zo?km$w?|-&8shQ5R=n0*z^00o{u+>TfZ+XEAyMZiVxMw<=4|bmbN^Jn7aNjd|qq8WOg*+A^Z4wnF(` zB&X)kWa3bDf$B7zc;FxaseyPdJtRJ>O1|N{{j68N@oB7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_compat.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_compat.py deleted file mode 100644 index 0320ae9d..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_compat.py +++ /dev/null @@ -1,175 +0,0 @@ -from abc import ABCMeta, abstractmethod -from contextlib import AbstractContextManager -from types import TracebackType -from typing import ( - TYPE_CHECKING, AsyncContextManager, Callable, ContextManager, Generator, Generic, Iterable, - List, Optional, Tuple, Type, TypeVar, Union, overload) -from warnings import warn - -if TYPE_CHECKING: - from ._testing import TaskInfo -else: - TaskInfo = object - -T = TypeVar('T') -AnyDeprecatedAwaitable = Union['DeprecatedAwaitable', 'DeprecatedAwaitableFloat', - 'DeprecatedAwaitableList', TaskInfo] - - -@overload -async def maybe_async(__obj: TaskInfo) -> TaskInfo: - ... - - -@overload -async def maybe_async(__obj: 'DeprecatedAwaitableFloat') -> float: - ... - - -@overload -async def maybe_async(__obj: 'DeprecatedAwaitableList[T]') -> List[T]: - ... - - -@overload -async def maybe_async(__obj: 'DeprecatedAwaitable') -> None: - ... - - -async def maybe_async(__obj: AnyDeprecatedAwaitable) -> Union[TaskInfo, float, list, None]: - """ - Await on the given object if necessary. - - This function is intended to bridge the gap between AnyIO 2.x and 3.x where some functions and - methods were converted from coroutine functions into regular functions. - - Do **not** try to use this for any other purpose! - - :return: the result of awaiting on the object if coroutine, or the object itself otherwise - - .. versionadded:: 2.2 - - """ - return __obj._unwrap() - - -class _ContextManagerWrapper: - def __init__(self, cm: ContextManager[T]): - self._cm = cm - - async def __aenter__(self) -> T: - return self._cm.__enter__() - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - return self._cm.__exit__(exc_type, exc_val, exc_tb) - - -def maybe_async_cm(cm: Union[ContextManager[T], AsyncContextManager[T]]) -> AsyncContextManager[T]: - """ - Wrap a regular context manager as an async one if necessary. - - This function is intended to bridge the gap between AnyIO 2.x and 3.x where some functions and - methods were changed to return regular context managers instead of async ones. - - :param cm: a regular or async context manager - :return: an async context manager - - .. versionadded:: 2.2 - - """ - if not isinstance(cm, AbstractContextManager): - raise TypeError('Given object is not an context manager') - - return _ContextManagerWrapper(cm) - - -def _warn_deprecation(awaitable: AnyDeprecatedAwaitable, stacklevel: int = 1) -> None: - warn(f'Awaiting on {awaitable._name}() is deprecated. Use "await ' - f'anyio.maybe_async({awaitable._name}(...)) if you have to support both AnyIO 2.x ' - f'and 3.x, or just remove the "await" if you are completely migrating to AnyIO 3+.', - DeprecationWarning, stacklevel=stacklevel + 1) - - -class DeprecatedAwaitable: - def __init__(self, func: Callable[..., 'DeprecatedAwaitable']): - self._name = f'{func.__module__}.{func.__qualname__}' - - def __await__(self) -> Generator[None, None, None]: - _warn_deprecation(self) - if False: - yield - - def __reduce__(self) -> Tuple[Type[None], Tuple]: - return type(None), () - - def _unwrap(self) -> None: - return None - - -class DeprecatedAwaitableFloat(float): - def __new__( - cls, x: float, func: Callable[..., 'DeprecatedAwaitableFloat'] - ) -> 'DeprecatedAwaitableFloat': - return super().__new__(cls, x) - - def __init__(self, x: float, func: Callable[..., 'DeprecatedAwaitableFloat']): - self._name = f'{func.__module__}.{func.__qualname__}' - - def __await__(self) -> Generator[None, None, float]: - _warn_deprecation(self) - if False: - yield - - return float(self) - - def __reduce__(self) -> Tuple[Type[float], Tuple[float]]: - return float, (float(self),) - - def _unwrap(self) -> float: - return float(self) - - -class DeprecatedAwaitableList(List[T]): - def __init__(self, iterable: Iterable[T] = (), *, - func: Callable[..., 'DeprecatedAwaitableList']): - super().__init__(iterable) - self._name = f'{func.__module__}.{func.__qualname__}' - - def __await__(self) -> Generator[None, None, List[T]]: - _warn_deprecation(self) - if False: - yield - - return list(self) - - def __reduce__(self) -> Tuple[Type[list], Tuple[List[T]]]: - return list, (list(self),) - - def _unwrap(self) -> List[T]: - return list(self) - - -class DeprecatedAsyncContextManager(Generic[T], metaclass=ABCMeta): - @abstractmethod - def __enter__(self) -> T: - pass - - @abstractmethod - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - pass - - async def __aenter__(self) -> T: - warn(f'Using {self.__class__.__name__} as an async context manager has been deprecated. ' - f'Use "async with anyio.maybe_async_cm(yourcontextmanager) as foo:" if you have to ' - f'support both AnyIO 2.x and 3.x, or just remove the "async" from "async with" if ' - f'you are completely migrating to AnyIO 3+.', DeprecationWarning) - return self.__enter__() - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - return self.__exit__(exc_type, exc_val, exc_tb) diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_eventloop.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_eventloop.py deleted file mode 100644 index f2364a3b..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_eventloop.py +++ /dev/null @@ -1,142 +0,0 @@ -import math -import sys -import threading -from contextlib import contextmanager -from importlib import import_module -from typing import Any, Callable, Coroutine, Dict, Generator, Optional, Tuple, Type, TypeVar - -import sniffio - -# This must be updated when new backends are introduced -from ._compat import DeprecatedAwaitableFloat - -BACKENDS = 'asyncio', 'trio' - -T_Retval = TypeVar('T_Retval') -threadlocals = threading.local() - - -def run(func: Callable[..., Coroutine[Any, Any, T_Retval]], *args: object, - backend: str = 'asyncio', backend_options: Optional[Dict[str, Any]] = None) -> T_Retval: - """ - Run the given coroutine function in an asynchronous event loop. - - The current thread must not be already running an event loop. - - :param func: a coroutine function - :param args: positional arguments to ``func`` - :param backend: name of the asynchronous event loop implementation – currently either - ``asyncio`` or ``trio`` - :param backend_options: keyword arguments to call the backend ``run()`` implementation with - (documented :ref:`here `) - :return: the return value of the coroutine function - :raises RuntimeError: if an asynchronous event loop is already running in this thread - :raises LookupError: if the named backend is not found - - """ - try: - asynclib_name = sniffio.current_async_library() - except sniffio.AsyncLibraryNotFoundError: - pass - else: - raise RuntimeError(f'Already running {asynclib_name} in this thread') - - try: - asynclib = import_module(f'..._backends._{backend}', package=__name__) - except ImportError as exc: - raise LookupError(f'No such backend: {backend}') from exc - - token = None - if sniffio.current_async_library_cvar.get(None) is None: - # Since we're in control of the event loop, we can cache the name of the async library - token = sniffio.current_async_library_cvar.set(backend) - - try: - backend_options = backend_options or {} - return asynclib.run(func, *args, **backend_options) # type: ignore - finally: - if token: - sniffio.current_async_library_cvar.reset(token) - - -async def sleep(delay: float) -> None: - """ - Pause the current task for the specified duration. - - :param delay: the duration, in seconds - - """ - return await get_asynclib().sleep(delay) - - -async def sleep_forever() -> None: - """ - Pause the current task until it's cancelled. - - This is a shortcut for ``sleep(math.inf)``. - - .. versionadded:: 3.1 - - """ - await sleep(math.inf) - - -async def sleep_until(deadline: float) -> None: - """ - Pause the current task until the given time. - - :param deadline: the absolute time to wake up at (according to the internal monotonic clock of - the event loop) - - .. versionadded:: 3.1 - - """ - now = current_time() - await sleep(max(deadline - now, 0)) - - -def current_time() -> DeprecatedAwaitableFloat: - """ - Return the current value of the event loop's internal clock. - - :return: the clock value (seconds) - - """ - return DeprecatedAwaitableFloat(get_asynclib().current_time(), current_time) - - -def get_all_backends() -> Tuple[str, ...]: - """Return a tuple of the names of all built-in backends.""" - return BACKENDS - - -def get_cancelled_exc_class() -> Type[BaseException]: - """Return the current async library's cancellation exception class.""" - return get_asynclib().CancelledError - - -# -# Private API -# - -@contextmanager -def claim_worker_thread(backend: str) -> Generator[Any, None, None]: - module = sys.modules['anyio._backends._' + backend] - threadlocals.current_async_module = module - token = sniffio.current_async_library_cvar.set(backend) - try: - yield - finally: - sniffio.current_async_library_cvar.reset(token) - del threadlocals.current_async_module - - -def get_asynclib(asynclib_name: Optional[str] = None) -> Any: - if asynclib_name is None: - asynclib_name = sniffio.current_async_library() - - modulename = 'anyio._backends._' + asynclib_name - try: - return sys.modules[modulename] - except KeyError: - return import_module(modulename) diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_exceptions.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_exceptions.py deleted file mode 100644 index f7d020c4..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_exceptions.py +++ /dev/null @@ -1,85 +0,0 @@ -from traceback import format_exception -from typing import Sequence - - -class BrokenResourceError(Exception): - """ - Raised when trying to use a resource that has been rendered unusuable due to external causes - (e.g. a send stream whose peer has disconnected). - """ - - -class BrokenWorkerProcess(Exception): - """ - Raised by :func:`run_sync_in_process` if the worker process terminates abruptly or otherwise - misbehaves. - """ - - -class BusyResourceError(Exception): - """Raised when two tasks are trying to read from or write to the same resource concurrently.""" - - def __init__(self, action: str): - super().__init__(f'Another task is already {action} this resource') - - -class ClosedResourceError(Exception): - """Raised when trying to use a resource that has been closed.""" - - -class DelimiterNotFound(Exception): - """ - Raised during :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the - maximum number of bytes has been read without the delimiter being found. - """ - - def __init__(self, max_bytes: int) -> None: - super().__init__(f'The delimiter was not found among the first {max_bytes} bytes') - - -class EndOfStream(Exception): - """Raised when trying to read from a stream that has been closed from the other end.""" - - -class ExceptionGroup(BaseException): - """ - Raised when multiple exceptions have been raised in a task group. - - :var ~typing.Sequence[BaseException] exceptions: the sequence of exceptions raised together - """ - - SEPARATOR = '----------------------------\n' - - exceptions: Sequence[BaseException] - - def __str__(self) -> str: - tracebacks = [''.join(format_exception(type(exc), exc, exc.__traceback__)) - for exc in self.exceptions] - return f'{len(self.exceptions)} exceptions were raised in the task group:\n' \ - f'{self.SEPARATOR}{self.SEPARATOR.join(tracebacks)}' - - def __repr__(self) -> str: - exception_reprs = ', '.join(repr(exc) for exc in self.exceptions) - return f'<{self.__class__.__name__}: {exception_reprs}>' - - -class IncompleteRead(Exception): - """ - Raised during :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_exactly` or - :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the - connection is closed before the requested amount of bytes has been read. - """ - - def __init__(self) -> None: - super().__init__('The stream was closed before the read operation could be completed') - - -class TypedAttributeLookupError(LookupError): - """ - Raised by :meth:`~anyio.TypedAttributeProvider.extra` when the given typed attribute is not - found and no default value has been given. - """ - - -class WouldBlock(Exception): - """Raised by ``X_nowait`` functions if ``X()`` would block.""" diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_fileio.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_fileio.py deleted file mode 100644 index 6f8f3f42..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_fileio.py +++ /dev/null @@ -1,527 +0,0 @@ -import os -import pathlib -import sys -from dataclasses import dataclass -from functools import partial -from os import PathLike -from typing import ( - IO, TYPE_CHECKING, Any, AnyStr, AsyncIterator, Callable, Generic, Iterable, Iterator, List, - Optional, Sequence, Tuple, Union, cast, overload) - -from .. import to_thread -from ..abc import AsyncResource - -if sys.version_info >= (3, 8): - from typing import Final -else: - from typing_extensions import Final - -if TYPE_CHECKING: - from _typeshed import OpenBinaryMode, OpenTextMode, ReadableBuffer, WriteableBuffer -else: - ReadableBuffer = OpenBinaryMode = OpenTextMode = WriteableBuffer = object - - -class AsyncFile(AsyncResource, Generic[AnyStr]): - """ - An asynchronous file object. - - This class wraps a standard file object and provides async friendly versions of the following - blocking methods (where available on the original file object): - - * read - * read1 - * readline - * readlines - * readinto - * readinto1 - * write - * writelines - * truncate - * seek - * tell - * flush - - All other methods are directly passed through. - - This class supports the asynchronous context manager protocol which closes the underlying file - at the end of the context block. - - This class also supports asynchronous iteration:: - - async with await open_file(...) as f: - async for line in f: - print(line) - """ - - def __init__(self, fp: IO[AnyStr]) -> None: - self._fp: Any = fp - - def __getattr__(self, name: str) -> object: - return getattr(self._fp, name) - - @property - def wrapped(self) -> IO[AnyStr]: - """The wrapped file object.""" - return self._fp - - async def __aiter__(self) -> AsyncIterator[AnyStr]: - while True: - line = await self.readline() - if line: - yield line - else: - break - - async def aclose(self) -> None: - return await to_thread.run_sync(self._fp.close) - - async def read(self, size: int = -1) -> AnyStr: - return await to_thread.run_sync(self._fp.read, size) - - async def read1(self: 'AsyncFile[bytes]', size: int = -1) -> bytes: - return await to_thread.run_sync(self._fp.read1, size) - - async def readline(self) -> AnyStr: - return await to_thread.run_sync(self._fp.readline) - - async def readlines(self) -> List[AnyStr]: - return await to_thread.run_sync(self._fp.readlines) - - async def readinto(self: 'AsyncFile[bytes]', b: WriteableBuffer) -> bytes: - return await to_thread.run_sync(self._fp.readinto, b) - - async def readinto1(self: 'AsyncFile[bytes]', b: WriteableBuffer) -> bytes: - return await to_thread.run_sync(self._fp.readinto1, b) - - @overload - async def write(self: 'AsyncFile[bytes]', b: ReadableBuffer) -> int: ... - - @overload - async def write(self: 'AsyncFile[str]', b: str) -> int: ... - - async def write(self, b: Union[ReadableBuffer, str]) -> int: - return await to_thread.run_sync(self._fp.write, b) - - @overload - async def writelines(self: 'AsyncFile[bytes]', lines: Iterable[ReadableBuffer]) -> None: ... - - @overload - async def writelines(self: 'AsyncFile[str]', lines: Iterable[str]) -> None: ... - - async def writelines(self, lines: Union[Iterable[ReadableBuffer], Iterable[str]]) -> None: - return await to_thread.run_sync(self._fp.writelines, lines) - - async def truncate(self, size: Optional[int] = None) -> int: - return await to_thread.run_sync(self._fp.truncate, size) - - async def seek(self, offset: int, whence: Optional[int] = os.SEEK_SET) -> int: - return await to_thread.run_sync(self._fp.seek, offset, whence) - - async def tell(self) -> int: - return await to_thread.run_sync(self._fp.tell) - - async def flush(self) -> None: - return await to_thread.run_sync(self._fp.flush) - - -@overload -async def open_file(file: Union[str, PathLike, int], mode: OpenBinaryMode, - buffering: int = ..., encoding: Optional[str] = ..., - errors: Optional[str] = ..., newline: Optional[str] = ..., closefd: bool = ..., - opener: Optional[Callable[[str, int], int]] = ...) -> AsyncFile[bytes]: - ... - - -@overload -async def open_file(file: Union[str, PathLike, int], mode: OpenTextMode = ..., - buffering: int = ..., encoding: Optional[str] = ..., - errors: Optional[str] = ..., newline: Optional[str] = ..., closefd: bool = ..., - opener: Optional[Callable[[str, int], int]] = ...) -> AsyncFile[str]: - ... - - -async def open_file(file: Union[str, PathLike, int], mode: str = 'r', buffering: int = -1, - encoding: Optional[str] = None, errors: Optional[str] = None, - newline: Optional[str] = None, closefd: bool = True, - opener: Optional[Callable[[str, int], int]] = None) -> AsyncFile: - """ - Open a file asynchronously. - - The arguments are exactly the same as for the builtin :func:`open`. - - :return: an asynchronous file object - - """ - fp = await to_thread.run_sync(open, file, mode, buffering, encoding, errors, newline, - closefd, opener) - return AsyncFile(fp) - - -def wrap_file(file: IO[AnyStr]) -> AsyncFile[AnyStr]: - """ - Wrap an existing file as an asynchronous file. - - :param file: an existing file-like object - :return: an asynchronous file object - - """ - return AsyncFile(file) - - -@dataclass(eq=False) -class _PathIterator(AsyncIterator['Path']): - iterator: Iterator[PathLike] - - async def __anext__(self) -> 'Path': - nextval = await to_thread.run_sync(next, self.iterator, None, cancellable=True) - if nextval is None: - raise StopAsyncIteration from None - - return Path(cast(PathLike, nextval)) - - -class Path: - """ - An asynchronous version of :class:`pathlib.Path`. - - This class cannot be substituted for :class:`pathlib.Path` or :class:`pathlib.PurePath`, but - it is compatible with the :class:`os.PathLike` interface. - - It implements the Python 3.10 version of :class:`pathlib.Path` interface, except for the - deprecated :meth:`~pathlib.Path.link_to` method. - - Any methods that do disk I/O need to be awaited on. These methods are: - - * :meth:`~pathlib.Path.absolute` - * :meth:`~pathlib.Path.chmod` - * :meth:`~pathlib.Path.cwd` - * :meth:`~pathlib.Path.exists` - * :meth:`~pathlib.Path.expanduser` - * :meth:`~pathlib.Path.group` - * :meth:`~pathlib.Path.hardlink_to` - * :meth:`~pathlib.Path.home` - * :meth:`~pathlib.Path.is_block_device` - * :meth:`~pathlib.Path.is_char_device` - * :meth:`~pathlib.Path.is_dir` - * :meth:`~pathlib.Path.is_fifo` - * :meth:`~pathlib.Path.is_file` - * :meth:`~pathlib.Path.is_mount` - * :meth:`~pathlib.Path.lchmod` - * :meth:`~pathlib.Path.lstat` - * :meth:`~pathlib.Path.mkdir` - * :meth:`~pathlib.Path.open` - * :meth:`~pathlib.Path.owner` - * :meth:`~pathlib.Path.read_bytes` - * :meth:`~pathlib.Path.read_text` - * :meth:`~pathlib.Path.readlink` - * :meth:`~pathlib.Path.rename` - * :meth:`~pathlib.Path.replace` - * :meth:`~pathlib.Path.rmdir` - * :meth:`~pathlib.Path.samefile` - * :meth:`~pathlib.Path.stat` - * :meth:`~pathlib.Path.touch` - * :meth:`~pathlib.Path.unlink` - * :meth:`~pathlib.Path.write_bytes` - * :meth:`~pathlib.Path.write_text` - - Additionally, the following methods return an async iterator yielding :class:`~.Path` objects: - - * :meth:`~pathlib.Path.glob` - * :meth:`~pathlib.Path.iterdir` - * :meth:`~pathlib.Path.rglob` - """ - - __slots__ = '_path', '__weakref__' - - def __init__(self, *args: Union[str, PathLike]) -> None: - self._path: Final[pathlib.Path] = pathlib.Path(*args) - - def __fspath__(self) -> str: - return self._path.__fspath__() - - def __str__(self) -> str: - return self._path.__str__() - - def __repr__(self) -> str: - return f'{self.__class__.__name__}({self.as_posix()!r})' - - def __bytes__(self) -> bytes: - return self._path.__bytes__() - - def __hash__(self) -> int: - return self._path.__hash__() - - def __eq__(self, other: object) -> bool: - target = other._path if isinstance(other, Path) else other - return self._path.__eq__(target) - - def __lt__(self, other: 'Path') -> bool: - target = other._path if isinstance(other, Path) else other - return self._path.__lt__(target) - - def __le__(self, other: 'Path') -> bool: - target = other._path if isinstance(other, Path) else other - return self._path.__le__(target) - - def __gt__(self, other: 'Path') -> bool: - target = other._path if isinstance(other, Path) else other - return self._path.__gt__(target) - - def __ge__(self, other: 'Path') -> bool: - target = other._path if isinstance(other, Path) else other - return self._path.__ge__(target) - - def __truediv__(self, other: Any) -> 'Path': - return Path(self._path / other) - - def __rtruediv__(self, other: Any) -> 'Path': - return Path(other) / self - - @property - def parts(self) -> Tuple[str, ...]: - return self._path.parts - - @property - def drive(self) -> str: - return self._path.drive - - @property - def root(self) -> str: - return self._path.root - - @property - def anchor(self) -> str: - return self._path.anchor - - @property - def parents(self) -> Sequence['Path']: - return tuple(Path(p) for p in self._path.parents) - - @property - def parent(self) -> 'Path': - return Path(self._path.parent) - - @property - def name(self) -> str: - return self._path.name - - @property - def suffix(self) -> str: - return self._path.suffix - - @property - def suffixes(self) -> List[str]: - return self._path.suffixes - - @property - def stem(self) -> str: - return self._path.stem - - async def absolute(self) -> 'Path': - path = await to_thread.run_sync(self._path.absolute) - return Path(path) - - def as_posix(self) -> str: - return self._path.as_posix() - - def as_uri(self) -> str: - return self._path.as_uri() - - def match(self, path_pattern: str) -> bool: - return self._path.match(path_pattern) - - def is_relative_to(self, *other: Union[str, PathLike]) -> bool: - try: - self.relative_to(*other) - return True - except ValueError: - return False - - async def chmod(self, mode: int, *, follow_symlinks: bool = True) -> None: - func = partial(os.chmod, follow_symlinks=follow_symlinks) - return await to_thread.run_sync(func, self._path, mode) - - @classmethod - async def cwd(cls) -> 'Path': - path = await to_thread.run_sync(pathlib.Path.cwd) - return cls(path) - - async def exists(self) -> bool: - return await to_thread.run_sync(self._path.exists, cancellable=True) - - async def expanduser(self) -> 'Path': - return Path(await to_thread.run_sync(self._path.expanduser, cancellable=True)) - - def glob(self, pattern: str) -> AsyncIterator['Path']: - gen = self._path.glob(pattern) - return _PathIterator(gen) - - async def group(self) -> str: - return await to_thread.run_sync(self._path.group, cancellable=True) - - async def hardlink_to(self, target: Union[str, pathlib.Path, 'Path']) -> None: - if isinstance(target, Path): - target = target._path - - await to_thread.run_sync(os.link, target, self) - - @classmethod - async def home(cls) -> 'Path': - home_path = await to_thread.run_sync(pathlib.Path.home) - return cls(home_path) - - def is_absolute(self) -> bool: - return self._path.is_absolute() - - async def is_block_device(self) -> bool: - return await to_thread.run_sync(self._path.is_block_device, cancellable=True) - - async def is_char_device(self) -> bool: - return await to_thread.run_sync(self._path.is_char_device, cancellable=True) - - async def is_dir(self) -> bool: - return await to_thread.run_sync(self._path.is_dir, cancellable=True) - - async def is_fifo(self) -> bool: - return await to_thread.run_sync(self._path.is_fifo, cancellable=True) - - async def is_file(self) -> bool: - return await to_thread.run_sync(self._path.is_file, cancellable=True) - - async def is_mount(self) -> bool: - return await to_thread.run_sync(os.path.ismount, self._path, cancellable=True) - - def is_reserved(self) -> bool: - return self._path.is_reserved() - - async def is_socket(self) -> bool: - return await to_thread.run_sync(self._path.is_socket, cancellable=True) - - async def is_symlink(self) -> bool: - return await to_thread.run_sync(self._path.is_symlink, cancellable=True) - - def iterdir(self) -> AsyncIterator['Path']: - gen = self._path.iterdir() - return _PathIterator(gen) - - def joinpath(self, *args: Union[str, 'PathLike[str]']) -> 'Path': - return Path(self._path.joinpath(*args)) - - async def lchmod(self, mode: int) -> None: - await to_thread.run_sync(self._path.lchmod, mode) - - async def lstat(self) -> os.stat_result: - return await to_thread.run_sync(self._path.lstat, cancellable=True) - - async def mkdir(self, mode: int = 0o777, parents: bool = False, - exist_ok: bool = False) -> None: - await to_thread.run_sync(self._path.mkdir, mode, parents, exist_ok) - - @overload - async def open(self, mode: OpenBinaryMode, buffering: int = ..., encoding: Optional[str] = ..., - errors: Optional[str] = ..., newline: Optional[str] = ...) -> AsyncFile[bytes]: - ... - - @overload - async def open(self, mode: OpenTextMode = ..., buffering: int = ..., - encoding: Optional[str] = ..., errors: Optional[str] = ..., - newline: Optional[str] = ...) -> AsyncFile[str]: - ... - - async def open(self, mode: str = 'r', buffering: int = -1, encoding: Optional[str] = None, - errors: Optional[str] = None, newline: Optional[str] = None) -> AsyncFile: - fp = await to_thread.run_sync(self._path.open, mode, buffering, encoding, errors, newline) - return AsyncFile(fp) - - async def owner(self) -> str: - return await to_thread.run_sync(self._path.owner, cancellable=True) - - async def read_bytes(self) -> bytes: - return await to_thread.run_sync(self._path.read_bytes) - - async def read_text(self, encoding: Optional[str] = None, errors: Optional[str] = None) -> str: - return await to_thread.run_sync(self._path.read_text, encoding, errors) - - def relative_to(self, *other: Union[str, PathLike]) -> 'Path': - return Path(self._path.relative_to(*other)) - - async def readlink(self) -> 'Path': - target = await to_thread.run_sync(os.readlink, self._path) - return Path(cast(str, target)) - - async def rename(self, target: Union[str, pathlib.PurePath, 'Path']) -> 'Path': - if isinstance(target, Path): - target = target._path - - await to_thread.run_sync(self._path.rename, target) - return Path(target) - - async def replace(self, target: Union[str, pathlib.PurePath, 'Path']) -> 'Path': - if isinstance(target, Path): - target = target._path - - await to_thread.run_sync(self._path.replace, target) - return Path(target) - - async def resolve(self, strict: bool = False) -> 'Path': - func = partial(self._path.resolve, strict=strict) - return Path(await to_thread.run_sync(func, cancellable=True)) - - def rglob(self, pattern: str) -> AsyncIterator['Path']: - gen = self._path.rglob(pattern) - return _PathIterator(gen) - - async def rmdir(self) -> None: - await to_thread.run_sync(self._path.rmdir) - - async def samefile(self, other_path: Union[str, bytes, int, pathlib.Path, 'Path']) -> bool: - if isinstance(other_path, Path): - other_path = other_path._path - - return await to_thread.run_sync(self._path.samefile, other_path, cancellable=True) - - async def stat(self, *, follow_symlinks: bool = True) -> os.stat_result: - func = partial(os.stat, follow_symlinks=follow_symlinks) - return await to_thread.run_sync(func, self._path, cancellable=True) - - async def symlink_to(self, target: Union[str, pathlib.Path, 'Path'], - target_is_directory: bool = False) -> None: - if isinstance(target, Path): - target = target._path - - await to_thread.run_sync(self._path.symlink_to, target, target_is_directory) - - async def touch(self, mode: int = 0o666, exist_ok: bool = True) -> None: - await to_thread.run_sync(self._path.touch, mode, exist_ok) - - async def unlink(self, missing_ok: bool = False) -> None: - try: - await to_thread.run_sync(self._path.unlink) - except FileNotFoundError: - if not missing_ok: - raise - - def with_name(self, name: str) -> 'Path': - return Path(self._path.with_name(name)) - - def with_stem(self, stem: str) -> 'Path': - return Path(self._path.with_name(stem + self._path.suffix)) - - def with_suffix(self, suffix: str) -> 'Path': - return Path(self._path.with_suffix(suffix)) - - async def write_bytes(self, data: bytes) -> int: - return await to_thread.run_sync(self._path.write_bytes, data) - - async def write_text(self, data: str, encoding: Optional[str] = None, - errors: Optional[str] = None, newline: Optional[str] = None) -> int: - # Path.write_text() does not support the "newline" parameter before Python 3.10 - def sync_write_text() -> int: - with self._path.open('w', encoding=encoding, errors=errors, newline=newline) as fp: - return fp.write(data) - - return await to_thread.run_sync(sync_write_text) - - -PathLike.register(Path) diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_resources.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_resources.py deleted file mode 100644 index b9414f7b..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_resources.py +++ /dev/null @@ -1,16 +0,0 @@ -from ..abc import AsyncResource -from ._tasks import CancelScope - - -async def aclose_forcefully(resource: AsyncResource) -> None: - """ - Close an asynchronous resource in a cancelled scope. - - Doing this closes the resource without waiting on anything. - - :param resource: the resource to close - - """ - with CancelScope() as scope: - scope.cancel() - await resource.aclose() diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_signals.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_signals.py deleted file mode 100644 index f761982c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_signals.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import AsyncIterator - -from ._compat import DeprecatedAsyncContextManager -from ._eventloop import get_asynclib - - -def open_signal_receiver(*signals: int) -> DeprecatedAsyncContextManager[AsyncIterator[int]]: - """ - Start receiving operating system signals. - - :param signals: signals to receive (e.g. ``signal.SIGINT``) - :return: an asynchronous context manager for an asynchronous iterator which yields signal - numbers - - .. warning:: Windows does not support signals natively so it is best to avoid relying on this - in cross-platform applications. - - .. warning:: On asyncio, this permanently replaces any previous signal handler for the given - signals, as set via :meth:`~asyncio.loop.add_signal_handler`. - - """ - return get_asynclib().open_signal_receiver(*signals) diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_sockets.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_sockets.py deleted file mode 100644 index f58cdc3a..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_sockets.py +++ /dev/null @@ -1,503 +0,0 @@ -import socket -import ssl -import sys -from ipaddress import IPv6Address, ip_address -from os import PathLike, chmod -from pathlib import Path -from socket import AddressFamily, SocketKind -from typing import Awaitable, List, Optional, Tuple, Union, cast, overload - -from .. import to_thread -from ..abc import ( - ConnectedUDPSocket, IPAddressType, IPSockAddrType, SocketListener, SocketStream, UDPSocket, - UNIXSocketStream) -from ..streams.stapled import MultiListener -from ..streams.tls import TLSStream -from ._eventloop import get_asynclib -from ._resources import aclose_forcefully -from ._synchronization import Event -from ._tasks import create_task_group, move_on_after - -if sys.version_info >= (3, 8): - from typing import Literal -else: - from typing_extensions import Literal - -IPPROTO_IPV6 = getattr(socket, 'IPPROTO_IPV6', 41) # https://bugs.python.org/issue29515 - -GetAddrInfoReturnType = List[Tuple[AddressFamily, SocketKind, int, str, Tuple[str, int]]] -AnyIPAddressFamily = Literal[AddressFamily.AF_UNSPEC, AddressFamily.AF_INET, - AddressFamily.AF_INET6] -IPAddressFamily = Literal[AddressFamily.AF_INET, AddressFamily.AF_INET6] - - -# tls_hostname given -@overload -async def connect_tcp( - remote_host: IPAddressType, remote_port: int, *, local_host: Optional[IPAddressType] = ..., - ssl_context: Optional[ssl.SSLContext] = ..., tls_standard_compatible: bool = ..., - tls_hostname: str, happy_eyeballs_delay: float = ... -) -> TLSStream: - ... - - -# ssl_context given -@overload -async def connect_tcp( - remote_host: IPAddressType, remote_port: int, *, local_host: Optional[IPAddressType] = ..., - ssl_context: ssl.SSLContext, tls_standard_compatible: bool = ..., - tls_hostname: Optional[str] = ..., happy_eyeballs_delay: float = ... -) -> TLSStream: - ... - - -# tls=True -@overload -async def connect_tcp( - remote_host: IPAddressType, remote_port: int, *, local_host: Optional[IPAddressType] = ..., - tls: Literal[True], ssl_context: Optional[ssl.SSLContext] = ..., - tls_standard_compatible: bool = ..., tls_hostname: Optional[str] = ..., - happy_eyeballs_delay: float = ... -) -> TLSStream: - ... - - -# tls=False -@overload -async def connect_tcp( - remote_host: IPAddressType, remote_port: int, *, local_host: Optional[IPAddressType] = ..., - tls: Literal[False], ssl_context: Optional[ssl.SSLContext] = ..., - tls_standard_compatible: bool = ..., tls_hostname: Optional[str] = ..., - happy_eyeballs_delay: float = ... -) -> SocketStream: - ... - - -# No TLS arguments -@overload -async def connect_tcp( - remote_host: IPAddressType, remote_port: int, *, local_host: Optional[IPAddressType] = ..., - happy_eyeballs_delay: float = ... -) -> SocketStream: - ... - - -async def connect_tcp( - remote_host: IPAddressType, remote_port: int, *, local_host: Optional[IPAddressType] = None, - tls: bool = False, ssl_context: Optional[ssl.SSLContext] = None, - tls_standard_compatible: bool = True, tls_hostname: Optional[str] = None, - happy_eyeballs_delay: float = 0.25 -) -> Union[SocketStream, TLSStream]: - """ - Connect to a host using the TCP protocol. - - This function implements the stateless version of the Happy Eyeballs algorithm (RFC 6555). - If ``address`` is a host name that resolves to multiple IP addresses, each one is tried until - one connection attempt succeeds. If the first attempt does not connected within 250 - milliseconds, a second attempt is started using the next address in the list, and so on. - On IPv6 enabled systems, an IPv6 address (if available) is tried first. - - When the connection has been established, a TLS handshake will be done if either - ``ssl_context`` or ``tls_hostname`` is not ``None``, or if ``tls`` is ``True``. - - :param remote_host: the IP address or host name to connect to - :param remote_port: port on the target host to connect to - :param local_host: the interface address or name to bind the socket to before connecting - :param tls: ``True`` to do a TLS handshake with the connected stream and return a - :class:`~anyio.streams.tls.TLSStream` instead - :param ssl_context: the SSL context object to use (if omitted, a default context is created) - :param tls_standard_compatible: If ``True``, performs the TLS shutdown handshake before closing - the stream and requires that the server does this as well. Otherwise, - :exc:`~ssl.SSLEOFError` may be raised during reads from the stream. - Some protocols, such as HTTP, require this option to be ``False``. - See :meth:`~ssl.SSLContext.wrap_socket` for details. - :param tls_hostname: host name to check the server certificate against (defaults to the value - of ``remote_host``) - :param happy_eyeballs_delay: delay (in seconds) before starting the next connection attempt - :return: a socket stream object if no TLS handshake was done, otherwise a TLS stream - :raises OSError: if the connection attempt fails - - """ - # Placed here due to https://github.com/python/mypy/issues/7057 - connected_stream: Optional[SocketStream] = None - - async def try_connect(remote_host: str, event: Event) -> None: - nonlocal connected_stream - try: - stream = await asynclib.connect_tcp(remote_host, remote_port, local_address) - except OSError as exc: - oserrors.append(exc) - return - else: - if connected_stream is None: - connected_stream = stream - tg.cancel_scope.cancel() - else: - await stream.aclose() - finally: - event.set() - - asynclib = get_asynclib() - local_address: Optional[IPSockAddrType] = None - family = socket.AF_UNSPEC - if local_host: - gai_res = await getaddrinfo(str(local_host), None) - family, *_, local_address = gai_res[0] - - target_host = str(remote_host) - try: - addr_obj = ip_address(remote_host) - except ValueError: - # getaddrinfo() will raise an exception if name resolution fails - gai_res = await getaddrinfo(target_host, remote_port, family=family, - type=socket.SOCK_STREAM) - - # Organize the list so that the first address is an IPv6 address (if available) and the - # second one is an IPv4 addresses. The rest can be in whatever order. - v6_found = v4_found = False - target_addrs: List[Tuple[socket.AddressFamily, str]] = [] - for af, *rest, sa in gai_res: - if af == socket.AF_INET6 and not v6_found: - v6_found = True - target_addrs.insert(0, (af, sa[0])) - elif af == socket.AF_INET and not v4_found and v6_found: - v4_found = True - target_addrs.insert(1, (af, sa[0])) - else: - target_addrs.append((af, sa[0])) - else: - if isinstance(addr_obj, IPv6Address): - target_addrs = [(socket.AF_INET6, addr_obj.compressed)] - else: - target_addrs = [(socket.AF_INET, addr_obj.compressed)] - - oserrors: List[OSError] = [] - async with create_task_group() as tg: - for i, (af, addr) in enumerate(target_addrs): - event = Event() - tg.start_soon(try_connect, addr, event) - with move_on_after(happy_eyeballs_delay): - await event.wait() - - if connected_stream is None: - cause = oserrors[0] if len(oserrors) == 1 else asynclib.ExceptionGroup(oserrors) - raise OSError('All connection attempts failed') from cause - - if tls or tls_hostname or ssl_context: - try: - return await TLSStream.wrap(connected_stream, server_side=False, - hostname=tls_hostname or str(remote_host), - ssl_context=ssl_context, - standard_compatible=tls_standard_compatible) - except BaseException: - await aclose_forcefully(connected_stream) - raise - - return connected_stream - - -async def connect_unix(path: Union[str, PathLike]) -> UNIXSocketStream: - """ - Connect to the given UNIX socket. - - Not available on Windows. - - :param path: path to the socket - :return: a socket stream object - - """ - path = str(Path(path)) - return await get_asynclib().connect_unix(path) - - -async def create_tcp_listener( - *, local_host: Optional[IPAddressType] = None, local_port: int = 0, - family: AnyIPAddressFamily = socket.AddressFamily.AF_UNSPEC, backlog: int = 65536, - reuse_port: bool = False -) -> MultiListener[SocketStream]: - """ - Create a TCP socket listener. - - :param local_port: port number to listen on - :param local_host: IP address of the interface to listen on. If omitted, listen on all IPv4 - and IPv6 interfaces. To listen on all interfaces on a specific address family, use - ``0.0.0.0`` for IPv4 or ``::`` for IPv6. - :param family: address family (used if ``interface`` was omitted) - :param backlog: maximum number of queued incoming connections (up to a maximum of 2**16, or - 65536) - :param reuse_port: ``True`` to allow multiple sockets to bind to the same address/port - (not supported on Windows) - :return: a list of listener objects - - """ - asynclib = get_asynclib() - backlog = min(backlog, 65536) - local_host = str(local_host) if local_host is not None else None - gai_res = await getaddrinfo(local_host, local_port, family=family, # type: ignore[arg-type] - type=socket.SOCK_STREAM, - flags=socket.AI_PASSIVE | socket.AI_ADDRCONFIG) - listeners: List[SocketListener] = [] - try: - # The set() is here to work around a glibc bug: - # https://sourceware.org/bugzilla/show_bug.cgi?id=14969 - for fam, *_, sockaddr in sorted(set(gai_res)): - raw_socket = socket.socket(fam) - raw_socket.setblocking(False) - - # For Windows, enable exclusive address use. For others, enable address reuse. - if sys.platform == 'win32': - raw_socket.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) - else: - raw_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - if reuse_port: - raw_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - - # If only IPv6 was requested, disable dual stack operation - if fam == socket.AF_INET6: - raw_socket.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) - - raw_socket.bind(sockaddr) - raw_socket.listen(backlog) - listener = asynclib.TCPSocketListener(raw_socket) - listeners.append(listener) - except BaseException: - for listener in listeners: - await listener.aclose() - - raise - - return MultiListener(listeners) - - -async def create_unix_listener( - path: Union[str, PathLike], *, mode: Optional[int] = None, - backlog: int = 65536) -> SocketListener: - """ - Create a UNIX socket listener. - - Not available on Windows. - - :param path: path of the socket - :param mode: permissions to set on the socket - :param backlog: maximum number of queued incoming connections (up to a maximum of 2**16, or - 65536) - :return: a listener object - - .. versionchanged:: 3.0 - If a socket already exists on the file system in the given path, it will be removed first. - - """ - path_str = str(path) - path = Path(path) - if path.is_socket(): - path.unlink() - - backlog = min(backlog, 65536) - raw_socket = socket.socket(socket.AF_UNIX) - raw_socket.setblocking(False) - try: - await to_thread.run_sync(raw_socket.bind, path_str, cancellable=True) - if mode is not None: - await to_thread.run_sync(chmod, path_str, mode, cancellable=True) - - raw_socket.listen(backlog) - return get_asynclib().UNIXSocketListener(raw_socket) - except BaseException: - raw_socket.close() - raise - - -async def create_udp_socket( - family: AnyIPAddressFamily = AddressFamily.AF_UNSPEC, *, - local_host: Optional[IPAddressType] = None, local_port: int = 0, reuse_port: bool = False -) -> UDPSocket: - """ - Create a UDP socket. - - If ``port`` has been given, the socket will be bound to this port on the local machine, - making this socket suitable for providing UDP based services. - - :param family: address family (``AF_INET`` or ``AF_INET6``) – automatically determined from - ``local_host`` if omitted - :param local_host: IP address or host name of the local interface to bind to - :param local_port: local port to bind to - :param reuse_port: ``True`` to allow multiple sockets to bind to the same address/port - (not supported on Windows) - :return: a UDP socket - - """ - if family is AddressFamily.AF_UNSPEC and not local_host: - raise ValueError('Either "family" or "local_host" must be given') - - local_address: Optional[IPSockAddrType] = None - if local_host: - gai_res = await getaddrinfo(str(local_host), local_port, family=family, - type=socket.SOCK_DGRAM, - flags=socket.AI_PASSIVE | socket.AI_ADDRCONFIG) - family = cast(AnyIPAddressFamily, gai_res[0][0]) - local_address = gai_res[0][-1] - - return await get_asynclib().create_udp_socket(family, local_address, None, reuse_port) - - -async def create_connected_udp_socket( - remote_host: IPAddressType, remote_port: int, *, - family: AnyIPAddressFamily = AddressFamily.AF_UNSPEC, - local_host: Optional[IPAddressType] = None, local_port: int = 0, reuse_port: bool = False -) -> ConnectedUDPSocket: - """ - Create a connected UDP socket. - - Connected UDP sockets can only communicate with the specified remote host/port, and any packets - sent from other sources are dropped. - - :param remote_host: remote host to set as the default target - :param remote_port: port on the remote host to set as the default target - :param family: address family (``AF_INET`` or ``AF_INET6``) – automatically determined from - ``local_host`` or ``remote_host`` if omitted - :param local_host: IP address or host name of the local interface to bind to - :param local_port: local port to bind to - :param reuse_port: ``True`` to allow multiple sockets to bind to the same address/port - (not supported on Windows) - :return: a connected UDP socket - - """ - local_address = None - if local_host: - gai_res = await getaddrinfo(str(local_host), local_port, family=family, - type=socket.SOCK_DGRAM, - flags=socket.AI_PASSIVE | socket.AI_ADDRCONFIG) - family = cast(AnyIPAddressFamily, gai_res[0][0]) - local_address = gai_res[0][-1] - - gai_res = await getaddrinfo(str(remote_host), remote_port, family=family, - type=socket.SOCK_DGRAM) - family = cast(AnyIPAddressFamily, gai_res[0][0]) - remote_address = gai_res[0][-1] - - return await get_asynclib().create_udp_socket(family, local_address, remote_address, - reuse_port) - - -async def getaddrinfo(host: Union[bytearray, bytes, str], port: Union[str, int, None], *, - family: Union[int, AddressFamily] = 0, type: Union[int, SocketKind] = 0, - proto: int = 0, flags: int = 0) -> GetAddrInfoReturnType: - """ - Look up a numeric IP address given a host name. - - Internationalized domain names are translated according to the (non-transitional) IDNA 2008 - standard. - - .. note:: 4-tuple IPv6 socket addresses are automatically converted to 2-tuples of - (host, port), unlike what :func:`socket.getaddrinfo` does. - - :param host: host name - :param port: port number - :param family: socket family (`'AF_INET``, ...) - :param type: socket type (``SOCK_STREAM``, ...) - :param proto: protocol number - :param flags: flags to pass to upstream ``getaddrinfo()`` - :return: list of tuples containing (family, type, proto, canonname, sockaddr) - - .. seealso:: :func:`socket.getaddrinfo` - - """ - # Handle unicode hostnames - if isinstance(host, str): - try: - encoded_host = host.encode('ascii') - except UnicodeEncodeError: - import idna - encoded_host = idna.encode(host, uts46=True) - else: - encoded_host = host - - gai_res = await get_asynclib().getaddrinfo(encoded_host, port, family=family, type=type, - proto=proto, flags=flags) - return [(family, type, proto, canonname, convert_ipv6_sockaddr(sockaddr)) - for family, type, proto, canonname, sockaddr in gai_res] - - -def getnameinfo(sockaddr: IPSockAddrType, flags: int = 0) -> Awaitable[Tuple[str, str]]: - """ - Look up the host name of an IP address. - - :param sockaddr: socket address (e.g. (ipaddress, port) for IPv4) - :param flags: flags to pass to upstream ``getnameinfo()`` - :return: a tuple of (host name, service name) - - .. seealso:: :func:`socket.getnameinfo` - - """ - return get_asynclib().getnameinfo(sockaddr, flags) - - -def wait_socket_readable(sock: socket.socket) -> Awaitable[None]: - """ - Wait until the given socket has data to be read. - - This does **NOT** work on Windows when using the asyncio backend with a proactor event loop - (default on py3.8+). - - .. warning:: Only use this on raw sockets that have not been wrapped by any higher level - constructs like socket streams! - - :param sock: a socket object - :raises ~anyio.ClosedResourceError: if the socket was closed while waiting for the - socket to become readable - :raises ~anyio.BusyResourceError: if another task is already waiting for the socket - to become readable - - """ - return get_asynclib().wait_socket_readable(sock) - - -def wait_socket_writable(sock: socket.socket) -> Awaitable[None]: - """ - Wait until the given socket can be written to. - - This does **NOT** work on Windows when using the asyncio backend with a proactor event loop - (default on py3.8+). - - .. warning:: Only use this on raw sockets that have not been wrapped by any higher level - constructs like socket streams! - - :param sock: a socket object - :raises ~anyio.ClosedResourceError: if the socket was closed while waiting for the - socket to become writable - :raises ~anyio.BusyResourceError: if another task is already waiting for the socket - to become writable - - """ - return get_asynclib().wait_socket_writable(sock) - - -# -# Private API -# - -def convert_ipv6_sockaddr( - sockaddr: Union[Tuple[str, int, int, int], Tuple[str, int]] -) -> Tuple[str, int]: - """ - Convert a 4-tuple IPv6 socket address to a 2-tuple (address, port) format. - - If the scope ID is nonzero, it is added to the address, separated with ``%``. - Otherwise the flow id and scope id are simply cut off from the tuple. - Any other kinds of socket addresses are returned as-is. - - :param sockaddr: the result of :meth:`~socket.socket.getsockname` - :return: the converted socket address - - """ - # This is more complicated than it should be because of MyPy - if isinstance(sockaddr, tuple) and len(sockaddr) == 4: - host, port, flowinfo, scope_id = cast(Tuple[str, int, int, int], sockaddr) - if scope_id: - # Add scope_id to the address - return f"{host}%{scope_id}", port - else: - return host, port - else: - return cast(Tuple[str, int], sockaddr) diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_streams.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_streams.py deleted file mode 100644 index 4a003bea..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_streams.py +++ /dev/null @@ -1,42 +0,0 @@ -import math -from typing import Optional, Tuple, Type, TypeVar, overload - -from ..streams.memory import ( - MemoryObjectReceiveStream, MemoryObjectSendStream, MemoryObjectStreamState) - -T_Item = TypeVar('T_Item') - - -@overload -def create_memory_object_stream( - max_buffer_size: float, item_type: Type[T_Item] -) -> Tuple[MemoryObjectSendStream[T_Item], MemoryObjectReceiveStream[T_Item]]: - ... - - -@overload -def create_memory_object_stream( - max_buffer_size: float = 0 -) -> Tuple[MemoryObjectSendStream, MemoryObjectReceiveStream]: - ... - - -def create_memory_object_stream( - max_buffer_size: float = 0, item_type: Optional[Type[T_Item]] = None -) -> Tuple[MemoryObjectSendStream, MemoryObjectReceiveStream]: - """ - Create a memory object stream. - - :param max_buffer_size: number of items held in the buffer until ``send()`` starts blocking - :param item_type: type of item, for marking the streams with the right generic type for - static typing (not used at run time) - :return: a tuple of (send stream, receive stream) - - """ - if max_buffer_size != math.inf and not isinstance(max_buffer_size, int): - raise ValueError('max_buffer_size must be either an integer or math.inf') - if max_buffer_size < 0: - raise ValueError('max_buffer_size cannot be negative') - - state: MemoryObjectStreamState = MemoryObjectStreamState(max_buffer_size) - return MemoryObjectSendStream(state), MemoryObjectReceiveStream(state) diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_subprocesses.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_subprocesses.py deleted file mode 100644 index 7e4d968c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_subprocesses.py +++ /dev/null @@ -1,91 +0,0 @@ -from io import BytesIO -from os import PathLike -from subprocess import DEVNULL, PIPE, CalledProcessError, CompletedProcess -from typing import AsyncIterable, List, Mapping, Optional, Sequence, Union, cast - -from ..abc import Process -from ._eventloop import get_asynclib -from ._tasks import create_task_group - - -async def run_process(command: Union[str, Sequence[str]], *, input: Optional[bytes] = None, - stdout: int = PIPE, stderr: int = PIPE, check: bool = True, - cwd: Union[str, bytes, PathLike, None] = None, - env: Optional[Mapping[str, str]] = None) -> CompletedProcess: - """ - Run an external command in a subprocess and wait until it completes. - - .. seealso:: :func:`subprocess.run` - - :param command: either a string to pass to the shell, or an iterable of strings containing the - executable name or path and its arguments - :param input: bytes passed to the standard input of the subprocess - :param stdout: either :data:`subprocess.PIPE` or :data:`subprocess.DEVNULL` - :param stderr: one of :data:`subprocess.PIPE`, :data:`subprocess.DEVNULL` or - :data:`subprocess.STDOUT` - :param check: if ``True``, raise :exc:`~subprocess.CalledProcessError` if the process - terminates with a return code other than 0 - :param cwd: If not ``None``, change the working directory to this before running the command - :param env: if not ``None``, this mapping replaces the inherited environment variables from the - parent process - :return: an object representing the completed process - :raises ~subprocess.CalledProcessError: if ``check`` is ``True`` and the process exits with a - nonzero return code - - """ - async def drain_stream(stream: AsyncIterable[bytes], index: int) -> None: - buffer = BytesIO() - async for chunk in stream: - buffer.write(chunk) - - stream_contents[index] = buffer.getvalue() - - async with await open_process(command, stdin=PIPE if input else DEVNULL, stdout=stdout, - stderr=stderr, cwd=cwd, env=env) as process: - stream_contents: List[Optional[bytes]] = [None, None] - try: - async with create_task_group() as tg: - if process.stdout: - tg.start_soon(drain_stream, process.stdout, 0) - if process.stderr: - tg.start_soon(drain_stream, process.stderr, 1) - if process.stdin and input: - await process.stdin.send(input) - await process.stdin.aclose() - - await process.wait() - except BaseException: - process.kill() - raise - - output, errors = stream_contents - if check and process.returncode != 0: - raise CalledProcessError(cast(int, process.returncode), command, output, errors) - - return CompletedProcess(command, cast(int, process.returncode), output, errors) - - -async def open_process(command: Union[str, Sequence[str]], *, stdin: int = PIPE, - stdout: int = PIPE, stderr: int = PIPE, - cwd: Union[str, bytes, PathLike, None] = None, - env: Optional[Mapping[str, str]] = None) -> Process: - """ - Start an external command in a subprocess. - - .. seealso:: :class:`subprocess.Popen` - - :param command: either a string to pass to the shell, or an iterable of strings containing the - executable name or path and its arguments - :param stdin: either :data:`subprocess.PIPE` or :data:`subprocess.DEVNULL` - :param stdout: either :data:`subprocess.PIPE` or :data:`subprocess.DEVNULL` - :param stderr: one of :data:`subprocess.PIPE`, :data:`subprocess.DEVNULL` or - :data:`subprocess.STDOUT` - :param cwd: If not ``None``, the working directory is changed before executing - :param env: If env is not ``None``, it must be a mapping that defines the environment - variables for the new process - :return: an asynchronous process object - - """ - shell = isinstance(command, str) - return await get_asynclib().open_process(command, shell=shell, stdin=stdin, stdout=stdout, - stderr=stderr, cwd=cwd, env=env) diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_synchronization.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_synchronization.py deleted file mode 100644 index 6c691770..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_synchronization.py +++ /dev/null @@ -1,554 +0,0 @@ -from collections import deque -from dataclasses import dataclass -from types import TracebackType -from typing import Deque, Optional, Tuple, Type -from warnings import warn - -from ..lowlevel import cancel_shielded_checkpoint, checkpoint, checkpoint_if_cancelled -from ._compat import DeprecatedAwaitable -from ._eventloop import get_asynclib -from ._exceptions import BusyResourceError, WouldBlock -from ._tasks import CancelScope -from ._testing import TaskInfo, get_current_task - - -@dataclass(frozen=True) -class EventStatistics: - """ - :ivar int tasks_waiting: number of tasks waiting on :meth:`~.Event.wait` - """ - - tasks_waiting: int - - -@dataclass(frozen=True) -class CapacityLimiterStatistics: - """ - :ivar int borrowed_tokens: number of tokens currently borrowed by tasks - :ivar float total_tokens: total number of available tokens - :ivar tuple borrowers: tasks or other objects currently holding tokens borrowed from this - limiter - :ivar int tasks_waiting: number of tasks waiting on :meth:`~.CapacityLimiter.acquire` or - :meth:`~.CapacityLimiter.acquire_on_behalf_of` - """ - - borrowed_tokens: int - total_tokens: float - borrowers: Tuple[object, ...] - tasks_waiting: int - - -@dataclass(frozen=True) -class LockStatistics: - """ - :ivar bool locked: flag indicating if this lock is locked or not - :ivar ~anyio.TaskInfo owner: task currently holding the lock (or ``None`` if the lock is not - held by any task) - :ivar int tasks_waiting: number of tasks waiting on :meth:`~.Lock.acquire` - """ - - locked: bool - owner: Optional[TaskInfo] - tasks_waiting: int - - -@dataclass(frozen=True) -class ConditionStatistics: - """ - :ivar int tasks_waiting: number of tasks blocked on :meth:`~.Condition.wait` - :ivar ~anyio.LockStatistics lock_statistics: statistics of the underlying :class:`~.Lock` - """ - - tasks_waiting: int - lock_statistics: LockStatistics - - -@dataclass(frozen=True) -class SemaphoreStatistics: - """ - :ivar int tasks_waiting: number of tasks waiting on :meth:`~.Semaphore.acquire` - - """ - tasks_waiting: int - - -class Event: - def __new__(cls) -> 'Event': - return get_asynclib().Event() - - def set(self) -> DeprecatedAwaitable: - """Set the flag, notifying all listeners.""" - raise NotImplementedError - - def is_set(self) -> bool: - """Return ``True`` if the flag is set, ``False`` if not.""" - raise NotImplementedError - - async def wait(self) -> None: - """ - Wait until the flag has been set. - - If the flag has already been set when this method is called, it returns immediately. - - """ - raise NotImplementedError - - def statistics(self) -> EventStatistics: - """Return statistics about the current state of this event.""" - raise NotImplementedError - - -class Lock: - _owner_task: Optional[TaskInfo] = None - - def __init__(self) -> None: - self._waiters: Deque[Tuple[TaskInfo, Event]] = deque() - - async def __aenter__(self) -> None: - await self.acquire() - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> None: - self.release() - - async def acquire(self) -> None: - """Acquire the lock.""" - await checkpoint_if_cancelled() - try: - self.acquire_nowait() - except WouldBlock: - task = get_current_task() - event = Event() - token = task, event - self._waiters.append(token) - try: - await event.wait() - except BaseException: - if not event.is_set(): - self._waiters.remove(token) - - raise - - assert self._owner_task == task - else: - await cancel_shielded_checkpoint() - - def acquire_nowait(self) -> None: - """ - Acquire the lock, without blocking. - - :raises ~WouldBlock: if the operation would block - - """ - task = get_current_task() - if self._owner_task == task: - raise RuntimeError('Attempted to acquire an already held Lock') - - if self._owner_task is not None: - raise WouldBlock - - self._owner_task = task - - def release(self) -> DeprecatedAwaitable: - """Release the lock.""" - if self._owner_task != get_current_task(): - raise RuntimeError('The current task is not holding this lock') - - if self._waiters: - self._owner_task, event = self._waiters.popleft() - event.set() - else: - del self._owner_task - - return DeprecatedAwaitable(self.release) - - def locked(self) -> bool: - """Return True if the lock is currently held.""" - return self._owner_task is not None - - def statistics(self) -> LockStatistics: - """ - Return statistics about the current state of this lock. - - .. versionadded:: 3.0 - """ - return LockStatistics(self.locked(), self._owner_task, len(self._waiters)) - - -class Condition: - _owner_task: Optional[TaskInfo] = None - - def __init__(self, lock: Optional[Lock] = None): - self._lock = lock or Lock() - self._waiters: Deque[Event] = deque() - - async def __aenter__(self) -> None: - await self.acquire() - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> None: - self.release() - - def _check_acquired(self) -> None: - if self._owner_task != get_current_task(): - raise RuntimeError('The current task is not holding the underlying lock') - - async def acquire(self) -> None: - """Acquire the underlying lock.""" - await self._lock.acquire() - self._owner_task = get_current_task() - - def acquire_nowait(self) -> None: - """ - Acquire the underlying lock, without blocking. - - :raises ~WouldBlock: if the operation would block - - """ - self._lock.acquire_nowait() - self._owner_task = get_current_task() - - def release(self) -> DeprecatedAwaitable: - """Release the underlying lock.""" - self._lock.release() - return DeprecatedAwaitable(self.release) - - def locked(self) -> bool: - """Return True if the lock is set.""" - return self._lock.locked() - - def notify(self, n: int = 1) -> None: - """Notify exactly n listeners.""" - self._check_acquired() - for _ in range(n): - try: - event = self._waiters.popleft() - except IndexError: - break - - event.set() - - def notify_all(self) -> None: - """Notify all the listeners.""" - self._check_acquired() - for event in self._waiters: - event.set() - - self._waiters.clear() - - async def wait(self) -> None: - """Wait for a notification.""" - await checkpoint() - event = Event() - self._waiters.append(event) - self.release() - try: - await event.wait() - except BaseException: - if not event.is_set(): - self._waiters.remove(event) - - raise - finally: - with CancelScope(shield=True): - await self.acquire() - - def statistics(self) -> ConditionStatistics: - """ - Return statistics about the current state of this condition. - - .. versionadded:: 3.0 - """ - return ConditionStatistics(len(self._waiters), self._lock.statistics()) - - -class Semaphore: - def __init__(self, initial_value: int, *, max_value: Optional[int] = None): - if not isinstance(initial_value, int): - raise TypeError('initial_value must be an integer') - if initial_value < 0: - raise ValueError('initial_value must be >= 0') - if max_value is not None: - if not isinstance(max_value, int): - raise TypeError('max_value must be an integer or None') - if max_value < initial_value: - raise ValueError('max_value must be equal to or higher than initial_value') - - self._value = initial_value - self._max_value = max_value - self._waiters: Deque[Event] = deque() - - async def __aenter__(self) -> 'Semaphore': - await self.acquire() - return self - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> None: - self.release() - - async def acquire(self) -> None: - """Decrement the semaphore value, blocking if necessary.""" - await checkpoint_if_cancelled() - try: - self.acquire_nowait() - except WouldBlock: - event = Event() - self._waiters.append(event) - try: - await event.wait() - except BaseException: - if not event.is_set(): - self._waiters.remove(event) - - raise - else: - await cancel_shielded_checkpoint() - - def acquire_nowait(self) -> None: - """ - Acquire the underlying lock, without blocking. - - :raises ~WouldBlock: if the operation would block - - """ - if self._value == 0: - raise WouldBlock - - self._value -= 1 - - def release(self) -> DeprecatedAwaitable: - """Increment the semaphore value.""" - if self._max_value is not None and self._value == self._max_value: - raise ValueError('semaphore released too many times') - - if self._waiters: - self._waiters.popleft().set() - else: - self._value += 1 - - return DeprecatedAwaitable(self.release) - - @property - def value(self) -> int: - """The current value of the semaphore.""" - return self._value - - @property - def max_value(self) -> Optional[int]: - """The maximum value of the semaphore.""" - return self._max_value - - def statistics(self) -> SemaphoreStatistics: - """ - Return statistics about the current state of this semaphore. - - .. versionadded:: 3.0 - """ - return SemaphoreStatistics(len(self._waiters)) - - -class CapacityLimiter: - def __new__(cls, total_tokens: float) -> 'CapacityLimiter': - return get_asynclib().CapacityLimiter(total_tokens) - - async def __aenter__(self) -> None: - raise NotImplementedError - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - raise NotImplementedError - - @property - def total_tokens(self) -> float: - """ - The total number of tokens available for borrowing. - - This is a read-write property. If the total number of tokens is increased, the - proportionate number of tasks waiting on this limiter will be granted their tokens. - - .. versionchanged:: 3.0 - The property is now writable. - - """ - raise NotImplementedError - - @total_tokens.setter - def total_tokens(self, value: float) -> None: - raise NotImplementedError - - async def set_total_tokens(self, value: float) -> None: - warn('CapacityLimiter.set_total_tokens has been deprecated. Set the value of the' - '"total_tokens" attribute directly.', DeprecationWarning) - self.total_tokens = value - - @property - def borrowed_tokens(self) -> int: - """The number of tokens that have currently been borrowed.""" - raise NotImplementedError - - @property - def available_tokens(self) -> float: - """The number of tokens currently available to be borrowed""" - raise NotImplementedError - - def acquire_nowait(self) -> DeprecatedAwaitable: - """ - Acquire a token for the current task without waiting for one to become available. - - :raises ~anyio.WouldBlock: if there are no tokens available for borrowing - - """ - raise NotImplementedError - - def acquire_on_behalf_of_nowait(self, borrower: object) -> DeprecatedAwaitable: - """ - Acquire a token without waiting for one to become available. - - :param borrower: the entity borrowing a token - :raises ~anyio.WouldBlock: if there are no tokens available for borrowing - - """ - raise NotImplementedError - - async def acquire(self) -> None: - """ - Acquire a token for the current task, waiting if necessary for one to become available. - - """ - raise NotImplementedError - - async def acquire_on_behalf_of(self, borrower: object) -> None: - """ - Acquire a token, waiting if necessary for one to become available. - - :param borrower: the entity borrowing a token - - """ - raise NotImplementedError - - def release(self) -> None: - """ - Release the token held by the current task. - :raises RuntimeError: if the current task has not borrowed a token from this limiter. - - """ - raise NotImplementedError - - def release_on_behalf_of(self, borrower: object) -> None: - """ - Release the token held by the given borrower. - - :raises RuntimeError: if the borrower has not borrowed a token from this limiter. - - """ - raise NotImplementedError - - def statistics(self) -> CapacityLimiterStatistics: - """ - Return statistics about the current state of this limiter. - - .. versionadded:: 3.0 - - """ - raise NotImplementedError - - -def create_lock() -> Lock: - """ - Create an asynchronous lock. - - :return: a lock object - - .. deprecated:: 3.0 - Use :class:`~Lock` directly. - - """ - warn('create_lock() is deprecated -- use Lock() directly', DeprecationWarning) - return Lock() - - -def create_condition(lock: Optional[Lock] = None) -> Condition: - """ - Create an asynchronous condition. - - :param lock: the lock to base the condition object on - :return: a condition object - - .. deprecated:: 3.0 - Use :class:`~Condition` directly. - - """ - warn('create_condition() is deprecated -- use Condition() directly', DeprecationWarning) - return Condition(lock=lock) - - -def create_event() -> Event: - """ - Create an asynchronous event object. - - :return: an event object - - .. deprecated:: 3.0 - Use :class:`~Event` directly. - - """ - warn('create_event() is deprecated -- use Event() directly', DeprecationWarning) - return get_asynclib().Event() - - -def create_semaphore(value: int, *, max_value: Optional[int] = None) -> Semaphore: - """ - Create an asynchronous semaphore. - - :param value: the semaphore's initial value - :param max_value: if set, makes this a "bounded" semaphore that raises :exc:`ValueError` if the - semaphore's value would exceed this number - :return: a semaphore object - - .. deprecated:: 3.0 - Use :class:`~Semaphore` directly. - - """ - warn('create_semaphore() is deprecated -- use Semaphore() directly', DeprecationWarning) - return Semaphore(value, max_value=max_value) - - -def create_capacity_limiter(total_tokens: float) -> CapacityLimiter: - """ - Create a capacity limiter. - - :param total_tokens: the total number of tokens available for borrowing (can be an integer or - :data:`math.inf`) - :return: a capacity limiter object - - .. deprecated:: 3.0 - Use :class:`~CapacityLimiter` directly. - - """ - warn('create_capacity_limiter() is deprecated -- use CapacityLimiter() directly', - DeprecationWarning) - return get_asynclib().CapacityLimiter(total_tokens) - - -class ResourceGuard: - __slots__ = 'action', '_guarded' - - def __init__(self, action: str): - self.action = action - self._guarded = False - - def __enter__(self) -> None: - if self._guarded: - raise BusyResourceError(self.action) - - self._guarded = True - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - self._guarded = False - return None diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_tasks.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_tasks.py deleted file mode 100644 index 8bbad974..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_tasks.py +++ /dev/null @@ -1,158 +0,0 @@ -import math -from types import TracebackType -from typing import Optional, Type -from warnings import warn - -from ..abc._tasks import TaskGroup, TaskStatus -from ._compat import DeprecatedAsyncContextManager, DeprecatedAwaitable, DeprecatedAwaitableFloat -from ._eventloop import get_asynclib - - -class _IgnoredTaskStatus(TaskStatus): - def started(self, value: object = None) -> None: - pass - - -TASK_STATUS_IGNORED = _IgnoredTaskStatus() - - -class CancelScope(DeprecatedAsyncContextManager['CancelScope']): - """ - Wraps a unit of work that can be made separately cancellable. - - :param deadline: The time (clock value) when this scope is cancelled automatically - :param shield: ``True`` to shield the cancel scope from external cancellation - """ - - def __new__(cls, *, deadline: float = math.inf, shield: bool = False) -> 'CancelScope': - return get_asynclib().CancelScope(shield=shield, deadline=deadline) - - def cancel(self) -> DeprecatedAwaitable: - """Cancel this scope immediately.""" - raise NotImplementedError - - @property - def deadline(self) -> float: - """ - The time (clock value) when this scope is cancelled automatically. - - Will be ``float('inf')`` if no timeout has been set. - - """ - raise NotImplementedError - - @deadline.setter - def deadline(self, value: float) -> None: - raise NotImplementedError - - @property - def cancel_called(self) -> bool: - """``True`` if :meth:`cancel` has been called.""" - raise NotImplementedError - - @property - def shield(self) -> bool: - """ - ``True`` if this scope is shielded from external cancellation. - - While a scope is shielded, it will not receive cancellations from outside. - - """ - raise NotImplementedError - - @shield.setter - def shield(self, value: bool) -> None: - raise NotImplementedError - - def __enter__(self) -> 'CancelScope': - raise NotImplementedError - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - raise NotImplementedError - - -def open_cancel_scope(*, shield: bool = False) -> CancelScope: - """ - Open a cancel scope. - - :param shield: ``True`` to shield the cancel scope from external cancellation - :return: a cancel scope - - .. deprecated:: 3.0 - Use :class:`~CancelScope` directly. - - """ - warn('open_cancel_scope() is deprecated -- use CancelScope() directly', DeprecationWarning) - return get_asynclib().CancelScope(shield=shield) - - -class FailAfterContextManager(DeprecatedAsyncContextManager): - def __init__(self, cancel_scope: CancelScope): - self._cancel_scope = cancel_scope - - def __enter__(self) -> CancelScope: - return self._cancel_scope.__enter__() - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - retval = self._cancel_scope.__exit__(exc_type, exc_val, exc_tb) - if self._cancel_scope.cancel_called: - raise TimeoutError - - return retval - - -def fail_after(delay: Optional[float], shield: bool = False) -> FailAfterContextManager: - """ - Create a context manager which raises a :class:`TimeoutError` if does not finish in time. - - :param delay: maximum allowed time (in seconds) before raising the exception, or ``None`` to - disable the timeout - :param shield: ``True`` to shield the cancel scope from external cancellation - :return: a context manager that yields a cancel scope - :rtype: :class:`~typing.ContextManager`\\[:class:`~anyio.abc.CancelScope`\\] - - """ - deadline = (get_asynclib().current_time() + delay) if delay is not None else math.inf - cancel_scope = get_asynclib().CancelScope(deadline=deadline, shield=shield) - return FailAfterContextManager(cancel_scope) - - -def move_on_after(delay: Optional[float], shield: bool = False) -> CancelScope: - """ - Create a cancel scope with a deadline that expires after the given delay. - - :param delay: maximum allowed time (in seconds) before exiting the context block, or ``None`` - to disable the timeout - :param shield: ``True`` to shield the cancel scope from external cancellation - :return: a cancel scope - - """ - deadline = (get_asynclib().current_time() + delay) if delay is not None else math.inf - return get_asynclib().CancelScope(deadline=deadline, shield=shield) - - -def current_effective_deadline() -> DeprecatedAwaitableFloat: - """ - Return the nearest deadline among all the cancel scopes effective for the current task. - - :return: a clock value from the event loop's internal clock (``float('inf')`` if there is no - deadline in effect) - :rtype: float - - """ - return DeprecatedAwaitableFloat(get_asynclib().current_effective_deadline(), - current_effective_deadline) - - -def create_task_group() -> 'TaskGroup': - """ - Create a task group. - - :return: a task group - - """ - return get_asynclib().TaskGroup() diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_testing.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_testing.py deleted file mode 100644 index c48bd45e..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_testing.py +++ /dev/null @@ -1,74 +0,0 @@ -from typing import Coroutine, Generator, Optional - -from ._compat import DeprecatedAwaitableList, _warn_deprecation -from ._eventloop import get_asynclib - - -class TaskInfo: - """ - Represents an asynchronous task. - - :ivar int id: the unique identifier of the task - :ivar parent_id: the identifier of the parent task, if any - :vartype parent_id: Optional[int] - :ivar str name: the description of the task (if any) - :ivar ~collections.abc.Coroutine coro: the coroutine object of the task - """ - - __slots__ = '_name', 'id', 'parent_id', 'name', 'coro' - - def __init__(self, id: int, parent_id: Optional[int], name: Optional[str], coro: Coroutine): - func = get_current_task - self._name = f'{func.__module__}.{func.__qualname__}' - self.id = id - self.parent_id = parent_id - self.name = name - self.coro = coro - - def __eq__(self, other: object) -> bool: - if isinstance(other, TaskInfo): - return self.id == other.id - - return NotImplemented - - def __hash__(self) -> int: - return hash(self.id) - - def __repr__(self) -> str: - return f'{self.__class__.__name__}(id={self.id!r}, name={self.name!r})' - - def __await__(self) -> Generator[None, None, "TaskInfo"]: - _warn_deprecation(self) - if False: - yield - - return self - - def _unwrap(self) -> 'TaskInfo': - return self - - -def get_current_task() -> TaskInfo: - """ - Return the current task. - - :return: a representation of the current task - - """ - return get_asynclib().get_current_task() - - -def get_running_tasks() -> DeprecatedAwaitableList[TaskInfo]: - """ - Return a list of running tasks in the current event loop. - - :return: a list of task info objects - - """ - tasks = get_asynclib().get_running_tasks() - return DeprecatedAwaitableList(tasks, func=get_running_tasks) - - -async def wait_all_tasks_blocked() -> None: - """Wait until all other tasks are waiting for something.""" - await get_asynclib().wait_all_tasks_blocked() diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_typedattr.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_typedattr.py deleted file mode 100644 index 797287db..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/_core/_typedattr.py +++ /dev/null @@ -1,79 +0,0 @@ -import sys -from typing import Any, Callable, Dict, Mapping, TypeVar, Union, overload - -from ._exceptions import TypedAttributeLookupError - -if sys.version_info >= (3, 8): - from typing import final -else: - from typing_extensions import final - -T_Attr = TypeVar('T_Attr') -T_Default = TypeVar('T_Default') -undefined = object() - - -def typed_attribute() -> Any: - """Return a unique object, used to mark typed attributes.""" - return object() - - -class TypedAttributeSet: - """ - Superclass for typed attribute collections. - - Checks that every public attribute of every subclass has a type annotation. - """ - - def __init_subclass__(cls) -> None: - annotations: Dict[str, Any] = getattr(cls, '__annotations__', {}) - for attrname in dir(cls): - if not attrname.startswith('_') and attrname not in annotations: - raise TypeError(f'Attribute {attrname!r} is missing its type annotation') - - super().__init_subclass__() - - -class TypedAttributeProvider: - """Base class for classes that wish to provide typed extra attributes.""" - - @property - def extra_attributes(self) -> Mapping[T_Attr, Callable[[], T_Attr]]: - """ - A mapping of the extra attributes to callables that return the corresponding values. - - If the provider wraps another provider, the attributes from that wrapper should also be - included in the returned mapping (but the wrapper may override the callables from the - wrapped instance). - - """ - return {} - - @overload - def extra(self, attribute: T_Attr) -> T_Attr: - ... - - @overload - def extra(self, attribute: T_Attr, default: T_Default) -> Union[T_Attr, T_Default]: - ... - - @final - def extra(self, attribute: Any, default: object = undefined) -> object: - """ - extra(attribute, default=undefined) - - Return the value of the given typed extra attribute. - - :param attribute: the attribute (member of a :class:`~TypedAttributeSet`) to look for - :param default: the value that should be returned if no value is found for the attribute - :raises ~anyio.TypedAttributeLookupError: if the search failed and no default value was - given - - """ - try: - return self.extra_attributes[attribute]() - except KeyError: - if default is undefined: - raise TypedAttributeLookupError('Attribute not found') from None - else: - return default diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__init__.py deleted file mode 100644 index 59f8960d..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -__all__ = ('AsyncResource', 'IPAddressType', 'IPSockAddrType', 'SocketAttribute', 'SocketStream', - 'SocketListener', 'UDPSocket', 'UNIXSocketStream', 'UDPPacketType', - 'ConnectedUDPSocket', 'UnreliableObjectReceiveStream', 'UnreliableObjectSendStream', - 'UnreliableObjectStream', 'ObjectReceiveStream', 'ObjectSendStream', 'ObjectStream', - 'ByteReceiveStream', 'ByteSendStream', 'ByteStream', 'AnyUnreliableByteReceiveStream', - 'AnyUnreliableByteSendStream', 'AnyUnreliableByteStream', 'AnyByteReceiveStream', - 'AnyByteSendStream', 'AnyByteStream', 'Listener', 'Process', 'Event', - 'Condition', 'Lock', 'Semaphore', 'CapacityLimiter', 'CancelScope', 'TaskGroup', - 'TaskStatus', 'TestRunner', 'BlockingPortal') - -from ._resources import AsyncResource -from ._sockets import ( - ConnectedUDPSocket, IPAddressType, IPSockAddrType, SocketAttribute, SocketListener, - SocketStream, UDPPacketType, UDPSocket, UNIXSocketStream) -from ._streams import ( - AnyByteReceiveStream, AnyByteSendStream, AnyByteStream, AnyUnreliableByteReceiveStream, - AnyUnreliableByteSendStream, AnyUnreliableByteStream, ByteReceiveStream, ByteSendStream, - ByteStream, Listener, ObjectReceiveStream, ObjectSendStream, ObjectStream, - UnreliableObjectReceiveStream, UnreliableObjectSendStream, UnreliableObjectStream) -from ._subprocesses import Process -from ._tasks import TaskGroup, TaskStatus -from ._testing import TestRunner - -# Re-exported here, for backwards compatibility -# isort: off -from .._core._synchronization import CapacityLimiter, Condition, Event, Lock, Semaphore -from .._core._tasks import CancelScope -from ..from_thread import BlockingPortal - -# Re-export imports so they look like they live directly in this package -for key, value in list(locals().items()): - if getattr(value, '__module__', '').startswith('anyio.abc.'): - value.__module__ = __name__ diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 7954d1808cc39238b1f8ef8d2db691e5e150a335..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1703 zcmb_cTW=dh6yEjS>-8l!=YDO{#wB%tl#38TxJd;OQL*AiLPtiU@$L{W+1WKS;~@7n ze}JFRKJu654e`{M{s0~jXLbWg2|OUNlD~7?b7pxN%2t{6k5-&rUJK*pNRJaRn@@_7y z@*3259qPOR4L$`^d>W?t49xIZnB{XY$D7dP^DxgBV1X~fB42_fz6{HJ1y=YftR{8x z;Tm6u^+Yd(8+;Qs`4(&?b}_uiw_zLgl3xyY_`hws5& zqF2I4ybW#JV*BjfE9>QZudFNk$oh7ppMm$`fIVghzUx=7vM)dIYp-nahJDBm$VWfC z@#{US)oAVLYDZ2Y@07`SEIg*G$K8(a3nu0B$%yINakm$H7si#?bz?ErQAz}Zv0~ay z9X%x&<+_$yCxKKfVnUbCj*@()bmQ#V@i%Y1T*Y9QnsQ0$>BBgRn5US3leBsk2^I!) z5VEfa-(&EUc`UeO*T*gWJ=|lFe;sSyiKU-7^G}5usqmw*1B(V`4a^y68kjOLZD7X0l7X6mx`Bp)iUHR^6#>6v*@%qTGOl~6Ya7LD z^G&V1*gzpx4XhYgGq8?;nVYHDL7^Q&cjg*5|POs$^X;`z_f%?`G5BVszi%$jGOLHOK9=d?TLqnWYoINge z_JU1x{*s1criyNKPfm14;8xMJkfPejq~`?L~P*#VS$hI$0;+!5?gM-Gknb zWFk|DX{i+;(cGu9C0F*4R$DfJMB8=xc3z2R%IcXBYVoy|!RQ|l$wu6&OcdPOY+IX* z7X{3;ReV&ajN{3%(UqRr%p7E}y_Qe$LYvnXLNZ>R4ivho)oz`YyyCBv$=;49VhqRY znW=16k5x9QY|SeHPHk1Oo#`r5aK>DLTrv{?!ul&VQ0I-8+#`DF!*(Zi&+kE9B0TKk zWoAK7NQ*vxU*NM5n0I88e5QlXU<`JY=^UD0TX!~wPv_%WS3?8W>vFg$##$G{2M_P| znH7dll^OPSRJAjFG#L%;q*hm_P;nqIPb_u@`*fvroRu=CGa(E zScV>rm-=<1CG&HzYVd@)faXXDa~7tqiI6~K#&CBDJ6v4)8@7+>(j~J0YA-4DVX(Mx z8~e)F|4^ykV0rzSzk!%FSi5`#Ay}-PhH${C<5I>dUMj{=@>0uLfqt8@H#1%w>?Djy zEf_N?UWD~9`1VW;#&vGN6S%u8lz+Geg*6w^glG`P35~p3D3ob}!E_eWr8G)b!xoKc z`n%l-sNV(Yo6x|36kgY$yW&D<6N5$bsa*q0ZT*EV27gk$I)-HujPrQ$rhh?j>GdVw Q8z{fU*j3u5Ye5?R0q%ZA(f|Me diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_sockets.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_sockets.cpython-39.pyc deleted file mode 100644 index e161ee33d3ae325ae6f84d35426b15c19cdd0da8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6657 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 n&Hx|+;;$;$ diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_streams.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_streams.cpython-39.pyc deleted file mode 100644 index fbae3e03a14409263fbe061f4b2fae5f21a34982..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7466 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-39.pyc deleted file mode 100644 index ae8cad977a740077d595330453bf137e8b1e6bd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2901 zcmcIm&2HO95GJXAS(0rzanMV!#|TK7{-8i06ouW!NL0JFVYzTX2qjnCwMB$K>h8*} zd`%uBFOYlRpij_S!CTQ&&b<^p6rCX{nsr@6Y0(9CFuSw6^UcTES<-g9sX_bsk8S!} zP1AnCL9vx#umxQ{1Hm+=`&yt|x{kWx8$rn`fnH)|zZ_JoN}^Z%YEZLkLEWnB+Ea~H zS?!g^YP|BYWHnfQsP!6e;WVwM#~nJBN>En?TumYdGxdY1@}iLXZ}oIZdt1&!_lV1A zCS2Y#;`PtxiXU;8d*^(p1gAmV!Kon+Svq#{^kS>PU<qE!PQKJE|R}!sAK;Dy2ONFI(RcK zziE=JolsAaS*Sdps0k<8v4nr;DQPzIW&QNisv`8$B*d?w<-w z(nS1z@}xgHoKI8~jsy)^6pV)MB#QjeV0UNRmad>vE=J}#56?$?-gqQE#owP&_XR!U zazw+q7d@h5_mO=SK9}Zn9+xj5h!qUc0HGO|t&B_)4f{7T@&zt0F!E~-{+Nrv3#sC= z7~4Z~2FcD(XTCot-YJBW( z!-L`AIgxXzc(B+k;ZES@;o#}<&e2znLsV1*RB&vXL~>4j8TI?5kN5HKDPpQcSWfPF zKm9n!+|_3iZ5YOleE9|vmGQd1;5D}{#qE!|$6XH@DWpsxivNwi-ND}8f2QvRAYY2P zGOoN|AT3WuG(ZuoO79Gcq-ekzHz5`jY^dX9y`Gxi=k#HnB$T8FEb`&%HWbKQDkU(* z?DR0FaMh<&&>(Y?Uii#mI19#HkO$m6GfAIOMIq0UU`)u;XI~#Wy&P(qTRlUxAR@7j zBCiB#imepf_rShLvW-QO73@o;+5O`}0UJEIR-DXRvb{9**vC19(&fqm0?aSv`XY}T zF{HKfrV442!CxvSnNUf>NRc^LB)?QFs~;DTFl5a0vmIwY3VE@1+!9kWdk&yXKQ4sU zU4(XJUMj*5F)(=W;mszekx1^aR8YpLV8jcjGxZL9SEOQIxK)7FUcgE$OCkE`Hbl`( zy&I$|IEGC-1x%d+CNM1p>hW!$xDdeHzk&u^zx)SiVCrqeb=wYUz->Ej+IA4JnU8wQ zw!fWGKeNG8$qSX}fF@Q^tfAUNr&GKH2PMejF3i|e1J1bv3pR^qaj-ZEPHTIo+k5W$oH diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_tasks.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/__pycache__/_tasks.cpython-39.pyc deleted file mode 100644 index d96c0662202da2ada2522a82340bdcae6bb0c30e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3727 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 G T: - return self - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> None: - await self.aclose() - - @abstractmethod - async def aclose(self) -> None: - """Close the resource.""" diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_sockets.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_sockets.py deleted file mode 100644 index a05151eb..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_sockets.py +++ /dev/null @@ -1,156 +0,0 @@ -import socket -from abc import abstractmethod -from io import IOBase -from ipaddress import IPv4Address, IPv6Address -from socket import AddressFamily -from types import TracebackType -from typing import ( - Any, AsyncContextManager, Callable, Collection, Dict, List, Mapping, Optional, Tuple, Type, - TypeVar, Union) - -from .._core._typedattr import TypedAttributeProvider, TypedAttributeSet, typed_attribute -from ._streams import ByteStream, Listener, T_Stream, UnreliableObjectStream -from ._tasks import TaskGroup - -IPAddressType = Union[str, IPv4Address, IPv6Address] -IPSockAddrType = Tuple[str, int] -SockAddrType = Union[IPSockAddrType, str] -UDPPacketType = Tuple[bytes, IPSockAddrType] -T_Retval = TypeVar('T_Retval') - - -class _NullAsyncContextManager: - async def __aenter__(self) -> None: - pass - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - return None - - -class SocketAttribute(TypedAttributeSet): - #: the address family of the underlying socket - family: AddressFamily = typed_attribute() - #: the local socket address of the underlying socket - local_address: SockAddrType = typed_attribute() - #: for IP addresses, the local port the underlying socket is bound to - local_port: int = typed_attribute() - #: the underlying stdlib socket object - raw_socket: socket.socket = typed_attribute() - #: the remote address the underlying socket is connected to - remote_address: SockAddrType = typed_attribute() - #: for IP addresses, the remote port the underlying socket is connected to - remote_port: int = typed_attribute() - - -class _SocketProvider(TypedAttributeProvider): - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - from .._core._sockets import convert_ipv6_sockaddr as convert - - attributes: Dict[Any, Callable[[], Any]] = { - SocketAttribute.family: lambda: self._raw_socket.family, - SocketAttribute.local_address: lambda: convert(self._raw_socket.getsockname()), - SocketAttribute.raw_socket: lambda: self._raw_socket - } - try: - peername: Optional[Tuple[str, int]] = convert(self._raw_socket.getpeername()) - except OSError: - peername = None - - # Provide the remote address for connected sockets - if peername is not None: - attributes[SocketAttribute.remote_address] = lambda: peername - - # Provide local and remote ports for IP based sockets - if self._raw_socket.family in (AddressFamily.AF_INET, AddressFamily.AF_INET6): - attributes[SocketAttribute.local_port] = lambda: self._raw_socket.getsockname()[1] - if peername is not None: - remote_port = peername[1] - attributes[SocketAttribute.remote_port] = lambda: remote_port - - return attributes - - @property - @abstractmethod - def _raw_socket(self) -> socket.socket: - pass - - -class SocketStream(ByteStream, _SocketProvider): - """ - Transports bytes over a socket. - - Supports all relevant extra attributes from :class:`~SocketAttribute`. - """ - - -class UNIXSocketStream(SocketStream): - @abstractmethod - async def send_fds(self, message: bytes, fds: Collection[Union[int, IOBase]]) -> None: - """ - Send file descriptors along with a message to the peer. - - :param message: a non-empty bytestring - :param fds: a collection of files (either numeric file descriptors or open file or socket - objects) - """ - - @abstractmethod - async def receive_fds(self, msglen: int, maxfds: int) -> Tuple[bytes, List[int]]: - """ - Receive file descriptors along with a message from the peer. - - :param msglen: length of the message to expect from the peer - :param maxfds: maximum number of file descriptors to expect from the peer - :return: a tuple of (message, file descriptors) - """ - - -class SocketListener(Listener[SocketStream], _SocketProvider): - """ - Listens to incoming socket connections. - - Supports all relevant extra attributes from :class:`~SocketAttribute`. - """ - - @abstractmethod - async def accept(self) -> SocketStream: - """Accept an incoming connection.""" - - async def serve(self, handler: Callable[[T_Stream], Any], - task_group: Optional[TaskGroup] = None) -> None: - from .. import create_task_group - - context_manager: AsyncContextManager - if task_group is None: - task_group = context_manager = create_task_group() - else: - # Can be replaced with AsyncExitStack once on py3.7+ - context_manager = _NullAsyncContextManager() - - async with context_manager: - while True: - stream = await self.accept() - task_group.start_soon(handler, stream) - - -class UDPSocket(UnreliableObjectStream[UDPPacketType], _SocketProvider): - """ - Represents an unconnected UDP socket. - - Supports all relevant extra attributes from :class:`~SocketAttribute`. - """ - - async def sendto(self, data: bytes, host: str, port: int) -> None: - """Alias for :meth:`~.UnreliableObjectSendStream.send` ((data, (host, port))).""" - return await self.send((data, (host, port))) - - -class ConnectedUDPSocket(UnreliableObjectStream[bytes], _SocketProvider): - """ - Represents an connected UDP socket. - - Supports all relevant extra attributes from :class:`~SocketAttribute`. - """ diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_streams.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_streams.py deleted file mode 100644 index 635b8184..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_streams.py +++ /dev/null @@ -1,187 +0,0 @@ -from abc import abstractmethod -from typing import Any, Callable, Generic, Optional, TypeVar, Union - -from .._core._exceptions import EndOfStream -from .._core._typedattr import TypedAttributeProvider -from ._resources import AsyncResource -from ._tasks import TaskGroup - -T_Item = TypeVar('T_Item') -T_Stream = TypeVar('T_Stream') - - -class UnreliableObjectReceiveStream(Generic[T_Item], AsyncResource, TypedAttributeProvider): - """ - An interface for receiving objects. - - This interface makes no guarantees that the received messages arrive in the order in which they - were sent, or that no messages are missed. - - Asynchronously iterating over objects of this type will yield objects matching the given type - parameter. - """ - - def __aiter__(self) -> "UnreliableObjectReceiveStream[T_Item]": - return self - - async def __anext__(self) -> T_Item: - try: - return await self.receive() - except EndOfStream: - raise StopAsyncIteration - - @abstractmethod - async def receive(self) -> T_Item: - """ - Receive the next item. - - :raises ~anyio.ClosedResourceError: if the receive stream has been explicitly - closed - :raises ~anyio.EndOfStream: if this stream has been closed from the other end - :raises ~anyio.BrokenResourceError: if this stream has been rendered unusable - due to external causes - """ - - -class UnreliableObjectSendStream(Generic[T_Item], AsyncResource, TypedAttributeProvider): - """ - An interface for sending objects. - - This interface makes no guarantees that the messages sent will reach the recipient(s) in the - same order in which they were sent, or at all. - """ - - @abstractmethod - async def send(self, item: T_Item) -> None: - """ - Send an item to the peer(s). - - :param item: the item to send - :raises ~anyio.ClosedResourceError: if the send stream has been explicitly - closed - :raises ~anyio.BrokenResourceError: if this stream has been rendered unusable - due to external causes - """ - - -class UnreliableObjectStream(UnreliableObjectReceiveStream[T_Item], - UnreliableObjectSendStream[T_Item]): - """ - A bidirectional message stream which does not guarantee the order or reliability of message - delivery. - """ - - -class ObjectReceiveStream(UnreliableObjectReceiveStream[T_Item]): - """ - A receive message stream which guarantees that messages are received in the same order in - which they were sent, and that no messages are missed. - """ - - -class ObjectSendStream(UnreliableObjectSendStream[T_Item]): - """ - A send message stream which guarantees that messages are delivered in the same order in which - they were sent, without missing any messages in the middle. - """ - - -class ObjectStream(ObjectReceiveStream[T_Item], ObjectSendStream[T_Item], - UnreliableObjectStream[T_Item]): - """ - A bidirectional message stream which guarantees the order and reliability of message delivery. - """ - - @abstractmethod - async def send_eof(self) -> None: - """ - Send an end-of-file indication to the peer. - - You should not try to send any further data to this stream after calling this method. - This method is idempotent (does nothing on successive calls). - """ - - -class ByteReceiveStream(AsyncResource, TypedAttributeProvider): - """ - An interface for receiving bytes from a single peer. - - Iterating this byte stream will yield a byte string of arbitrary length, but no more than - 65536 bytes. - """ - - def __aiter__(self) -> 'ByteReceiveStream': - return self - - async def __anext__(self) -> bytes: - try: - return await self.receive() - except EndOfStream: - raise StopAsyncIteration - - @abstractmethod - async def receive(self, max_bytes: int = 65536) -> bytes: - """ - Receive at most ``max_bytes`` bytes from the peer. - - .. note:: Implementors of this interface should not return an empty :class:`bytes` object, - and users should ignore them. - - :param max_bytes: maximum number of bytes to receive - :return: the received bytes - :raises ~anyio.EndOfStream: if this stream has been closed from the other end - """ - - -class ByteSendStream(AsyncResource, TypedAttributeProvider): - """An interface for sending bytes to a single peer.""" - - @abstractmethod - async def send(self, item: bytes) -> None: - """ - Send the given bytes to the peer. - - :param item: the bytes to send - """ - - -class ByteStream(ByteReceiveStream, ByteSendStream): - """A bidirectional byte stream.""" - - @abstractmethod - async def send_eof(self) -> None: - """ - Send an end-of-file indication to the peer. - - You should not try to send any further data to this stream after calling this method. - This method is idempotent (does nothing on successive calls). - """ - - -#: Type alias for all unreliable bytes-oriented receive streams. -AnyUnreliableByteReceiveStream = Union[UnreliableObjectReceiveStream[bytes], ByteReceiveStream] -#: Type alias for all unreliable bytes-oriented send streams. -AnyUnreliableByteSendStream = Union[UnreliableObjectSendStream[bytes], ByteSendStream] -#: Type alias for all unreliable bytes-oriented streams. -AnyUnreliableByteStream = Union[UnreliableObjectStream[bytes], ByteStream] -#: Type alias for all bytes-oriented receive streams. -AnyByteReceiveStream = Union[ObjectReceiveStream[bytes], ByteReceiveStream] -#: Type alias for all bytes-oriented send streams. -AnyByteSendStream = Union[ObjectSendStream[bytes], ByteSendStream] -#: Type alias for all bytes-oriented streams. -AnyByteStream = Union[ObjectStream[bytes], ByteStream] - - -class Listener(Generic[T_Stream], AsyncResource, TypedAttributeProvider): - """An interface for objects that let you accept incoming connections.""" - - @abstractmethod - async def serve(self, handler: Callable[[T_Stream], Any], - task_group: Optional[TaskGroup] = None) -> None: - """ - Accept incoming connections as they come in and start tasks to handle them. - - :param handler: a callable that will be used to handle each accepted connection - :param task_group: the task group that will be used to start tasks for handling each - accepted connection (if omitted, an ad-hoc task group will be created) - """ diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_subprocesses.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_subprocesses.py deleted file mode 100644 index d2f95831..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_subprocesses.py +++ /dev/null @@ -1,77 +0,0 @@ -from abc import abstractmethod -from typing import Optional - -from ._resources import AsyncResource -from ._streams import ByteReceiveStream, ByteSendStream - - -class Process(AsyncResource): - """An asynchronous version of :class:`subprocess.Popen`.""" - - @abstractmethod - async def wait(self) -> int: - """ - Wait until the process exits. - - :return: the exit code of the process - """ - - @abstractmethod - def terminate(self) -> None: - """ - Terminates the process, gracefully if possible. - - On Windows, this calls ``TerminateProcess()``. - On POSIX systems, this sends ``SIGTERM`` to the process. - - .. seealso:: :meth:`subprocess.Popen.terminate` - """ - - @abstractmethod - def kill(self) -> None: - """ - Kills the process. - - On Windows, this calls ``TerminateProcess()``. - On POSIX systems, this sends ``SIGKILL`` to the process. - - .. seealso:: :meth:`subprocess.Popen.kill` - """ - - @abstractmethod - def send_signal(self, signal: int) -> None: - """ - Send a signal to the subprocess. - - .. seealso:: :meth:`subprocess.Popen.send_signal` - - :param signal: the signal number (e.g. :data:`signal.SIGHUP`) - """ - - @property - @abstractmethod - def pid(self) -> int: - """The process ID of the process.""" - - @property - @abstractmethod - def returncode(self) -> Optional[int]: - """ - The return code of the process. If the process has not yet terminated, this will be - ``None``. - """ - - @property - @abstractmethod - def stdin(self) -> Optional[ByteSendStream]: - """The stream for the standard input of the process.""" - - @property - @abstractmethod - def stdout(self) -> Optional[ByteReceiveStream]: - """The stream for the standard output of the process.""" - - @property - @abstractmethod - def stderr(self) -> Optional[ByteReceiveStream]: - """The stream for the standard error output of the process.""" diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_tasks.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_tasks.py deleted file mode 100644 index afa2d983..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_tasks.py +++ /dev/null @@ -1,87 +0,0 @@ -import typing -from abc import ABCMeta, abstractmethod -from types import TracebackType -from typing import Callable, Coroutine, Optional, Type, TypeVar -from warnings import warn - -if typing.TYPE_CHECKING: - from anyio._core._tasks import CancelScope - -T_Retval = TypeVar('T_Retval') - - -class TaskStatus(metaclass=ABCMeta): - @abstractmethod - def started(self, value: object = None) -> None: - """ - Signal that the task has started. - - :param value: object passed back to the starter of the task - """ - - -class TaskGroup(metaclass=ABCMeta): - """ - Groups several asynchronous tasks together. - - :ivar cancel_scope: the cancel scope inherited by all child tasks - :vartype cancel_scope: CancelScope - """ - - cancel_scope: 'CancelScope' - - async def spawn(self, func: Callable[..., Coroutine], - *args: object, name: object = None) -> None: - """ - Start a new task in this task group. - - :param func: a coroutine function - :param args: positional arguments to call the function with - :param name: name of the task, for the purposes of introspection and debugging - - .. deprecated:: 3.0 - Use :meth:`start_soon` instead. If your code needs AnyIO 2 compatibility, you - can keep using this until AnyIO 4. - - """ - warn('spawn() is deprecated -- use start_soon() (without the "await") instead', - DeprecationWarning) - self.start_soon(func, *args, name=name) - - @abstractmethod - def start_soon(self, func: Callable[..., Coroutine], - *args: object, name: object = None) -> None: - """ - Start a new task in this task group. - - :param func: a coroutine function - :param args: positional arguments to call the function with - :param name: name of the task, for the purposes of introspection and debugging - - .. versionadded:: 3.0 - """ - - @abstractmethod - async def start(self, func: Callable[..., Coroutine], - *args: object, name: object = None) -> object: - """ - Start a new task and wait until it signals for readiness. - - :param func: a coroutine function - :param args: positional arguments to call the function with - :param name: name of the task, for the purposes of introspection and debugging - :return: the value passed to ``task_status.started()`` - :raises RuntimeError: if the task finishes without calling ``task_status.started()`` - - .. versionadded:: 3.0 - """ - - @abstractmethod - async def __aenter__(self) -> 'TaskGroup': - """Enter the task group context and allow starting new tasks.""" - - @abstractmethod - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - """Exit the task group context waiting for all tasks to finish.""" diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_testing.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_testing.py deleted file mode 100644 index 2cc9822f..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/abc/_testing.py +++ /dev/null @@ -1,37 +0,0 @@ -import types -from abc import ABCMeta, abstractmethod -from typing import Any, Awaitable, Callable, Dict, Optional, Type, TypeVar - -_T = TypeVar("_T") - - -class TestRunner(metaclass=ABCMeta): - """ - Encapsulates a running event loop. Every call made through this object will use the same event - loop. - """ - - def __enter__(self) -> 'TestRunner': - return self - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[types.TracebackType]) -> Optional[bool]: - self.close() - return None - - @abstractmethod - def close(self) -> None: - """Close the event loop.""" - - @abstractmethod - def call(self, func: Callable[..., Awaitable[_T]], - *args: object, **kwargs: Dict[str, Any]) -> _T: - """ - Call the given function within the backend's event loop. - - :param func: a callable returning an awaitable - :param args: positional arguments to call ``func`` with - :param kwargs: keyword arguments to call ``func`` with - :return: the return value of ``func`` - """ diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/from_thread.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/from_thread.py deleted file mode 100644 index d845f993..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/from_thread.py +++ /dev/null @@ -1,406 +0,0 @@ -import threading -from asyncio import iscoroutine -from concurrent.futures import FIRST_COMPLETED, Future, ThreadPoolExecutor, wait -from contextlib import AbstractContextManager, contextmanager -from types import TracebackType -from typing import ( - Any, AsyncContextManager, Callable, ContextManager, Coroutine, Dict, Generator, Iterable, - Optional, Tuple, Type, TypeVar, Union, cast, overload) -from warnings import warn - -from ._core import _eventloop -from ._core._eventloop import get_asynclib, get_cancelled_exc_class, threadlocals -from ._core._synchronization import Event -from ._core._tasks import CancelScope, create_task_group -from .abc._tasks import TaskStatus - -T_Retval = TypeVar('T_Retval') -T_co = TypeVar('T_co') - - -def run(func: Callable[..., Coroutine[Any, Any, T_Retval]], *args: object) -> T_Retval: - """ - Call a coroutine function from a worker thread. - - :param func: a coroutine function - :param args: positional arguments for the callable - :return: the return value of the coroutine function - - """ - try: - asynclib = threadlocals.current_async_module - except AttributeError: - raise RuntimeError('This function can only be run from an AnyIO worker thread') - - return asynclib.run_async_from_thread(func, *args) - - -def run_async_from_thread(func: Callable[..., Coroutine[Any, Any, T_Retval]], - *args: object) -> T_Retval: - warn('run_async_from_thread() has been deprecated, use anyio.from_thread.run() instead', - DeprecationWarning) - return run(func, *args) - - -def run_sync(func: Callable[..., T_Retval], *args: object) -> T_Retval: - """ - Call a function in the event loop thread from a worker thread. - - :param func: a callable - :param args: positional arguments for the callable - :return: the return value of the callable - - """ - try: - asynclib = threadlocals.current_async_module - except AttributeError: - raise RuntimeError('This function can only be run from an AnyIO worker thread') - - return asynclib.run_sync_from_thread(func, *args) - - -def run_sync_from_thread(func: Callable[..., T_Retval], *args: object) -> T_Retval: - warn('run_sync_from_thread() has been deprecated, use anyio.from_thread.run_sync() instead', - DeprecationWarning) - return run_sync(func, *args) - - -class _BlockingAsyncContextManager(AbstractContextManager): - _enter_future: Future - _exit_future: Future - _exit_event: Event - _exit_exc_info: Tuple[Optional[Type[BaseException]], Optional[BaseException], - Optional[TracebackType]] - - def __init__(self, async_cm: AsyncContextManager[T_co], portal: 'BlockingPortal'): - self._async_cm = async_cm - self._portal = portal - - async def run_async_cm(self) -> Optional[bool]: - try: - self._exit_event = Event() - value = await self._async_cm.__aenter__() - except BaseException as exc: - self._enter_future.set_exception(exc) - raise - else: - self._enter_future.set_result(value) - - await self._exit_event.wait() - return await self._async_cm.__aexit__(*self._exit_exc_info) - - def __enter__(self) -> T_co: - self._enter_future = Future() - self._exit_future = self._portal.start_task_soon(self.run_async_cm) - cm = self._enter_future.result() - return cast(T_co, cm) - - def __exit__(self, __exc_type: Optional[Type[BaseException]], - __exc_value: Optional[BaseException], - __traceback: Optional[TracebackType]) -> Optional[bool]: - self._exit_exc_info = __exc_type, __exc_value, __traceback - self._portal.call(self._exit_event.set) - return self._exit_future.result() - - -class _BlockingPortalTaskStatus(TaskStatus): - def __init__(self, future: Future): - self._future = future - - def started(self, value: object = None) -> None: - self._future.set_result(value) - - -class BlockingPortal: - """An object that lets external threads run code in an asynchronous event loop.""" - - def __new__(cls) -> 'BlockingPortal': - return get_asynclib().BlockingPortal() - - def __init__(self) -> None: - self._event_loop_thread_id: Optional[int] = threading.get_ident() - self._stop_event = Event() - self._task_group = create_task_group() - self._cancelled_exc_class = get_cancelled_exc_class() - - async def __aenter__(self) -> 'BlockingPortal': - await self._task_group.__aenter__() - return self - - async def __aexit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> Optional[bool]: - await self.stop() - return await self._task_group.__aexit__(exc_type, exc_val, exc_tb) - - def _check_running(self) -> None: - if self._event_loop_thread_id is None: - raise RuntimeError('This portal is not running') - if self._event_loop_thread_id == threading.get_ident(): - raise RuntimeError('This method cannot be called from the event loop thread') - - async def sleep_until_stopped(self) -> None: - """Sleep until :meth:`stop` is called.""" - await self._stop_event.wait() - - async def stop(self, cancel_remaining: bool = False) -> None: - """ - Signal the portal to shut down. - - This marks the portal as no longer accepting new calls and exits from - :meth:`sleep_until_stopped`. - - :param cancel_remaining: ``True`` to cancel all the remaining tasks, ``False`` to let them - finish before returning - - """ - self._event_loop_thread_id = None - self._stop_event.set() - if cancel_remaining: - self._task_group.cancel_scope.cancel() - - async def _call_func(self, func: Callable, args: tuple, kwargs: Dict[str, Any], - future: Future) -> None: - def callback(f: Future) -> None: - if f.cancelled() and self._event_loop_thread_id not in (None, threading.get_ident()): - self.call(scope.cancel) - - try: - retval = func(*args, **kwargs) - if iscoroutine(retval): - with CancelScope() as scope: - if future.cancelled(): - scope.cancel() - else: - future.add_done_callback(callback) - - retval = await retval - except self._cancelled_exc_class: - future.cancel() - except BaseException as exc: - if not future.cancelled(): - future.set_exception(exc) - - # Let base exceptions fall through - if not isinstance(exc, Exception): - raise - else: - if not future.cancelled(): - future.set_result(retval) - finally: - scope = None # type: ignore[assignment] - - def _spawn_task_from_thread(self, func: Callable, args: tuple, kwargs: Dict[str, Any], - name: object, future: Future) -> None: - """ - Spawn a new task using the given callable. - - Implementors must ensure that the future is resolved when the task finishes. - - :param func: a callable - :param args: positional arguments to be passed to the callable - :param kwargs: keyword arguments to be passed to the callable - :param name: name of the task (will be coerced to a string if not ``None``) - :param future: a future that will resolve to the return value of the callable, or the - exception raised during its execution - - """ - raise NotImplementedError - - @overload - def call(self, func: Callable[..., Coroutine[Any, Any, T_Retval]], *args: object) -> T_Retval: - ... - - @overload - def call(self, func: Callable[..., T_Retval], *args: object) -> T_Retval: - ... - - def call(self, func: Callable[..., Union[Coroutine[Any, Any, T_Retval], T_Retval]], - *args: object) -> T_Retval: - """ - Call the given function in the event loop thread. - - If the callable returns a coroutine object, it is awaited on. - - :param func: any callable - :raises RuntimeError: if the portal is not running or if this method is called from within - the event loop thread - - """ - return cast(T_Retval, self.start_task_soon(func, *args).result()) - - @overload - def spawn_task(self, func: Callable[..., Coroutine[Any, Any, T_Retval]], - *args: object, name: object = None) -> "Future[T_Retval]": - ... - - @overload - def spawn_task(self, func: Callable[..., T_Retval], - *args: object, name: object = None) -> "Future[T_Retval]": ... - - def spawn_task(self, func: Callable[..., Union[Coroutine[Any, Any, T_Retval], T_Retval]], - *args: object, name: object = None) -> "Future[T_Retval]": - """ - Start a task in the portal's task group. - - :param func: the target coroutine function - :param args: positional arguments passed to ``func`` - :param name: name of the task (will be coerced to a string if not ``None``) - :return: a future that resolves with the return value of the callable if the task completes - successfully, or with the exception raised in the task - :raises RuntimeError: if the portal is not running or if this method is called from within - the event loop thread - - .. versionadded:: 2.1 - .. deprecated:: 3.0 - Use :meth:`start_task_soon` instead. If your code needs AnyIO 2 compatibility, you - can keep using this until AnyIO 4. - - """ - warn('spawn_task() is deprecated -- use start_task_soon() instead', DeprecationWarning) - return self.start_task_soon(func, *args, name=name) # type: ignore[arg-type] - - @overload - def start_task_soon(self, func: Callable[..., Coroutine[Any, Any, T_Retval]], - *args: object, name: object = None) -> "Future[T_Retval]": - ... - - @overload - def start_task_soon(self, func: Callable[..., T_Retval], - *args: object, name: object = None) -> "Future[T_Retval]": ... - - def start_task_soon(self, func: Callable[..., Union[Coroutine[Any, Any, T_Retval], T_Retval]], - *args: object, name: object = None) -> "Future[T_Retval]": - """ - Start a task in the portal's task group. - - The task will be run inside a cancel scope which can be cancelled by cancelling the - returned future. - - :param func: the target coroutine function - :param args: positional arguments passed to ``func`` - :param name: name of the task (will be coerced to a string if not ``None``) - :return: a future that resolves with the return value of the callable if the task completes - successfully, or with the exception raised in the task - :raises RuntimeError: if the portal is not running or if this method is called from within - the event loop thread - - .. versionadded:: 3.0 - - """ - self._check_running() - f: Future = Future() - self._spawn_task_from_thread(func, args, {}, name, f) - return f - - def start_task(self, func: Callable[..., Coroutine], *args: object, - name: object = None) -> Tuple[Future, Any]: - """ - Start a task in the portal's task group and wait until it signals for readiness. - - This method works the same way as :meth:`TaskGroup.start`. - - :param func: the target coroutine function - :param args: positional arguments passed to ``func`` - :param name: name of the task (will be coerced to a string if not ``None``) - :return: a tuple of (future, task_status_value) where the ``task_status_value`` is the - value passed to ``task_status.started()`` from within the target function - - .. versionadded:: 3.0 - - """ - def task_done(future: Future) -> None: - if not task_status_future.done(): - if future.cancelled(): - task_status_future.cancel() - elif future.exception(): - task_status_future.set_exception(future.exception()) - else: - exc = RuntimeError('Task exited without calling task_status.started()') - task_status_future.set_exception(exc) - - self._check_running() - task_status_future: Future = Future() - task_status = _BlockingPortalTaskStatus(task_status_future) - f: Future = Future() - f.add_done_callback(task_done) - self._spawn_task_from_thread(func, args, {'task_status': task_status}, name, f) - return f, task_status_future.result() - - def wrap_async_context_manager(self, cm: AsyncContextManager[T_co]) -> ContextManager[T_co]: - """ - Wrap an async context manager as a synchronous context manager via this portal. - - Spawns a task that will call both ``__aenter__()`` and ``__aexit__()``, stopping in the - middle until the synchronous context manager exits. - - :param cm: an asynchronous context manager - :return: a synchronous context manager - - .. versionadded:: 2.1 - - """ - return _BlockingAsyncContextManager(cm, self) - - -def create_blocking_portal() -> BlockingPortal: - """ - Create a portal for running functions in the event loop thread from external threads. - - Use this function in asynchronous code when you need to allow external threads access to the - event loop where your asynchronous code is currently running. - - .. deprecated:: 3.0 - Use :class:`.BlockingPortal` directly. - - """ - warn('create_blocking_portal() has been deprecated -- use anyio.from_thread.BlockingPortal() ' - 'directly', DeprecationWarning) - return BlockingPortal() - - -@contextmanager -def start_blocking_portal( - backend: str = 'asyncio', - backend_options: Optional[Dict[str, Any]] = None) -> Generator[BlockingPortal, Any, None]: - """ - Start a new event loop in a new thread and run a blocking portal in its main task. - - The parameters are the same as for :func:`~anyio.run`. - - :param backend: name of the backend - :param backend_options: backend options - :return: a context manager that yields a blocking portal - - .. versionchanged:: 3.0 - Usage as a context manager is now required. - - """ - async def run_portal() -> None: - async with BlockingPortal() as portal_: - if future.set_running_or_notify_cancel(): - future.set_result(portal_) - await portal_.sleep_until_stopped() - - future: Future[BlockingPortal] = Future() - with ThreadPoolExecutor(1) as executor: - run_future = executor.submit(_eventloop.run, run_portal, backend=backend, - backend_options=backend_options) - try: - wait(cast(Iterable[Future], [run_future, future]), return_when=FIRST_COMPLETED) - except BaseException: - future.cancel() - run_future.cancel() - raise - - if future.done(): - portal = future.result() - try: - yield portal - except BaseException: - portal.call(portal.stop, True) - raise - - portal.call(portal.stop, False) - - run_future.result() diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/lowlevel.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/lowlevel.py deleted file mode 100644 index 471b7e6b..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/lowlevel.py +++ /dev/null @@ -1,160 +0,0 @@ -import enum -import sys -from dataclasses import dataclass -from typing import Any, Dict, Generic, Set, TypeVar, Union, overload -from weakref import WeakKeyDictionary - -from ._core._eventloop import get_asynclib - -if sys.version_info >= (3, 8): - from typing import Literal -else: - from typing_extensions import Literal - -T = TypeVar('T') -D = TypeVar('D') - - -async def checkpoint() -> None: - """ - Check for cancellation and allow the scheduler to switch to another task. - - Equivalent to (but more efficient than):: - - await checkpoint_if_cancelled() - await cancel_shielded_checkpoint() - - .. versionadded:: 3.0 - - """ - await get_asynclib().checkpoint() - - -async def checkpoint_if_cancelled() -> None: - """ - Enter a checkpoint if the enclosing cancel scope has been cancelled. - - This does not allow the scheduler to switch to a different task. - - .. versionadded:: 3.0 - - """ - await get_asynclib().checkpoint_if_cancelled() - - -async def cancel_shielded_checkpoint() -> None: - """ - Allow the scheduler to switch to another task but without checking for cancellation. - - Equivalent to (but potentially more efficient than):: - - with CancelScope(shield=True): - await checkpoint() - - .. versionadded:: 3.0 - - """ - await get_asynclib().cancel_shielded_checkpoint() - - -def current_token() -> object: - """Return a backend specific token object that can be used to get back to the event loop.""" - return get_asynclib().current_token() - - -_run_vars = WeakKeyDictionary() # type: WeakKeyDictionary[Any, Dict[str, Any]] -_token_wrappers: Dict[Any, '_TokenWrapper'] = {} - - -@dataclass(frozen=True) -class _TokenWrapper: - __slots__ = '_token', '__weakref__' - _token: object - - -class _NoValueSet(enum.Enum): - NO_VALUE_SET = enum.auto() - - -class RunvarToken(Generic[T]): - __slots__ = '_var', '_value', '_redeemed' - - def __init__(self, var: 'RunVar', value: Union[T, Literal[_NoValueSet.NO_VALUE_SET]]): - self._var = var - self._value: Union[T, Literal[_NoValueSet.NO_VALUE_SET]] = value - self._redeemed = False - - -class RunVar(Generic[T]): - """Like a :class:`~contextvars.ContextVar`, expect scoped to the running event loop.""" - __slots__ = '_name', '_default' - - NO_VALUE_SET: Literal[_NoValueSet.NO_VALUE_SET] = _NoValueSet.NO_VALUE_SET - - _token_wrappers: Set[_TokenWrapper] = set() - - def __init__(self, name: str, - default: Union[T, Literal[_NoValueSet.NO_VALUE_SET]] = NO_VALUE_SET): - self._name = name - self._default = default - - @property - def _current_vars(self) -> Dict[str, T]: - token = current_token() - while True: - try: - return _run_vars[token] - except TypeError: - # Happens when token isn't weak referable (TrioToken). - # This workaround does mean that some memory will leak on Trio until the problem - # is fixed on their end. - token = _TokenWrapper(token) - self._token_wrappers.add(token) - except KeyError: - run_vars = _run_vars[token] = {} - return run_vars - - @overload - def get(self, default: D) -> Union[T, D]: ... - - @overload - def get(self) -> T: ... - - def get( - self, default: Union[D, Literal[_NoValueSet.NO_VALUE_SET]] = NO_VALUE_SET - ) -> Union[T, D]: - try: - return self._current_vars[self._name] - except KeyError: - if default is not RunVar.NO_VALUE_SET: - return default - elif self._default is not RunVar.NO_VALUE_SET: - return self._default - - raise LookupError(f'Run variable "{self._name}" has no value and no default set') - - def set(self, value: T) -> RunvarToken[T]: - current_vars = self._current_vars - token = RunvarToken(self, current_vars.get(self._name, RunVar.NO_VALUE_SET)) - current_vars[self._name] = value - return token - - def reset(self, token: RunvarToken[T]) -> None: - if token._var is not self: - raise ValueError('This token does not belong to this RunVar') - - if token._redeemed: - raise ValueError('This token has already been used') - - if token._value is _NoValueSet.NO_VALUE_SET: - try: - del self._current_vars[self._name] - except KeyError: - pass - else: - self._current_vars[self._name] = token._value - - token._redeemed = True - - def __repr__(self) -> str: - return f'' diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/py.typed b/IKEA_scraper/.venv/Lib/site-packages/anyio/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/pytest_plugin.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/pytest_plugin.py deleted file mode 100644 index d0cc2fb5..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/pytest_plugin.py +++ /dev/null @@ -1,152 +0,0 @@ -from contextlib import contextmanager -from inspect import isasyncgenfunction, iscoroutinefunction -from typing import TYPE_CHECKING, Any, Dict, Iterator, Optional, Tuple, cast - -import pytest -import sniffio - -from ._core._eventloop import get_all_backends, get_asynclib -from .abc import TestRunner - -if TYPE_CHECKING: - from _pytest.config import Config - -_current_runner: Optional[TestRunner] = None - - -def extract_backend_and_options(backend: object) -> Tuple[str, Dict[str, Any]]: - if isinstance(backend, str): - return backend, {} - elif isinstance(backend, tuple) and len(backend) == 2: - if isinstance(backend[0], str) and isinstance(backend[1], dict): - return cast(Tuple[str, Dict[str, Any]], backend) - - raise TypeError('anyio_backend must be either a string or tuple of (string, dict)') - - -@contextmanager -def get_runner(backend_name: str, backend_options: Dict[str, Any]) -> Iterator[TestRunner]: - global _current_runner - if _current_runner: - yield _current_runner - return - - asynclib = get_asynclib(backend_name) - token = None - if sniffio.current_async_library_cvar.get(None) is None: - # Since we're in control of the event loop, we can cache the name of the async library - token = sniffio.current_async_library_cvar.set(backend_name) - - try: - backend_options = backend_options or {} - with asynclib.TestRunner(**backend_options) as runner: - _current_runner = runner - yield runner - finally: - _current_runner = None - if token: - sniffio.current_async_library_cvar.reset(token) - - -def pytest_configure(config: "Config") -> None: - config.addinivalue_line('markers', 'anyio: mark the (coroutine function) test to be run ' - 'asynchronously via anyio.') - - -def pytest_fixture_setup(fixturedef: Any, request: Any) -> None: - def wrapper(*args, anyio_backend, **kwargs): # type: ignore[no-untyped-def] - backend_name, backend_options = extract_backend_and_options(anyio_backend) - if has_backend_arg: - kwargs['anyio_backend'] = anyio_backend - - with get_runner(backend_name, backend_options) as runner: - if isasyncgenfunction(func): - gen = func(*args, **kwargs) - try: - value = runner.call(gen.asend, None) - except StopAsyncIteration: - raise RuntimeError('Async generator did not yield') - - yield value - - try: - runner.call(gen.asend, None) - except StopAsyncIteration: - pass - else: - runner.call(gen.aclose) - raise RuntimeError('Async generator fixture did not stop') - else: - yield runner.call(func, *args, **kwargs) - - # Only apply this to coroutine functions and async generator functions in requests that involve - # the anyio_backend fixture - func = fixturedef.func - if isasyncgenfunction(func) or iscoroutinefunction(func): - if 'anyio_backend' in request.fixturenames: - has_backend_arg = 'anyio_backend' in fixturedef.argnames - fixturedef.func = wrapper - if not has_backend_arg: - fixturedef.argnames += ('anyio_backend',) - - -@pytest.hookimpl(tryfirst=True) -def pytest_pycollect_makeitem(collector: Any, name: Any, obj: Any) -> None: - if collector.istestfunction(obj, name): - inner_func = obj.hypothesis.inner_test if hasattr(obj, 'hypothesis') else obj - if iscoroutinefunction(inner_func): - marker = collector.get_closest_marker('anyio') - own_markers = getattr(obj, 'pytestmark', ()) - if marker or any(marker.name == 'anyio' for marker in own_markers): - pytest.mark.usefixtures('anyio_backend')(obj) - - -@pytest.hookimpl(tryfirst=True) -def pytest_pyfunc_call(pyfuncitem: Any) -> Optional[bool]: - def run_with_hypothesis(**kwargs: Any) -> None: - with get_runner(backend_name, backend_options) as runner: - runner.call(original_func, **kwargs) - - backend = pyfuncitem.funcargs.get('anyio_backend') - if backend: - backend_name, backend_options = extract_backend_and_options(backend) - - if hasattr(pyfuncitem.obj, 'hypothesis'): - # Wrap the inner test function unless it's already wrapped - original_func = pyfuncitem.obj.hypothesis.inner_test - if original_func.__qualname__ != run_with_hypothesis.__qualname__: - if iscoroutinefunction(original_func): - pyfuncitem.obj.hypothesis.inner_test = run_with_hypothesis - - return None - - if iscoroutinefunction(pyfuncitem.obj): - funcargs = pyfuncitem.funcargs - testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames} - with get_runner(backend_name, backend_options) as runner: - runner.call(pyfuncitem.obj, **testargs) - - return True - - return None - - -@pytest.fixture(params=get_all_backends()) -def anyio_backend(request: Any) -> Any: - return request.param - - -@pytest.fixture -def anyio_backend_name(anyio_backend: Any) -> str: - if isinstance(anyio_backend, str): - return anyio_backend - else: - return anyio_backend[0] - - -@pytest.fixture -def anyio_backend_options(anyio_backend: Any) -> Dict[str, Any]: - if isinstance(anyio_backend, str): - return {} - else: - return anyio_backend[1] diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 5c728b4efaa1fb8090270886bf2c388c34d0d3f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177 zcmYe~<>g`kf`|Vc6G8N25P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_mi&acOWkyMU zUQAJ9UP^v$OmK2Wetu4jr?;zPd~tG7VnJ$Aj9yu4URjJ!W>QRXW=X1UL1J=tVtQ(E uOk!STX1;!LNl|KIZn1uRd}dx|NqoFsLFFwDo80`A(wtN~kbR$lm;nG#gD(^S diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/buffered.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/buffered.cpython-39.pyc deleted file mode 100644 index c4ecd7601853dc587e19a0634dd7aaa43a2f7d8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3940 zcmbtX&2JmW72nw}E-8tkW!aYFv|XnkDcxELiWDdWr-@|~CuazwImh`w2FDEO#m89KkGea`ripJOMSBCIJ^Qj@4vVCM7vEHg^ z?HJvqm)Otfnq^b)f`>8B^U@haG8SE{w63S)(!0UqnD=8@Ha_RWVU*r`Y0?tAJbNR~ zaw)!$c{Wm^ys1>C$}^wHI7*^Is_m?}m5owSF5OJUZw5Psk~}Hfx6?37hOsQ<7m^F? zypCNy9#c1z(Se-JJ9BF2R+p8gd=QetuRbn1AED%bLnVzK6GqScElk+6q%9p`UNfXC zEZGqD*JjU?4U9R}7>wv*tSMUt|c9cd%xhmvR4~ySMsq`=>SKe%_lkz}V zOcPeZ9|hHk&qGqEPlN_N778({2F{<+AVpQHU{3&;`=7 zskvhmHb$JnJu=lDY8^MG>^ZA|w?pzUG6&+JS$I?Ph)vnPt^P=oj+;|+3L+xu&l!Wn z`CeEH=>%EzT`1OVX_zXqX5~3DOWBI@D9sC=hEkhVtnO2w&}7pw#;mlHM_%>&2^N?q{dA-Q4J`_L%NDK4fRWAcG^k6k!0eh)M3V|Qw5 z$^6(el6Y5`kA zu6W{CrrOeT(oxcvYOxr!j0;gLmQ(~-O|Imh_|7BZ^~aioHotj|Zu!yR6;1qyJohVZ z_4^VmF7-zxABaRDY!=5}N$%NzHNbl(@;DE>KM>KB9N8t$^m#gzDXXcupV`5HBXDqdu z$J#)%XPT(jf#)`R+njX2716;=7Sf%jn5Ql}n3Sd!qLTU3M59LdKhOcbLD7enV24B( z>=?KPu7J3y1GGEpvl+e}jdpk5tJYlrJplFA)FsrsaF)yEWDu zHP(-Tb#I1sug1Ff*wa|Yo3LIqYq{12lEw?TGmp%fwykMH$H20V0h@mg4y~b~W8j4M zeZW78HI`~y`B9EM0ePOEDZl1qe~%yF%94m0Lh!L1E!s0mMhLc(0k+2r|6vrzHI`?gpb$v&tcL=Co-M#_>#JF8ol0T9T5SLN zDD{7wW(713qZ(6AP%Ig0+hHJakLP>p!ckP6Fbc;^8po>#Ssu`meNRFgaRL*=D z6?;_{Sc{~M7R2O_hU6|{$GHdaqmVrWyVNTxj(AB-(Op^)MQIPBR4BUX6vb3U7j#Q4 zn4+{GwW5n=MHfG%@0U^a+O^I>9!+HFW`jX4i_(Eq`3V0n`nSWTKN@v~R-H(MR^~jS z;d}=(a=MF+w#RI%Vv=>{QOh!!W)f?IP2T->F46M3O!*Mjy-<2Vkn%(ZLD>p|Bom{U z+RH)kV8r9umqrkXEDQp*j5XzI5bzXE;6;?BIYx-cc9n?>sTK9FJkuiSO5S3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/file.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/file.cpython-39.pyc deleted file mode 100644 index 53aae95462b6e5173d85a0df11ffa5ecbd0b5524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5385 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/stapled.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/stapled.cpython-39.pyc deleted file mode 100644 index e75c3548e07eeb1fdcce74b070a34adeed4fd7a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5349 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/tls.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/__pycache__/tls.cpython-39.pyc deleted file mode 100644 index 0b183767fae78ac03b3b54be0681361bec39b97d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10073 zcmb7K+ix3JdY>D~;YAcB%d#Y2GI6#WGwU!3vYTxcBO52NV{aWfwUjtv)lwtQp)~Sb z=rcnnB&aMJd7E_6v;hjV59=)~p!<-bZ@oUWPeIZC0sAy>MS&K1DHbUDvJY{8-#Nn} zb#Z{DG>7Ll-}%n@?%$z3HC0mZ`H!zJ+h07RDE~=~$xj}QSMfx@MBylo>M2e6tu|HB z)|wi=HBa}ArlHc9?&bV^GcW3fSMbfI=@*+tztk-Goz<8#+fQbIKp3%BC&YNC=Xw3))E0|dZ98Z)&tp!Deb{bEB(-FQ zmT@k}F?Tn6F{<4JMNj_$n4!(KNr*IKt& ze9!jUbTX5lj8lGrUZxOtG_`lYF-@HrdrC9M@~p6^Fw@a4DWa#yN@(e6tIR5_fWN7Z zE@l~Ne--adqrZk{rlTz?^oSX`bjB=ZltfQH?K#2b0J)I1PO|w)*kY!cj-6r)JByfG zOxsK1%~IMrjWtcDd`WRC;D)KBvUX!NJJG@SUJrxVc7w=T<8}~rLmpc<>^|exDr@(+ z8}}{FJUeENl^uE1NTzJB8??GSjKg;5B}?sXI|!K9+H?a44AY9esMQPHyFHfV+irIo z1gLcxdVC> zF8myIJV71CW*BW!OXTl_qYJcZ&5g+EVqDt`4lZ!E9B-QSMG zU>&4#LVta=y$xvV*MIxU&JTt!DxW|Hf>o?rZ^~jCcvt7G=$KGPmx*hc0@HuP; zQW!mlBWiT}d=YS`@kH||N~)pFYE^APKQF$|Xf?g6i8)uHFf?}eh`i7ly-M#xQ67;O zmJ?Ev$2ZAGVaG&`B%-iWM2$FK)`;UvPC@*Eiys)wU}csEk3*hBS=gDvcOH7V^dRq) zoyz?@v|knaa*EYRme>rdIn@WcGwsyw8_ijE0x;%i#F=@ZI6`UosPdjHYV=h6TJQ9P7S8 zdfO>L!p=k0+*p;m$X>*`lq`HMTk_~FQoEp&6>rP)czbz+ zR^7lTl%ef3Bt}@0eHe2rH`1k%)#0IUEepuY8y`(-iVX`=Xhpp)sR#xb0?6_`n_CCe zuLX!wkF?~Dm$6lrZre#uLB5>S4$l>wpOjk@B3^8PV;yLQ5aRm*6cVHQ%39r!0%dN8 zQA|<{tpUZ*hB~8NkqFiE{JZ!P^Z0L4?YF3)p(M{)+~Yx8LxVmBo-!U1$}jOm0~ABe zQF{un4)uz%s|}6l`Ju+o#mbJlqXl{Kt?%Odp)t(wtGfnjxqW4~kbav(V<$f>49%f7 z)E(_JW4Aa|hUzdkEK;wdf0o-V4NDIT!{Uy)uU?0pxu&SfummnL?0?r&)*<$}4f=sC zKrq-dDAXEXXupcIFK*n&N1=@iI>N?*1%Hr9BLZGa;?SQosEe_CHovPkb+Aq_DL1P!3- zp?NRjwX3!l$@en&w8kWiw&#){2^bduKlI%g40{o~1jldEBC!P|CxM|cVk00$BDKj_ za9|18x_dwiaK?71_7(5+Y+y>Dk9okH|wvrR21XxbUQhvmt zX5f~^Taon<^h^UsBfMLIC-Lb)iR##{7fCHg8(*nwQd>=@VlX0JJttKZ=_LL=Dqf=E z`zY!~-oRHo=}nSy^jcerN4kQeM4s>)k82WMf_)Y%ArqkrGUbZ!tgQ z{nxJFOiZ!>LW|DB*Y-S8v67}OvJjz@RGhGt9csOt=xr~0y#6e7C05Nmv~kM~ng#j} zd$IIr3aObJyD$6&+KfT{%cw;b3T56@^O~W~sU^)+O|_(IkEo5muk-q>I;durv_UU6 z>Uv^ydO6J3Sv9aN!jwLejI_1ntlYEUv1(%SuhR-tEA zW$@jhvZL+j{8fA#4|CLdnBP}~E>?strvAdd0^N-Eu5nul-UAG?A4mvzqxi724_NOj z!4EM~?*Fx_?B)Rb+v70-SImkl!`#Q(ZOnEs>!VySFTbBxo>#>DsiCp2612N8Nx-$* z|F3MNV=>HTPGdHFq0iMmB20n7?BUh!rmLo_VdtN#{1VnZ7V=PE1s0C7s(hiY)Mq3& z*1-6;?I6AdqbvkK@M==%GU50OhDi*#GEQQU;Z6#v|H8@76x^K@r5R^oCn?-ql~Ae} zrI-}W(`-BuG6pdJnp(x51~y#K=G2O4mB5g2f>A%CE~sbp62=B3=+e1s94|;;sFE+i zec6ZVFz3>Z;aFw>7J1S z%tUz7j!S1}8CqJzBV;EoNC|a>B~RUni_)xH9_z$#7KOegB3hfhPKWXOq(U>r2@0K+ z$SR30m6;z-`5-Yk|8%7Fha`u+edBu)R4 z-n)eYr=##!2D3O(btI>%0y+H_#W0F@*$Q*co{2p;T{~^G_ zcN99Aa7?CNvmmNhyjkaQpNyUjALKN$| zq{#+#yhp_${BNS~FYrj}sPm+iwZY7oI;mg-YXfrXAJxVh-p&wSLgP4uDZ@5GRG&bU zXbY<;_{K*4FnVvH?=SI0w2E@TRFL*Lz%)6`phujXg9;%M3*p;UV+ft2(h0)F*Z6yJ zZU`gbKrr{zw65=~-IpA&j|M}sYYg?F(b1gT9UNR-aPmX-r^?T?J@sQ1tpa`1mg?rp z;3Q7#-i3ANJM{}cSYB_4TKxxK5kqsbQ=Dqpr8 zLnLiDc?9l-#)~goaJ9Jba#=)a4syyOYw-Pvmq$)yAKorGvzF^46XD|}_^Aj3gu@~u zw5V<-IS~qqU|(b&5{g}HSKi=`;=-`Zd8WkLg5_TpaA^$j|EJ!E&x-)O&;QYrae;77QOvA z(EmV#-;6W)kOVr#7`E&DH$nWzUmIdwm7f0NaQvqcMEG2kzes9_=_oM#9p7I+EXZ!LYhaNuyBH4#Ekqdiod}V zok5{!nwo#4X=KAo!hIr#ivCLfH&}W+kK#01c)R`t{}#UZZ&2}VDxRidj*2=J&r;E# z;yEf_MUj+6qDsauB45idPV5AoHw_(KK0_Uv=`$5^|_H zaf?u4Q>^MxepMH@OE726X=e_15;I#Wn-y79+&Lg)YC09nnR2SgiJnAj8aY$CT|&+j z8Pf$e%WBAhiZ?`tmBvMe6%ZF46DsXwQU=9GcQ5vzLvDrFdYKX-NKhj~(`J^J-p#mpvKbjyX&f>?;s1vo!({n4Pb zOv~=XjBm*7S7MHiK;(wkg#P=AbYe1d1cMd$%A0SCAt- zDaE*1Z;9|gN(4#3=tIVm%^zRD@ERqu;OWsk{282+AJn z2(YwKKr7=za6Q5#u{#kLlZQF_&=O?I{|rw=AtAZ;p5m*!D$;P*hAIKwQ~&fC2$sHM z3>CC7%ImHiXN--yQ@tsJ);>*Pcg2PJi#?K|0|jq!SALpCGk{8H015st-+| zsf^J~lY06`da!_`9=<8f_9-rr#zHURLSse5ez;OCjr9?Bmt9WbM;QwLLu`Z(sUV*~ z`Z3uI{(IC%XNqeuaVj*uSxs{~>CKy934|8+Y4SJ$BbZ`3r5>)-#C_y1F()E#OVQw# zh&U_{C#9iR)eG9-nMsZiDeQ4*aR?9)BKk|uZGc*m6EC1&pdgU>G0pfRD#%OXpHd;b zr=OtqKX@YYc@!uLyVPwA=GJoF0;E`|;PKH#xv<*rNO(ulKNd}D*R?^!W2Ok0t zfdaXKkMN8V3lxcF%gb!dk)??RY1bl}r3|x(4Ml|MQi!J?jR&(BiFP^>Z}2YK@>s^$ z3B)MoLSk9QFN4M;T89IKF?B|PANXsL01N+q3|Q0z^t%|<06n6;D0=nL;LJCzP*+## zOUJtG^R$d`*@d@$kD6jt;lU5lOmZDBwBw`#RTsPM)PEN&E&P4rYw5EK)+dCdcYlg% z#3GV>?6;p5*a+Bxqbs None: - await self.receive_stream.aclose() - self._closed = True - - @property - def buffer(self) -> bytes: - """The bytes currently in the buffer.""" - return bytes(self._buffer) - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - return self.receive_stream.extra_attributes - - async def receive(self, max_bytes: int = 65536) -> bytes: - if self._closed: - raise ClosedResourceError - - if self._buffer: - chunk = bytes(self._buffer[:max_bytes]) - del self._buffer[:max_bytes] - return chunk - elif isinstance(self.receive_stream, ByteReceiveStream): - return await self.receive_stream.receive(max_bytes) - else: - # With a bytes-oriented object stream, we need to handle any surplus bytes we get from - # the receive() call - chunk = await self.receive_stream.receive() - if len(chunk) > max_bytes: - # Save the surplus bytes in the buffer - self._buffer.extend(chunk[max_bytes:]) - return chunk[:max_bytes] - else: - return chunk - - async def receive_exactly(self, nbytes: int) -> bytes: - """ - Read exactly the given amount of bytes from the stream. - - :param nbytes: the number of bytes to read - :return: the bytes read - :raises ~anyio.IncompleteRead: if the stream was closed before the requested - amount of bytes could be read from the stream - - """ - while True: - remaining = nbytes - len(self._buffer) - if remaining <= 0: - retval = self._buffer[:nbytes] - del self._buffer[:nbytes] - return bytes(retval) - - try: - if isinstance(self.receive_stream, ByteReceiveStream): - chunk = await self.receive_stream.receive(remaining) - else: - chunk = await self.receive_stream.receive() - except EndOfStream as exc: - raise IncompleteRead from exc - - self._buffer.extend(chunk) - - async def receive_until(self, delimiter: bytes, max_bytes: int) -> bytes: - """ - Read from the stream until the delimiter is found or max_bytes have been read. - - :param delimiter: the marker to look for in the stream - :param max_bytes: maximum number of bytes that will be read before raising - :exc:`~anyio.DelimiterNotFound` - :return: the bytes read (not including the delimiter) - :raises ~anyio.IncompleteRead: if the stream was closed before the delimiter - was found - :raises ~anyio.DelimiterNotFound: if the delimiter is not found within the - bytes read up to the maximum allowed - - """ - delimiter_size = len(delimiter) - offset = 0 - while True: - # Check if the delimiter can be found in the current buffer - index = self._buffer.find(delimiter, offset) - if index >= 0: - found = self._buffer[:index] - del self._buffer[:index + len(delimiter):] - return bytes(found) - - # Check if the buffer is already at or over the limit - if len(self._buffer) >= max_bytes: - raise DelimiterNotFound(max_bytes) - - # Read more data into the buffer from the socket - try: - data = await self.receive_stream.receive() - except EndOfStream as exc: - raise IncompleteRead from exc - - # Move the offset forward and add the new data to the buffer - offset = max(len(self._buffer) - delimiter_size + 1, 0) - self._buffer.extend(data) diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/file.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/file.py deleted file mode 100644 index deb5e623..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/file.py +++ /dev/null @@ -1,139 +0,0 @@ -from io import SEEK_SET, UnsupportedOperation -from os import PathLike -from pathlib import Path -from typing import Any, BinaryIO, Callable, Dict, Mapping, Union, cast - -from .. import ( - BrokenResourceError, ClosedResourceError, EndOfStream, TypedAttributeSet, to_thread, - typed_attribute) -from ..abc import ByteReceiveStream, ByteSendStream - - -class FileStreamAttribute(TypedAttributeSet): - #: the open file descriptor - file: BinaryIO = typed_attribute() - #: the path of the file on the file system, if available (file must be a real file) - path: Path = typed_attribute() - #: the file number, if available (file must be a real file or a TTY) - fileno: int = typed_attribute() - - -class _BaseFileStream: - def __init__(self, file: BinaryIO): - self._file = file - - async def aclose(self) -> None: - await to_thread.run_sync(self._file.close) - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - attributes: Dict[Any, Callable[[], Any]] = { - FileStreamAttribute.file: lambda: self._file, - } - - if hasattr(self._file, 'name'): - attributes[FileStreamAttribute.path] = lambda: Path(self._file.name) - - try: - self._file.fileno() - except UnsupportedOperation: - pass - else: - attributes[FileStreamAttribute.fileno] = lambda: self._file.fileno() - - return attributes - - -class FileReadStream(_BaseFileStream, ByteReceiveStream): - """ - A byte stream that reads from a file in the file system. - - :param file: a file that has been opened for reading in binary mode - - .. versionadded:: 3.0 - """ - - @classmethod - async def from_path(cls, path: Union[str, PathLike]) -> 'FileReadStream': - """ - Create a file read stream by opening the given file. - - :param path: path of the file to read from - - """ - file = await to_thread.run_sync(Path(path).open, 'rb') - return cls(cast(BinaryIO, file)) - - async def receive(self, max_bytes: int = 65536) -> bytes: - try: - data = await to_thread.run_sync(self._file.read, max_bytes) - except ValueError: - raise ClosedResourceError from None - except OSError as exc: - raise BrokenResourceError from exc - - if data: - return data - else: - raise EndOfStream - - async def seek(self, position: int, whence: int = SEEK_SET) -> int: - """ - Seek the file to the given position. - - .. seealso:: :meth:`io.IOBase.seek` - - .. note:: Not all file descriptors are seekable. - - :param position: position to seek the file to - :param whence: controls how ``position`` is interpreted - :return: the new absolute position - :raises OSError: if the file is not seekable - - """ - return await to_thread.run_sync(self._file.seek, position, whence) - - async def tell(self) -> int: - """ - Return the current stream position. - - .. note:: Not all file descriptors are seekable. - - :return: the current absolute position - :raises OSError: if the file is not seekable - - """ - return await to_thread.run_sync(self._file.tell) - - -class FileWriteStream(_BaseFileStream, ByteSendStream): - """ - A byte stream that writes to a file in the file system. - - :param file: a file that has been opened for writing in binary mode - - .. versionadded:: 3.0 - """ - - @classmethod - async def from_path(cls, path: Union[str, PathLike], - append: bool = False) -> 'FileWriteStream': - """ - Create a file write stream by opening the given file for writing. - - :param path: path of the file to write to - :param append: if ``True``, open the file for appending; if ``False``, any existing file - at the given path will be truncated - - """ - mode = 'ab' if append else 'wb' - file = await to_thread.run_sync(Path(path).open, mode) - return cls(cast(BinaryIO, file)) - - async def send(self, item: bytes) -> None: - try: - await to_thread.run_sync(self._file.write, item) - except ValueError: - raise ClosedResourceError from None - except OSError as exc: - raise BrokenResourceError from exc diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/memory.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/memory.py deleted file mode 100644 index 91924f39..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/memory.py +++ /dev/null @@ -1,256 +0,0 @@ -from collections import OrderedDict, deque -from dataclasses import dataclass, field -from types import TracebackType -from typing import Deque, Generic, List, NamedTuple, Optional, Type, TypeVar - -from .. import ( - BrokenResourceError, ClosedResourceError, EndOfStream, WouldBlock, get_cancelled_exc_class) -from .._core._compat import DeprecatedAwaitable -from ..abc import Event, ObjectReceiveStream, ObjectSendStream -from ..lowlevel import checkpoint - -T_Item = TypeVar('T_Item') - - -class MemoryObjectStreamStatistics(NamedTuple): - current_buffer_used: int #: number of items stored in the buffer - #: maximum number of items that can be stored on this stream (or :data:`math.inf`) - max_buffer_size: float - open_send_streams: int #: number of unclosed clones of the send stream - open_receive_streams: int #: number of unclosed clones of the receive stream - tasks_waiting_send: int #: number of tasks blocked on :meth:`MemoryObjectSendStream.send` - #: number of tasks blocked on :meth:`MemoryObjectReceiveStream.receive` - tasks_waiting_receive: int - - -@dataclass(eq=False) -class MemoryObjectStreamState(Generic[T_Item]): - max_buffer_size: float = field() - buffer: Deque[T_Item] = field(init=False, default_factory=deque) - open_send_channels: int = field(init=False, default=0) - open_receive_channels: int = field(init=False, default=0) - waiting_receivers: 'OrderedDict[Event, List[T_Item]]' = field(init=False, - default_factory=OrderedDict) - waiting_senders: 'OrderedDict[Event, T_Item]' = field(init=False, default_factory=OrderedDict) - - def statistics(self) -> MemoryObjectStreamStatistics: - return MemoryObjectStreamStatistics( - len(self.buffer), self.max_buffer_size, self.open_send_channels, - self.open_receive_channels, len(self.waiting_senders), len(self.waiting_receivers)) - - -@dataclass(eq=False) -class MemoryObjectReceiveStream(Generic[T_Item], ObjectReceiveStream[T_Item]): - _state: MemoryObjectStreamState[T_Item] - _closed: bool = field(init=False, default=False) - - def __post_init__(self) -> None: - self._state.open_receive_channels += 1 - - def receive_nowait(self) -> T_Item: - """ - Receive the next item if it can be done without waiting. - - :return: the received item - :raises ~anyio.ClosedResourceError: if this send stream has been closed - :raises ~anyio.EndOfStream: if the buffer is empty and this stream has been - closed from the sending end - :raises ~anyio.WouldBlock: if there are no items in the buffer and no tasks - waiting to send - - """ - if self._closed: - raise ClosedResourceError - - if self._state.waiting_senders: - # Get the item from the next sender - send_event, item = self._state.waiting_senders.popitem(last=False) - self._state.buffer.append(item) - send_event.set() - - if self._state.buffer: - return self._state.buffer.popleft() - elif not self._state.open_send_channels: - raise EndOfStream - - raise WouldBlock - - async def receive(self) -> T_Item: - await checkpoint() - try: - return self.receive_nowait() - except WouldBlock: - # Add ourselves in the queue - receive_event = Event() - container: List[T_Item] = [] - self._state.waiting_receivers[receive_event] = container - - try: - await receive_event.wait() - except get_cancelled_exc_class(): - # Ignore the immediate cancellation if we already received an item, so as not to - # lose it - if not container: - raise - finally: - self._state.waiting_receivers.pop(receive_event, None) - - if container: - return container[0] - else: - raise EndOfStream - - def clone(self) -> 'MemoryObjectReceiveStream': - """ - Create a clone of this receive stream. - - Each clone can be closed separately. Only when all clones have been closed will the - receiving end of the memory stream be considered closed by the sending ends. - - :return: the cloned stream - - """ - if self._closed: - raise ClosedResourceError - - return MemoryObjectReceiveStream(_state=self._state) - - def close(self) -> None: - """ - Close the stream. - - This works the exact same way as :meth:`aclose`, but is provided as a special case for the - benefit of synchronous callbacks. - - """ - if not self._closed: - self._closed = True - self._state.open_receive_channels -= 1 - if self._state.open_receive_channels == 0: - send_events = list(self._state.waiting_senders.keys()) - for event in send_events: - event.set() - - async def aclose(self) -> None: - self.close() - - def statistics(self) -> MemoryObjectStreamStatistics: - """ - Return statistics about the current state of this stream. - - .. versionadded:: 3.0 - """ - return self._state.statistics() - - def __enter__(self) -> 'MemoryObjectReceiveStream[T_Item]': - return self - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> None: - self.close() - - -@dataclass(eq=False) -class MemoryObjectSendStream(Generic[T_Item], ObjectSendStream[T_Item]): - _state: MemoryObjectStreamState[T_Item] - _closed: bool = field(init=False, default=False) - - def __post_init__(self) -> None: - self._state.open_send_channels += 1 - - def send_nowait(self, item: T_Item) -> DeprecatedAwaitable: - """ - Send an item immediately if it can be done without waiting. - - :param item: the item to send - :raises ~anyio.ClosedResourceError: if this send stream has been closed - :raises ~anyio.BrokenResourceError: if the stream has been closed from the - receiving end - :raises ~anyio.WouldBlock: if the buffer is full and there are no tasks waiting - to receive - - """ - if self._closed: - raise ClosedResourceError - if not self._state.open_receive_channels: - raise BrokenResourceError - - if self._state.waiting_receivers: - receive_event, container = self._state.waiting_receivers.popitem(last=False) - container.append(item) - receive_event.set() - elif len(self._state.buffer) < self._state.max_buffer_size: - self._state.buffer.append(item) - else: - raise WouldBlock - - return DeprecatedAwaitable(self.send_nowait) - - async def send(self, item: T_Item) -> None: - await checkpoint() - try: - self.send_nowait(item) - except WouldBlock: - # Wait until there's someone on the receiving end - send_event = Event() - self._state.waiting_senders[send_event] = item - try: - await send_event.wait() - except BaseException: - self._state.waiting_senders.pop(send_event, None) # type: ignore[arg-type] - raise - - if self._state.waiting_senders.pop(send_event, None): # type: ignore[arg-type] - raise BrokenResourceError - - def clone(self) -> 'MemoryObjectSendStream': - """ - Create a clone of this send stream. - - Each clone can be closed separately. Only when all clones have been closed will the - sending end of the memory stream be considered closed by the receiving ends. - - :return: the cloned stream - - """ - if self._closed: - raise ClosedResourceError - - return MemoryObjectSendStream(_state=self._state) - - def close(self) -> None: - """ - Close the stream. - - This works the exact same way as :meth:`aclose`, but is provided as a special case for the - benefit of synchronous callbacks. - - """ - if not self._closed: - self._closed = True - self._state.open_send_channels -= 1 - if self._state.open_send_channels == 0: - receive_events = list(self._state.waiting_receivers.keys()) - self._state.waiting_receivers.clear() - for event in receive_events: - event.set() - - async def aclose(self) -> None: - self.close() - - def statistics(self) -> MemoryObjectStreamStatistics: - """ - Return statistics about the current state of this stream. - - .. versionadded:: 3.0 - """ - return self._state.statistics() - - def __enter__(self) -> 'MemoryObjectSendStream[T_Item]': - return self - - def __exit__(self, exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> None: - self.close() diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/stapled.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/stapled.py deleted file mode 100644 index 0d5e7fb2..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/stapled.py +++ /dev/null @@ -1,124 +0,0 @@ -from dataclasses import dataclass -from typing import Any, Callable, Generic, List, Mapping, Optional, Sequence, TypeVar - -from ..abc import ( - ByteReceiveStream, ByteSendStream, ByteStream, Listener, ObjectReceiveStream, ObjectSendStream, - ObjectStream, TaskGroup) - -T_Item = TypeVar('T_Item') -T_Stream = TypeVar('T_Stream') - - -@dataclass(eq=False) -class StapledByteStream(ByteStream): - """ - Combines two byte streams into a single, bidirectional byte stream. - - Extra attributes will be provided from both streams, with the receive stream providing the - values in case of a conflict. - - :param ByteSendStream send_stream: the sending byte stream - :param ByteReceiveStream receive_stream: the receiving byte stream - """ - - send_stream: ByteSendStream - receive_stream: ByteReceiveStream - - async def receive(self, max_bytes: int = 65536) -> bytes: - return await self.receive_stream.receive(max_bytes) - - async def send(self, item: bytes) -> None: - await self.send_stream.send(item) - - async def send_eof(self) -> None: - await self.send_stream.aclose() - - async def aclose(self) -> None: - await self.send_stream.aclose() - await self.receive_stream.aclose() - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - return {**self.send_stream.extra_attributes, **self.receive_stream.extra_attributes} - - -@dataclass(eq=False) -class StapledObjectStream(Generic[T_Item], ObjectStream[T_Item]): - """ - Combines two object streams into a single, bidirectional object stream. - - Extra attributes will be provided from both streams, with the receive stream providing the - values in case of a conflict. - - :param ObjectSendStream send_stream: the sending object stream - :param ObjectReceiveStream receive_stream: the receiving object stream - """ - - send_stream: ObjectSendStream[T_Item] - receive_stream: ObjectReceiveStream[T_Item] - - async def receive(self) -> T_Item: - return await self.receive_stream.receive() - - async def send(self, item: T_Item) -> None: - await self.send_stream.send(item) - - async def send_eof(self) -> None: - await self.send_stream.aclose() - - async def aclose(self) -> None: - await self.send_stream.aclose() - await self.receive_stream.aclose() - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - return {**self.send_stream.extra_attributes, **self.receive_stream.extra_attributes} - - -@dataclass(eq=False) -class MultiListener(Generic[T_Stream], Listener[T_Stream]): - """ - Combines multiple listeners into one, serving connections from all of them at once. - - Any MultiListeners in the given collection of listeners will have their listeners moved into - this one. - - Extra attributes are provided from each listener, with each successive listener overriding any - conflicting attributes from the previous one. - - :param listeners: listeners to serve - :type listeners: Sequence[Listener[T_Stream]] - """ - - listeners: Sequence[Listener[T_Stream]] - - def __post_init__(self) -> None: - listeners: List[Listener[T_Stream]] = [] - for listener in self.listeners: - if isinstance(listener, MultiListener): - listeners.extend(listener.listeners) - del listener.listeners[:] # type: ignore[attr-defined] - else: - listeners.append(listener) - - self.listeners = listeners - - async def serve(self, handler: Callable[[T_Stream], Any], - task_group: Optional[TaskGroup] = None) -> None: - from .. import create_task_group - - async with create_task_group() as tg: - for listener in self.listeners: - tg.start_soon(listener.serve, handler, task_group) - - async def aclose(self) -> None: - for listener in self.listeners: - await listener.aclose() - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - attributes: dict = {} - for listener in self.listeners: - attributes.update(listener.extra_attributes) - - return attributes diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/text.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/text.py deleted file mode 100644 index d352b5ba..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/text.py +++ /dev/null @@ -1,130 +0,0 @@ -import codecs -from dataclasses import InitVar, dataclass, field -from typing import Any, Callable, Mapping, Tuple - -from ..abc import ( - AnyByteReceiveStream, AnyByteSendStream, AnyByteStream, ObjectReceiveStream, ObjectSendStream, - ObjectStream) - - -@dataclass(eq=False) -class TextReceiveStream(ObjectReceiveStream[str]): - """ - Stream wrapper that decodes bytes to strings using the given encoding. - - Decoding is done using :class:`~codecs.IncrementalDecoder` which returns any completely - received unicode characters as soon as they come in. - - :param transport_stream: any bytes-based receive stream - :param encoding: character encoding to use for decoding bytes to strings (defaults to - ``utf-8``) - :param errors: handling scheme for decoding errors (defaults to ``strict``; see the - `codecs module documentation`_ for a comprehensive list of options) - - .. _codecs module documentation: https://docs.python.org/3/library/codecs.html#codec-objects - """ - - transport_stream: AnyByteReceiveStream - encoding: InitVar[str] = 'utf-8' - errors: InitVar[str] = 'strict' - _decoder: codecs.IncrementalDecoder = field(init=False) - - def __post_init__(self, encoding: str, errors: str) -> None: - decoder_class = codecs.getincrementaldecoder(encoding) - self._decoder = decoder_class(errors=errors) - - async def receive(self) -> str: - while True: - chunk = await self.transport_stream.receive() - decoded = self._decoder.decode(chunk) - if decoded: - return decoded - - async def aclose(self) -> None: - await self.transport_stream.aclose() - self._decoder.reset() - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - return self.transport_stream.extra_attributes - - -@dataclass(eq=False) -class TextSendStream(ObjectSendStream[str]): - """ - Sends strings to the wrapped stream as bytes using the given encoding. - - :param AnyByteSendStream transport_stream: any bytes-based send stream - :param str encoding: character encoding to use for encoding strings to bytes (defaults to - ``utf-8``) - :param str errors: handling scheme for encoding errors (defaults to ``strict``; see the - `codecs module documentation`_ for a comprehensive list of options) - - .. _codecs module documentation: https://docs.python.org/3/library/codecs.html#codec-objects - """ - - transport_stream: AnyByteSendStream - encoding: InitVar[str] = 'utf-8' - errors: str = 'strict' - _encoder: Callable[..., Tuple[bytes, int]] = field(init=False) - - def __post_init__(self, encoding: str) -> None: - self._encoder = codecs.getencoder(encoding) - - async def send(self, item: str) -> None: - encoded = self._encoder(item, self.errors)[0] - await self.transport_stream.send(encoded) - - async def aclose(self) -> None: - await self.transport_stream.aclose() - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - return self.transport_stream.extra_attributes - - -@dataclass(eq=False) -class TextStream(ObjectStream[str]): - """ - A bidirectional stream that decodes bytes to strings on receive and encodes strings to bytes on - send. - - Extra attributes will be provided from both streams, with the receive stream providing the - values in case of a conflict. - - :param AnyByteStream transport_stream: any bytes-based stream - :param str encoding: character encoding to use for encoding/decoding strings to/from bytes - (defaults to ``utf-8``) - :param str errors: handling scheme for encoding errors (defaults to ``strict``; see the - `codecs module documentation`_ for a comprehensive list of options) - - .. _codecs module documentation: https://docs.python.org/3/library/codecs.html#codec-objects - """ - - transport_stream: AnyByteStream - encoding: InitVar[str] = 'utf-8' - errors: InitVar[str] = 'strict' - _receive_stream: TextReceiveStream = field(init=False) - _send_stream: TextSendStream = field(init=False) - - def __post_init__(self, encoding: str, errors: str) -> None: - self._receive_stream = TextReceiveStream(self.transport_stream, encoding=encoding, - errors=errors) - self._send_stream = TextSendStream(self.transport_stream, encoding=encoding, errors=errors) - - async def receive(self) -> str: - return await self._receive_stream.receive() - - async def send(self, item: str) -> None: - await self._send_stream.send(item) - - async def send_eof(self) -> None: - await self.transport_stream.send_eof() - - async def aclose(self) -> None: - await self._send_stream.aclose() - await self._receive_stream.aclose() - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - return {**self._send_stream.extra_attributes, **self._receive_stream.extra_attributes} diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/tls.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/tls.py deleted file mode 100644 index 1d84c05c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/streams/tls.py +++ /dev/null @@ -1,262 +0,0 @@ -import logging -import re -import ssl -from dataclasses import dataclass -from functools import wraps -from typing import Any, Callable, Dict, List, Mapping, Optional, Tuple, TypeVar, Union - -from .. import BrokenResourceError, EndOfStream, aclose_forcefully, get_cancelled_exc_class -from .._core._typedattr import TypedAttributeSet, typed_attribute -from ..abc import AnyByteStream, ByteStream, Listener, TaskGroup - -T_Retval = TypeVar('T_Retval') - - -class TLSAttribute(TypedAttributeSet): - """Contains Transport Layer Security related attributes.""" - #: the selected ALPN protocol - alpn_protocol: Optional[str] = typed_attribute() - #: the channel binding for type ``tls-unique`` - channel_binding_tls_unique: bytes = typed_attribute() - #: the selected cipher - cipher: Tuple[str, str, int] = typed_attribute() - #: the peer certificate in dictionary form (see :meth:`ssl.SSLSocket.getpeercert` for more - #: information) - peer_certificate: Optional[Dict[str, Union[str, tuple]]] = typed_attribute() - #: the peer certificate in binary form - peer_certificate_binary: Optional[bytes] = typed_attribute() - #: ``True`` if this is the server side of the connection - server_side: bool = typed_attribute() - #: ciphers shared between both ends of the TLS connection - shared_ciphers: List[Tuple[str, str, int]] = typed_attribute() - #: the :class:`~ssl.SSLObject` used for encryption - ssl_object: ssl.SSLObject = typed_attribute() - #: ``True`` if this stream does (and expects) a closing TLS handshake when the stream is being - #: closed - standard_compatible: bool = typed_attribute() - #: the TLS protocol version (e.g. ``TLSv1.2``) - tls_version: str = typed_attribute() - - -@dataclass(eq=False) -class TLSStream(ByteStream): - """ - A stream wrapper that encrypts all sent data and decrypts received data. - - This class has no public initializer; use :meth:`wrap` instead. - All extra attributes from :class:`~TLSAttribute` are supported. - - :var AnyByteStream transport_stream: the wrapped stream - - """ - transport_stream: AnyByteStream - standard_compatible: bool - _ssl_object: ssl.SSLObject - _read_bio: ssl.MemoryBIO - _write_bio: ssl.MemoryBIO - - @classmethod - async def wrap(cls, transport_stream: AnyByteStream, *, server_side: Optional[bool] = None, - hostname: Optional[str] = None, ssl_context: Optional[ssl.SSLContext] = None, - standard_compatible: bool = True) -> 'TLSStream': - """ - Wrap an existing stream with Transport Layer Security. - - This performs a TLS handshake with the peer. - - :param transport_stream: a bytes-transporting stream to wrap - :param server_side: ``True`` if this is the server side of the connection, ``False`` if - this is the client side (if omitted, will be set to ``False`` if ``hostname`` has been - provided, ``False`` otherwise). Used only to create a default context when an explicit - context has not been provided. - :param hostname: host name of the peer (if host name checking is desired) - :param ssl_context: the SSLContext object to use (if not provided, a secure default will be - created) - :param standard_compatible: if ``False``, skip the closing handshake when closing the - connection, and don't raise an exception if the peer does the same - :raises ~ssl.SSLError: if the TLS handshake fails - - """ - if server_side is None: - server_side = not hostname - - if not ssl_context: - purpose = ssl.Purpose.CLIENT_AUTH if server_side else ssl.Purpose.SERVER_AUTH - ssl_context = ssl.create_default_context(purpose) - - bio_in = ssl.MemoryBIO() - bio_out = ssl.MemoryBIO() - ssl_object = ssl_context.wrap_bio(bio_in, bio_out, server_side=server_side, - server_hostname=hostname) - wrapper = cls(transport_stream=transport_stream, - standard_compatible=standard_compatible, _ssl_object=ssl_object, - _read_bio=bio_in, _write_bio=bio_out) - await wrapper._call_sslobject_method(ssl_object.do_handshake) - return wrapper - - async def _call_sslobject_method( - self, func: Callable[..., T_Retval], *args: object - ) -> T_Retval: - while True: - try: - result = func(*args) - except ssl.SSLWantReadError: - try: - # Flush any pending writes first - if self._write_bio.pending: - await self.transport_stream.send(self._write_bio.read()) - - data = await self.transport_stream.receive() - except EndOfStream: - self._read_bio.write_eof() - except OSError as exc: - self._read_bio.write_eof() - self._write_bio.write_eof() - raise BrokenResourceError from exc - else: - self._read_bio.write(data) - except ssl.SSLWantWriteError: - await self.transport_stream.send(self._write_bio.read()) - except (ssl.SSLEOFError, ssl.SSLSyscallError) as exc: - raise BrokenResourceError from exc - else: - # Flush any pending writes first - if self._write_bio.pending: - await self.transport_stream.send(self._write_bio.read()) - - return result - - async def unwrap(self) -> Tuple[AnyByteStream, bytes]: - """ - Does the TLS closing handshake. - - :return: a tuple of (wrapped byte stream, bytes left in the read buffer) - - """ - await self._call_sslobject_method(self._ssl_object.unwrap) - self._read_bio.write_eof() - self._write_bio.write_eof() - return self.transport_stream, self._read_bio.read() - - async def aclose(self) -> None: - if self.standard_compatible: - try: - await self.unwrap() - except BaseException: - await aclose_forcefully(self.transport_stream) - raise - - await self.transport_stream.aclose() - - async def receive(self, max_bytes: int = 65536) -> bytes: - data = await self._call_sslobject_method(self._ssl_object.read, max_bytes) - if not data: - raise EndOfStream - - return data - - async def send(self, item: bytes) -> None: - await self._call_sslobject_method(self._ssl_object.write, item) - - async def send_eof(self) -> None: - tls_version = self.extra(TLSAttribute.tls_version) - match = re.match(r'TLSv(\d+)(?:\.(\d+))?', tls_version) - if match: - major, minor = int(match.group(1)), int(match.group(2) or 0) - if (major, minor) < (1, 3): - raise NotImplementedError(f'send_eof() requires at least TLSv1.3; current ' - f'session uses {tls_version}') - - raise NotImplementedError('send_eof() has not yet been implemented for TLS streams') - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - return { - **self.transport_stream.extra_attributes, - TLSAttribute.alpn_protocol: self._ssl_object.selected_alpn_protocol, - TLSAttribute.channel_binding_tls_unique: self._ssl_object.get_channel_binding, - TLSAttribute.cipher: self._ssl_object.cipher, - TLSAttribute.peer_certificate: lambda: self._ssl_object.getpeercert(False), - TLSAttribute.peer_certificate_binary: lambda: self._ssl_object.getpeercert(True), - TLSAttribute.server_side: lambda: self._ssl_object.server_side, - TLSAttribute.shared_ciphers: lambda: self._ssl_object.shared_ciphers(), - TLSAttribute.standard_compatible: lambda: self.standard_compatible, - TLSAttribute.ssl_object: lambda: self._ssl_object, - TLSAttribute.tls_version: self._ssl_object.version - } - - -@dataclass(eq=False) -class TLSListener(Listener[TLSStream]): - """ - A convenience listener that wraps another listener and auto-negotiates a TLS session on every - accepted connection. - - If the TLS handshake times out or raises an exception, :meth:`handle_handshake_error` is - called to do whatever post-mortem processing is deemed necessary. - - Supports only the :attr:`~TLSAttribute.standard_compatible` extra attribute. - - :param Listener listener: the listener to wrap - :param ssl_context: the SSL context object - :param standard_compatible: a flag passed through to :meth:`TLSStream.wrap` - :param handshake_timeout: time limit for the TLS handshake - (passed to :func:`~anyio.fail_after`) - """ - - listener: Listener - ssl_context: ssl.SSLContext - standard_compatible: bool = True - handshake_timeout: float = 30 - - @staticmethod - async def handle_handshake_error(exc: BaseException, stream: AnyByteStream) -> None: - f""" - Handle an exception raised during the TLS handshake. - - This method does 3 things: - - #. Forcefully closes the original stream - #. Logs the exception (unless it was a cancellation exception) using the ``{__name__}`` - logger - #. Reraises the exception if it was a base exception or a cancellation exception - - :param exc: the exception - :param stream: the original stream - - """ - await aclose_forcefully(stream) - - # Log all except cancellation exceptions - if not isinstance(exc, get_cancelled_exc_class()): - logging.getLogger(__name__).exception('Error during TLS handshake') - - # Only reraise base exceptions and cancellation exceptions - if not isinstance(exc, Exception) or isinstance(exc, get_cancelled_exc_class()): - raise - - async def serve(self, handler: Callable[[TLSStream], Any], - task_group: Optional[TaskGroup] = None) -> None: - @wraps(handler) - async def handler_wrapper(stream: AnyByteStream) -> None: - from .. import fail_after - try: - with fail_after(self.handshake_timeout): - wrapped_stream = await TLSStream.wrap( - stream, ssl_context=self.ssl_context, - standard_compatible=self.standard_compatible) - except BaseException as exc: - await self.handle_handshake_error(exc, stream) - else: - await handler(wrapped_stream) - - await self.listener.serve(handler_wrapper, task_group) - - async def aclose(self) -> None: - await self.listener.aclose() - - @property - def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: - return { - TLSAttribute.standard_compatible: lambda: self.standard_compatible, - } diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/to_process.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/to_process.py deleted file mode 100644 index 5675e9eb..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/to_process.py +++ /dev/null @@ -1,230 +0,0 @@ -import os -import pickle -import subprocess -import sys -from collections import deque -from importlib.abc import Loader -from importlib.util import module_from_spec, spec_from_file_location -from typing import Callable, Deque, List, Optional, Set, Tuple, TypeVar, cast - -from ._core._eventloop import current_time, get_asynclib, get_cancelled_exc_class -from ._core._exceptions import BrokenWorkerProcess -from ._core._subprocesses import open_process -from ._core._synchronization import CapacityLimiter -from ._core._tasks import CancelScope, fail_after -from .abc import ByteReceiveStream, ByteSendStream, Process -from .lowlevel import RunVar, checkpoint_if_cancelled -from .streams.buffered import BufferedByteReceiveStream - -WORKER_MAX_IDLE_TIME = 300 # 5 minutes - -T_Retval = TypeVar('T_Retval') -_process_pool_workers: RunVar[Set[Process]] = RunVar('_process_pool_workers') -_process_pool_idle_workers: RunVar[Deque[Tuple[Process, float]]] = RunVar( - '_process_pool_idle_workers') -_default_process_limiter: RunVar[CapacityLimiter] = RunVar('_default_process_limiter') - - -async def run_sync( - func: Callable[..., T_Retval], *args: object, cancellable: bool = False, - limiter: Optional[CapacityLimiter] = None) -> T_Retval: - """ - Call the given function with the given arguments in a worker process. - - If the ``cancellable`` option is enabled and the task waiting for its completion is cancelled, - the worker process running it will be abruptly terminated using SIGKILL (or - ``terminateProcess()`` on Windows). - - :param func: a callable - :param args: positional arguments for the callable - :param cancellable: ``True`` to allow cancellation of the operation while it's running - :param limiter: capacity limiter to use to limit the total amount of processes running - (if omitted, the default limiter is used) - :return: an awaitable that yields the return value of the function. - - """ - async def send_raw_command(pickled_cmd: bytes) -> object: - try: - await stdin.send(pickled_cmd) - response = await buffered.receive_until(b'\n', 50) - status, length = response.split(b' ') - if status not in (b'RETURN', b'EXCEPTION'): - raise RuntimeError(f'Worker process returned unexpected response: {response!r}') - - pickled_response = await buffered.receive_exactly(int(length)) - except BaseException as exc: - workers.discard(process) - try: - process.kill() - with CancelScope(shield=True): - await process.aclose() - except ProcessLookupError: - pass - - if isinstance(exc, get_cancelled_exc_class()): - raise - else: - raise BrokenWorkerProcess from exc - - retval = pickle.loads(pickled_response) - if status == b'EXCEPTION': - assert isinstance(retval, BaseException) - raise retval - else: - return retval - - # First pickle the request before trying to reserve a worker process - await checkpoint_if_cancelled() - request = pickle.dumps(('run', func, args), protocol=pickle.HIGHEST_PROTOCOL) - - # If this is the first run in this event loop thread, set up the necessary variables - try: - workers = _process_pool_workers.get() - idle_workers = _process_pool_idle_workers.get() - except LookupError: - workers = set() - idle_workers = deque() - _process_pool_workers.set(workers) - _process_pool_idle_workers.set(idle_workers) - get_asynclib().setup_process_pool_exit_at_shutdown(workers) - - async with (limiter or current_default_process_limiter()): - # Pop processes from the pool (starting from the most recently used) until we find one that - # hasn't exited yet - process: Process - while idle_workers: - process, idle_since = idle_workers.pop() - if process.returncode is None: - stdin = cast(ByteSendStream, process.stdin) - buffered = BufferedByteReceiveStream(cast(ByteReceiveStream, process.stdout)) - - # Prune any other workers that have been idle for WORKER_MAX_IDLE_TIME seconds or - # longer - now = current_time() - killed_processes: List[Process] = [] - while idle_workers: - if now - idle_workers[0][1] < WORKER_MAX_IDLE_TIME: - break - - process, idle_since = idle_workers.popleft() - process.kill() - workers.remove(process) - killed_processes.append(process) - - with CancelScope(shield=True): - for process in killed_processes: - await process.aclose() - - break - - workers.remove(process) - else: - command = [sys.executable, '-u', '-m', __name__] - process = await open_process(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - try: - stdin = cast(ByteSendStream, process.stdin) - buffered = BufferedByteReceiveStream(cast(ByteReceiveStream, process.stdout)) - with fail_after(20): - message = await buffered.receive(6) - - if message != b'READY\n': - raise BrokenWorkerProcess( - f'Worker process returned unexpected response: {message!r}') - - main_module_path = getattr(sys.modules['__main__'], '__file__', None) - pickled = pickle.dumps(('init', sys.path, main_module_path), - protocol=pickle.HIGHEST_PROTOCOL) - await send_raw_command(pickled) - except (BrokenWorkerProcess, get_cancelled_exc_class()): - raise - except BaseException as exc: - process.kill() - raise BrokenWorkerProcess('Error during worker process initialization') from exc - - workers.add(process) - - with CancelScope(shield=not cancellable): - try: - return cast(T_Retval, await send_raw_command(request)) - finally: - if process in workers: - idle_workers.append((process, current_time())) - - -def current_default_process_limiter() -> CapacityLimiter: - """ - Return the capacity limiter that is used by default to limit the number of worker processes. - - :return: a capacity limiter object - - """ - try: - return _default_process_limiter.get() - except LookupError: - limiter = CapacityLimiter(os.cpu_count() or 2) - _default_process_limiter.set(limiter) - return limiter - - -def process_worker() -> None: - # Redirect standard streams to os.devnull so that user code won't interfere with the - # parent-worker communication - stdin = sys.stdin - stdout = sys.stdout - sys.stdin = open(os.devnull) - sys.stdout = open(os.devnull, 'w') - - stdout.buffer.write(b'READY\n') - while True: - retval = exception = None - try: - command, *args = pickle.load(stdin.buffer) - except EOFError: - return - except BaseException as exc: - exception = exc - else: - if command == 'run': - func, args = args - try: - retval = func(*args) - except BaseException as exc: - exception = exc - elif command == 'init': - main_module_path: Optional[str] - sys.path, main_module_path = args - del sys.modules['__main__'] - if main_module_path: - # Load the parent's main module but as __mp_main__ instead of __main__ - # (like multiprocessing does) to avoid infinite recursion - try: - spec = spec_from_file_location('__mp_main__', main_module_path) - if spec and spec.loader: - main = module_from_spec(spec) - cast(Loader, spec.loader).exec_module(main) - sys.modules['__main__'] = main - except BaseException as exc: - exception = exc - - try: - if exception is not None: - status = b'EXCEPTION' - pickled = pickle.dumps(exception, pickle.HIGHEST_PROTOCOL) - else: - status = b'RETURN' - pickled = pickle.dumps(retval, pickle.HIGHEST_PROTOCOL) - except BaseException as exc: - exception = exc - status = b'EXCEPTION' - pickled = pickle.dumps(exc, pickle.HIGHEST_PROTOCOL) - - stdout.buffer.write(b'%s %d\n' % (status, len(pickled))) - stdout.buffer.write(pickled) - - # Respect SIGTERM - if isinstance(exception, SystemExit): - raise exception - - -if __name__ == '__main__': - process_worker() diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio/to_thread.py b/IKEA_scraper/.venv/Lib/site-packages/anyio/to_thread.py deleted file mode 100644 index 5fc95894..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/anyio/to_thread.py +++ /dev/null @@ -1,54 +0,0 @@ -from typing import Callable, Optional, TypeVar -from warnings import warn - -from ._core._eventloop import get_asynclib -from .abc import CapacityLimiter - -T_Retval = TypeVar('T_Retval') - - -async def run_sync( - func: Callable[..., T_Retval], *args: object, cancellable: bool = False, - limiter: Optional[CapacityLimiter] = None) -> T_Retval: - """ - Call the given function with the given arguments in a worker thread. - - If the ``cancellable`` option is enabled and the task waiting for its completion is cancelled, - the thread will still run its course but its return value (or any raised exception) will be - ignored. - - :param func: a callable - :param args: positional arguments for the callable - :param cancellable: ``True`` to allow cancellation of the operation - :param limiter: capacity limiter to use to limit the total amount of threads running - (if omitted, the default limiter is used) - :return: an awaitable that yields the return value of the function. - - """ - return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable, - limiter=limiter) - - -async def run_sync_in_worker_thread( - func: Callable[..., T_Retval], *args: object, cancellable: bool = False, - limiter: Optional[CapacityLimiter] = None) -> T_Retval: - warn('run_sync_in_worker_thread() has been deprecated, use anyio.to_thread.run_sync() instead', - DeprecationWarning) - return await run_sync(func, *args, cancellable=cancellable, limiter=limiter) - - -def current_default_thread_limiter() -> CapacityLimiter: - """ - Return the capacity limiter that is used by default to limit the number of concurrent threads. - - :return: a capacity limiter object - - """ - return get_asynclib().current_default_thread_limiter() - - -def current_default_worker_thread_limiter() -> CapacityLimiter: - warn('current_default_worker_thread_limiter() has been deprecated, ' - 'use anyio.to_thread.current_default_thread_limiter() instead', - DeprecationWarning) - return current_default_thread_limiter() diff --git a/IKEA_scraper/.venv/Lib/site-packages/bottle_websocket/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bottle_websocket/__pycache__/__init__.cpython-39.pyc index 695197874673ec7a5be34c005c9aca52c8d29f7f..ae52f6c563e6e77977b185f1f503cbf952b5b5e0 100644 GIT binary patch delta 11 ScmX@kbew6zRYtdo*9rk0mIW68 delta 11 ScmX@kbew6zRYsSI*9rk0js+C} diff --git a/IKEA_scraper/.venv/Lib/site-packages/bottle_websocket/__pycache__/plugin.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bottle_websocket/__pycache__/plugin.cpython-39.pyc index f3aa39a0ffa6b614ba47051e9bbcb8f02f8ece3e..93be116d6290ae5004399697f325d00d1180b078 100644 GIT binary patch delta 14 VcmbQtGMQzAAS0vOW+6sKMgSaD0{{R3 delta 14 VcmbQtGMQzAAS0v8W+6sKMgSa10{#F1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/bottle_websocket/__pycache__/server.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bottle_websocket/__pycache__/server.cpython-39.pyc index d1b105e362503ed4c7b15e28e1dfce19322eaf95..8db352dbf6ce5b0e09a5d1a9be9e22162b377bcb 100644 GIT binary patch delta 14 VcmdnZzMFl6I}@YZW)G%fMgSyQ1U3Kw delta 14 VcmdnZzMFl6I}@YJW)G%fMgSyE1T+8u diff --git a/IKEA_scraper/.venv/Lib/site-packages/bs4/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bs4/__pycache__/__init__.cpython-39.pyc index f0b85e05dd880780e9deea3147f2b0f6a1c09ad4..3df043c1d33461bba07429256daced2769262fda 100644 GIT binary patch delta 29 jcmeC(%GkS=kvox>mx}=iLXEsOa%-_Ox@|UN4-Wmx}=iG%q`Bb82sQHB$URq?(QWfeWx3A)epLvi delta 29 jcmX@UmgV?b7Vbn|UM>b8(7f!hk$bK(qs!)%%5t9pgO&*n diff --git a/IKEA_scraper/.venv/Lib/site-packages/bs4/__pycache__/diagnose.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bs4/__pycache__/diagnose.cpython-39.pyc index 9ecdbcf047ccbe2bc719fdc219fff65d76085d09..09a338e5b0afa002e3f8fe9bbee66119e5587b66 100644 GIT binary patch delta 27 hcmeBj>T=>vuZ`SkoQ!Upi#TV90{~PI21x(_ delta 27 hcmeBj>T=>vb82sQHB$i0=B(QWfV<}1Geg{ldW delta 29 kcmbRGpLyzkX6{5@UM>b8(7f!hk$WpMqs!)l%vXK`0E+7g`Tzg` diff --git a/IKEA_scraper/.venv/Lib/site-packages/bs4/__pycache__/formatter.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bs4/__pycache__/formatter.cpython-39.pyc index f68e6b1f5f8df229373eee35b117a63ab531a656..462d19e474e1068e5da172544233e2102cf62507 100644 GIT binary patch delta 27 hcmbPjFx!ATk(ZZ?0SH2kyf$(Nurs=Cj$z*~002`H1~&iz delta 27 hcmbPjFx!ATk(ZZ?0SGiNJ8a|*U}tpM9K*g}003B22A}`{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/bs4/__pycache__/testing.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bs4/__pycache__/testing.cpython-39.pyc index 746e173c4f6937d9887e8c7bb3742d8b9ac3cd6d..d18a444c3d3a0ec569b3a19dd8602b7204573d6d 100644 GIT binary patch delta 29 jcmdmRi)q6xChkODUM>b82sQHB$bE;0(QWe!9*+e8goX(8 delta 29 jcmdmRi)q6xChkODUM>b8(7f!hk^2r0qs!(OJRS=GiN^_D diff --git a/IKEA_scraper/.venv/Lib/site-packages/bs4/builder/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bs4/builder/__pycache__/__init__.cpython-39.pyc index 2c13aac076a8c32e454d66dbc3a59ea5c4094509..59032c9e6498a767e550bcaea67c0e8fc3f7aaff 100644 GIT binary patch delta 27 hcmZ2ovATjgk(ZZ?0SH2kyf$)YGBdhuE@j?k0RUx^2QUBt delta 27 hcmZ2ovATjgk(ZZ?0SGiNJ8b06WM*{PT*|!70sv~$2bll> diff --git a/IKEA_scraper/.venv/Lib/site-packages/bs4/builder/__pycache__/_html5lib.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bs4/builder/__pycache__/_html5lib.cpython-39.pyc index a854461033b4e2cdbd1caf0ae585f67bd460d127..9fb11ddc87906ff732639000542701dd04c90bc1 100644 GIT binary patch delta 27 hcmX?`cs7wck(ZZ?0SH2kyf$)gU}bdMyoXg#8vtrn2POaj delta 27 hcmX?`cs7wck(ZZ?0SGiNJ8b0Mz{=>dc@L|gHUMvz2af;% diff --git a/IKEA_scraper/.venv/Lib/site-packages/bs4/builder/__pycache__/_htmlparser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/bs4/builder/__pycache__/_htmlparser.cpython-39.pyc index 17e415833ceef9ff7f84383a2245e3b814543ca2..aed8245e7c89cabd6a53a80366a09cdd866a2334 100644 GIT binary patch delta 27 hcmeB5>q_HJuZ`TRnHb$RZ)XZN003Rv2H^kz delta 27 hcmeB5>q_HJ@OE2LJ#7 delta 27 hcmbQ`HOq@Tk(ZZ?0SGiNJ8a~Bz{KdX`3;kv5&&a82WbER diff --git a/IKEA_scraper/.venv/Lib/site-packages/certifi/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/certifi/__pycache__/__init__.cpython-39.pyc index 76977a0e9ec05a22fd691949e625a4387c5c24be..6f3f627a5e637ce934828c80033b6230ae9206b5 100644 GIT binary patch delta 24 ecmey*_@9wGk(ZZ?0SMxZye4w@GrCQjodN(&y#{Rn delta 24 ecmey*_@9wGk(ZZ?0SIg_J51#6XLOl3I|TqzItJkY diff --git a/IKEA_scraper/.venv/Lib/site-packages/certifi/__pycache__/__main__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/certifi/__pycache__/__main__.cpython-39.pyc index b1ac99131aa7c83aa7d71d99ca243eff1c8c31d3..918e28dad694336e9567bd5f702f9747a73279cc 100644 GIT binary patch delta 26 gcmZ3&yo8xMk(ZZ?0SMxZyf$)cFfzJLHeoCP07K>l9RL6T delta 26 gcmZ3&yo8xMk(ZZ?0SIg_J8b0EU}SWeY{FOo07*>+kpKVy diff --git a/IKEA_scraper/.venv/Lib/site-packages/certifi/__pycache__/core.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/certifi/__pycache__/core.cpython-39.pyc index 8c9635a1b08fab2b6e8cf799db80f88a733389f4..07964ddd4eff1b316b36b6aaef9b35c1c7c5cced 100644 GIT binary patch delta 27 hcmeyx@r#2yk(ZZ?0SMxZyf$(#VPtgMyn*o)698iu2S)$^ delta 27 hcmeyx@r#2yk(ZZ?0SIg_J8a}$!pP{dc?07qCID#i2fF|O diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/__init__.cpython-39.pyc index 8dfe995f3069554c1465d4bc969b0d965cc3b933..f859cacfaddd778465ef466da45c5ae472a78b8d 100644 GIT binary patch delta 26 gcmey%{Fj+Kk(ZZ?0SMHMyf$*TF*3SMp2V0909JwqPXGV_ delta 26 gcmey%{Fj+Kk(ZZ?0SMeKJ8a}`V`OxhJc%(I0ADEw0{{R3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/api.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/api.cpython-39.pyc index 6c9eae69c7a3f0ec17982f9dd25015b6dd89e321..db1578d1c475051135474a29c8b9c41e4dcc485e 100644 GIT binary patch delta 29 jcmdnc!?dA?i93;(mx}=i)Q!A0a;Gvfx@|6G+}{EKY$^wV delta 29 jcmdnc!?dA?i93;(mx}=i+%7w8Z2|{* delta 29 jcmeC(!PL8hi93;(mx}=i+%7w8FF*>oG_30{~Fb1-bwL diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/commontypes.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/commontypes.cpython-39.pyc index 169689d2f99c5fe3bd99f61c6cdb67e9f93a50b5..15d62dc8b5dd02a6019a838a61692dc67e74eb0a 100644 GIT binary patch delta 27 hcmaFF_lS=>k(ZZ?0SMHMyf$*bVPk(ZZ?0SMeKJ8a~B!_4Ti`3G|rGXQA22h{)o diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/cparser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/cparser.cpython-39.pyc index 7abdf69de6cabd1917f3a5f43f280e2606790d0e..f898be997fcc9b770b57366604541d912915182d 100644 GIT binary patch delta 29 jcmZ3ulX2lrM(#vjUM>b8P&e}0$bFuP(QWf>rel!+cV7r? delta 29 jcmZ3ulX2lrM(#vjUM>b8aJ%fVk^4Loqs!*oOvfStfVv4G diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/error.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/error.cpython-39.pyc index f3f040bbdea0160e882be73c4bba6e0ed294a659..77fac51e716b8f696dffa22ac5097c844c06f620 100644 GIT binary patch delta 25 fcmaFH{fwJCk(ZZ?0SMHMye4wLV|3g2>kSJ4Q~U>l delta 25 fcmaFH{fwJCk(ZZ?0SMeKJ51z$$LO;0*Bcf9TkQxo diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/ffiplatform.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/ffiplatform.cpython-39.pyc index c6e542296d60ac5d82b2ac31ce395cf4c053c9d6..9b694c4f13515f2a190478cf0ab176450a7a0181 100644 GIT binary patch delta 27 hcmaDa{a%_ok(ZZ?0SMHMyf$(tFfqDq&S7fi1^`{523!CD delta 27 hcmaDa{a%_ok(ZZ?0SMeKJ8a}mU}ALHoWs=24FG2R2M_=N diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/lock.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/lock.cpython-39.pyc index b137e5d792dda45490c983fc5108c1bcc87df737..842cf51e14a554631242932db97e031c2350947a 100644 GIT binary patch delta 26 gcmbQvJe`?4k(ZZ?0SMHMyf$*nF*3SM)?&;B06riDwEzGB delta 26 gcmbQvJe`?4k(ZZ?0SMeKJ8a~ZV`Oxhti_lM07l0JX#fBK diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/model.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/model.cpython-39.pyc index 2e47a0bd03fe50a707b112dcac866daa9b654a10..a953c7729bbe522ca82b728bfe2ed2b1fd0ae1d5 100644 GIT binary patch delta 29 jcmZ2Fi*e~JM(#vjUM>b8P&e}0$gRrE=(gFA`HLq2X@v&^ delta 29 jcmZ2Fi*e~JM(#vjUM>b8aJ%fVkz19S(PgtC^A}G5a^MHI diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/pkgconfig.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/pkgconfig.cpython-39.pyc index 0dc91d45f309419d1145ef387257144a8e778f2e..70033ec805f33970348c5a17ce1e3fcb03973f5d 100644 GIT binary patch delta 27 hcmbQKF;jy(k(ZZ?0SMHMyf$*jGcmet&SqLC2mnt41^EB~ delta 27 hcmbQKF;jy(k(ZZ?0SMeKJ8a~RXJT~OoXxaO5CB+R2CV=9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/recompiler.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/recompiler.cpython-39.pyc index 378fb6510dc71362f7d1aeadfb93b4cbec19c3f4..ed1772c225cd9ec8efcf9248ced0feec22ae4ead 100644 GIT binary patch delta 29 jcmaFxj_JWWChkODUM>b8P&e}0$i1G4(QWf?rlnf|j*SUX delta 29 kcmaFxj_JWWChkODUM>b8aJ%fVk$XK8qs!*qOiQ-_0GH?r1poj5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/setuptools_ext.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/setuptools_ext.cpython-39.pyc index 9f3bbcf0dbe0be39c6a03f8edf13101fc2ee51bd..5cb1a097caba09f707ccd4bfe94631429111c378 100644 GIT binary patch delta 27 hcmexj@x_8Wk(ZZ?0SMHMyf$)6F*3SsR%7&&1^{4O1?>O; delta 27 hcmexj@x_8Wk(ZZ?0SMeKJ8a~ZVq|pLtj6dk4FGAk2B81| diff --git a/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/vengine_cpy.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/cffi/__pycache__/vengine_cpy.cpython-39.pyc index ec22b3a0915b943b15d94b69eac87b31704e5987..83ef1b5d30fc9eae1c4420fc134ee48169be3c6b 100644 GIT binary patch delta 29 jcmeC1%G5WNi93;(mx}=i)Q!A0a%VC#x@|6HmTU(AWx58q delta 29 jcmeC1%G5WNi93;(mx}=i+%7w8mx}=i)Q!A0azA2Xbld!nNzoqwZp#Oj delta 29 jcmeBQ!q~rrkvox>mx}=i+%7w8@w|2bKT; delta 27 hcmaFp@z8@ik(ZZ?0SMeKJ8a~>%E;)l`5|M25&&}L2uc6| diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/INSTALLER b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/RECORD deleted file mode 100644 index 4bc537c3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/RECORD +++ /dev/null @@ -1,33 +0,0 @@ -../../Scripts/normalizer.exe,sha256=Tb318KAuAZX3JDK2YH_V8XoRI9mah1OfwjHG0lkxy0k,106395 -charset_normalizer-2.0.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -charset_normalizer-2.0.4.dist-info/LICENSE,sha256=6zGgxaT7Cbik4yBV0lweX5w1iidS_vPNcgIT0cz-4kE,1070 -charset_normalizer-2.0.4.dist-info/METADATA,sha256=iGaSYKAbW7dltLfO_sIm347XsC5kqKiFrvR3IHolDio,11710 -charset_normalizer-2.0.4.dist-info/RECORD,, -charset_normalizer-2.0.4.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92 -charset_normalizer-2.0.4.dist-info/entry_points.txt,sha256=5AJq_EPtGGUwJPgQLnBZfbVr-FYCIwT0xP7dIEZO3NI,77 -charset_normalizer-2.0.4.dist-info/top_level.txt,sha256=7ASyzePr8_xuZWJsnqJjIBtyV8vhEo0wBCv1MPRRi3Q,19 -charset_normalizer/__init__.py,sha256=i8FSr9cSFIrh16O8h7com8LKtd9nsLY8wiEhSpk1_aY,1673 -charset_normalizer/__pycache__/__init__.cpython-39.pyc,, -charset_normalizer/__pycache__/api.cpython-39.pyc,, -charset_normalizer/__pycache__/cd.cpython-39.pyc,, -charset_normalizer/__pycache__/constant.cpython-39.pyc,, -charset_normalizer/__pycache__/legacy.cpython-39.pyc,, -charset_normalizer/__pycache__/md.cpython-39.pyc,, -charset_normalizer/__pycache__/models.cpython-39.pyc,, -charset_normalizer/__pycache__/utils.cpython-39.pyc,, -charset_normalizer/__pycache__/version.cpython-39.pyc,, -charset_normalizer/api.py,sha256=xf9L11VEFJGNcGFSS0uJxZwfdPYy87ya97AiVhNr-MI,15685 -charset_normalizer/assets/__init__.py,sha256=JTs2XX9qbYSBhS4EEI93IqEOnzzrHhVmX1gp2vKjZdE,6938 -charset_normalizer/assets/__pycache__/__init__.cpython-39.pyc,, -charset_normalizer/cd.py,sha256=_HLe1wgJAifJPl4dlBctjK5yIvH0ja67jePw36OrrhI,9223 -charset_normalizer/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -charset_normalizer/cli/__pycache__/__init__.cpython-39.pyc,, -charset_normalizer/cli/__pycache__/normalizer.cpython-39.pyc,, -charset_normalizer/cli/normalizer.py,sha256=HWLuXnvQa12U2zjv6rXtashpNnxgxN3lZtVCnqHjIFQ,8334 -charset_normalizer/constant.py,sha256=YA8r7rNGeuLlnqWLs2MISs1mFLmaralG99HNevHuUuo,18390 -charset_normalizer/legacy.py,sha256=L3Qn-DSLjRQoYPtDIzkXcqO0mnFIjOl0p6-gAzYUY54,1640 -charset_normalizer/md.py,sha256=m3XxcK9UhsSCFK7-vrOU6ztn-eaeXKLuS8dP88QY6zw,16263 -charset_normalizer/models.py,sha256=A7vIN3PCJuM1KMDBs60Gb_WF1lHJsrkrllc5_RMV-nE,12541 -charset_normalizer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -charset_normalizer/utils.py,sha256=0HasZ3NtRNiw-HbmgnfhSDySJfSa4pO4azPTn6vOrP0,8594 -charset_normalizer/version.py,sha256=Ou-PvSj5-2Ci5Y_bH8OSoXrbbTt8sxO5pJRagAzlYUc,79 diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/WHEEL b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/WHEEL deleted file mode 100644 index 385faab0..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.36.2) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/INSTALLER b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/INSTALLER similarity index 100% rename from IKEA_scraper/.venv/Lib/site-packages/MarkupSafe-2.0.1.dist-info/INSTALLER rename to IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/INSTALLER diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/LICENSE b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/LICENSE similarity index 100% rename from IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/LICENSE rename to IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/LICENSE diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/METADATA b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/METADATA similarity index 89% rename from IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/METADATA rename to IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/METADATA index 794282b1..94cc938c 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/METADATA +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/METADATA @@ -1,11 +1,13 @@ Metadata-Version: 2.1 Name: charset-normalizer -Version: 2.0.4 +Version: 2.0.6 Summary: The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet. Home-page: https://github.com/ousret/charset_normalizer Author: Ahmed TAHRI @Ousret Author-email: ahmed.tahri@cloudnursery.dev License: MIT +Project-URL: Bug Reports, https://github.com/Ousret/charset_normalizer/issues +Project-URL: Documentation, https://charset-normalizer.readthedocs.io/en/latest Keywords: encoding,i18n,txt,text,charset,charset-detector,normalization,unicode,chardet Platform: UNKNOWN Classifier: License :: OSI Approved :: MIT License @@ -23,8 +25,10 @@ Classifier: Programming Language :: Python :: 3.10 Classifier: Topic :: Text Processing :: Linguistic Classifier: Topic :: Utilities Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Typing :: Typed Requires-Python: >=3.5.0 Description-Content-Type: text/markdown +License-File: LICENSE Provides-Extra: unicode_backport Requires-Dist: unicodedata2 ; extra == 'unicode_backport' @@ -33,21 +37,12 @@ Requires-Dist: unicodedata2 ; extra == 'unicode_backport'

The Real First Universal Charset Detector
- - - - - Code Quality Badge - - - Documentation Status - Download Count Total @@ -80,19 +75,23 @@ This project offers you an alternative to **Universal Charset Encoding Detector* *\*\* : They are clearly using specific code for a specific encoding even if covering most of used one*
+## ⭐ Your support + +*Fork, test-it, star-it, submit your ideas! We do listen.* + ## ⚡ Performance This package offer better performance than its counterpart Chardet. Here are some numbers. | Package | Accuracy | Mean per file (ns) | File per sec (est) | | ------------- | :-------------: | :------------------: | :------------------: | -| [chardet](https://github.com/chardet/chardet) | 93.0 % | 150 ms | 7 file/sec | -| charset-normalizer | **95.0 %** | **36 ms** | 28 file/sec | +| [chardet](https://github.com/chardet/chardet) | 92.0 % | 220 ms | 5 file/sec | +| charset-normalizer | **97.0 %** | **40 ms** | 25 file/sec | | Package | 99th percentile | 95th percentile | 50th percentile | | ------------- | :-------------: | :------------------: | :------------------: | -| [chardet](https://github.com/chardet/chardet) | 647 ms | 250 ms | 24 ms | -| charset-normalizer | 354 ms | 202 ms | 16 ms | +| [chardet](https://github.com/chardet/chardet) | 888 ms | 300 ms | 27 ms | +| charset-normalizer | 430 ms | 220 ms | 18 ms | Chardet's performance on larger file (1MB+) are very poor. Expect huge difference on large payload. @@ -102,24 +101,16 @@ Chardet's performance on larger file (1MB+) are very poor. Expect huge differenc [cchardet](https://github.com/PyYoshi/cChardet) is a non-native (cpp binding) faster alternative. If speed is the most important factor, you should try it. -## Your support - -Please ⭐ this repository if this project helped you! - ## ✨ Installation Using PyPi for latest stable ```sh -pip install charset-normalizer -``` -Or directly from dev-master for latest preview -```sh -pip install git+https://github.com/Ousret/charset_normalizer.git +pip install charset-normalizer -U ``` If you want a more up-to-date `unicodedata` than the one available in your Python setup. ```sh -pip install charset-normalizer[unicode_backport] +pip install charset-normalizer[unicode_backport] -U ``` ## 🚀 Basic Usage @@ -243,7 +234,7 @@ Don't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is - Discard all charset encoding table that could not fit the binary content. - Measure chaos, or the mess once opened (by chunks) with a corresponding charset encoding. - Extract matches with the lowest mess detected. - - Finally, if there is too much match left, we measure coherence. + - Finally, we measure coherence / probe for a language. **Wait a minute**, what is chaos/mess and coherence according to **YOU ?** @@ -270,6 +261,6 @@ Feel free to check [issues page](https://github.com/ousret/charset_normalizer/is Copyright © 2019 [Ahmed TAHRI @Ousret](https://github.com/Ousret).
This project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed. -Characters frequencies used in this project © 2012 [Denny Vrandečić](http://denny.vrandecic.de) +Characters frequencies used in this project © 2012 [Denny Vrandečić](http://simia.net/letters/) diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/RECORD new file mode 100644 index 00000000..fb4f8675 --- /dev/null +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/RECORD @@ -0,0 +1,33 @@ +../../Scripts/normalizer.exe,sha256=E_XOYvCQJ9_b0Ik2oaeZ7MIEqGafDrd7m41LRRMYRng,106395 +charset_normalizer-2.0.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +charset_normalizer-2.0.6.dist-info/LICENSE,sha256=6zGgxaT7Cbik4yBV0lweX5w1iidS_vPNcgIT0cz-4kE,1070 +charset_normalizer-2.0.6.dist-info/METADATA,sha256=zWnIKeYWdCmL4F61s9ci-Q4mjCKzbioT18dp-T0gEag,11241 +charset_normalizer-2.0.6.dist-info/RECORD,, +charset_normalizer-2.0.6.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +charset_normalizer-2.0.6.dist-info/entry_points.txt,sha256=5AJq_EPtGGUwJPgQLnBZfbVr-FYCIwT0xP7dIEZO3NI,77 +charset_normalizer-2.0.6.dist-info/top_level.txt,sha256=7ASyzePr8_xuZWJsnqJjIBtyV8vhEo0wBCv1MPRRi3Q,19 +charset_normalizer/__init__.py,sha256=zPNiH2V-xY-kLTkpOfzCIUmf4tly8t7tg7hkgMW7528,1467 +charset_normalizer/__pycache__/__init__.cpython-39.pyc,, +charset_normalizer/__pycache__/api.cpython-39.pyc,, +charset_normalizer/__pycache__/cd.cpython-39.pyc,, +charset_normalizer/__pycache__/constant.cpython-39.pyc,, +charset_normalizer/__pycache__/legacy.cpython-39.pyc,, +charset_normalizer/__pycache__/md.cpython-39.pyc,, +charset_normalizer/__pycache__/models.cpython-39.pyc,, +charset_normalizer/__pycache__/utils.cpython-39.pyc,, +charset_normalizer/__pycache__/version.cpython-39.pyc,, +charset_normalizer/api.py,sha256=fpxRxVAXxeaRXACxYl8EhXfAoybWkaorvCM3kYPv-gU,17738 +charset_normalizer/assets/__init__.py,sha256=wY6V36jmSumayW1HFQNbD19mxuT9AhcUUzl4LQN07Vk,25069 +charset_normalizer/assets/__pycache__/__init__.cpython-39.pyc,, +charset_normalizer/cd.py,sha256=tfM5s7iwdy7Mr-cLbv4l9hZbs0RnsW3-BaKuJRyUjvI,9520 +charset_normalizer/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +charset_normalizer/cli/__pycache__/__init__.cpython-39.pyc,, +charset_normalizer/cli/__pycache__/normalizer.cpython-39.pyc,, +charset_normalizer/cli/normalizer.py,sha256=H_2C2e81PqNCmUaXuwBJ5Lir_l0wwzELSxjPXcUL9O4,9453 +charset_normalizer/constant.py,sha256=rx8g-2vg-dIVV6iU6PWYWog9jBJQDvUr8vj4tcTo8OI,19011 +charset_normalizer/legacy.py,sha256=VXqlU-W1NdE7fUXV_DZ1BDUyyX4qnFegiedMI7i8n9A,3213 +charset_normalizer/md.py,sha256=OH-UeRKuprWUxoGffHNRH16W6Tmiu3OGYzzC8tZyarA,17654 +charset_normalizer/models.py,sha256=IfkHAPRbC7Veqic9C7XPtoEb4F08P4o970WIdBg7Elc,13332 +charset_normalizer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +charset_normalizer/utils.py,sha256=6vfdA59u0VQD3_dDXf2B8viuUWPo9xIfKq4b0nXX6Mo,9026 +charset_normalizer/version.py,sha256=GJ53Q4s3c6EeoKiY91GIgH_aP4WKIZ36Hg65AHVSUoQ,79 diff --git a/IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/WHEEL b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/WHEEL similarity index 100% rename from IKEA_scraper/.venv/Lib/site-packages/anyio-3.3.1.dist-info/WHEEL rename to IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/WHEEL diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/entry_points.txt b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/entry_points.txt similarity index 100% rename from IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/entry_points.txt rename to IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/entry_points.txt diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/top_level.txt b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/top_level.txt similarity index 100% rename from IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.4.dist-info/top_level.txt rename to IKEA_scraper/.venv/Lib/site-packages/charset_normalizer-2.0.6.dist-info/top_level.txt diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__init__.py index f14a90b1..f899bce6 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__init__.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__init__.py @@ -8,24 +8,39 @@ All IANA character set names for which the Python core library provides codecs a Basic usage: >>> from charset_normalizer import from_bytes - >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието трябва да бъде безплатно, поне що се отнася до началното и основното образование.'.encode('utf_8')) - >>> "utf_8" in results - True - >>> best_result = results.best() - >>> str(best_result) - 'Bсеки човек има право на образование. Oбразованието трябва да бъде безплатно, поне що се отнася до началното и основното образование.' + >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието!'.encode('utf_8')) + >>> best_guess = results.best() + >>> str(best_guess) + 'Bсеки човек има право на образование. Oбразованието!' Others methods and usages are available - see the full documentation at . :copyright: (c) 2021 by Ahmed TAHRI :license: MIT, see LICENSE for more details. """ -from charset_normalizer.api import from_fp, from_path, from_bytes, normalize -from charset_normalizer.legacy import detect -from charset_normalizer.version import __version__, VERSION -from charset_normalizer.models import CharsetMatch, CharsetMatches +from .api import from_bytes, from_fp, from_path, normalize +from .legacy import ( + CharsetDetector, + CharsetDoctor, + CharsetNormalizerMatch, + CharsetNormalizerMatches, + detect, +) +from .models import CharsetMatch, CharsetMatches +from .version import VERSION, __version__ -# Backward-compatible v1 imports -from charset_normalizer.models import CharsetNormalizerMatch -import charset_normalizer.api as CharsetDetector -CharsetNormalizerMatches = CharsetDetector +__all__ = ( + "from_fp", + "from_path", + "from_bytes", + "normalize", + "detect", + "CharsetMatch", + "CharsetMatches", + "CharsetNormalizerMatch", + "CharsetNormalizerMatches", + "CharsetDetector", + "CharsetDoctor", + "__version__", + "VERSION", +) diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/__init__.cpython-39.pyc index 7b2681adcad93b7f494e1f9511ce0fdd376f452b..2de2a66d5aeebf1ec4a8b7b189843bff63e88a01 100644 GIT binary patch delta 522 zcmYk2Jxjw-6o!-LJ8jbX1sxn(L23{joSf?52Pjy&Rv$z@7BF-W+IbW z$YM6KSs9gODUbs-sxSvR%tdZ7Yf+WeP>s!@xqQ~qd|-4X&m7+>FArvEwb|OBLq87a zT5Fv4@m9<8>_(%}Znqm3G)eL0m?lYfqpWDZ-IL( z==&pK70rmG17Qtg&PWtqQ%@7sodMwqO?PQZ{WRvnnJ!`&voEc_BI ai7!C_!1vjH_Nj+1sHlr|dD*DRwbBpEE{BQ$ delta 830 zcmd5)L5tHs6i(8#Y0@@Z_fXfx!`NHUEgnVKBDf+VR1cz)gwSlB5lT=tQyWNYd zmu1OKyom>IsaSSFjQ#;-25<47cycDKdyxJBb9nQ8@B7}H_n5q?|1wRx(J&?JO=uQa^W|U-Hf0Gn;RRRg zOICIAL!Bj6WgoCZcEFD5jDDmkpr1sTvDX~TIiPcTO25+2G-ZeM3(c+p&N7bXfF02c zu&Jzzr#TMN?kLi@3^DXTmoXoZobwZDstn1MWO6@+nu&=)9A>RW`TU zlX!q`w1GDQ1V~_0g7e_H#XvsIFU0Xm)$jP?y?0;SEe(8H(JgcSV z+JJ-s8jN$j0Ao8I=0*W`_hKC7`Y0rU?Rzh=CFd0v$JmK2C9fg$0+YxKM+oKGlRJ<4 z_a63=_v)3Ka^AWb|^&sxtlgxt_U2)3Ms2c5SkoupH~xDPL_P<;H{ zcJ@exj|?|g=*v-v#toz@T&ubSp^N>9=)xraYEt7NFWF-ct}RF2xn3+761cI<{Idj( eK1jqA#UlKEx|6&sd+P$Ltqr*@H|1uj&d)!usBFyu diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/api.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/api.cpython-39.pyc index 9b6d3c8363bc97522e0606eccaab890ccd27c9f9..aa1e21d932e8d314d40bca44f8d028e2ff48f057 100644 GIT binary patch delta 4849 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 P;kCP`iOwVP`m_H74uhad delta 4396 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 N_I9>pKg^2g+aC*i8V>*f diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/legacy.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/legacy.cpython-39.pyc index 651b515e7a2f59c325f6b08bf280cb0e10fe2642..e524e8f6272861fca727e9f565ed86ec3c7d1ed4 100644 GIT binary patch literal 3032 zcmb_eOOG5i5N^ABdU|GOHk&1cfRHfn41^`T1d0#@?JnUtiSiJlwaTcs?U`w|yFJ*R zT_((OU~`3Ez+oeCiNp`!z=@yXD<^K8K`2zYXCH(m5-2UXrpjfzK9|d%Cuz5v9(>nd z{vi3L<$1rLarmo)aUPof5d`-*$-NkVX-*0n)54GaB8UUxai0fytq9|=sK@mpild?t zH(Y-$Zx(a$oYTX+RkY)FF(1zpPaG3eEC^o&AdmOy!`{OlN?!kt@`yKX2Jzwrk2m?; zO^?rs_KqJv0CtPF!ETFruup(J&yRt9Oq>AwL9iG2aj=g&`y?kgD} zsj<<;k;!D4rU^FY{My|#0+htl&VPb?1tzNdvf`` zcP_82UhOSkynK1}%B73lmDTR@YKPj^@-R_an2!^a4(>$kjZ zG9{djiTY?tK8s4q={BA9456pN{S99^4Sd12Kl6RXYv663^4yGI*1J2UJlvpa7kqOd zDX+io!FtrRHi`OSO3To+rf`5$e;V-UJ0DWtNPdRRH5q& z!idx`GZajespMHXV6yM*LAEJMh6!VkFmNof_YKoSInFs-7p#!l$Ed~$}R62jzFUbsxhg(wZ|4VLap4%U?G z4kaGYWK_-54C3GdiBbt5A4qeKeR+1fYwOp_jS_Nfy#bUme80VIYh%;zyCA{1Mo^Ei550y(4^+_GXAbpZRsTz) zi4CCuA*T%pqfdkIn)8H`fP{DGouJkv5pB^$@+dhOoFq{Y-U(?4e)@-c9LAfVO*_j*{n|yc|xifnMXG(?ihfJaT%S zH-Jc*_SDgP5c+RX5lsN?B1U}#gz2l~84iD&$&mw8k2J^2>ih1;}yV*|>{WNAf4 zY{vO#D#ex8Oh^8AcX8ft}pd11l@pD@$kLg^7TqN}w8T1Jvx| z%8Vi4=6+JS6u!B)sSOeZ!$PFBfxbKWIOa9np?kh*Kq#eu2DKZG)}Y?*I%lDmW?TEe zxl&l4oj`TqM?Ht)c@%iX)EN|bS1Q3!L&sat?gseeza3%)(53u7V~h~bQ5ey2;RuXR z+#4g7!hME_3~(ewbX@vR5clh|+lkauxbD*^o&jN7hl}0SS#^LeLk`2iDLRee)Mr7w z3QaG7h=72a(Lr*q2tj?Nu_x@;=kra}ZqCB;T>RwVrvCRs0nh{y?ginPdr|J1V! J!NM~O!C#8m?6&{_ delta 443 zcmZvXKTiTN7{>dy*WPjbF(C#;7@SO4`~+$=Kte*I39#4&53UID%9-9d;KJe;Agu1j z*^lC4?i)C{n;3n|qJtfNectwY`#yc!dCHf9V$mnKj$coMsaTcj%K=s)2_YgHB!Ja4 zqMAvz(JXQ_ms|@ev@2a8%2QnBlu$0xpU^6)63fteq#+N*gCp~y+b0e0-41F%=1)wl zhoeQR609oC&RMV39t@ioyjU#^GFy1^OiUHG&&$^OfL|>I>SP~5{1ONd--7wz(E=?)9V$)*JXQt@^vl%H zbKWS(3QjVKN{92<=pdTiD{~m!&Ww#EYyVu1<9U(>^K_Fd6Y1i1HorCw+70ho+6<3(#^b0)IZp>Chthc;a#Lo0IS3{7oY&!><3j2VjTbg diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/md.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/md.cpython-39.pyc index 791b53b9498c62ef8f49bb637d15a28b91111d15..7649142faffcd67f21d881ea071cea9b218bcf43 100644 GIT binary patch literal 14330 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 BNooK9 literal 14076 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 xVdgcnxo}#A;J*SM|39g10CfNW diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/models.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/models.cpython-39.pyc index 6ea64ae42d03aeae2461ed0581a6db3362ab0649..5a52b01f0e707e9c3e22fc35d8f33c25d88c3627 100644 GIT binary patch delta 5175 zcma(VTW}o3ac6gLZ||wo=_K8qtkc`l*_LbzKLFzwHaJc|fDIV7fb~hUSSR0$*;RyH zf}@aQ@_-7?BtXKuk{|NJhklY&C4A%~m8zsF`AH>P3E?AE6cs*5g?tb~obKL}u*In= zy1Krep6;IRneLt*y@hT(Sv zSW>(bSUN#ql(W-HG5rCWKT~9W_*i|h<~c%|Y+y$9!*lg&qg-)(&0U-=n!a|lcEQ(= zm*+g+JPB+iuP%K3juJ>=i~{>MP7jtW(faq$JlV=onHu zfRZAqH18rxr=!z2!@EIix;5(Iy-gT)!9g)HBFl3y&VYEpp67ie-VKxzfRf4 zw-cqXPT9dHi825bjf|S&JBcy~lpe0MjNip~6LkovV0;s{cADQnq+w)S_i_*4OVp9; zsQdVSqK?9z;j!GvZ-N~gYmIK^2Vk_7A9Hjt;vgLBA%6H$$QlP7fxk!iQIema$UE+@ zzNfvw#Vm*rl$JmZS#kaP;ue@c245HQQBl;3 z{m14@!gahmOWxf4)CO0WgI28m!t7-saTxgJyOHsH8W37X+=|#W3&^2puImI4-6#Mh ztiz70|JC)?JEIA224TjI)s?5U1*Q7KUydfCB64S9MK3 zm{{12F%&pFfY=~{jb;PQ58Jlu3EQs8j}uFic*J54g1wswn6@pP21t1FrR0!&zL1xH zO*ZF(=t7|z5s;!A5F>1z9h7%CtCjRTE8>2 zS)|fD6}}CpX|C!2A+WhvE)~PjplE0*-MkuC&CgUL10}>%FLqy-%WHD-^`0@>?jjRI zxKz6nzZoXpkstItFo{_z@Y)twp2Q;v+DROMiC@ZE@8c6F+m6LgG#oMK)I57`zEpRA zEtA{A6wzjnqP1x>$~2XaTZVYGmwm?Ujg zn`?>jM_EYaxuPexh=m>-kplD8M%-jF6Ez4J#86k z^Ap;#CJM{!4SiXAlQHG7f*11OGQs-2tk_t=p>_*0G%QA8MQE}dFDNkGG=v294Yw{l zhxlDvkNltmC=wfuNfPpr}!1z$ea3xb5O>^-N!h?WBBQ6no&N z1#CX6ZpaJq5Rm@~U-7Vff6JkfK}0v(3^50@AIdNF%R#cK&8hgIN6W(X{v|){KRWtV zRJJLnKI^#Nr}AuJ+@SQBT79mNW(USmXc~ZTP`Wu{D-6H^y4i?x!-g33MX#~wF(&^UmYE3`y#>iwdgHaVGyXSTru+3PouS?P$`Dc=46q($rerR{Q9Kr4e8cf^X zDf`BU<&k3k0EQ5Cq)^#7!&X^TQTqAKRDi>nMz%c-d)99R`0B~=yI8Yb&ohmBsPQ?1 z7=?W&Vq_zARg@l-OxTyu$zAKeAEG8`!wv}K-HUsk2Sf?M!yp2+(hNGIY;hFc76*%0 z3g1ALZ3-Ku*h%?e@r?o{TRRp^#e3wBw~aP4;z`s)+58k>xRJa*2dy8aKIS5o6cI)2 zTL?N3Jcod`;M<5@L9l}0I|#_#IAUZ1W&Y>qOcIeVccFkMbc5LhXOak zSA`=CK*UJ|_`LHC??M9}6oKXBLsWq<5AumTP9QIqCrTyDoP+hf5>!qsAC_9>0<*yn zEqdjOE2xNOkQ>`Cx*aJkf-S^7vy#WwI#GHki(X_zPuKPf%m~o!^1`k{HqKIPLXAWJ QmC=$-u+B^#hmK79AC@{Y?f?J) delta 4673 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/utils.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/__pycache__/utils.cpython-39.pyc index 0aa430d56c805699581d322d998e4a25f051dbab..af023b002009f7c13e2f913593958c2da1904b65 100644 GIT binary patch delta 3670 zcmZ`*O>7&-72a9yE|>q5L`t$HOY%=-)Bl!iNtPWqlqK7gWy!Uu*x0sVSDcZw^^#O( zmv)snkpnvgnlwm_xfHE|_Rx!gqG*vKC<>o?DbQSd>0Wy3!R@Vw9@56{dqav=saSyC z4Bvb6&HJDI-NaXClXfBzRp9Tfky(3c|D$BTs)ZgMJ!TU(WQC|gRadL%mQEDdhg_o) zw!(6+xn?C|MdV(0qm`HylY7IBR}xmDlC+YQl$ENat#qZs>X5Rq+ga(dx?pe8$fG~( z*^IE=H2Mi)eXO6x9;-A?6A!fq#M;ANO8TTENmEiXuuYO=eY+GXP16o39o!~uAa>F& zDH&?rk)hd#nza`-H~;VQZrUSN_w4}brMskL{|?D++9xFkc1Zf^9w~Wkhh%^bO35(W z-12*f?gg6;?oi!F_e<47J0u6_Yf_TiAsMCzrR4Aq$swAPk|SG^%~ntj(<4%J6hy~Z z?*r0`%uz_oF?w7|kJAD>!A`P9;7>jd(NlEfp>CaG5jxsBaT-pXp=0vI2$Cs?v64W{htKJIeH!#r|B#j#QNw3fc^%31E9|UCn58k2fZnJ5%k7@*T=@` zG-%DxOTd|soPNoS^56p#i->Fq? zHwY~A8G*jY89{Pp{^G)PVg7RITK>k>#h|;8pU;;Tm#$x5 zxKW&$E-egCsC)y5*Ph;7{hp3Fc zDk{GMj=!F7UC7b>_M5se3Ea5@2`kk-R;pFqjgJsRLkz5{*=AL}F7C&TQ7oyZSDgI)eUbLSMu|hm*!p#g*CJWT~&8~{WU<>n?Tc3 zuXG>`0REco{Qhf>e-n66J=p&|3s8H+RO--B$4hPyzRfo7);QfB7V%MPuCrX~P+ERq0QgL)d z^mR=y#qcW9xT@VF2!EyS`c7$i1L}Coqkq5&FAhY}&8SM!M18LQo7WLXZNw)F1NgIn z1aSDbk$eY85cPbU``%s0UxQh^BtFOt#kO52ewFDx_yQC?9NGX4d5IDO!V@JKmA?Z# zfd4)$5RrdoM)uZl>morEa6!tpBVNe%55uQlvvG;+_+l;;gv;x)vjW5Oxl{H5@P4*# zScvs4@t^FWO&hm3_;@S#9G^7q0|D#r;r=}&6bVDJ?PmBHL>y=!c}*5gkP}#DIt|^g zk)+Ds2eq6Ur18b0P%$2RyACmCU=F@tpLb7f&Y+4GggoZUaT$bcN(0S>4+yYg6YnwP zyXC!lj7FtG$t&B{eJ?G+z~W1ws&SP+#A`x9tYvb^mOsS1JrR->AND-GxehA)CX!o7 z07!X;+2U9T&z=LxnX(2rN3MqigT--Z2D-FC)&c)6Fme%&6P5o!{G@kbpe=FjMs82-jOOaYE|@Gue_JUoH~KU=I+qs6ept2|k*98p#zTvq-KXnMbmKYho*##^j zZw-hFABb^i2~)1P?}xG+ikhS|1^=*iC*(eD!jf$MM}*qHKQ#!yGX0%tEtAM3JG1`- D-^DYJ delta 3378 zcmaJ@&2Jn@6`$_u?&C65gx!jwiOk zl7Ch8-m71|kE+-6pP64xYeqVqh``^KKfZ2!f8dc;6h9Lmjh;0`JL*WfBt%GrL~Yqo zbcN3)JLagm>csW9lh6}RQcpT5J;il`oz~M}FWZ{arnhmKVrQIoy`9fvcGk)1IX+h( z{ib&(XZDczM}k=}izM+xBuSFml^zOuueq-&a7~(MT+`R0QO!b6glpSKhHHFE|#s2Lz9xMui}<|G;9n$jW7DKf-0BZoAn$uQTP0nMn{@le>0zXZu2 zA!oSyEV*Hhndi(fy=R|9$rw4eE9a5G9w%6`(#3q9m{8RWN*wybgvJKvpoP$SgQ;jm&}M zB9|1o z{S6X*AZ$fol=en>Z&YvuPh#xv(h{4K2MalPQbCfKUX@zho2L<40NKCazRo_7H#$)7 z@rNghf+nN{RiM4BJ&|Wa%8Jm*8p==^ZS({&t2L)y^Gp)R)fzBzo)C(7N}8HZZOg0} z)vD?GDDv_E5iuc1f+Qy308vl`@wxbdo??Ghe$tl0ZL;N?j#rXsjy;ZzOrUeEqz%`? z(<;<(H_TB`hTh7mm;qlCA}z6hwB?zWzVezbFVB{jR%i!O^fY-mBll3Xyozo3mV2qm zvmf;c6HZfPs}r<=S~Yxgqei!B36@Wz z5ZN!|rHcn5(}1zwaI1a;JgT{GAg=}h`4Uygm&%b&0k?a39OQHo;Q&h^)63SAcjwVLIsx!hq&&v+M-Zlv(5xHO@N0AvIaPoNWE)FJuR)fUCdQ7~ zn1PK|!!s*e2DOYe+oZTz!_{dh_$^!=9y+m-yAeQXFJR z0>h?7jSa&!K0JbExkOaI$E2Il^zVf~o>LhFi`L^_PoI1MxcX~Qc_#oO67&PO-PjHKpG$HIS3-tAXKX(ikrJ?a_C5eO+XVx-k8e}UeWx66 z`0JJNsmhued_Kj-iqeaLg2UuQxSS3RCMPOjz-?g)+qlvAl+H!d70=pWpXILKj^lAc zcwCF`APqVprB1{4t;*Uq+)LAihGe-Le+FHcC^;cyps!I6Im9pvdG;{>NnaaCsE+V1 zK#=f!gZkcm%in~Cx5~;L{VyeIr=$DyU%=4I07PWWenLiUzT2oxheq@qB7keIQ-!Y$$Id*E{Uf z&f)b6PQQxKtTOG!CBAKl;60pw6JZUZiqLX0EQ7cOSDhd8FIa{RidQ=WuUQf_kv?Ew z>gpEqtkHFM2fJ%Y3ZkCr^X3^u4MGCRh7TqjhwnE~_?N&7JJ4JuyMaH9eo znFX5&&my)|5e^k!C=&euq>zMU)4z%lXf3NXNJqK*w_kMeh&u>(5r8rB>;(d!J%?FI z<&~#()PEfT(?dmoK<3Wy>eH`)pcJPMQMt=DdT#X{$Ww&1Il;7 zx+=17r@C40*w1#_kwe_$K%#>ba98(PhB1EhBO=r9;ZA|R#fNffMo;a1S_$-{3EBzr zAh`rzc3psp4pZ<@QQ@LH|8!oHPW!nt9VyDWE9~iRtj!CViCGs q3TI-!qzYLT{@YZcGmZ013{b;=_PgTAwqBSeirI{mPvSE$fSE$f*>O diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/api.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/api.py index fd023409..37795a4b 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/api.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/api.py @@ -1,38 +1,48 @@ -from os.path import splitext, basename -from typing import List, BinaryIO, Optional, Set, Union +from os.path import basename, splitext +from typing import BinaryIO, List, Optional, Set try: from os import PathLike -except ImportError: - PathLike = Union[str, 'os.PathLike[str]'] # type: ignore +except ImportError: # pragma: no cover + PathLike = str # type: ignore -from charset_normalizer.constant import TOO_SMALL_SEQUENCE, TOO_BIG_SEQUENCE, IANA_SUPPORTED -from charset_normalizer.md import mess_ratio -from charset_normalizer.models import CharsetMatches, CharsetMatch -from warnings import warn import logging -from charset_normalizer.utils import any_specified_encoding, is_multi_byte_encoding, identify_sig_or_bom, \ - should_strip_sig_or_bom, is_cp_similar, iana_name -from charset_normalizer.cd import coherence_ratio, encoding_languages, mb_encoding_languages, merge_coherence_ratios +from .cd import ( + coherence_ratio, + encoding_languages, + mb_encoding_languages, + merge_coherence_ratios, +) +from .constant import IANA_SUPPORTED, TOO_BIG_SEQUENCE, TOO_SMALL_SEQUENCE +from .md import mess_ratio +from .models import CharsetMatch, CharsetMatches +from .utils import ( + any_specified_encoding, + iana_name, + identify_sig_or_bom, + is_cp_similar, + is_multi_byte_encoding, + should_strip_sig_or_bom, +) logger = logging.getLogger("charset_normalizer") logger.setLevel(logging.DEBUG) handler = logging.StreamHandler() -handler.setFormatter(logging.Formatter('%(asctime)s | %(levelname)s | %(message)s')) +handler.setFormatter(logging.Formatter("%(asctime)s | %(levelname)s | %(message)s")) logger.addHandler(handler) def from_bytes( - sequences: bytes, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.2, - cp_isolation: List[str] = None, - cp_exclusion: List[str] = None, - preemptive_behaviour: bool = True, - explain: bool = False + sequences: bytes, + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.2, + cp_isolation: List[str] = None, + cp_exclusion: List[str] = None, + preemptive_behaviour: bool = True, + explain: bool = False, ) -> CharsetMatches: """ Given a raw bytes sequence, return the best possibles charset usable to render str objects. @@ -49,6 +59,13 @@ def from_bytes( This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. """ + if not isinstance(sequences, (bytearray, bytes)): + raise TypeError( + "Expected object of type bytes or bytearray, got: {0}".format( + type(sequences) + ) + ) + if not explain: logger.setLevel(logging.CRITICAL) else: @@ -57,41 +74,38 @@ def from_bytes( length = len(sequences) # type: int if length == 0: - logger.warning("Given content is empty, stopping the process very early, returning empty utf_8 str match") - return CharsetMatches( - [ - CharsetMatch( - sequences, - "utf_8", - 0., - False, - [], - "" - ) - ] + logger.warning( + "Given content is empty, stopping the process very early, returning empty utf_8 str match" ) + return CharsetMatches([CharsetMatch(sequences, "utf_8", 0.0, False, [], "")]) if cp_isolation is not None: - logger.warning('cp_isolation is set. use this flag for debugging purpose. ' - 'limited list of encoding allowed : %s.', - ', '.join(cp_isolation)) + logger.warning( + "cp_isolation is set. use this flag for debugging purpose. " + "limited list of encoding allowed : %s.", + ", ".join(cp_isolation), + ) cp_isolation = [iana_name(cp, False) for cp in cp_isolation] else: cp_isolation = [] if cp_exclusion is not None: logger.warning( - 'cp_exclusion is set. use this flag for debugging purpose. ' - 'limited list of encoding excluded : %s.', - ', '.join(cp_exclusion)) + "cp_exclusion is set. use this flag for debugging purpose. " + "limited list of encoding excluded : %s.", + ", ".join(cp_exclusion), + ) cp_exclusion = [iana_name(cp, False) for cp in cp_exclusion] else: cp_exclusion = [] if length <= (chunk_size * steps): logger.warning( - 'override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.', - steps, chunk_size, length) + "override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.", + steps, + chunk_size, + length, + ) steps = 1 chunk_size = length @@ -102,15 +116,30 @@ def from_bytes( is_too_large_sequence = len(sequences) >= TOO_BIG_SEQUENCE # type: bool if is_too_small_sequence: - warn('Trying to detect encoding from a tiny portion of ({}) byte(s).'.format(length)) + logger.warning( + "Trying to detect encoding from a tiny portion of ({}) byte(s).".format( + length + ) + ) + elif is_too_large_sequence: + logger.info( + "Using lazy str decoding because the payload is quite large, ({}) byte(s).".format( + length + ) + ) prioritized_encodings = [] # type: List[str] - specified_encoding = any_specified_encoding(sequences) if preemptive_behaviour is True else None # type: Optional[str] + specified_encoding = ( + any_specified_encoding(sequences) if preemptive_behaviour is True else None + ) # type: Optional[str] if specified_encoding is not None: prioritized_encodings.append(specified_encoding) - logger.info('Detected declarative mark in sequence. Priority +1 given for %s.', specified_encoding) + logger.info( + "Detected declarative mark in sequence. Priority +1 given for %s.", + specified_encoding, + ) tested = set() # type: Set[str] tested_but_hard_failure = [] # type: List[str] @@ -129,14 +158,18 @@ def from_bytes( if sig_encoding is not None: prioritized_encodings.append(sig_encoding) - logger.info('Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.', len(sig_payload), sig_encoding) + logger.info( + "Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.", + len(sig_payload), + sig_encoding, + ) prioritized_encodings.append("ascii") if "utf_8" not in prioritized_encodings: prioritized_encodings.append("utf_8") - for encoding_iana in prioritized_encodings+IANA_SUPPORTED: + for encoding_iana in prioritized_encodings + IANA_SUPPORTED: if cp_isolation and encoding_iana not in cp_isolation: continue @@ -151,31 +184,46 @@ def from_bytes( decoded_payload = None # type: Optional[str] bom_or_sig_available = sig_encoding == encoding_iana # type: bool - strip_sig_or_bom = bom_or_sig_available and should_strip_sig_or_bom(encoding_iana) # type: bool + strip_sig_or_bom = bom_or_sig_available and should_strip_sig_or_bom( + encoding_iana + ) # type: bool if encoding_iana in {"utf_16", "utf_32"} and bom_or_sig_available is False: - logger.info("Encoding %s wont be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", encoding_iana) + logger.info( + "Encoding %s wont be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", + encoding_iana, + ) continue try: is_multi_byte_decoder = is_multi_byte_encoding(encoding_iana) # type: bool except (ModuleNotFoundError, ImportError): - logger.debug("Encoding %s does not provide an IncrementalDecoder", encoding_iana) + logger.debug( + "Encoding %s does not provide an IncrementalDecoder", encoding_iana + ) continue try: if is_too_large_sequence and is_multi_byte_decoder is False: str( - sequences[:int(50e4)] if strip_sig_or_bom is False else sequences[len(sig_payload):int(50e4)], - encoding=encoding_iana + sequences[: int(50e4)] + if strip_sig_or_bom is False + else sequences[len(sig_payload) : int(50e4)], + encoding=encoding_iana, ) else: decoded_payload = str( - sequences if strip_sig_or_bom is False else sequences[len(sig_payload):], - encoding=encoding_iana + sequences + if strip_sig_or_bom is False + else sequences[len(sig_payload) :], + encoding=encoding_iana, ) except UnicodeDecodeError as e: - logger.warning('Code page %s does not fit given bytes sequence at ALL. %s', encoding_iana, str(e)) + logger.warning( + "Code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) tested_but_hard_failure.append(encoding_iana) if not is_multi_byte_decoder: single_byte_hard_failure_count += 1 @@ -194,19 +242,31 @@ def from_bytes( break if similar_soft_failure_test: - logger.warning("%s is deemed too similar to code page %s and was consider unsuited already. Continuing!", encoding_iana, encoding_soft_failed) + logger.warning( + "%s is deemed too similar to code page %s and was consider unsuited already. Continuing!", + encoding_iana, + encoding_soft_failed, + ) continue r_ = range( 0 if bom_or_sig_available is False else len(sig_payload), length, - int(length / steps) + int(length / steps), ) - multi_byte_bonus = is_multi_byte_decoder and decoded_payload is not None and len(decoded_payload) < length # type: bool + multi_byte_bonus = ( + is_multi_byte_decoder + and decoded_payload is not None + and len(decoded_payload) < length + ) # type: bool if multi_byte_bonus: - logger.info('Code page %s is a multi byte encoding table and it appear that at least one character was encoded using n-bytes.', encoding_iana) + logger.info( + "Code page %s is a multi byte encoding table and it appear that at least one character " + "was encoded using n-bytes.", + encoding_iana, + ) max_chunk_gave_up = int(len(r_) / 4) # type: int @@ -219,51 +279,68 @@ def from_bytes( md_ratios = [] for i in r_: - cut_sequence = sequences[i:i + chunk_size] + cut_sequence = sequences[i : i + chunk_size] if bom_or_sig_available and strip_sig_or_bom is False: - cut_sequence = sig_payload+cut_sequence + cut_sequence = sig_payload + cut_sequence chunk = cut_sequence.decode(encoding_iana, errors="ignore") # type: str + # multi-byte bad cutting detector and adjustment + # not the cleanest way to perform that fix but clever enough for now. + if is_multi_byte_decoder and i > 0 and sequences[i] >= 0x80: + + chunk_partial_size_chk = ( + 16 if chunk_size > 16 else chunk_size + ) # type: int + + if ( + decoded_payload + and chunk[:chunk_partial_size_chk] not in decoded_payload + ): + for j in range(i, i - 4, -1): + cut_sequence = sequences[j : i + chunk_size] + + if bom_or_sig_available and strip_sig_or_bom is False: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode(encoding_iana, errors="ignore") + + if chunk[:chunk_partial_size_chk] in decoded_payload: + break + md_chunks.append(chunk) - md_ratios.append( - mess_ratio( - chunk, - threshold - ) - ) + md_ratios.append(mess_ratio(chunk, threshold)) if md_ratios[-1] >= threshold: early_stop_count += 1 - if (early_stop_count >= max_chunk_gave_up) or (bom_or_sig_available and strip_sig_or_bom is False): + if (early_stop_count >= max_chunk_gave_up) or ( + bom_or_sig_available and strip_sig_or_bom is False + ): break if md_ratios: mean_mess_ratio = sum(md_ratios) / len(md_ratios) # type: float else: - mean_mess_ratio = 0. + mean_mess_ratio = 0.0 if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up: tested_but_soft_failure.append(encoding_iana) if not is_multi_byte_decoder: single_byte_soft_failure_count += 1 - logger.warning('%s was excluded because of initial chaos probing. Gave up %i time(s). ' - 'Computed mean chaos is %f %%.', - encoding_iana, - early_stop_count, - round(mean_mess_ratio * 100, ndigits=3)) + logger.warning( + "%s was excluded because of initial chaos probing. Gave up %i time(s). " + "Computed mean chaos is %f %%.", + encoding_iana, + early_stop_count, + round(mean_mess_ratio * 100, ndigits=3), + ) # Preparing those fallbacks in case we got nothing. if encoding_iana in ["ascii", "utf_8", specified_encoding]: fallback_entry = CharsetMatch( - sequences, - encoding_iana, - threshold, - False, - [], - decoded_payload + sequences, encoding_iana, threshold, False, [], decoded_payload ) if encoding_iana == specified_encoding: fallback_specified = fallback_entry @@ -274,9 +351,9 @@ def from_bytes( continue logger.info( - '%s passed initial chaos probing. Mean measured chaos is %f %%', + "%s passed initial chaos probing. Mean measured chaos is %f %%", encoding_iana, - round(mean_mess_ratio * 100, ndigits=3) + round(mean_mess_ratio * 100, ndigits=3), ) if not is_multi_byte_decoder: @@ -285,21 +362,29 @@ def from_bytes( target_languages = mb_encoding_languages(encoding_iana) if target_languages: - logger.info("{} should target any language(s) of {}".format(encoding_iana, str(target_languages))) + logger.info( + "{} should target any language(s) of {}".format( + encoding_iana, str(target_languages) + ) + ) cd_ratios = [] for chunk in md_chunks: - chunk_languages = coherence_ratio(chunk, 0.1, ",".join(target_languages) if target_languages else None) - - cd_ratios.append( - chunk_languages + chunk_languages = coherence_ratio( + chunk, 0.1, ",".join(target_languages) if target_languages else None ) + cd_ratios.append(chunk_languages) + cd_ratios_merged = merge_coherence_ratios(cd_ratios) if cd_ratios_merged: - logger.info("We detected language {} using {}".format(cd_ratios_merged, encoding_iana)) + logger.info( + "We detected language {} using {}".format( + cd_ratios_merged, encoding_iana + ) + ) results.append( CharsetMatch( @@ -308,40 +393,53 @@ def from_bytes( mean_mess_ratio, bom_or_sig_available, cd_ratios_merged, - decoded_payload + decoded_payload, ) ) - if encoding_iana in [specified_encoding, "ascii", "utf_8"] and mean_mess_ratio < 0.1: - logger.info("%s is most likely the one. Stopping the process.", encoding_iana) - return CharsetMatches( - [results[encoding_iana]] + if ( + encoding_iana in [specified_encoding, "ascii", "utf_8"] + and mean_mess_ratio < 0.1 + ): + logger.info( + "%s is most likely the one. Stopping the process.", encoding_iana ) + return CharsetMatches([results[encoding_iana]]) if encoding_iana == sig_encoding: logger.info( "%s is most likely the one as we detected a BOM or SIG within the beginning of the sequence.", - encoding_iana - ) - return CharsetMatches( - [results[encoding_iana]] + encoding_iana, ) + return CharsetMatches([results[encoding_iana]]) if results[-1].languages: logger.info( "Using %s code page we detected the following languages: %s", encoding_iana, - results[encoding_iana]._languages + results[encoding_iana]._languages, ) if len(results) == 0: if fallback_u8 or fallback_ascii or fallback_specified: - logger.warning("Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback.") + logger.warning( + "Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback." + ) if fallback_specified: - logger.warning("%s will be used as a fallback match", fallback_specified.encoding) + logger.warning( + "%s will be used as a fallback match", fallback_specified.encoding + ) results.append(fallback_specified) - elif (fallback_u8 and fallback_ascii is None) or (fallback_u8 and fallback_u8.fingerprint != fallback_ascii.fingerprint): + elif ( + (fallback_u8 and fallback_ascii is None) + or ( + fallback_u8 + and fallback_ascii + and fallback_u8.fingerprint != fallback_ascii.fingerprint + ) + or (fallback_u8 is not None) + ): logger.warning("utf_8 will be used as a fallback match") results.append(fallback_u8) elif fallback_ascii: @@ -352,14 +450,14 @@ def from_bytes( def from_fp( - fp: BinaryIO, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.20, - cp_isolation: List[str] = None, - cp_exclusion: List[str] = None, - preemptive_behaviour: bool = True, - explain: bool = False + fp: BinaryIO, + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: List[str] = None, + cp_exclusion: List[str] = None, + preemptive_behaviour: bool = True, + explain: bool = False, ) -> CharsetMatches: """ Same thing than the function from_bytes but using a file pointer that is already ready. @@ -373,29 +471,46 @@ def from_fp( cp_isolation, cp_exclusion, preemptive_behaviour, - explain + explain, ) def from_path( - path: PathLike, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.20, - cp_isolation: List[str] = None, - cp_exclusion: List[str] = None, - preemptive_behaviour: bool = True, - explain: bool = False + path: PathLike, + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: List[str] = None, + cp_exclusion: List[str] = None, + preemptive_behaviour: bool = True, + explain: bool = False, ) -> CharsetMatches: """ Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode. Can raise IOError. """ - with open(path, 'rb') as fp: - return from_fp(fp, steps, chunk_size, threshold, cp_isolation, cp_exclusion, preemptive_behaviour, explain) + with open(path, "rb") as fp: + return from_fp( + fp, + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + preemptive_behaviour, + explain, + ) -def normalize(path: PathLike, steps: int = 5, chunk_size: int = 512, threshold: float = 0.20, cp_isolation: List[str] = None, cp_exclusion: List[str] = None, preemptive_behaviour: bool = True) -> CharsetMatch: +def normalize( + path: PathLike, + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: List[str] = None, + cp_exclusion: List[str] = None, + preemptive_behaviour: bool = True, +) -> CharsetMatch: """ Take a (text-based) file path and try to create another file next to it, this time using UTF-8. """ @@ -406,22 +521,26 @@ def normalize(path: PathLike, steps: int = 5, chunk_size: int = 512, threshold: threshold, cp_isolation, cp_exclusion, - preemptive_behaviour + preemptive_behaviour, ) filename = basename(path) target_extensions = list(splitext(filename)) if len(results) == 0: - raise IOError('Unable to normalize "{}", no encoding charset seems to fit.'.format(filename)) + raise IOError( + 'Unable to normalize "{}", no encoding charset seems to fit.'.format( + filename + ) + ) result = results.best() - target_extensions[0] += '-' + result.encoding # type: ignore + target_extensions[0] += "-" + result.encoding # type: ignore - with open('{}'.format(path.replace(filename, ''.join(target_extensions))), 'wb') as fp: - fp.write( - result.output() # type: ignore - ) + with open( + "{}".format(str(path).replace(filename, "".join(target_extensions))), "wb" + ) as fp: + fp.write(result.output()) # type: ignore return result # type: ignore diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/assets/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/assets/__init__.py index 2d937736..830b2332 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/assets/__init__.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/assets/__init__.py @@ -7,46 +7,1213 @@ the core detection. """ from collections import OrderedDict - FREQUENCIES = OrderedDict( [ - ('English', ['e', 'a', 't', 'i', 'o', 'n', 's', 'r', 'h', 'l', 'd', 'c', 'u', 'm', 'f', 'p', 'g', 'w', 'y', 'b', 'v', 'k', 'x', 'j', 'z', 'q']), - ('German', ['e', 'n', 'i', 'r', 's', 't', 'a', 'd', 'h', 'u', 'l', 'g', 'o', 'c', 'm', 'b', 'f', 'k', 'w', 'z', 'p', 'v', 'ü', 'ä', 'ö', 'j']), - ('French', ['e', 'a', 's', 'n', 'i', 't', 'r', 'l', 'u', 'o', 'd', 'c', 'p', 'm', 'é', 'v', 'g', 'f', 'b', 'h', 'q', 'à', 'x', 'è', 'y', 'j']), - ('Dutch', ['e', 'n', 'a', 'i', 'r', 't', 'o', 'd', 's', 'l', 'g', 'h', 'v', 'm', 'u', 'k', 'c', 'p', 'b', 'w', 'j', 'z', 'f', 'y', 'x', 'ë']), - ('Italian', ['e', 'i', 'a', 'o', 'n', 'l', 't', 'r', 's', 'c', 'd', 'u', 'p', 'm', 'g', 'v', 'f', 'b', 'z', 'h', 'q', 'è', 'à', 'k', 'y', 'ò']), - ('Polish', ['a', 'i', 'o', 'e', 'n', 'r', 'z', 'w', 's', 'c', 't', 'k', 'y', 'd', 'p', 'm', 'u', 'l', 'j', 'ł', 'g', 'b', 'h', 'ą', 'ę', 'ó']), - ('Spanish', ['e', 'a', 'o', 'n', 's', 'r', 'i', 'l', 'd', 't', 'c', 'u', 'm', 'p', 'b', 'g', 'v', 'f', 'y', 'ó', 'h', 'q', 'í', 'j', 'z', 'á']), - ('Russian', ['о', 'а', 'е', 'и', 'н', 'с', 'т', 'р', 'в', 'л', 'к', 'м', 'д', 'п', 'у', 'г', 'я', 'ы', 'з', 'б', 'й', 'ь', 'ч', 'х', 'ж', 'ц']), - ('Japanese', ['の', 'に', 'る', 'た', 'は', 'ー', 'と', 'し', 'を', 'で', 'て', 'が', 'い', 'ン', 'れ', 'な', '年', 'ス', 'っ', 'ル', 'か', 'ら', 'あ', 'さ', 'も', 'り']), - ('Portuguese', ['a', 'e', 'o', 's', 'i', 'r', 'd', 'n', 't', 'm', 'u', 'c', 'l', 'p', 'g', 'v', 'b', 'f', 'h', 'ã', 'q', 'é', 'ç', 'á', 'z', 'í']), - ('Swedish', ['e', 'a', 'n', 'r', 't', 's', 'i', 'l', 'd', 'o', 'm', 'k', 'g', 'v', 'h', 'f', 'u', 'p', 'ä', 'c', 'b', 'ö', 'å', 'y', 'j', 'x']), - ('Chinese', ['的', '一', '是', '不', '了', '在', '人', '有', '我', '他', '这', '个', '们', '中', '来', '上', '大', '为', '和', '国', '地', '到', '以', '说', '时', '要', '就', '出', '会']), - ('Ukrainian', ['о', 'а', 'н', 'і', 'и', 'р', 'в', 'т', 'е', 'с', 'к', 'л', 'у', 'д', 'м', 'п', 'з', 'я', 'ь', 'б', 'г', 'й', 'ч', 'х', 'ц', 'ї']), - ('Norwegian', ['e', 'r', 'n', 't', 'a', 's', 'i', 'o', 'l', 'd', 'g', 'k', 'm', 'v', 'f', 'p', 'u', 'b', 'h', 'å', 'y', 'j', 'ø', 'c', 'æ', 'w']), - ('Finnish', ['a', 'i', 'n', 't', 'e', 's', 'l', 'o', 'u', 'k', 'ä', 'm', 'r', 'v', 'j', 'h', 'p', 'y', 'd', 'ö', 'g', 'c', 'b', 'f', 'w', 'z']), - ('Vietnamese', ['n', 'h', 't', 'i', 'c', 'g', 'a', 'o', 'u', 'm', 'l', 'r', 'à', 'đ', 's', 'e', 'v', 'p', 'b', 'y', 'ư', 'd', 'á', 'k', 'ộ', 'ế']), - ('Czech', ['o', 'e', 'a', 'n', 't', 's', 'i', 'l', 'v', 'r', 'k', 'd', 'u', 'm', 'p', 'í', 'c', 'h', 'z', 'á', 'y', 'j', 'b', 'ě', 'é', 'ř']), - ('Hungarian', ['e', 'a', 't', 'l', 's', 'n', 'k', 'r', 'i', 'o', 'z', 'á', 'é', 'g', 'm', 'b', 'y', 'v', 'd', 'h', 'u', 'p', 'j', 'ö', 'f', 'c']), - ('Korean', ['이', '다', '에', '의', '는', '로', '하', '을', '가', '고', '지', '서', '한', '은', '기', '으', '년', '대', '사', '시', '를', '리', '도', '인', '스', '일']), - ('Indonesian', ['a', 'n', 'e', 'i', 'r', 't', 'u', 's', 'd', 'k', 'm', 'l', 'g', 'p', 'b', 'o', 'h', 'y', 'j', 'c', 'w', 'f', 'v', 'z', 'x', 'q']), - ('Turkish', ['a', 'e', 'i', 'n', 'r', 'l', 'ı', 'k', 'd', 't', 's', 'm', 'y', 'u', 'o', 'b', 'ü', 'ş', 'v', 'g', 'z', 'h', 'c', 'p', 'ç', 'ğ']), - ('Romanian', ['e', 'i', 'a', 'r', 'n', 't', 'u', 'l', 'o', 'c', 's', 'd', 'p', 'm', 'ă', 'f', 'v', 'î', 'g', 'b', 'ș', 'ț', 'z', 'h', 'â', 'j']), - ('Farsi', ['ا', 'ی', 'ر', 'د', 'ن', 'ه', 'و', 'م', 'ت', 'ب', 'س', 'ل', 'ک', 'ش', 'ز', 'ف', 'گ', 'ع', 'خ', 'ق', 'ج', 'آ', 'پ', 'ح', 'ط', 'ص']), - ('Arabic', ['ا', 'ل', 'ي', 'م', 'و', 'ن', 'ر', 'ت', 'ب', 'ة', 'ع', 'د', 'س', 'ف', 'ه', 'ك', 'ق', 'أ', 'ح', 'ج', 'ش', 'ط', 'ص', 'ى', 'خ', 'إ']), - ('Danish', ['e', 'r', 'n', 't', 'a', 'i', 's', 'd', 'l', 'o', 'g', 'm', 'k', 'f', 'v', 'u', 'b', 'h', 'p', 'å', 'y', 'ø', 'æ', 'c', 'j', 'w']), - ('Serbian', ['а', 'и', 'о', 'е', 'н', 'р', 'с', 'у', 'т', 'к', 'ј', 'в', 'д', 'м', 'п', 'л', 'г', 'з', 'б', 'a', 'i', 'e', 'o', 'n', 'ц', 'ш']), - ('Lithuanian', ['i', 'a', 's', 'o', 'r', 'e', 't', 'n', 'u', 'k', 'm', 'l', 'p', 'v', 'd', 'j', 'g', 'ė', 'b', 'y', 'ų', 'š', 'ž', 'c', 'ą', 'į']), - ('Slovene', ['e', 'a', 'i', 'o', 'n', 'r', 's', 'l', 't', 'j', 'v', 'k', 'd', 'p', 'm', 'u', 'z', 'b', 'g', 'h', 'č', 'c', 'š', 'ž', 'f', 'y']), - ('Slovak', ['o', 'a', 'e', 'n', 'i', 'r', 'v', 't', 's', 'l', 'k', 'd', 'm', 'p', 'u', 'c', 'h', 'j', 'b', 'z', 'á', 'y', 'ý', 'í', 'č', 'é']), - ('Hebrew', ['י', 'ו', 'ה', 'ל', 'ר', 'ב', 'ת', 'מ', 'א', 'ש', 'נ', 'ע', 'ם', 'ד', 'ק', 'ח', 'פ', 'ס', 'כ', 'ג', 'ט', 'צ', 'ן', 'ז', 'ך']), - ('Bulgarian', ['а', 'и', 'о', 'е', 'н', 'т', 'р', 'с', 'в', 'л', 'к', 'д', 'п', 'м', 'з', 'г', 'я', 'ъ', 'у', 'б', 'ч', 'ц', 'й', 'ж', 'щ', 'х']), - ('Croatian', ['a', 'i', 'o', 'e', 'n', 'r', 'j', 's', 't', 'u', 'k', 'l', 'v', 'd', 'm', 'p', 'g', 'z', 'b', 'c', 'č', 'h', 'š', 'ž', 'ć', 'f']), - ('Hindi', ['क', 'र', 'स', 'न', 'त', 'म', 'ह', 'प', 'य', 'ल', 'व', 'ज', 'द', 'ग', 'ब', 'श', 'ट', 'अ', 'ए', 'थ', 'भ', 'ड', 'च', 'ध', 'ष', 'इ']), - ('Estonian', ['a', 'i', 'e', 's', 't', 'l', 'u', 'n', 'o', 'k', 'r', 'd', 'm', 'v', 'g', 'p', 'j', 'h', 'ä', 'b', 'õ', 'ü', 'f', 'c', 'ö', 'y']), - ('Simple English', ['e', 'a', 't', 'i', 'o', 'n', 's', 'r', 'h', 'l', 'd', 'c', 'm', 'u', 'f', 'p', 'g', 'w', 'b', 'y', 'v', 'k', 'j', 'x', 'z', 'q']), - ('Thai', ['า', 'น', 'ร', 'อ', 'ก', 'เ', 'ง', 'ม', 'ย', 'ล', 'ว', 'ด', 'ท', 'ส', 'ต', 'ะ', 'ป', 'บ', 'ค', 'ห', 'แ', 'จ', 'พ', 'ช', 'ข', 'ใ']), - ('Greek', ['α', 'τ', 'ο', 'ι', 'ε', 'ν', 'ρ', 'σ', 'κ', 'η', 'π', 'ς', 'υ', 'μ', 'λ', 'ί', 'ό', 'ά', 'γ', 'έ', 'δ', 'ή', 'ω', 'χ', 'θ', 'ύ']), - ('Tamil', ['க', 'த', 'ப', 'ட', 'ர', 'ம', 'ல', 'ன', 'வ', 'ற', 'ய', 'ள', 'ச', 'ந', 'இ', 'ண', 'அ', 'ஆ', 'ழ', 'ங', 'எ', 'உ', 'ஒ', 'ஸ']), - ('Classical Chinese', ['之', '年', '為', '也', '以', '一', '人', '其', '者', '國', '有', '二', '十', '於', '曰', '三', '不', '大', '而', '子', '中', '五', '四'])] + ( + "English", + [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "u", + "m", + "f", + "p", + "g", + "w", + "y", + "b", + "v", + "k", + "x", + "j", + "z", + "q", + ], + ), + ( + "German", + [ + "e", + "n", + "i", + "r", + "s", + "t", + "a", + "d", + "h", + "u", + "l", + "g", + "o", + "c", + "m", + "b", + "f", + "k", + "w", + "z", + "p", + "v", + "ü", + "ä", + "ö", + "j", + ], + ), + ( + "French", + [ + "e", + "a", + "s", + "n", + "i", + "t", + "r", + "l", + "u", + "o", + "d", + "c", + "p", + "m", + "é", + "v", + "g", + "f", + "b", + "h", + "q", + "à", + "x", + "è", + "y", + "j", + ], + ), + ( + "Dutch", + [ + "e", + "n", + "a", + "i", + "r", + "t", + "o", + "d", + "s", + "l", + "g", + "h", + "v", + "m", + "u", + "k", + "c", + "p", + "b", + "w", + "j", + "z", + "f", + "y", + "x", + "ë", + ], + ), + ( + "Italian", + [ + "e", + "i", + "a", + "o", + "n", + "l", + "t", + "r", + "s", + "c", + "d", + "u", + "p", + "m", + "g", + "v", + "f", + "b", + "z", + "h", + "q", + "è", + "à", + "k", + "y", + "ò", + ], + ), + ( + "Polish", + [ + "a", + "i", + "o", + "e", + "n", + "r", + "z", + "w", + "s", + "c", + "t", + "k", + "y", + "d", + "p", + "m", + "u", + "l", + "j", + "ł", + "g", + "b", + "h", + "ą", + "ę", + "ó", + ], + ), + ( + "Spanish", + [ + "e", + "a", + "o", + "n", + "s", + "r", + "i", + "l", + "d", + "t", + "c", + "u", + "m", + "p", + "b", + "g", + "v", + "f", + "y", + "ó", + "h", + "q", + "í", + "j", + "z", + "á", + ], + ), + ( + "Russian", + [ + "о", + "а", + "е", + "и", + "н", + "с", + "т", + "р", + "в", + "л", + "к", + "м", + "д", + "п", + "у", + "г", + "я", + "ы", + "з", + "б", + "й", + "ь", + "ч", + "х", + "ж", + "ц", + ], + ), + ( + "Japanese", + [ + "の", + "に", + "る", + "た", + "は", + "ー", + "と", + "し", + "を", + "で", + "て", + "が", + "い", + "ン", + "れ", + "な", + "年", + "ス", + "っ", + "ル", + "か", + "ら", + "あ", + "さ", + "も", + "り", + ], + ), + ( + "Portuguese", + [ + "a", + "e", + "o", + "s", + "i", + "r", + "d", + "n", + "t", + "m", + "u", + "c", + "l", + "p", + "g", + "v", + "b", + "f", + "h", + "ã", + "q", + "é", + "ç", + "á", + "z", + "í", + ], + ), + ( + "Swedish", + [ + "e", + "a", + "n", + "r", + "t", + "s", + "i", + "l", + "d", + "o", + "m", + "k", + "g", + "v", + "h", + "f", + "u", + "p", + "ä", + "c", + "b", + "ö", + "å", + "y", + "j", + "x", + ], + ), + ( + "Chinese", + [ + "的", + "一", + "是", + "不", + "了", + "在", + "人", + "有", + "我", + "他", + "这", + "个", + "们", + "中", + "来", + "上", + "大", + "为", + "和", + "国", + "地", + "到", + "以", + "说", + "时", + "要", + "就", + "出", + "会", + ], + ), + ( + "Ukrainian", + [ + "о", + "а", + "н", + "і", + "и", + "р", + "в", + "т", + "е", + "с", + "к", + "л", + "у", + "д", + "м", + "п", + "з", + "я", + "ь", + "б", + "г", + "й", + "ч", + "х", + "ц", + "ї", + ], + ), + ( + "Norwegian", + [ + "e", + "r", + "n", + "t", + "a", + "s", + "i", + "o", + "l", + "d", + "g", + "k", + "m", + "v", + "f", + "p", + "u", + "b", + "h", + "å", + "y", + "j", + "ø", + "c", + "æ", + "w", + ], + ), + ( + "Finnish", + [ + "a", + "i", + "n", + "t", + "e", + "s", + "l", + "o", + "u", + "k", + "ä", + "m", + "r", + "v", + "j", + "h", + "p", + "y", + "d", + "ö", + "g", + "c", + "b", + "f", + "w", + "z", + ], + ), + ( + "Vietnamese", + [ + "n", + "h", + "t", + "i", + "c", + "g", + "a", + "o", + "u", + "m", + "l", + "r", + "à", + "đ", + "s", + "e", + "v", + "p", + "b", + "y", + "ư", + "d", + "á", + "k", + "ộ", + "ế", + ], + ), + ( + "Czech", + [ + "o", + "e", + "a", + "n", + "t", + "s", + "i", + "l", + "v", + "r", + "k", + "d", + "u", + "m", + "p", + "í", + "c", + "h", + "z", + "á", + "y", + "j", + "b", + "ě", + "é", + "ř", + ], + ), + ( + "Hungarian", + [ + "e", + "a", + "t", + "l", + "s", + "n", + "k", + "r", + "i", + "o", + "z", + "á", + "é", + "g", + "m", + "b", + "y", + "v", + "d", + "h", + "u", + "p", + "j", + "ö", + "f", + "c", + ], + ), + ( + "Korean", + [ + "이", + "다", + "에", + "의", + "는", + "로", + "하", + "을", + "가", + "고", + "지", + "서", + "한", + "은", + "기", + "으", + "년", + "대", + "사", + "시", + "를", + "리", + "도", + "인", + "스", + "일", + ], + ), + ( + "Indonesian", + [ + "a", + "n", + "e", + "i", + "r", + "t", + "u", + "s", + "d", + "k", + "m", + "l", + "g", + "p", + "b", + "o", + "h", + "y", + "j", + "c", + "w", + "f", + "v", + "z", + "x", + "q", + ], + ), + ( + "Turkish", + [ + "a", + "e", + "i", + "n", + "r", + "l", + "ı", + "k", + "d", + "t", + "s", + "m", + "y", + "u", + "o", + "b", + "ü", + "ş", + "v", + "g", + "z", + "h", + "c", + "p", + "ç", + "ğ", + ], + ), + ( + "Romanian", + [ + "e", + "i", + "a", + "r", + "n", + "t", + "u", + "l", + "o", + "c", + "s", + "d", + "p", + "m", + "ă", + "f", + "v", + "î", + "g", + "b", + "ș", + "ț", + "z", + "h", + "â", + "j", + ], + ), + ( + "Farsi", + [ + "ا", + "ی", + "ر", + "د", + "ن", + "ه", + "و", + "م", + "ت", + "ب", + "س", + "ل", + "ک", + "ش", + "ز", + "ف", + "گ", + "ع", + "خ", + "ق", + "ج", + "آ", + "پ", + "ح", + "ط", + "ص", + ], + ), + ( + "Arabic", + [ + "ا", + "ل", + "ي", + "م", + "و", + "ن", + "ر", + "ت", + "ب", + "ة", + "ع", + "د", + "س", + "ف", + "ه", + "ك", + "ق", + "أ", + "ح", + "ج", + "ش", + "ط", + "ص", + "ى", + "خ", + "إ", + ], + ), + ( + "Danish", + [ + "e", + "r", + "n", + "t", + "a", + "i", + "s", + "d", + "l", + "o", + "g", + "m", + "k", + "f", + "v", + "u", + "b", + "h", + "p", + "å", + "y", + "ø", + "æ", + "c", + "j", + "w", + ], + ), + ( + "Serbian", + [ + "а", + "и", + "о", + "е", + "н", + "р", + "с", + "у", + "т", + "к", + "ј", + "в", + "д", + "м", + "п", + "л", + "г", + "з", + "б", + "a", + "i", + "e", + "o", + "n", + "ц", + "ш", + ], + ), + ( + "Lithuanian", + [ + "i", + "a", + "s", + "o", + "r", + "e", + "t", + "n", + "u", + "k", + "m", + "l", + "p", + "v", + "d", + "j", + "g", + "ė", + "b", + "y", + "ų", + "š", + "ž", + "c", + "ą", + "į", + ], + ), + ( + "Slovene", + [ + "e", + "a", + "i", + "o", + "n", + "r", + "s", + "l", + "t", + "j", + "v", + "k", + "d", + "p", + "m", + "u", + "z", + "b", + "g", + "h", + "č", + "c", + "š", + "ž", + "f", + "y", + ], + ), + ( + "Slovak", + [ + "o", + "a", + "e", + "n", + "i", + "r", + "v", + "t", + "s", + "l", + "k", + "d", + "m", + "p", + "u", + "c", + "h", + "j", + "b", + "z", + "á", + "y", + "ý", + "í", + "č", + "é", + ], + ), + ( + "Hebrew", + [ + "י", + "ו", + "ה", + "ל", + "ר", + "ב", + "ת", + "מ", + "א", + "ש", + "נ", + "ע", + "ם", + "ד", + "ק", + "ח", + "פ", + "ס", + "כ", + "ג", + "ט", + "צ", + "ן", + "ז", + "ך", + ], + ), + ( + "Bulgarian", + [ + "а", + "и", + "о", + "е", + "н", + "т", + "р", + "с", + "в", + "л", + "к", + "д", + "п", + "м", + "з", + "г", + "я", + "ъ", + "у", + "б", + "ч", + "ц", + "й", + "ж", + "щ", + "х", + ], + ), + ( + "Croatian", + [ + "a", + "i", + "o", + "e", + "n", + "r", + "j", + "s", + "t", + "u", + "k", + "l", + "v", + "d", + "m", + "p", + "g", + "z", + "b", + "c", + "č", + "h", + "š", + "ž", + "ć", + "f", + ], + ), + ( + "Hindi", + [ + "क", + "र", + "स", + "न", + "त", + "म", + "ह", + "प", + "य", + "ल", + "व", + "ज", + "द", + "ग", + "ब", + "श", + "ट", + "अ", + "ए", + "थ", + "भ", + "ड", + "च", + "ध", + "ष", + "इ", + ], + ), + ( + "Estonian", + [ + "a", + "i", + "e", + "s", + "t", + "l", + "u", + "n", + "o", + "k", + "r", + "d", + "m", + "v", + "g", + "p", + "j", + "h", + "ä", + "b", + "õ", + "ü", + "f", + "c", + "ö", + "y", + ], + ), + ( + "Simple English", + [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "m", + "u", + "f", + "p", + "g", + "w", + "b", + "y", + "v", + "k", + "j", + "x", + "z", + "q", + ], + ), + ( + "Thai", + [ + "า", + "น", + "ร", + "อ", + "ก", + "เ", + "ง", + "ม", + "ย", + "ล", + "ว", + "ด", + "ท", + "ส", + "ต", + "ะ", + "ป", + "บ", + "ค", + "ห", + "แ", + "จ", + "พ", + "ช", + "ข", + "ใ", + ], + ), + ( + "Greek", + [ + "α", + "τ", + "ο", + "ι", + "ε", + "ν", + "ρ", + "σ", + "κ", + "η", + "π", + "ς", + "υ", + "μ", + "λ", + "ί", + "ό", + "ά", + "γ", + "έ", + "δ", + "ή", + "ω", + "χ", + "θ", + "ύ", + ], + ), + ( + "Tamil", + [ + "க", + "த", + "ப", + "ட", + "ர", + "ம", + "ல", + "ன", + "வ", + "ற", + "ய", + "ள", + "ச", + "ந", + "இ", + "ண", + "அ", + "ஆ", + "ழ", + "ங", + "எ", + "உ", + "ஒ", + "ஸ", + ], + ), + ( + "Classical Chinese", + [ + "之", + "年", + "為", + "也", + "以", + "一", + "人", + "其", + "者", + "國", + "有", + "二", + "十", + "於", + "曰", + "三", + "不", + "大", + "而", + "子", + "中", + "五", + "四", + ], + ), + ] ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/assets/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/assets/__pycache__/__init__.cpython-39.pyc index 4d2a6c70698ce3d28fe2a323e864dc13f68f10d2..72fa1491ec4a9b002ffc3e1f4800205e793a5bea 100644 GIT binary patch delta 296 zcmaEDG1H1Kk(ZZ?0SMxZyb|9gZseOJ&FD6Hp>#n#3nK#q3p)=J6EhPd+dn1+ib-XX bOsJ>KN_mnj`^O{)R^Pw?hg?wRQ>Om_{M|h@ delta 120 zcmbPf_1c0jk(ZZ?0SIg_J0wa;Z{(XK&FC_Dp>#o17*LRforjr;iHnhn@FvrL0MJ?t AGynhq diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/cd.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/cd.py index c4fc1ba5..78ecb2c6 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/cd.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/cd.py @@ -1,13 +1,13 @@ -from codecs import IncrementalDecoder -from functools import lru_cache -from typing import List, Set, Optional, Tuple, Dict import importlib - -from charset_normalizer.models import CoherenceMatches -from charset_normalizer.utils import unicode_range, is_unicode_range_secondary, is_multi_byte_encoding -from charset_normalizer.md import is_suspiciously_successive_range -from charset_normalizer.assets import FREQUENCIES +from codecs import IncrementalDecoder from collections import Counter +from functools import lru_cache +from typing import Dict, List, Optional, Set, Tuple + +from .assets import FREQUENCIES +from .md import is_suspiciously_successive_range +from .models import CoherenceMatches +from .utils import is_multi_byte_encoding, is_unicode_range_secondary, unicode_range def encoding_unicode_range(iana_name: str) -> List[str]: @@ -17,15 +17,13 @@ def encoding_unicode_range(iana_name: str) -> List[str]: if is_multi_byte_encoding(iana_name): raise IOError("Function not supported on multi-byte code page") - decoder = importlib.import_module('encodings.{}'.format(iana_name)).IncrementalDecoder # type: ignore + decoder = importlib.import_module("encodings.{}".format(iana_name)).IncrementalDecoder # type: ignore p = decoder(errors="ignore") # type: IncrementalDecoder seen_ranges = set() # type: Set[str] for i in range(48, 255): - chunk = p.decode( - bytes([i]) - ) # type: str + chunk = p.decode(bytes([i])) # type: str if chunk: character_range = unicode_range(chunk) # type: Optional[str] @@ -79,7 +77,12 @@ def mb_encoding_languages(iana_name: str) -> List[str]: Multi-byte encoding language association. Some code page are heavily linked to particular language(s). This function does the correspondence. """ - if iana_name.startswith("shift_") or iana_name.startswith("iso2022_jp") or iana_name.startswith("euc_j") or iana_name in {"cp932"}: + if ( + iana_name.startswith("shift_") + or iana_name.startswith("iso2022_jp") + or iana_name.startswith("euc_j") + or iana_name in {"cp932"} + ): return ["Japanese"] if iana_name.startswith("gb") or iana_name in {"big5", "cp950", "big5hkscs"}: return ["Chinese", "Classical Chinese"] @@ -109,7 +112,9 @@ def alphabet_languages(characters: List[str]) -> List[str]: return languages -def characters_popularity_compare(language: str, ordered_characters: List[str]) -> float: +def characters_popularity_compare( + language: str, ordered_characters: List[str] +) -> float: """ Determine if a ordered characters list (by occurrence from most appearance to rarest) match a particular language. The result is a ratio between 0. (absolutely no correspondence) and 1. (near perfect fit). @@ -124,14 +129,30 @@ def characters_popularity_compare(language: str, ordered_characters: List[str]) if character not in FREQUENCIES[language]: continue - characters_before_source = FREQUENCIES[language][0:FREQUENCIES[language].index(character)] # type: List[str] - characters_after_source = FREQUENCIES[language][FREQUENCIES[language].index(character):] # type: List[str] + characters_before_source = FREQUENCIES[language][ + 0 : FREQUENCIES[language].index(character) + ] # type: List[str] + characters_after_source = FREQUENCIES[language][ + FREQUENCIES[language].index(character) : + ] # type: List[str] - characters_before = ordered_characters[0:ordered_characters.index(character)] # type: List[str] - characters_after = ordered_characters[ordered_characters.index(character):] # type: List[str] + characters_before = ordered_characters[ + 0 : ordered_characters.index(character) + ] # type: List[str] + characters_after = ordered_characters[ + ordered_characters.index(character) : + ] # type: List[str] - before_match_count = [e in characters_before for e in characters_before_source].count(True) # type: int - after_match_count = [e in characters_after for e in characters_after_source].count(True) # type: int + before_match_count = [ + e in characters_before for e in characters_before_source + ].count( + True + ) # type: int + after_match_count = [ + e in characters_after for e in characters_after_source + ].count( + True + ) # type: int if len(characters_before_source) == 0 and before_match_count <= 4: character_approved_count += 1 @@ -141,7 +162,10 @@ def characters_popularity_compare(language: str, ordered_characters: List[str]) character_approved_count += 1 continue - if before_match_count / len(characters_before_source) >= 0.4 or after_match_count / len(characters_after_source) >= 0.4: + if ( + before_match_count / len(characters_before_source) >= 0.4 + or after_match_count / len(characters_after_source) >= 0.4 + ): character_approved_count += 1 continue @@ -160,12 +184,18 @@ def alpha_unicode_split(decoded_sequence: str) -> List[str]: if character.isalpha() is False: continue - character_range = unicode_range(character) # type: str + character_range = unicode_range(character) # type: Optional[str] + + if character_range is None: + continue layer_target_range = None # type: Optional[str] for discovered_range in layers: - if is_suspiciously_successive_range(discovered_range, character_range) is False: + if ( + is_suspiciously_successive_range(discovered_range, character_range) + is False + ): layer_target_range = discovered_range break @@ -195,20 +225,17 @@ def merge_coherence_ratios(results: List[CoherenceMatches]) -> CoherenceMatches: if language not in per_language_ratios: per_language_ratios[language] = [ratio] continue - per_language_ratios[language].append( - ratio - ) + per_language_ratios[language].append(ratio) for language in per_language_ratios: merge.append( ( language, round( - sum( - per_language_ratios[language] - ) / len(per_language_ratios[language]), - 4 - ) + sum(per_language_ratios[language]) + / len(per_language_ratios[language]), + 4, + ), ) ) @@ -216,21 +243,24 @@ def merge_coherence_ratios(results: List[CoherenceMatches]) -> CoherenceMatches: @lru_cache(maxsize=2048) -def coherence_ratio(decoded_sequence: str, threshold: float = 0.1, lg_inclusion: Optional[str] = None) -> CoherenceMatches: +def coherence_ratio( + decoded_sequence: str, threshold: float = 0.1, lg_inclusion: Optional[str] = None +) -> CoherenceMatches: """ Detect ANY language that can be identified in given sequence. The sequence will be analysed by layers. A layer = Character extraction by alphabets/ranges. """ results = [] # type: List[Tuple[str, float]] + lg_inclusion_list = [] # type: List[str] sufficient_match_count = 0 # type: int if lg_inclusion is not None: - lg_inclusion = lg_inclusion.split(",") + lg_inclusion_list = lg_inclusion.split(",") - if lg_inclusion is not None and "Latin Based" in lg_inclusion: - lg_inclusion.remove("Latin Based") + if "Latin Based" in lg_inclusion_list: + lg_inclusion_list.remove("Latin Based") for layer in alpha_unicode_split(decoded_sequence): sequence_frequencies = Counter(layer) # type: Counter @@ -243,17 +273,19 @@ def coherence_ratio(decoded_sequence: str, threshold: float = 0.1, lg_inclusion: popular_character_ordered = [c for c, o in most_common] # type: List[str] - for language in lg_inclusion or alphabet_languages(popular_character_ordered): - ratio = characters_popularity_compare(language, popular_character_ordered) # type: float + for language in lg_inclusion_list or alphabet_languages( + popular_character_ordered + ): + ratio = characters_popularity_compare( + language, popular_character_ordered + ) # type: float if ratio < threshold: continue elif ratio >= 0.8: sufficient_match_count += 1 - results.append( - (language, round(ratio, 4)) - ) + results.append((language, round(ratio, 4))) if sufficient_match_count >= 3: break diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-39.pyc index 2c99c4760d0102c78daf52c612db8c0e644c4c88..d80cabacbb4b15e676f498048dab9a3122ad89c1 100644 GIT binary patch delta 24 ecmdnRxQmfHk(ZZ?0SMxZye4wnGP+IlECc{P)CEic delta 24 ecmdnRxQmfHk(ZZ?0SIg_J51!ZWptV7SqK0_Q3b#N diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/cli/__pycache__/normalizer.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/cli/__pycache__/normalizer.cpython-39.pyc index 5e9be9c5cf32f21da0809ae121380e38f62b7e29..87fec14c267f5f54073804d0fbb3f9c72d7ed6ba 100644 GIT binary patch delta 2553 zcmb^zO>Y}j@Xg!j^~QD`$8p`JEv0D#t(!JUqkg2Hlu#%wA+1zI)j-+0ew)Ouvv%ID zOA{P?Fj7;Aid1_;J=nmd$5O$O12+)AV8sE!2?-=nB_s+Y%&e0p?ST`!n%Q~t=FQie z8T*I5fAsfe*R6{%eBK#6oBg$iv7czM_6gzQB!bhp)BARfNuwB_Y9DI{COfPIz8x}h zSCdg0`ye!ylu4`2N^~)+Q?9$qWn8u+H)XAtiECWlwNiD4=ima%bpA{>Ml;}tWM!)C zAQ8@9b;?TzxVY_yr8SU6-BI~h{i(Kv&Fph^|C5W zl~F-%vXswR_n7L!-ACD1yibL5ZY$C(mH-3v72q)~0TCb`zFciai46BeR!v-2Fuo7{~R*2#UhIk2kMSnsCY4J26yIW)m0m^_9Ml?UX0IVAh* z(Ix;};PwE?)>eh*Sz#kW*G)DK^0++lfq|<{r&t~EyBT2%!ZQe45uROD!r>|+q8F|vRc|dDWsCC^0H1|Sa4wlUUngcWkXb#XE1m>bE zo==aUk%;Wa%m_tJZES3pCz}v(xcUuq^=B3@5lR)^uyMTaxt5?N4+oG z#|8DK*PR%Cox1)W_=aWYN-}Rx+~Yp)8}NCqj58>5744Z5ICY$0Jg7~iDRQicqbY~u zc&kr3%v~c^ddQmRPxB z6Mq1*j^%yW`9|2+ik7W*c|Ugc!Dg=`wY8Qa6&mXD!)MODtW-&<-K2vPdJ$2^P+Lew z51dxPFMu<~ZKrTIhP`GKBjxG z=>qtYjyS%gYe=uYkMy>u*2e$32L7kscCw{XfWE{vjwT~~Bg8>Gfd!B8BsX{jofEic zEE$~t&2@naye;dWsU=8@L3L!2D2mXjJ)$q2DhB^4e2t2J#RF-Q=${G3M=!+*F)h`duCa;%{{p!4J_P^( delta 2209 zcmaJ?&2Jk;6rY)$U2oQo?Ko+YrXNY0e#A)=JAt+-P1CeVp#_>&s??9rYPHF%8$0&e zo!yis*tLXz8qjVAXvn?Tn~kU^&q9+O>prqlas5FLhgI)LV$qRiu0T6r z|1_rDAE_PMD?Eo3Og9wbUYB=tcfx!Q3u)sK=|+J>V)lpYAIT0be^a7POOX~yCIS>= zM^~ki?6el;3TC4VWDWD5ogh0_m5VgfCQ$6~0s`r0>;;Rk<2B-hGR%~ywBv1@ z!fc$Kyr;r!=M<`7`0fJQ4b%Nv z?5*s_x`MzR0(S`9P5ACm!yN*52;3oXhrk{3-32!@xpftsXe_aa)+q0TV7jWk>{Jc= z62c!r?M~NgSHn+Kie~n)An4#Sw~Dm7zXtuYhHt?*(^fseCTqA90K-i_NaCZ#K=mM- z66T>z5TNSn5_dMWtuerd8+ga*V`nzqvKK34Q~p>JH~f|xj+bYh4)#)2W|P%;F;K%b zT!AfNquY_*?+nyOnSOSbontSrO7HG2sYSJV$QfJ#oY>PVh>cN1QANVYiVdSR$^I${ zw#9o5=nAqfQsfM+(WL_zm6|YGKH>zO!E&*w@~py89^TCC3K(ExrKY=}#9q177$;G3 zs}7slfFr+(B$MznruF8~e6BG5 z7R-MGLhi%pwL?B62{S$d4E`^~%x>xNBOrWVtR4mCR$3mki@(4!9ZI}W^6=}+@}iR( z9OX&3KX&Z6umu)WU1#YzN7p|g{5hdJDwyxcXCffq@YgV~2`~k_AH+u7$yiUqNBHra z{12_~x3uCT?)BEwWknzZz&x#BaNE=ke$(a$g>=7=$_1Xb93B>9#desZ9}-z z{kUy+S^OnE2_RnJ+=Vlo=Q%$hY=}Q69|soKJPJYH_7p#0?$7KQaz~#D>dQlGxgY^xb%cgZ^I_8{{EQ8ceiq23dCL4;(1_5aPjN~@L?9@pe=ABD_rVD69$!ny;Vo}YekU7hi;7iJhky!> z3B|?>P(aXVJE&_Q6K0-`QKKOe!|f0jARvGcgcZUXBox{JE09`!h2SpIj>{A)8+}p~ zoC$FkED99>O4>h~5BKB!3+_5iWTJqKZUCu#7OEyXI0uJI*W;Lr`!tTH<1Ks=M)f8N z bool: """Ask a yes/no question via input() and return their answer. "question" is a string that is presented to the user. @@ -22,8 +22,7 @@ def query_yes_no(question, default="yes"): Credit goes to (c) https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input """ - valid = {"yes": True, "y": True, "ye": True, - "no": False, "n": False} + valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} if default is None: prompt = " [y/n] " elif default == "yes": @@ -36,16 +35,15 @@ def query_yes_no(question, default="yes"): while True: sys.stdout.write(question + prompt) choice = input().lower() - if default is not None and choice == '': + if default is not None and choice == "": return valid[default] elif choice in valid: return valid[choice] else: - sys.stdout.write("Please respond with 'yes' or 'no' " - "(or 'y' or 'n').\n") + sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") -def cli_detect(argv=None): +def cli_detect(argv: List[str] = None) -> int: """ CLI assistant using ARGV and ArgumentParser :param argv: @@ -53,58 +51,112 @@ def cli_detect(argv=None): """ parser = argparse.ArgumentParser( description="The Real First Universal Charset Detector. " - "Discover originating encoding used on text file. " - "Normalize text to unicode." + "Discover originating encoding used on text file. " + "Normalize text to unicode." ) - parser.add_argument('files', type=argparse.FileType('rb'), nargs='+', help='File(s) to be analysed') - parser.add_argument('-v', '--verbose', action="store_true", default=False, dest='verbose', - help='Display complementary information about file if any. Stdout will contain logs about the detection process.') - parser.add_argument('-a', '--with-alternative', action="store_true", default=False, dest='alternatives', - help='Output complementary possibilities if any. Top-level JSON WILL be a list.') - parser.add_argument('-n', '--normalize', action="store_true", default=False, dest='normalize', - help='Permit to normalize input file. If not set, program does not write anything.') - parser.add_argument('-m', '--minimal', action="store_true", default=False, dest='minimal', - help='Only output the charset detected to STDOUT. Disabling JSON output.') - parser.add_argument('-r', '--replace', action="store_true", default=False, dest='replace', - help='Replace file when trying to normalize it instead of creating a new one.') - parser.add_argument('-f', '--force', action="store_true", default=False, dest='force', - help='Replace file without asking if you are sure, use this flag with caution.') - parser.add_argument('-t', '--threshold', action="store", default=0.1, type=float, dest='threshold', - help="Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1.") + parser.add_argument( + "files", type=argparse.FileType("rb"), nargs="+", help="File(s) to be analysed" + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + default=False, + dest="verbose", + help="Display complementary information about file if any. " + "Stdout will contain logs about the detection process.", + ) + parser.add_argument( + "-a", + "--with-alternative", + action="store_true", + default=False, + dest="alternatives", + help="Output complementary possibilities if any. Top-level JSON WILL be a list.", + ) + parser.add_argument( + "-n", + "--normalize", + action="store_true", + default=False, + dest="normalize", + help="Permit to normalize input file. If not set, program does not write anything.", + ) + parser.add_argument( + "-m", + "--minimal", + action="store_true", + default=False, + dest="minimal", + help="Only output the charset detected to STDOUT. Disabling JSON output.", + ) + parser.add_argument( + "-r", + "--replace", + action="store_true", + default=False, + dest="replace", + help="Replace file when trying to normalize it instead of creating a new one.", + ) + parser.add_argument( + "-f", + "--force", + action="store_true", + default=False, + dest="force", + help="Replace file without asking if you are sure, use this flag with caution.", + ) + parser.add_argument( + "-t", + "--threshold", + action="store", + default=0.1, + type=float, + dest="threshold", + help="Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1.", + ) parser.add_argument( "--version", action="version", - version="Charset-Normalizer {} - Python {}".format(__version__, python_version()), - help="Show version information and exit." + version="Charset-Normalizer {} - Python {}".format( + __version__, python_version() + ), + help="Show version information and exit.", ) args = parser.parse_args(argv) if args.replace is True and args.normalize is False: - print('Use --replace in addition of --normalize only.', file=sys.stderr) + print("Use --replace in addition of --normalize only.", file=sys.stderr) return 1 if args.force is True and args.replace is False: - print('Use --force in addition of --replace only.', file=sys.stderr) + print("Use --force in addition of --replace only.", file=sys.stderr) return 1 - if args.threshold < 0. or args.threshold > 1.: - print('--threshold VALUE should be between 0. AND 1.', file=sys.stderr) + if args.threshold < 0.0 or args.threshold > 1.0: + print("--threshold VALUE should be between 0. AND 1.", file=sys.stderr) return 1 x_ = [] for my_file in args.files: - matches = from_fp( - my_file, - threshold=args.threshold, - explain=args.verbose - ) + matches = from_fp(my_file, threshold=args.threshold, explain=args.verbose) - if len(matches) == 0: - print('Unable to identify originating encoding for "{}". {}'.format(my_file.name, 'Maybe try increasing maximum amount of chaos.' if args.threshold < 1. else ''), file=sys.stderr) + best_guess = matches.best() + + if best_guess is None: + print( + 'Unable to identify originating encoding for "{}". {}'.format( + my_file.name, + "Maybe try increasing maximum amount of chaos." + if args.threshold < 1.0 + else "", + ), + file=sys.stderr, + ) x_.append( CliDetectionResult( abspath(my_file.name), @@ -114,80 +166,95 @@ def cli_detect(argv=None): "Unknown", [], False, - 1., - 0., + 1.0, + 0.0, None, - True + True, ) ) else: - - r_ = matches.best() - p_ = r_.first() - x_.append( CliDetectionResult( abspath(my_file.name), - p_.encoding, - p_.encoding_aliases, - [cp for cp in p_.could_be_from_charset if cp != p_.encoding], - p_.language, - p_.alphabets, - p_.bom, - p_.percent_chaos, - p_.percent_coherence, + best_guess.encoding, + best_guess.encoding_aliases, + [ + cp + for cp in best_guess.could_be_from_charset + if cp != best_guess.encoding + ], + best_guess.language, + best_guess.alphabets, + best_guess.bom, + best_guess.percent_chaos, + best_guess.percent_coherence, None, - True + True, ) ) if len(matches) > 1 and args.alternatives: for el in matches: - if el != p_: + if el != best_guess: x_.append( CliDetectionResult( abspath(my_file.name), el.encoding, el.encoding_aliases, - [cp for cp in el.could_be_from_charset if cp != el.encoding], + [ + cp + for cp in el.could_be_from_charset + if cp != el.encoding + ], el.language, el.alphabets, el.bom, el.percent_chaos, el.percent_coherence, None, - False + False, ) ) if args.normalize is True: - if p_.encoding.startswith('utf') is True: - print('"{}" file does not need to be normalized, as it already came from unicode.'.format(my_file.name), file=sys.stderr) + if best_guess.encoding.startswith("utf") is True: + print( + '"{}" file does not need to be normalized, as it already came from unicode.'.format( + my_file.name + ), + file=sys.stderr, + ) if my_file.closed is False: my_file.close() continue - o_ = my_file.name.split('.') # type: list[str] + o_ = my_file.name.split(".") # type: List[str] if args.replace is False: - o_.insert(-1, p_.encoding) + o_.insert(-1, best_guess.encoding) if my_file.closed is False: my_file.close() else: - if args.force is False and query_yes_no( - 'Are you sure to normalize "{}" by replacing it ?'.format(my_file.name), 'no') is False: + if ( + args.force is False + and query_yes_no( + 'Are you sure to normalize "{}" by replacing it ?'.format( + my_file.name + ), + "no", + ) + is False + ): if my_file.closed is False: my_file.close() continue try: - x_[0].unicode_path = abspath('./{}'.format('.'.join(o_))) + x_[0].unicode_path = abspath("./{}".format(".".join(o_))) - with open(x_[0].unicode_path, 'w', encoding='utf-8') as fp: - fp.write( - str(p_) - ) + with open(x_[0].unicode_path, "w", encoding="utf-8") as fp: + fp.write(str(best_guess)) except IOError as e: print(str(e), file=sys.stderr) if my_file.closed is False: @@ -200,24 +267,25 @@ def cli_detect(argv=None): if args.minimal is False: print( dumps( - [ - el.__dict__ for el in x_ - ] if len(x_) > 1 else x_[0].__dict__, + [el.__dict__ for el in x_] if len(x_) > 1 else x_[0].__dict__, ensure_ascii=True, - indent=4 + indent=4, ) ) else: - print( - ', '.join( - [ - el.encoding for el in x_ - ] + for my_file in args.files: + print( + ", ".join( + [ + el.encoding if el.encoding else "undefined" + for el in x_ + if el.path == abspath(my_file.name) + ] + ) ) - ) return 0 -if __name__ == '__main__': +if __name__ == "__main__": cli_detect() diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/constant.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/constant.py index c9c96555..a0c20280 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/constant.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/constant.py @@ -1,64 +1,344 @@ from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE -from typing import Dict, List, Union -from encodings.aliases import aliases -from re import compile as re_compile, IGNORECASE from collections import OrderedDict +from encodings.aliases import aliases +from re import IGNORECASE, compile as re_compile +from typing import Dict, List, Union # Contain for each eligible encoding a list of/item bytes SIG/BOM -ENCODING_MARKS = OrderedDict([ - ('utf_8', BOM_UTF8), - ('utf_7', [ - b'\x2b\x2f\x76\x38', - b'\x2b\x2f\x76\x39', - b'\x2b\x2f\x76\x2b', - b'\x2b\x2f\x76\x2f', - b'\x2b\x2f\x76\x38\x2d' - ]), - ('gb18030', b'\x84\x31\x95\x33'), - ('utf_32', [ - BOM_UTF32_BE, - BOM_UTF32_LE - ]), - ('utf_16', [ - BOM_UTF16_BE, - BOM_UTF16_LE - ]), -]) # type: Dict[str, Union[bytes, List[bytes]]] +ENCODING_MARKS = OrderedDict( + [ + ("utf_8", BOM_UTF8), + ( + "utf_7", + [ + b"\x2b\x2f\x76\x38", + b"\x2b\x2f\x76\x39", + b"\x2b\x2f\x76\x2b", + b"\x2b\x2f\x76\x2f", + b"\x2b\x2f\x76\x38\x2d", + ], + ), + ("gb18030", b"\x84\x31\x95\x33"), + ("utf_32", [BOM_UTF32_BE, BOM_UTF32_LE]), + ("utf_16", [BOM_UTF16_BE, BOM_UTF16_LE]), + ] +) # type: Dict[str, Union[bytes, List[bytes]]] TOO_SMALL_SEQUENCE = 32 # type: int TOO_BIG_SEQUENCE = int(10e6) # type: int UTF8_MAXIMAL_ALLOCATION = 1112064 # type: int -UNICODE_RANGES_COMBINED = {'Control character': range(0, 31+1), 'Basic Latin': range(32, 127+1), 'Latin-1 Supplement': range(128, 255+1), 'Latin Extended-A': range(256, 383+1), 'Latin Extended-B': range(384, 591+1), 'IPA Extensions': range(592, 687+1), 'Spacing Modifier Letters': range(688, 767+1), 'Combining Diacritical Marks': range(768, 879+1), 'Greek and Coptic': range(880, 1023+1), 'Cyrillic': range(1024, 1279+1), 'Cyrillic Supplement': range(1280, 1327+1), 'Armenian': range(1328, 1423+1), 'Hebrew': range(1424, 1535+1), 'Arabic': range(1536, 1791+1), 'Syriac': range(1792, 1871+1), 'Arabic Supplement': range(1872, 1919+1), 'Thaana': range(1920, 1983+1), 'NKo': range(1984, 2047+1), 'Samaritan': range(2048, 2111+1), 'Mandaic': range(2112, 2143+1), 'Syriac Supplement': range(2144, 2159+1), 'Arabic Extended-A': range(2208, 2303+1), 'Devanagari': range(2304, 2431+1), 'Bengali': range(2432, 2559+1), 'Gurmukhi': range(2560, 2687+1), 'Gujarati': range(2688, 2815+1), 'Oriya': range(2816, 2943+1), 'Tamil': range(2944, 3071+1), 'Telugu': range(3072, 3199+1), 'Kannada': range(3200, 3327+1), 'Malayalam': range(3328, 3455+1), 'Sinhala': range(3456, 3583+1), 'Thai': range(3584, 3711+1), 'Lao': range(3712, 3839+1), 'Tibetan': range(3840, 4095+1), 'Myanmar': range(4096, 4255+1), 'Georgian': range(4256, 4351+1), 'Hangul Jamo': range(4352, 4607+1), 'Ethiopic': range(4608, 4991+1), 'Ethiopic Supplement': range(4992, 5023+1), 'Cherokee': range(5024, 5119+1), 'Unified Canadian Aboriginal Syllabics': range(5120, 5759+1), 'Ogham': range(5760, 5791+1), 'Runic': range(5792, 5887+1), 'Tagalog': range(5888, 5919+1), 'Hanunoo': range(5920, 5951+1), 'Buhid': range(5952, 5983+1), 'Tagbanwa': range(5984, 6015+1), 'Khmer': range(6016, 6143+1), 'Mongolian': range(6144, 6319+1), 'Unified Canadian Aboriginal Syllabics Extended': range(6320, 6399+1), 'Limbu': range(6400, 6479+1), 'Tai Le': range(6480, 6527+1), 'New Tai Lue': range(6528, 6623+1), 'Khmer Symbols': range(6624, 6655+1), 'Buginese': range(6656, 6687+1), 'Tai Tham': range(6688, 6831+1), 'Combining Diacritical Marks Extended': range(6832, 6911+1), 'Balinese': range(6912, 7039+1), 'Sundanese': range(7040, 7103+1), 'Batak': range(7104, 7167+1), 'Lepcha': range(7168, 7247+1), 'Ol Chiki': range(7248, 7295+1), 'Cyrillic Extended C': range(7296, 7311+1), 'Sundanese Supplement': range(7360, 7375+1), 'Vedic Extensions': range(7376, 7423+1), 'Phonetic Extensions': range(7424, 7551+1), 'Phonetic Extensions Supplement': range(7552, 7615+1), 'Combining Diacritical Marks Supplement': range(7616, 7679+1), 'Latin Extended Additional': range(7680, 7935+1), 'Greek Extended': range(7936, 8191+1), 'General Punctuation': range(8192, 8303+1), 'Superscripts and Subscripts': range(8304, 8351+1), 'Currency Symbols': range(8352, 8399+1), 'Combining Diacritical Marks for Symbols': range(8400, 8447+1), 'Letterlike Symbols': range(8448, 8527+1), 'Number Forms': range(8528, 8591+1), 'Arrows': range(8592, 8703+1), 'Mathematical Operators': range(8704, 8959+1), 'Miscellaneous Technical': range(8960, 9215+1), 'Control Pictures': range(9216, 9279+1), 'Optical Character Recognition': range(9280, 9311+1), 'Enclosed Alphanumerics': range(9312, 9471+1), 'Box Drawing': range(9472, 9599+1), 'Block Elements': range(9600, 9631+1), 'Geometric Shapes': range(9632, 9727+1), 'Miscellaneous Symbols': range(9728, 9983+1), 'Dingbats': range(9984, 10175+1), 'Miscellaneous Mathematical Symbols-A': range(10176, 10223+1), 'Supplemental Arrows-A': range(10224, 10239+1), 'Braille Patterns': range(10240, 10495+1), 'Supplemental Arrows-B': range(10496, 10623+1), 'Miscellaneous Mathematical Symbols-B': range(10624, 10751+1), 'Supplemental Mathematical Operators': range(10752, 11007+1), 'Miscellaneous Symbols and Arrows': range(11008, 11263+1), 'Glagolitic': range(11264, 11359+1), 'Latin Extended-C': range(11360, 11391+1), 'Coptic': range(11392, 11519+1), 'Georgian Supplement': range(11520, 11567+1), 'Tifinagh': range(11568, 11647+1), 'Ethiopic Extended': range(11648, 11743+1), 'Cyrillic Extended-A': range(11744, 11775+1), 'Supplemental Punctuation': range(11776, 11903+1), 'CJK Radicals Supplement': range(11904, 12031+1), 'Kangxi Radicals': range(12032, 12255+1), 'Ideographic Description Characters': range(12272, 12287+1), 'CJK Symbols and Punctuation': range(12288, 12351+1), 'Hiragana': range(12352, 12447+1), 'Katakana': range(12448, 12543+1), 'Bopomofo': range(12544, 12591+1), 'Hangul Compatibility Jamo': range(12592, 12687+1), 'Kanbun': range(12688, 12703+1), 'Bopomofo Extended': range(12704, 12735+1), 'CJK Strokes': range(12736, 12783+1), 'Katakana Phonetic Extensions': range(12784, 12799+1), 'Enclosed CJK Letters and Months': range(12800, 13055+1), 'CJK Compatibility': range(13056, 13311+1), 'CJK Unified Ideographs Extension A': range(13312, 19903+1), 'Yijing Hexagram Symbols': range(19904, 19967+1), 'CJK Unified Ideographs': range(19968, 40959+1), 'Yi Syllables': range(40960, 42127+1), 'Yi Radicals': range(42128, 42191+1), 'Lisu': range(42192, 42239+1), 'Vai': range(42240, 42559+1), 'Cyrillic Extended-B': range(42560, 42655+1), 'Bamum': range(42656, 42751+1), 'Modifier Tone Letters': range(42752, 42783+1), 'Latin Extended-D': range(42784, 43007+1), 'Syloti Nagri': range(43008, 43055+1), 'Common Indic Number Forms': range(43056, 43071+1), 'Phags-pa': range(43072, 43135+1), 'Saurashtra': range(43136, 43231+1), 'Devanagari Extended': range(43232, 43263+1), 'Kayah Li': range(43264, 43311+1), 'Rejang': range(43312, 43359+1), 'Hangul Jamo Extended-A': range(43360, 43391+1), 'Javanese': range(43392, 43487+1), 'Myanmar Extended-B': range(43488, 43519+1), 'Cham': range(43520, 43615+1), 'Myanmar Extended-A': range(43616, 43647+1), 'Tai Viet': range(43648, 43743+1), 'Meetei Mayek Extensions': range(43744, 43775+1), 'Ethiopic Extended-A': range(43776, 43823+1), 'Latin Extended-E': range(43824, 43887+1), 'Cherokee Supplement': range(43888, 43967+1), 'Meetei Mayek': range(43968, 44031+1), 'Hangul Syllables': range(44032, 55215+1), 'Hangul Jamo Extended-B': range(55216, 55295+1), 'High Surrogates': range(55296, 56191+1), 'High Private Use Surrogates': range(56192, 56319+1), 'Low Surrogates': range(56320, 57343+1), 'Private Use Area': range(57344, 63743+1), 'CJK Compatibility Ideographs': range(63744, 64255+1), 'Alphabetic Presentation Forms': range(64256, 64335+1), 'Arabic Presentation Forms-A': range(64336, 65023+1), 'Variation Selectors': range(65024, 65039+1), 'Vertical Forms': range(65040, 65055+1), 'Combining Half Marks': range(65056, 65071+1), 'CJK Compatibility Forms': range(65072, 65103+1), 'Small Form Variants': range(65104, 65135+1), 'Arabic Presentation Forms-B': range(65136, 65279+1), 'Halfwidth and Fullwidth Forms': range(65280, 65519+1), 'Specials': range(65520, 65535+1), 'Linear B Syllabary': range(65536, 65663+1), 'Linear B Ideograms': range(65664, 65791+1), 'Aegean Numbers': range(65792, 65855+1), 'Ancient Greek Numbers': range(65856, 65935+1), 'Ancient Symbols': range(65936, 65999+1), 'Phaistos Disc': range(66000, 66047+1), 'Lycian': range(66176, 66207+1), 'Carian': range(66208, 66271+1), 'Coptic Epact Numbers': range(66272, 66303+1), 'Old Italic': range(66304, 66351+1), 'Gothic': range(66352, 66383+1), 'Old Permic': range(66384, 66431+1), 'Ugaritic': range(66432, 66463+1), 'Old Persian': range(66464, 66527+1), 'Deseret': range(66560, 66639+1), 'Shavian': range(66640, 66687+1), 'Osmanya': range(66688, 66735+1), 'Osage': range(66736, 66815+1), 'Elbasan': range(66816, 66863+1), 'Caucasian Albanian': range(66864, 66927+1), 'Linear A': range(67072, 67455+1), 'Cypriot Syllabary': range(67584, 67647+1), 'Imperial Aramaic': range(67648, 67679+1), 'Palmyrene': range(67680, 67711+1), 'Nabataean': range(67712, 67759+1), 'Hatran': range(67808, 67839+1), 'Phoenician': range(67840, 67871+1), 'Lydian': range(67872, 67903+1), 'Meroitic Hieroglyphs': range(67968, 67999+1), 'Meroitic Cursive': range(68000, 68095+1), 'Kharoshthi': range(68096, 68191+1), 'Old South Arabian': range(68192, 68223+1), 'Old North Arabian': range(68224, 68255+1), 'Manichaean': range(68288, 68351+1), 'Avestan': range(68352, 68415+1), 'Inscriptional Parthian': range(68416, 68447+1), 'Inscriptional Pahlavi': range(68448, 68479+1), 'Psalter Pahlavi': range(68480, 68527+1), 'Old Turkic': range(68608, 68687+1), 'Old Hungarian': range(68736, 68863+1), 'Rumi Numeral Symbols': range(69216, 69247+1), 'Brahmi': range(69632, 69759+1), 'Kaithi': range(69760, 69839+1), 'Sora Sompeng': range(69840, 69887+1), 'Chakma': range(69888, 69967+1), 'Mahajani': range(69968, 70015+1), 'Sharada': range(70016, 70111+1), 'Sinhala Archaic Numbers': range(70112, 70143+1), 'Khojki': range(70144, 70223+1), 'Multani': range(70272, 70319+1), 'Khudawadi': range(70320, 70399+1), 'Grantha': range(70400, 70527+1), 'Newa': range(70656, 70783+1), 'Tirhuta': range(70784, 70879+1), 'Siddham': range(71040, 71167+1), 'Modi': range(71168, 71263+1), 'Mongolian Supplement': range(71264, 71295+1), 'Takri': range(71296, 71375+1), 'Ahom': range(71424, 71487+1), 'Warang Citi': range(71840, 71935+1), 'Zanabazar Square': range(72192, 72271+1), 'Soyombo': range(72272, 72367+1), 'Pau Cin Hau': range(72384, 72447+1), 'Bhaiksuki': range(72704, 72815+1), 'Marchen': range(72816, 72895+1), 'Masaram Gondi': range(72960, 73055+1), 'Cuneiform': range(73728, 74751+1), 'Cuneiform Numbers and Punctuation': range(74752, 74879+1), 'Early Dynastic Cuneiform': range(74880, 75087+1), 'Egyptian Hieroglyphs': range(77824, 78895+1), 'Anatolian Hieroglyphs': range(82944, 83583+1), 'Bamum Supplement': range(92160, 92735+1), 'Mro': range(92736, 92783+1), 'Bassa Vah': range(92880, 92927+1), 'Pahawh Hmong': range(92928, 93071+1), 'Miao': range(93952, 94111+1), 'Ideographic Symbols and Punctuation': range(94176, 94207+1), 'Tangut': range(94208, 100351+1), 'Tangut Components': range(100352, 101119+1), 'Kana Supplement': range(110592, 110847+1), 'Kana Extended-A': range(110848, 110895+1), 'Nushu': range(110960, 111359+1), 'Duployan': range(113664, 113823+1), 'Shorthand Format Controls': range(113824, 113839+1), 'Byzantine Musical Symbols': range(118784, 119039+1), 'Musical Symbols': range(119040, 119295+1), 'Ancient Greek Musical Notation': range(119296, 119375+1), 'Tai Xuan Jing Symbols': range(119552, 119647+1), 'Counting Rod Numerals': range(119648, 119679+1), 'Mathematical Alphanumeric Symbols': range(119808, 120831+1), 'Sutton SignWriting': range(120832, 121519+1), 'Glagolitic Supplement': range(122880, 122927+1), 'Mende Kikakui': range(124928, 125151+1), 'Adlam': range(125184, 125279+1), 'Arabic Mathematical Alphabetic Symbols': range(126464, 126719+1), 'Mahjong Tiles': range(126976, 127023+1), 'Domino Tiles': range(127024, 127135+1), 'Playing Cards': range(127136, 127231+1), 'Enclosed Alphanumeric Supplement': range(127232, 127487+1), 'Enclosed Ideographic Supplement': range(127488, 127743+1), 'Miscellaneous Symbols and Pictographs': range(127744, 128511+1), 'Emoticons range(Emoji)': range(128512, 128591+1), 'Ornamental Dingbats': range(128592, 128639+1), 'Transport and Map Symbols': range(128640, 128767+1), 'Alchemical Symbols': range(128768, 128895+1), 'Geometric Shapes Extended': range(128896, 129023+1), 'Supplemental Arrows-C': range(129024, 129279+1), 'Supplemental Symbols and Pictographs': range(129280, 129535+1), 'CJK Unified Ideographs Extension B': range(131072, 173791+1), 'CJK Unified Ideographs Extension C': range(173824, 177983+1), 'CJK Unified Ideographs Extension D': range(177984, 178207+1), 'CJK Unified Ideographs Extension E': range(178208, 183983+1), 'CJK Unified Ideographs Extension F': range(183984, 191471+1), 'CJK Compatibility Ideographs Supplement': range(194560, 195103+1), 'Tags': range(917504, 917631+1), 'Variation Selectors Supplement': range(917760, 917999+1)} # type: Dict[str, range] +UNICODE_RANGES_COMBINED = { + "Control character": range(0, 31 + 1), + "Basic Latin": range(32, 127 + 1), + "Latin-1 Supplement": range(128, 255 + 1), + "Latin Extended-A": range(256, 383 + 1), + "Latin Extended-B": range(384, 591 + 1), + "IPA Extensions": range(592, 687 + 1), + "Spacing Modifier Letters": range(688, 767 + 1), + "Combining Diacritical Marks": range(768, 879 + 1), + "Greek and Coptic": range(880, 1023 + 1), + "Cyrillic": range(1024, 1279 + 1), + "Cyrillic Supplement": range(1280, 1327 + 1), + "Armenian": range(1328, 1423 + 1), + "Hebrew": range(1424, 1535 + 1), + "Arabic": range(1536, 1791 + 1), + "Syriac": range(1792, 1871 + 1), + "Arabic Supplement": range(1872, 1919 + 1), + "Thaana": range(1920, 1983 + 1), + "NKo": range(1984, 2047 + 1), + "Samaritan": range(2048, 2111 + 1), + "Mandaic": range(2112, 2143 + 1), + "Syriac Supplement": range(2144, 2159 + 1), + "Arabic Extended-A": range(2208, 2303 + 1), + "Devanagari": range(2304, 2431 + 1), + "Bengali": range(2432, 2559 + 1), + "Gurmukhi": range(2560, 2687 + 1), + "Gujarati": range(2688, 2815 + 1), + "Oriya": range(2816, 2943 + 1), + "Tamil": range(2944, 3071 + 1), + "Telugu": range(3072, 3199 + 1), + "Kannada": range(3200, 3327 + 1), + "Malayalam": range(3328, 3455 + 1), + "Sinhala": range(3456, 3583 + 1), + "Thai": range(3584, 3711 + 1), + "Lao": range(3712, 3839 + 1), + "Tibetan": range(3840, 4095 + 1), + "Myanmar": range(4096, 4255 + 1), + "Georgian": range(4256, 4351 + 1), + "Hangul Jamo": range(4352, 4607 + 1), + "Ethiopic": range(4608, 4991 + 1), + "Ethiopic Supplement": range(4992, 5023 + 1), + "Cherokee": range(5024, 5119 + 1), + "Unified Canadian Aboriginal Syllabics": range(5120, 5759 + 1), + "Ogham": range(5760, 5791 + 1), + "Runic": range(5792, 5887 + 1), + "Tagalog": range(5888, 5919 + 1), + "Hanunoo": range(5920, 5951 + 1), + "Buhid": range(5952, 5983 + 1), + "Tagbanwa": range(5984, 6015 + 1), + "Khmer": range(6016, 6143 + 1), + "Mongolian": range(6144, 6319 + 1), + "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6399 + 1), + "Limbu": range(6400, 6479 + 1), + "Tai Le": range(6480, 6527 + 1), + "New Tai Lue": range(6528, 6623 + 1), + "Khmer Symbols": range(6624, 6655 + 1), + "Buginese": range(6656, 6687 + 1), + "Tai Tham": range(6688, 6831 + 1), + "Combining Diacritical Marks Extended": range(6832, 6911 + 1), + "Balinese": range(6912, 7039 + 1), + "Sundanese": range(7040, 7103 + 1), + "Batak": range(7104, 7167 + 1), + "Lepcha": range(7168, 7247 + 1), + "Ol Chiki": range(7248, 7295 + 1), + "Cyrillic Extended C": range(7296, 7311 + 1), + "Sundanese Supplement": range(7360, 7375 + 1), + "Vedic Extensions": range(7376, 7423 + 1), + "Phonetic Extensions": range(7424, 7551 + 1), + "Phonetic Extensions Supplement": range(7552, 7615 + 1), + "Combining Diacritical Marks Supplement": range(7616, 7679 + 1), + "Latin Extended Additional": range(7680, 7935 + 1), + "Greek Extended": range(7936, 8191 + 1), + "General Punctuation": range(8192, 8303 + 1), + "Superscripts and Subscripts": range(8304, 8351 + 1), + "Currency Symbols": range(8352, 8399 + 1), + "Combining Diacritical Marks for Symbols": range(8400, 8447 + 1), + "Letterlike Symbols": range(8448, 8527 + 1), + "Number Forms": range(8528, 8591 + 1), + "Arrows": range(8592, 8703 + 1), + "Mathematical Operators": range(8704, 8959 + 1), + "Miscellaneous Technical": range(8960, 9215 + 1), + "Control Pictures": range(9216, 9279 + 1), + "Optical Character Recognition": range(9280, 9311 + 1), + "Enclosed Alphanumerics": range(9312, 9471 + 1), + "Box Drawing": range(9472, 9599 + 1), + "Block Elements": range(9600, 9631 + 1), + "Geometric Shapes": range(9632, 9727 + 1), + "Miscellaneous Symbols": range(9728, 9983 + 1), + "Dingbats": range(9984, 10175 + 1), + "Miscellaneous Mathematical Symbols-A": range(10176, 10223 + 1), + "Supplemental Arrows-A": range(10224, 10239 + 1), + "Braille Patterns": range(10240, 10495 + 1), + "Supplemental Arrows-B": range(10496, 10623 + 1), + "Miscellaneous Mathematical Symbols-B": range(10624, 10751 + 1), + "Supplemental Mathematical Operators": range(10752, 11007 + 1), + "Miscellaneous Symbols and Arrows": range(11008, 11263 + 1), + "Glagolitic": range(11264, 11359 + 1), + "Latin Extended-C": range(11360, 11391 + 1), + "Coptic": range(11392, 11519 + 1), + "Georgian Supplement": range(11520, 11567 + 1), + "Tifinagh": range(11568, 11647 + 1), + "Ethiopic Extended": range(11648, 11743 + 1), + "Cyrillic Extended-A": range(11744, 11775 + 1), + "Supplemental Punctuation": range(11776, 11903 + 1), + "CJK Radicals Supplement": range(11904, 12031 + 1), + "Kangxi Radicals": range(12032, 12255 + 1), + "Ideographic Description Characters": range(12272, 12287 + 1), + "CJK Symbols and Punctuation": range(12288, 12351 + 1), + "Hiragana": range(12352, 12447 + 1), + "Katakana": range(12448, 12543 + 1), + "Bopomofo": range(12544, 12591 + 1), + "Hangul Compatibility Jamo": range(12592, 12687 + 1), + "Kanbun": range(12688, 12703 + 1), + "Bopomofo Extended": range(12704, 12735 + 1), + "CJK Strokes": range(12736, 12783 + 1), + "Katakana Phonetic Extensions": range(12784, 12799 + 1), + "Enclosed CJK Letters and Months": range(12800, 13055 + 1), + "CJK Compatibility": range(13056, 13311 + 1), + "CJK Unified Ideographs Extension A": range(13312, 19903 + 1), + "Yijing Hexagram Symbols": range(19904, 19967 + 1), + "CJK Unified Ideographs": range(19968, 40959 + 1), + "Yi Syllables": range(40960, 42127 + 1), + "Yi Radicals": range(42128, 42191 + 1), + "Lisu": range(42192, 42239 + 1), + "Vai": range(42240, 42559 + 1), + "Cyrillic Extended-B": range(42560, 42655 + 1), + "Bamum": range(42656, 42751 + 1), + "Modifier Tone Letters": range(42752, 42783 + 1), + "Latin Extended-D": range(42784, 43007 + 1), + "Syloti Nagri": range(43008, 43055 + 1), + "Common Indic Number Forms": range(43056, 43071 + 1), + "Phags-pa": range(43072, 43135 + 1), + "Saurashtra": range(43136, 43231 + 1), + "Devanagari Extended": range(43232, 43263 + 1), + "Kayah Li": range(43264, 43311 + 1), + "Rejang": range(43312, 43359 + 1), + "Hangul Jamo Extended-A": range(43360, 43391 + 1), + "Javanese": range(43392, 43487 + 1), + "Myanmar Extended-B": range(43488, 43519 + 1), + "Cham": range(43520, 43615 + 1), + "Myanmar Extended-A": range(43616, 43647 + 1), + "Tai Viet": range(43648, 43743 + 1), + "Meetei Mayek Extensions": range(43744, 43775 + 1), + "Ethiopic Extended-A": range(43776, 43823 + 1), + "Latin Extended-E": range(43824, 43887 + 1), + "Cherokee Supplement": range(43888, 43967 + 1), + "Meetei Mayek": range(43968, 44031 + 1), + "Hangul Syllables": range(44032, 55215 + 1), + "Hangul Jamo Extended-B": range(55216, 55295 + 1), + "High Surrogates": range(55296, 56191 + 1), + "High Private Use Surrogates": range(56192, 56319 + 1), + "Low Surrogates": range(56320, 57343 + 1), + "Private Use Area": range(57344, 63743 + 1), + "CJK Compatibility Ideographs": range(63744, 64255 + 1), + "Alphabetic Presentation Forms": range(64256, 64335 + 1), + "Arabic Presentation Forms-A": range(64336, 65023 + 1), + "Variation Selectors": range(65024, 65039 + 1), + "Vertical Forms": range(65040, 65055 + 1), + "Combining Half Marks": range(65056, 65071 + 1), + "CJK Compatibility Forms": range(65072, 65103 + 1), + "Small Form Variants": range(65104, 65135 + 1), + "Arabic Presentation Forms-B": range(65136, 65279 + 1), + "Halfwidth and Fullwidth Forms": range(65280, 65519 + 1), + "Specials": range(65520, 65535 + 1), + "Linear B Syllabary": range(65536, 65663 + 1), + "Linear B Ideograms": range(65664, 65791 + 1), + "Aegean Numbers": range(65792, 65855 + 1), + "Ancient Greek Numbers": range(65856, 65935 + 1), + "Ancient Symbols": range(65936, 65999 + 1), + "Phaistos Disc": range(66000, 66047 + 1), + "Lycian": range(66176, 66207 + 1), + "Carian": range(66208, 66271 + 1), + "Coptic Epact Numbers": range(66272, 66303 + 1), + "Old Italic": range(66304, 66351 + 1), + "Gothic": range(66352, 66383 + 1), + "Old Permic": range(66384, 66431 + 1), + "Ugaritic": range(66432, 66463 + 1), + "Old Persian": range(66464, 66527 + 1), + "Deseret": range(66560, 66639 + 1), + "Shavian": range(66640, 66687 + 1), + "Osmanya": range(66688, 66735 + 1), + "Osage": range(66736, 66815 + 1), + "Elbasan": range(66816, 66863 + 1), + "Caucasian Albanian": range(66864, 66927 + 1), + "Linear A": range(67072, 67455 + 1), + "Cypriot Syllabary": range(67584, 67647 + 1), + "Imperial Aramaic": range(67648, 67679 + 1), + "Palmyrene": range(67680, 67711 + 1), + "Nabataean": range(67712, 67759 + 1), + "Hatran": range(67808, 67839 + 1), + "Phoenician": range(67840, 67871 + 1), + "Lydian": range(67872, 67903 + 1), + "Meroitic Hieroglyphs": range(67968, 67999 + 1), + "Meroitic Cursive": range(68000, 68095 + 1), + "Kharoshthi": range(68096, 68191 + 1), + "Old South Arabian": range(68192, 68223 + 1), + "Old North Arabian": range(68224, 68255 + 1), + "Manichaean": range(68288, 68351 + 1), + "Avestan": range(68352, 68415 + 1), + "Inscriptional Parthian": range(68416, 68447 + 1), + "Inscriptional Pahlavi": range(68448, 68479 + 1), + "Psalter Pahlavi": range(68480, 68527 + 1), + "Old Turkic": range(68608, 68687 + 1), + "Old Hungarian": range(68736, 68863 + 1), + "Rumi Numeral Symbols": range(69216, 69247 + 1), + "Brahmi": range(69632, 69759 + 1), + "Kaithi": range(69760, 69839 + 1), + "Sora Sompeng": range(69840, 69887 + 1), + "Chakma": range(69888, 69967 + 1), + "Mahajani": range(69968, 70015 + 1), + "Sharada": range(70016, 70111 + 1), + "Sinhala Archaic Numbers": range(70112, 70143 + 1), + "Khojki": range(70144, 70223 + 1), + "Multani": range(70272, 70319 + 1), + "Khudawadi": range(70320, 70399 + 1), + "Grantha": range(70400, 70527 + 1), + "Newa": range(70656, 70783 + 1), + "Tirhuta": range(70784, 70879 + 1), + "Siddham": range(71040, 71167 + 1), + "Modi": range(71168, 71263 + 1), + "Mongolian Supplement": range(71264, 71295 + 1), + "Takri": range(71296, 71375 + 1), + "Ahom": range(71424, 71487 + 1), + "Warang Citi": range(71840, 71935 + 1), + "Zanabazar Square": range(72192, 72271 + 1), + "Soyombo": range(72272, 72367 + 1), + "Pau Cin Hau": range(72384, 72447 + 1), + "Bhaiksuki": range(72704, 72815 + 1), + "Marchen": range(72816, 72895 + 1), + "Masaram Gondi": range(72960, 73055 + 1), + "Cuneiform": range(73728, 74751 + 1), + "Cuneiform Numbers and Punctuation": range(74752, 74879 + 1), + "Early Dynastic Cuneiform": range(74880, 75087 + 1), + "Egyptian Hieroglyphs": range(77824, 78895 + 1), + "Anatolian Hieroglyphs": range(82944, 83583 + 1), + "Bamum Supplement": range(92160, 92735 + 1), + "Mro": range(92736, 92783 + 1), + "Bassa Vah": range(92880, 92927 + 1), + "Pahawh Hmong": range(92928, 93071 + 1), + "Miao": range(93952, 94111 + 1), + "Ideographic Symbols and Punctuation": range(94176, 94207 + 1), + "Tangut": range(94208, 100351 + 1), + "Tangut Components": range(100352, 101119 + 1), + "Kana Supplement": range(110592, 110847 + 1), + "Kana Extended-A": range(110848, 110895 + 1), + "Nushu": range(110960, 111359 + 1), + "Duployan": range(113664, 113823 + 1), + "Shorthand Format Controls": range(113824, 113839 + 1), + "Byzantine Musical Symbols": range(118784, 119039 + 1), + "Musical Symbols": range(119040, 119295 + 1), + "Ancient Greek Musical Notation": range(119296, 119375 + 1), + "Tai Xuan Jing Symbols": range(119552, 119647 + 1), + "Counting Rod Numerals": range(119648, 119679 + 1), + "Mathematical Alphanumeric Symbols": range(119808, 120831 + 1), + "Sutton SignWriting": range(120832, 121519 + 1), + "Glagolitic Supplement": range(122880, 122927 + 1), + "Mende Kikakui": range(124928, 125151 + 1), + "Adlam": range(125184, 125279 + 1), + "Arabic Mathematical Alphabetic Symbols": range(126464, 126719 + 1), + "Mahjong Tiles": range(126976, 127023 + 1), + "Domino Tiles": range(127024, 127135 + 1), + "Playing Cards": range(127136, 127231 + 1), + "Enclosed Alphanumeric Supplement": range(127232, 127487 + 1), + "Enclosed Ideographic Supplement": range(127488, 127743 + 1), + "Miscellaneous Symbols and Pictographs": range(127744, 128511 + 1), + "Emoticons range(Emoji)": range(128512, 128591 + 1), + "Ornamental Dingbats": range(128592, 128639 + 1), + "Transport and Map Symbols": range(128640, 128767 + 1), + "Alchemical Symbols": range(128768, 128895 + 1), + "Geometric Shapes Extended": range(128896, 129023 + 1), + "Supplemental Arrows-C": range(129024, 129279 + 1), + "Supplemental Symbols and Pictographs": range(129280, 129535 + 1), + "CJK Unified Ideographs Extension B": range(131072, 173791 + 1), + "CJK Unified Ideographs Extension C": range(173824, 177983 + 1), + "CJK Unified Ideographs Extension D": range(177984, 178207 + 1), + "CJK Unified Ideographs Extension E": range(178208, 183983 + 1), + "CJK Unified Ideographs Extension F": range(183984, 191471 + 1), + "CJK Compatibility Ideographs Supplement": range(194560, 195103 + 1), + "Tags": range(917504, 917631 + 1), + "Variation Selectors Supplement": range(917760, 917999 + 1), +} # type: Dict[str, range] UNICODE_SECONDARY_RANGE_KEYWORD = [ - 'Supplement', - 'Extended', - 'Extensions', - 'Modifier', - 'Marks', - 'Punctuation', - 'Symbols', - 'Forms', - 'Operators', - 'Miscellaneous', - 'Drawing', - 'Block', - 'Shapes', - 'Supplemental', - 'Tags' + "Supplement", + "Extended", + "Extensions", + "Modifier", + "Marks", + "Punctuation", + "Symbols", + "Forms", + "Operators", + "Miscellaneous", + "Drawing", + "Block", + "Shapes", + "Supplemental", + "Tags", ] # type: List[str] RE_POSSIBLE_ENCODING_INDICATION = re_compile( - r'(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)', - IGNORECASE + r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)", + IGNORECASE, ) IANA_SUPPORTED = sorted( filter( - lambda x: x.endswith("_codec") is False and x not in {"rot_13", "tactis", "mbcs"}, - list(set(aliases.values())) + lambda x: x.endswith("_codec") is False + and x not in {"rot_13", "tactis", "mbcs"}, + list(set(aliases.values())), ) ) # type: List[str] @@ -66,157 +346,39 @@ IANA_SUPPORTED_COUNT = len(IANA_SUPPORTED) # type: int # pre-computed code page that are similar using the function cp_similarity. IANA_SUPPORTED_SIMILAR = { - "cp037": [ - "cp1026", - "cp1140", - "cp273", - "cp500" - ], - "cp1026": [ - "cp037", - "cp1140", - "cp273", - "cp500" - ], - "cp1125": [ - "cp866" - ], - "cp1140": [ - "cp037", - "cp1026", - "cp273", - "cp500" - ], - "cp1250": [ - "iso8859_2" - ], - "cp1251": [ - "kz1048", - "ptcp154" - ], - "cp1252": [ - "cp1258", - "iso8859_15", - "iso8859_9", - "latin_1" - ], - "cp1253": [ - "iso8859_7" - ], - "cp1254": [ - "cp1258", - "iso8859_15", - "iso8859_9", - "latin_1" - ], - "cp1257": [ - "iso8859_13" - ], - "cp1258": [ - "cp1252", - "cp1254", - "iso8859_9", - "latin_1" - ], - "cp273": [ - "cp037", - "cp1026", - "cp1140", - "cp500" - ], - "cp437": [ - "cp850", - "cp858", - "cp860", - "cp861", - "cp862", - "cp863", - "cp865" - ], - "cp500": [ - "cp037", - "cp1026", - "cp1140", - "cp273" - ], - "cp850": [ - "cp437", - "cp857", - "cp858", - "cp865" - ], - "cp857": [ - "cp850", - "cp858", - "cp865" - ], - "cp858": [ - "cp437", - "cp850", - "cp857", - "cp865" - ], - "cp860": [ - "cp437", - "cp861", - "cp862", - "cp863", - "cp865" - ], - "cp861": [ - "cp437", - "cp860", - "cp862", - "cp863", - "cp865" - ], - "cp862": [ - "cp437", - "cp860", - "cp861", - "cp863", - "cp865" - ], - "cp863": [ - "cp437", - "cp860", - "cp861", - "cp862", - "cp865" - ], - "cp865": [ - "cp437", - "cp850", - "cp857", - "cp858", - "cp860", - "cp861", - "cp862", - "cp863" - ], - "cp866": [ - "cp1125" - ], - "iso8859_10": [ - "iso8859_14", - "iso8859_15", - "iso8859_4", - "iso8859_9", - "latin_1" - ], - "iso8859_11": [ - "tis_620" - ], - "iso8859_13": [ - "cp1257" - ], + "cp037": ["cp1026", "cp1140", "cp273", "cp500"], + "cp1026": ["cp037", "cp1140", "cp273", "cp500"], + "cp1125": ["cp866"], + "cp1140": ["cp037", "cp1026", "cp273", "cp500"], + "cp1250": ["iso8859_2"], + "cp1251": ["kz1048", "ptcp154"], + "cp1252": ["cp1258", "iso8859_15", "iso8859_9", "latin_1"], + "cp1253": ["iso8859_7"], + "cp1254": ["cp1258", "iso8859_15", "iso8859_9", "latin_1"], + "cp1257": ["iso8859_13"], + "cp1258": ["cp1252", "cp1254", "iso8859_9", "latin_1"], + "cp273": ["cp037", "cp1026", "cp1140", "cp500"], + "cp437": ["cp850", "cp858", "cp860", "cp861", "cp862", "cp863", "cp865"], + "cp500": ["cp037", "cp1026", "cp1140", "cp273"], + "cp850": ["cp437", "cp857", "cp858", "cp865"], + "cp857": ["cp850", "cp858", "cp865"], + "cp858": ["cp437", "cp850", "cp857", "cp865"], + "cp860": ["cp437", "cp861", "cp862", "cp863", "cp865"], + "cp861": ["cp437", "cp860", "cp862", "cp863", "cp865"], + "cp862": ["cp437", "cp860", "cp861", "cp863", "cp865"], + "cp863": ["cp437", "cp860", "cp861", "cp862", "cp865"], + "cp865": ["cp437", "cp850", "cp857", "cp858", "cp860", "cp861", "cp862", "cp863"], + "cp866": ["cp1125"], + "iso8859_10": ["iso8859_14", "iso8859_15", "iso8859_4", "iso8859_9", "latin_1"], + "iso8859_11": ["tis_620"], + "iso8859_13": ["cp1257"], "iso8859_14": [ "iso8859_10", "iso8859_15", "iso8859_16", "iso8859_3", "iso8859_9", - "latin_1" + "latin_1", ], "iso8859_15": [ "cp1252", @@ -226,7 +388,7 @@ IANA_SUPPORTED_SIMILAR = { "iso8859_16", "iso8859_3", "iso8859_9", - "latin_1" + "latin_1", ], "iso8859_16": [ "iso8859_14", @@ -234,29 +396,12 @@ IANA_SUPPORTED_SIMILAR = { "iso8859_2", "iso8859_3", "iso8859_9", - "latin_1" - ], - "iso8859_2": [ - "cp1250", - "iso8859_16", - "iso8859_4" - ], - "iso8859_3": [ - "iso8859_14", - "iso8859_15", - "iso8859_16", - "iso8859_9", - "latin_1" - ], - "iso8859_4": [ - "iso8859_10", - "iso8859_2", - "iso8859_9", - "latin_1" - ], - "iso8859_7": [ - "cp1253" + "latin_1", ], + "iso8859_2": ["cp1250", "iso8859_16", "iso8859_4"], + "iso8859_3": ["iso8859_14", "iso8859_15", "iso8859_16", "iso8859_9", "latin_1"], + "iso8859_4": ["iso8859_10", "iso8859_2", "iso8859_9", "latin_1"], + "iso8859_7": ["cp1253"], "iso8859_9": [ "cp1252", "cp1254", @@ -267,12 +412,9 @@ IANA_SUPPORTED_SIMILAR = { "iso8859_16", "iso8859_3", "iso8859_4", - "latin_1" - ], - "kz1048": [ - "cp1251", - "ptcp154" + "latin_1", ], + "kz1048": ["cp1251", "ptcp154"], "latin_1": [ "cp1252", "cp1254", @@ -283,61 +425,47 @@ IANA_SUPPORTED_SIMILAR = { "iso8859_16", "iso8859_3", "iso8859_4", - "iso8859_9" + "iso8859_9", ], - "mac_iceland": [ - "mac_roman", - "mac_turkish" - ], - "mac_roman": [ - "mac_iceland", - "mac_turkish" - ], - "mac_turkish": [ - "mac_iceland", - "mac_roman" - ], - "ptcp154": [ - "cp1251", - "kz1048" - ], - "tis_620": [ - "iso8859_11" - ] + "mac_iceland": ["mac_roman", "mac_turkish"], + "mac_roman": ["mac_iceland", "mac_turkish"], + "mac_turkish": ["mac_iceland", "mac_roman"], + "ptcp154": ["cp1251", "kz1048"], + "tis_620": ["iso8859_11"], } # type: Dict[str, List[str]] CHARDET_CORRESPONDENCE = { - 'iso2022_kr': 'ISO-2022-KR', - 'iso2022_jp': 'ISO-2022-JP', - 'euc_kr': 'EUC-KR', - 'tis_620': 'TIS-620', - 'utf_32': 'UTF-32', - 'euc_jp': 'EUC-JP', - 'koi8_r': 'KOI8-R', - 'iso8859_1': 'ISO-8859-1', - 'iso8859_2': 'ISO-8859-2', - 'iso8859_5': 'ISO-8859-5', - 'iso8859_6': 'ISO-8859-6', - 'iso8859_7': 'ISO-8859-7', - 'iso8859_8': 'ISO-8859-8', - 'utf_16': 'UTF-16', - 'cp855': 'IBM855', - 'mac_cyrillic': 'MacCyrillic', - 'gb2312': 'GB2312', - 'gb18030': 'GB18030', - 'cp932': 'CP932', - 'cp866': 'IBM866', - 'utf_8': 'utf-8', - 'utf_8_sig': 'UTF-8-SIG', - 'shift_jis': 'SHIFT_JIS', - 'big5': 'Big5', - 'cp1250': 'windows-1250', - 'cp1251': 'windows-1251', - 'cp1252': 'Windows-1252', - 'cp1253': 'windows-1253', - 'cp1255': 'windows-1255', - 'cp1256': 'windows-1256', - 'cp1254': 'Windows-1254', - 'cp949': 'CP949' + "iso2022_kr": "ISO-2022-KR", + "iso2022_jp": "ISO-2022-JP", + "euc_kr": "EUC-KR", + "tis_620": "TIS-620", + "utf_32": "UTF-32", + "euc_jp": "EUC-JP", + "koi8_r": "KOI8-R", + "iso8859_1": "ISO-8859-1", + "iso8859_2": "ISO-8859-2", + "iso8859_5": "ISO-8859-5", + "iso8859_6": "ISO-8859-6", + "iso8859_7": "ISO-8859-7", + "iso8859_8": "ISO-8859-8", + "utf_16": "UTF-16", + "cp855": "IBM855", + "mac_cyrillic": "MacCyrillic", + "gb2312": "GB2312", + "gb18030": "GB18030", + "cp932": "CP932", + "cp866": "IBM866", + "utf_8": "utf-8", + "utf_8_sig": "UTF-8-SIG", + "shift_jis": "SHIFT_JIS", + "big5": "Big5", + "cp1250": "windows-1250", + "cp1251": "windows-1251", + "cp1252": "Windows-1252", + "cp1253": "windows-1253", + "cp1255": "windows-1255", + "cp1256": "windows-1256", + "cp1254": "Windows-1254", + "cp949": "CP949", } # type: Dict[str, str] diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/legacy.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/legacy.py index 7b28cb48..71fa3cf8 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/legacy.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/legacy.py @@ -1,7 +1,10 @@ -from charset_normalizer.api import from_bytes -from charset_normalizer.constant import CHARDET_CORRESPONDENCE +import warnings from typing import Dict, Optional, Union +from .api import from_bytes, from_fp, from_path, normalize +from .constant import CHARDET_CORRESPONDENCE +from .models import CharsetMatch, CharsetMatches + def detect(byte_str: bytes) -> Dict[str, Optional[Union[str, float]]]: """ @@ -14,8 +17,10 @@ def detect(byte_str: bytes) -> Dict[str, Optional[Union[str, float]]]: :param byte_str: The byte sequence to examine. """ if not isinstance(byte_str, (bytearray, bytes)): - raise TypeError('Expected object of type bytes or bytearray, got: ' - '{0}'.format(type(byte_str))) + raise TypeError( + "Expected object of type bytes or bytearray, got: " + "{0}".format(type(byte_str)) + ) if isinstance(byte_str, bytearray): byte_str = bytes(byte_str) @@ -23,16 +28,68 @@ def detect(byte_str: bytes) -> Dict[str, Optional[Union[str, float]]]: r = from_bytes(byte_str).best() encoding = r.encoding if r is not None else None - language = r.language if r is not None and r.language != 'Unknown' else '' - confidence = 1. - r.chaos if r is not None else None + language = r.language if r is not None and r.language != "Unknown" else "" + confidence = 1.0 - r.chaos if r is not None else None # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process # but chardet does return 'utf-8-sig' and it is a valid codec name. - if r is not None and encoding == 'utf_8' and r.bom: - encoding += '_sig' + if r is not None and encoding == "utf_8" and r.bom: + encoding += "_sig" return { - 'encoding': encoding if encoding not in CHARDET_CORRESPONDENCE else CHARDET_CORRESPONDENCE[encoding], - 'language': language, - 'confidence': confidence + "encoding": encoding + if encoding not in CHARDET_CORRESPONDENCE + else CHARDET_CORRESPONDENCE[encoding], + "language": language, + "confidence": confidence, } + + +class CharsetNormalizerMatch(CharsetMatch): + pass + + +class CharsetNormalizerMatches(CharsetMatches): + @staticmethod + def from_fp(*args, **kwargs): # type: ignore + warnings.warn( + "staticmethod from_fp, from_bytes, from_path and normalize are deprecated " + "and scheduled to be removed in 3.0", + DeprecationWarning, + ) + return from_fp(*args, **kwargs) + + @staticmethod + def from_bytes(*args, **kwargs): # type: ignore + warnings.warn( + "staticmethod from_fp, from_bytes, from_path and normalize are deprecated " + "and scheduled to be removed in 3.0", + DeprecationWarning, + ) + return from_bytes(*args, **kwargs) + + @staticmethod + def from_path(*args, **kwargs): # type: ignore + warnings.warn( + "staticmethod from_fp, from_bytes, from_path and normalize are deprecated " + "and scheduled to be removed in 3.0", + DeprecationWarning, + ) + return from_path(*args, **kwargs) + + @staticmethod + def normalize(*args, **kwargs): # type: ignore + warnings.warn( + "staticmethod from_fp, from_bytes, from_path and normalize are deprecated " + "and scheduled to be removed in 3.0", + DeprecationWarning, + ) + return normalize(*args, **kwargs) + + +class CharsetDetector(CharsetNormalizerMatches): + pass + + +class CharsetDoctor(CharsetNormalizerMatches): + pass diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/md.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/md.py index ad6d737d..af3852b5 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/md.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/md.py @@ -1,9 +1,24 @@ from functools import lru_cache -from typing import Optional, List +from typing import List, Optional -from charset_normalizer.constant import UNICODE_SECONDARY_RANGE_KEYWORD -from charset_normalizer.utils import is_punctuation, is_symbol, unicode_range, is_accentuated, is_latin, \ - remove_accent, is_separator, is_cjk, is_case_variable, is_hangul, is_katakana, is_hiragana, is_ascii, is_thai +from .constant import UNICODE_SECONDARY_RANGE_KEYWORD +from .utils import ( + is_accentuated, + is_ascii, + is_case_variable, + is_cjk, + is_emoticon, + is_hangul, + is_hiragana, + is_katakana, + is_latin, + is_punctuation, + is_separator, + is_symbol, + is_thai, + remove_accent, + unicode_range, +) class MessDetectorPlugin: @@ -41,8 +56,7 @@ class MessDetectorPlugin: class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): - - def __init__(self): + def __init__(self) -> None: self._punctuation_count = 0 # type: int self._symbol_count = 0 # type: int self._character_count = 0 # type: int @@ -56,10 +70,30 @@ class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): def feed(self, character: str) -> None: self._character_count += 1 - if character != self._last_printable_char and character not in ["<", ">", "=", ":", "/", "&", ";", "{", "}", "[", "]", ",", "|", '"']: + if character != self._last_printable_char and character not in [ + "<", + ">", + "=", + ":", + "/", + "&", + ";", + "{", + "}", + "[", + "]", + ",", + "|", + '"', + "-", + ]: if is_punctuation(character): self._punctuation_count += 1 - elif character.isdigit() is False and is_symbol(character): + elif ( + character.isdigit() is False + and is_symbol(character) + and is_emoticon(character) is False + ): self._symbol_count += 2 self._last_printable_char = character @@ -72,16 +106,17 @@ class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): @property def ratio(self) -> float: if self._character_count == 0: - return 0. + return 0.0 - ratio_of_punctuation = (self._punctuation_count + self._symbol_count) / self._character_count # type: float + ratio_of_punctuation = ( + self._punctuation_count + self._symbol_count + ) / self._character_count # type: float - return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0. + return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0 class TooManyAccentuatedPlugin(MessDetectorPlugin): - - def __init__(self): + def __init__(self) -> None: self._character_count = 0 # type: int self._accentuated_count = 0 # type: int @@ -101,14 +136,15 @@ class TooManyAccentuatedPlugin(MessDetectorPlugin): @property def ratio(self) -> float: if self._character_count == 0: - return 0. - ratio_of_accentuation = self._accentuated_count / self._character_count # type: float - return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0. + return 0.0 + ratio_of_accentuation = ( + self._accentuated_count / self._character_count + ) # type: float + return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0 class UnprintablePlugin(MessDetectorPlugin): - - def __init__(self): + def __init__(self) -> None: self._unprintable_count = 0 # type: int self._character_count = 0 # type: int @@ -116,7 +152,12 @@ class UnprintablePlugin(MessDetectorPlugin): return True def feed(self, character: str) -> None: - if character not in {'\n', '\t', '\r', '\v'} and character.isprintable() is False: + if ( + character not in {"\n", "\t", "\r", "\v"} + and character.isprintable() is False + and character.isspace() is False + and ord(character) != 0x1A # Why? Its the ASCII substitute character. + ): self._unprintable_count += 1 self._character_count += 1 @@ -126,14 +167,13 @@ class UnprintablePlugin(MessDetectorPlugin): @property def ratio(self) -> float: if self._character_count == 0: - return 0. + return 0.0 return (self._unprintable_count * 8) / self._character_count class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): - - def __init__(self): + def __init__(self) -> None: self._successive_count = 0 # type: int self._character_count = 0 # type: int @@ -149,7 +189,9 @@ class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): if character.isupper() and self._last_latin_character.isupper(): self._successive_count += 1 # Worse if its the same char duplicated with different accent. - if remove_accent(character) == remove_accent(self._last_latin_character): + if remove_accent(character) == remove_accent( + self._last_latin_character + ): self._successive_count += 1 self._last_latin_character = character @@ -161,14 +203,13 @@ class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): @property def ratio(self) -> float: if self._character_count == 0: - return 0. + return 0.0 return (self._successive_count * 2) / self._character_count class SuspiciousRange(MessDetectorPlugin): - - def __init__(self): + def __init__(self) -> None: self._suspicious_successive_range_count = 0 # type: int self._character_count = 0 # type: int self._last_printable_seen = None # type: Optional[str] @@ -179,7 +220,28 @@ class SuspiciousRange(MessDetectorPlugin): def feed(self, character: str) -> None: self._character_count += 1 - if character.isspace() or is_punctuation(character): + if ( + character.isspace() + or is_punctuation(character) + or character + in [ + "<", + ">", + "=", + ":", + "/", + "&", + ";", + "{", + "}", + "[", + "]", + ",", + "|", + '"', + "-", + ] + ): self._last_printable_seen = None return @@ -187,7 +249,9 @@ class SuspiciousRange(MessDetectorPlugin): self._last_printable_seen = character return - unicode_range_a = unicode_range(self._last_printable_seen) # type: Optional[str] + unicode_range_a = unicode_range( + self._last_printable_seen + ) # type: Optional[str] unicode_range_b = unicode_range(character) # type: Optional[str] if is_suspiciously_successive_range(unicode_range_a, unicode_range_b): @@ -203,19 +267,20 @@ class SuspiciousRange(MessDetectorPlugin): @property def ratio(self) -> float: if self._character_count == 0: - return 0. + return 0.0 - ratio_of_suspicious_range_usage = (self._suspicious_successive_range_count * 2) / self._character_count # type: float + ratio_of_suspicious_range_usage = ( + self._suspicious_successive_range_count * 2 + ) / self._character_count # type: float if ratio_of_suspicious_range_usage < 0.1: - return 0. + return 0.0 return ratio_of_suspicious_range_usage class SuperWeirdWordPlugin(MessDetectorPlugin): - - def __init__(self): + def __init__(self) -> None: self._word_count = 0 # type: int self._bad_word_count = 0 # type: int self._is_current_word_bad = False # type: bool @@ -235,12 +300,22 @@ class SuperWeirdWordPlugin(MessDetectorPlugin): self._buffer = "".join([self._buffer, character]) if is_accentuated(character): self._buffer_accent_count += 1 - if self._foreign_long_watch is False and is_latin(character) is False and is_cjk(character) is False and is_hangul(character) is False and is_katakana(character) is False and is_hiragana(character) is False and is_thai(character) is False: + if ( + self._foreign_long_watch is False + and is_latin(character) is False + and is_cjk(character) is False + and is_hangul(character) is False + and is_katakana(character) is False + and is_hiragana(character) is False + and is_thai(character) is False + ): self._foreign_long_watch = True return if not self._buffer: return - if (character.isspace() or is_punctuation(character) or is_separator(character)) and self._buffer: + if ( + character.isspace() or is_punctuation(character) or is_separator(character) + ) and self._buffer: self._word_count += 1 buffer_length = len(self._buffer) # type: int @@ -259,7 +334,11 @@ class SuperWeirdWordPlugin(MessDetectorPlugin): self._foreign_long_watch = False self._buffer = "" self._buffer_accent_count = 0 - elif character not in {"<", ">", "-", "="} and character.isdigit() is False and is_symbol(character): + elif ( + character not in {"<", ">", "-", "="} + and character.isdigit() is False + and is_symbol(character) + ): self._is_current_word_bad = True self._buffer += character @@ -275,18 +354,18 @@ class SuperWeirdWordPlugin(MessDetectorPlugin): @property def ratio(self) -> float: if self._word_count <= 10: - return 0. + return 0.0 return self._bad_character_count / self._character_count class CjkInvalidStopPlugin(MessDetectorPlugin): """ - GB(Chinese) based encoding often render the stop incorrectly when the content does not fit and can be easily detected. - Searching for the overuse of '丅' and '丄'. + GB(Chinese) based encoding often render the stop incorrectly when the content does not fit and + can be easily detected. Searching for the overuse of '丅' and '丄'. """ - def __init__(self): + def __init__(self) -> None: self._wrong_stop_count = 0 # type: int self._cjk_character_count = 0 # type: int @@ -307,13 +386,12 @@ class CjkInvalidStopPlugin(MessDetectorPlugin): @property def ratio(self) -> float: if self._cjk_character_count < 16: - return 0. + return 0.0 return self._wrong_stop_count / self._cjk_character_count class ArchaicUpperLowerPlugin(MessDetectorPlugin): - - def __init__(self): + def __init__(self) -> None: self._buf = False # type: bool self._character_count_since_last_sep = 0 # type: int @@ -334,8 +412,14 @@ class ArchaicUpperLowerPlugin(MessDetectorPlugin): chunk_sep = is_concerned is False if chunk_sep and self._character_count_since_last_sep > 0: - if self._character_count_since_last_sep <= 64 and character.isdigit() is False and self._current_ascii_only is False: - self._successive_upper_lower_count_final += self._successive_upper_lower_count + if ( + self._character_count_since_last_sep <= 64 + and character.isdigit() is False + and self._current_ascii_only is False + ): + self._successive_upper_lower_count_final += ( + self._successive_upper_lower_count + ) self._successive_upper_lower_count = 0 self._character_count_since_last_sep = 0 @@ -350,7 +434,9 @@ class ArchaicUpperLowerPlugin(MessDetectorPlugin): self._current_ascii_only = False if self._last_alpha_seen is not None: - if (character.isupper() and self._last_alpha_seen.islower()) or (character.islower() and self._last_alpha_seen.isupper()): + if (character.isupper() and self._last_alpha_seen.islower()) or ( + character.islower() and self._last_alpha_seen.isupper() + ): if self._buf is True: self._successive_upper_lower_count += 2 self._buf = False @@ -375,12 +461,14 @@ class ArchaicUpperLowerPlugin(MessDetectorPlugin): @property def ratio(self) -> float: if self._character_count == 0: - return 0. + return 0.0 return self._successive_upper_lower_count_final / self._character_count -def is_suspiciously_successive_range(unicode_range_a: Optional[str], unicode_range_b: Optional[str]) -> bool: +def is_suspiciously_successive_range( + unicode_range_a: Optional[str], unicode_range_b: Optional[str] +) -> bool: """ Determine if two Unicode range seen next to each other can be considered as suspicious. """ @@ -396,7 +484,9 @@ def is_suspiciously_successive_range(unicode_range_a: Optional[str], unicode_ran if "Emoticons" in unicode_range_a or "Emoticons" in unicode_range_b: return False - keywords_range_a, keywords_range_b = unicode_range_a.split(" "), unicode_range_b.split(" ") + keywords_range_a, keywords_range_b = unicode_range_a.split( + " " + ), unicode_range_b.split(" ") for el in keywords_range_a: if el in UNICODE_SECONDARY_RANGE_KEYWORD: @@ -405,10 +495,16 @@ def is_suspiciously_successive_range(unicode_range_a: Optional[str], unicode_ran return False # Japanese Exception - if unicode_range_a in ['Katakana', 'Hiragana'] and unicode_range_b in ['Katakana', 'Hiragana']: + if unicode_range_a in ["Katakana", "Hiragana"] and unicode_range_b in [ + "Katakana", + "Hiragana", + ]: return False - if unicode_range_a in ['Katakana', 'Hiragana'] or unicode_range_b in ['Katakana', 'Hiragana']: + if unicode_range_a in ["Katakana", "Hiragana"] or unicode_range_b in [ + "Katakana", + "Hiragana", + ]: if "CJK" in unicode_range_a or "CJK" in unicode_range_b: return False @@ -419,30 +515,33 @@ def is_suspiciously_successive_range(unicode_range_a: Optional[str], unicode_ran return False # Chinese/Japanese use dedicated range for punctuation and/or separators. - if ('CJK' in unicode_range_a or 'CJK' in unicode_range_b) or (unicode_range_a in ['Katakana', 'Hiragana'] and unicode_range_b in ['Katakana', 'Hiragana']): - if 'Punctuation' in unicode_range_a or 'Punctuation' in unicode_range_b: + if ("CJK" in unicode_range_a or "CJK" in unicode_range_b) or ( + unicode_range_a in ["Katakana", "Hiragana"] + and unicode_range_b in ["Katakana", "Hiragana"] + ): + if "Punctuation" in unicode_range_a or "Punctuation" in unicode_range_b: return False - if 'Forms' in unicode_range_a or 'Forms' in unicode_range_b: + if "Forms" in unicode_range_a or "Forms" in unicode_range_b: return False return True @lru_cache(maxsize=2048) -def mess_ratio(decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False) -> float: +def mess_ratio( + decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False +) -> float: """ Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier. """ detectors = [] # type: List[MessDetectorPlugin] for md_class in MessDetectorPlugin.__subclasses__(): - detectors.append( - md_class() - ) + detectors.append(md_class()) length = len(decoded_sequence) # type: int - mean_mess_ratio = 0. # type: float + mean_mess_ratio = 0.0 # type: float if length < 512: intermediary_mean_mess_ratio_calc = 32 # type: int @@ -456,25 +555,16 @@ def mess_ratio(decoded_sequence: str, maximum_threshold: float = 0.2, debug: boo if detector.eligible(character): detector.feed(character) - if (index > 0 and index % intermediary_mean_mess_ratio_calc == 0) or index == length-1: - mean_mess_ratio = sum( - [ - dt.ratio for dt in detectors - ] - ) + if ( + index > 0 and index % intermediary_mean_mess_ratio_calc == 0 + ) or index == length - 1: + mean_mess_ratio = sum([dt.ratio for dt in detectors]) if mean_mess_ratio >= maximum_threshold: break if debug: for dt in detectors: # pragma: nocover - print( - dt.__class__, - dt.ratio - ) - - return round( - mean_mess_ratio, - 3 - ) + print(dt.__class__, dt.ratio) + return round(mean_mess_ratio, 3) diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/models.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/models.py index bcea76ac..40d949dc 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/models.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/models.py @@ -1,25 +1,25 @@ import warnings +from collections import Counter from encodings.aliases import aliases from hashlib import sha256 from json import dumps -from typing import Optional, List, Tuple, Set -from collections import Counter -from re import sub, compile as re_compile +from re import compile as re_compile, sub +from typing import Any, Dict, Iterator, List, Optional, Set, Tuple, Union -from charset_normalizer.constant import TOO_BIG_SEQUENCE -from charset_normalizer.md import mess_ratio -from charset_normalizer.utils import iana_name, is_multi_byte_encoding, unicode_range +from .constant import TOO_BIG_SEQUENCE +from .md import mess_ratio +from .utils import iana_name, is_multi_byte_encoding, unicode_range class CharsetMatch: def __init__( - self, - payload: bytes, - guessed_encoding: str, - mean_mess_ratio: float, - has_sig_or_bom: bool, - languages: "CoherenceMatches", - decoded_payload: Optional[str] = None + self, + payload: bytes, + guessed_encoding: str, + mean_mess_ratio: float, + has_sig_or_bom: bool, + languages: "CoherenceMatches", + decoded_payload: Optional[str] = None, ): self._payload = payload # type: bytes @@ -30,19 +30,23 @@ class CharsetMatch: self._unicode_ranges = None # type: Optional[List[str]] self._leaves = [] # type: List[CharsetMatch] - self._mean_coherence_ratio = 0. # type: float + self._mean_coherence_ratio = 0.0 # type: float self._output_payload = None # type: Optional[bytes] self._output_encoding = None # type: Optional[str] self._string = decoded_payload # type: Optional[str] - def __eq__(self, other) -> bool: + def __eq__(self, other: object) -> bool: if not isinstance(other, CharsetMatch): - raise TypeError('__eq__ cannot be invoked on {} and {}.'.format(str(other.__class__), str(self.__class__))) + raise TypeError( + "__eq__ cannot be invoked on {} and {}.".format( + str(other.__class__), str(self.__class__) + ) + ) return self.encoding == other.encoding and self.fingerprint == other.fingerprint - def __lt__(self, other) -> bool: + def __lt__(self, other: object) -> bool: """ Implemented to make sorted available upon CharsetMatches items. """ @@ -53,10 +57,17 @@ class CharsetMatch: # Bellow 1% difference --> Use Coherence if chaos_difference < 0.01: + # When having a tough decision, use the result that decoded as many multi-byte as possible. + if chaos_difference == 0.0 and self.coherence == other.coherence: + return self.multi_byte_usage > other.multi_byte_usage return self.coherence > other.coherence return self.chaos < other.chaos + @property + def multi_byte_usage(self) -> float: + return 1.0 - len(str(self)) / len(self.raw) + @property def chaos_secondary_pass(self) -> float: """ @@ -64,11 +75,11 @@ class CharsetMatch: Use with caution, this can be very slow. Notice: Will be removed in 3.0 """ - warnings.warn("chaos_secondary_pass is deprecated and will be removed in 3.0", DeprecationWarning) - return mess_ratio( - str(self), - 1. + warnings.warn( + "chaos_secondary_pass is deprecated and will be removed in 3.0", + DeprecationWarning, ) + return mess_ratio(str(self), 1.0) @property def coherence_non_latin(self) -> float: @@ -76,8 +87,11 @@ class CharsetMatch: Coherence ratio on the first non-latin language detected if ANY. Notice: Will be removed in 3.0 """ - warnings.warn("coherence_non_latin is deprecated and will be removed in 3.0", DeprecationWarning) - return 0. + warnings.warn( + "coherence_non_latin is deprecated and will be removed in 3.0", + DeprecationWarning, + ) + return 0.0 @property def w_counter(self) -> Counter: @@ -85,9 +99,11 @@ class CharsetMatch: Word counter instance on decoded text. Notice: Will be removed in 3.0 """ - warnings.warn("w_counter is deprecated and will be removed in 3.0", DeprecationWarning) - not_printable_pattern = re_compile(r'[0-9\W\n\r\t]+') - string_printable_only = sub(not_printable_pattern, ' ', str(self).lower()) + warnings.warn( + "w_counter is deprecated and will be removed in 3.0", DeprecationWarning + ) + not_printable_pattern = re_compile(r"[0-9\W\n\r\t]+") + string_printable_only = sub(not_printable_pattern, " ", str(self).lower()) return Counter(string_printable_only.split()) @@ -102,7 +118,11 @@ class CharsetMatch: def add_submatch(self, other: "CharsetMatch") -> None: if not isinstance(other, CharsetMatch) or other == self: - raise ValueError("Unable to add instance <{}> as a submatch of a CharsetMatch".format(other.__class__)) + raise ValueError( + "Unable to add instance <{}> as a submatch of a CharsetMatch".format( + other.__class__ + ) + ) other._string = None # Unload RAM usage; dirty trick. self._leaves.append(other) @@ -153,9 +173,13 @@ class CharsetMatch: return "English" # doing it there to avoid circular import - from charset_normalizer.cd import mb_encoding_languages, encoding_languages + from charset_normalizer.cd import encoding_languages, mb_encoding_languages - languages = mb_encoding_languages(self.encoding) if is_multi_byte_encoding(self.encoding) else encoding_languages(self.encoding) + languages = ( + mb_encoding_languages(self.encoding) + if is_multi_byte_encoding(self.encoding) + else encoding_languages(self.encoding) + ) if len(languages) == 0 or "Latin Based" in languages: return "Unknown" @@ -171,7 +195,7 @@ class CharsetMatch: @property def coherence(self) -> float: if not self._languages: - return 0. + return 0.0 return self._languages[0][1] @property @@ -205,9 +229,7 @@ class CharsetMatch: for character in str(self): detected_range = unicode_range(character) # type: Optional[str] if detected_range: - detected_ranges.add( - unicode_range(character) - ) + detected_ranges.add(detected_range) self._unicode_ranges = sorted(list(detected_ranges)) return self._unicode_ranges @@ -256,14 +278,15 @@ class CharsetMatches: Container with every CharsetMatch items ordered by default from most probable to the less one. Act like a list(iterable) but does not implements all related methods. """ + def __init__(self, results: List[CharsetMatch] = None): self._results = sorted(results) if results else [] # type: List[CharsetMatch] - def __iter__(self): + def __iter__(self) -> Iterator[CharsetMatch]: for result in self._results: yield result - def __getitem__(self, item) -> CharsetMatch: + def __getitem__(self, item: Union[int, str]) -> CharsetMatch: """ Retrieve a single item either by its position or encoding name (alias may be used here). Raise KeyError upon invalid index or encoding not present in results. @@ -280,13 +303,20 @@ class CharsetMatches: def __len__(self) -> int: return len(self._results) + def __bool__(self) -> bool: + return len(self._results) > 0 + def append(self, item: CharsetMatch) -> None: """ Insert a single match. Will be inserted accordingly to preserve sort. Can be inserted as a submatch. """ if not isinstance(item, CharsetMatch): - raise ValueError("Cannot append instance '{}' to CharsetMatches".format(str(item.__class__))) + raise ValueError( + "Cannot append instance '{}' to CharsetMatches".format( + str(item.__class__) + ) + ) # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage) if len(item.raw) <= TOO_BIG_SEQUENCE: for match in self._results: @@ -316,11 +346,23 @@ CoherenceMatches = List[CoherenceMatch] class CliDetectionResult: - - def __init__(self, path: str, encoding: str, encoding_aliases: List[str], alternative_encodings: List[str], language: str, alphabets: List[str], has_sig_or_bom: bool, chaos: float, coherence: float, unicode_path: Optional[str], is_preferred: bool): + def __init__( + self, + path: str, + encoding: Optional[str], + encoding_aliases: List[str], + alternative_encodings: List[str], + language: str, + alphabets: List[str], + has_sig_or_bom: bool, + chaos: float, + coherence: float, + unicode_path: Optional[str], + is_preferred: bool, + ): self.path = path # type: str self.unicode_path = unicode_path # type: Optional[str] - self.encoding = encoding # type: str + self.encoding = encoding # type: Optional[str] self.encoding_aliases = encoding_aliases # type: List[str] self.alternative_encodings = alternative_encodings # type: List[str] self.language = language # type: str @@ -331,27 +373,20 @@ class CliDetectionResult: self.is_preferred = is_preferred # type: bool @property - def __dict__(self): + def __dict__(self) -> Dict[str, Any]: # type: ignore return { - 'path': self.path, - 'encoding': self.encoding, - 'encoding_aliases': self.encoding_aliases, - 'alternative_encodings': self.alternative_encodings, - 'language': self.language, - 'alphabets': self.alphabets, - 'has_sig_or_bom': self.has_sig_or_bom, - 'chaos': self.chaos, - 'coherence': self.coherence, - 'unicode_path': self.unicode_path, - 'is_preferred': self.is_preferred + "path": self.path, + "encoding": self.encoding, + "encoding_aliases": self.encoding_aliases, + "alternative_encodings": self.alternative_encodings, + "language": self.language, + "alphabets": self.alphabets, + "has_sig_or_bom": self.has_sig_or_bom, + "chaos": self.chaos, + "coherence": self.coherence, + "unicode_path": self.unicode_path, + "is_preferred": self.is_preferred, } def to_json(self) -> str: - return dumps( - self.__dict__, - ensure_ascii=True, - indent=4 - ) - - -CharsetNormalizerMatch = CharsetMatch + return dumps(self.__dict__, ensure_ascii=True, indent=4) diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/utils.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/utils.py index 95bb2b1b..b9d12784 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/utils.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/utils.py @@ -1,19 +1,25 @@ try: import unicodedata2 as unicodedata except ImportError: - import unicodedata + import unicodedata # type: ignore[no-redef] -from codecs import IncrementalDecoder -from re import findall -from typing import Optional, Tuple, Union, List, Set import importlib -from _multibytecodec import MultibyteIncrementalDecoder # type: ignore - +from codecs import IncrementalDecoder from encodings.aliases import aliases from functools import lru_cache +from re import findall +from typing import List, Optional, Set, Tuple, Union -from charset_normalizer.constant import UNICODE_RANGES_COMBINED, UNICODE_SECONDARY_RANGE_KEYWORD, \ - RE_POSSIBLE_ENCODING_INDICATION, ENCODING_MARKS, UTF8_MAXIMAL_ALLOCATION, IANA_SUPPORTED_SIMILAR +from _multibytecodec import MultibyteIncrementalDecoder # type: ignore + +from .constant import ( + ENCODING_MARKS, + IANA_SUPPORTED_SIMILAR, + RE_POSSIBLE_ENCODING_INDICATION, + UNICODE_RANGES_COMBINED, + UNICODE_SECONDARY_RANGE_KEYWORD, + UTF8_MAXIMAL_ALLOCATION, +) @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) @@ -22,7 +28,14 @@ def is_accentuated(character: str) -> bool: description = unicodedata.name(character) # type: str except ValueError: return False - return "WITH GRAVE" in description or "WITH ACUTE" in description or "WITH CEDILLA" in description or "WITH DIAERESIS" in description or "WITH CIRCUMFLEX" in description + return ( + "WITH GRAVE" in description + or "WITH ACUTE" in description + or "WITH CEDILLA" in description + or "WITH DIAERESIS" in description + or "WITH CIRCUMFLEX" in description + or "WITH TILDE" in description + ) @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) @@ -33,12 +46,7 @@ def remove_accent(character: str) -> str: codes = decomposed.split(" ") # type: List[str] - return chr( - int( - codes[0], - 16 - ) - ) + return chr(int(codes[0], 16)) @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) @@ -71,6 +79,7 @@ def is_ascii(character: str) -> bool: return False return True + @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) def is_punctuation(character: str) -> bool: character_category = unicodedata.category(character) # type: str @@ -101,6 +110,16 @@ def is_symbol(character: str) -> bool: return "Forms" in character_range +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_emoticon(character: str) -> bool: + character_range = unicode_range(character) # type: Optional[str] + + if character_range is None: + return False + + return "Emoticons" in character_range + + @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) def is_separator(character: str) -> bool: if character.isspace() or character in ["|", "+", ",", ";", "<", ">"]: @@ -192,14 +211,16 @@ def any_specified_encoding(sequence: bytes, search_zone: int = 4096) -> Optional results = findall( RE_POSSIBLE_ENCODING_INDICATION, - sequence[:seq_len if seq_len <= search_zone else search_zone].decode('ascii', errors='ignore') + sequence[: seq_len if seq_len <= search_zone else search_zone].decode( + "ascii", errors="ignore" + ), ) # type: List[str] if len(results) == 0: return None for specified_encoding in results: - specified_encoding = specified_encoding.lower().replace('-', '_') + specified_encoding = specified_encoding.lower().replace("-", "_") for encoding_alias, encoding_iana in aliases.items(): if encoding_alias == specified_encoding: @@ -215,9 +236,19 @@ def is_multi_byte_encoding(name: str) -> bool: """ Verify is a specific encoding is a multi byte one based on it IANA name """ - return name in {"utf_8", "utf_8_sig", "utf_16", "utf_16_be", "utf_16_le", "utf_32", "utf_32_le", "utf_32_be", "utf_7"} or issubclass( - importlib.import_module('encodings.{}'.format(name)).IncrementalDecoder, # type: ignore - MultibyteIncrementalDecoder + return name in { + "utf_8", + "utf_8_sig", + "utf_16", + "utf_16_be", + "utf_16_le", + "utf_32", + "utf_32_le", + "utf_32_be", + "utf_7", + } or issubclass( + importlib.import_module("encodings.{}".format(name)).IncrementalDecoder, # type: ignore + MultibyteIncrementalDecoder, ) @@ -244,7 +275,7 @@ def should_strip_sig_or_bom(iana_encoding: str) -> bool: def iana_name(cp_name: str, strict: bool = True) -> str: - cp_name = cp_name.lower().replace('-', '_') + cp_name = cp_name.lower().replace("-", "_") for encoding_alias, encoding_iana in aliases.items(): if cp_name == encoding_alias or cp_name == encoding_iana: @@ -265,9 +296,7 @@ def range_scan(decoded_sequence: str) -> List[str]: if character_range is None: continue - ranges.add( - character_range - ) + ranges.add(character_range) return list(ranges) @@ -275,10 +304,10 @@ def range_scan(decoded_sequence: str) -> List[str]: def cp_similarity(iana_name_a: str, iana_name_b: str) -> float: if is_multi_byte_encoding(iana_name_a) or is_multi_byte_encoding(iana_name_b): - return 0. + return 0.0 - decoder_a = importlib.import_module('encodings.{}'.format(iana_name_a)).IncrementalDecoder # type: ignore - decoder_b = importlib.import_module('encodings.{}'.format(iana_name_b)).IncrementalDecoder # type: ignore + decoder_a = importlib.import_module("encodings.{}".format(iana_name_a)).IncrementalDecoder # type: ignore + decoder_b = importlib.import_module("encodings.{}".format(iana_name_b)).IncrementalDecoder # type: ignore id_a = decoder_a(errors="ignore") # type: IncrementalDecoder id_b = decoder_b(errors="ignore") # type: IncrementalDecoder @@ -298,4 +327,7 @@ def is_cp_similar(iana_name_a: str, iana_name_b: str) -> bool: Determine if two code page are at least 80% similar. IANA_SUPPORTED_SIMILAR dict was generated using the function cp_similarity. """ - return iana_name_a in IANA_SUPPORTED_SIMILAR and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a] + return ( + iana_name_a in IANA_SUPPORTED_SIMILAR + and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a] + ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/version.py b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/version.py index 112ac0cc..bdba9fc2 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/version.py +++ b/IKEA_scraper/.venv/Lib/site-packages/charset_normalizer/version.py @@ -2,5 +2,5 @@ Expose version """ -__version__ = "2.0.4" -VERSION = __version__.split('.') +__version__ = "2.0.6" +VERSION = __version__.split(".") diff --git a/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/__init__.cpython-39.pyc index 690bcd1a63f8cf58f3030f5793f21cef4479b02f..b53a633bfe725933c0dd71f125843fa2b99c951c 100644 GIT binary patch delta 14 VcmdnwzsY|?2pgl@=1{g+MF1-K1mFMw delta 14 VcmdnwzsY|?2pglz=1{g+MF1-81l|Au diff --git a/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/__main__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/__main__.cpython-39.pyc index 13727e61372c3fcd6ec21760f18b2d98999a2a17..97b23432696bd27736a1aa0a28fd8de0c9d0fa75 100644 GIT binary patch delta 13 UcmdnVxs!8)0t=(tWJQ)403Ip>@Bjb+ delta 13 UcmdnVxs!8)0t=(dWJQ)403IL%?f?J) diff --git a/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/browsers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/browsers.cpython-39.pyc index 6649176510b7a6f050fb265ee2ebb035451d7bba..f7d73810a3fd4e716986d97ea4b038327ab994cb 100644 GIT binary patch delta 14 Wcmeyu_l0l6JVr*h&GQ+rvH}1v^aaQO delta 14 Wcmeyu_l0l6JVr*B&GQ+rvH}1v=mo|A diff --git a/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/chrome.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/chrome.cpython-39.pyc index 1fe24df059f40855302869a9d476b0b7d35c414c..e1ba719c2699754c135fbdca3b5ee4435b82b59f 100644 GIT binary patch delta 14 WcmaDM@&IQ;2 delta 14 WcmaDM@!Ufg< diff --git a/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/edge.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/edge.cpython-39.pyc index b705667171146f4dc2623a61c9be25d1da8415f1..43733d4a38b16555714bb4424bae71762347a3c7 100644 GIT binary patch delta 14 VcmbQtI+=BYKO>{t<^V=#MgSle1Hb?P delta 14 VcmbQtI+=BYKO>{d<^V=#MgSlS1HJ$N diff --git a/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/electron.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/eel/__pycache__/electron.cpython-39.pyc index 93ed2edb3a01de98d80461576afe092f54496913..730ed520fc10023e1c2fec2b0a18d6edf5f1e8b8 100644 GIT binary patch delta 14 VcmX@hc9v~J7$c+G=5WSui~uLp1or>{ delta 14 VcmX@hc9v~J7$c+0=5WSui~uLd1oZ#_ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/__pycache__/__init__.cpython-39.pyc index 8d0d0cbc90d2c9653d932227fd83feacfe8ab7f1..8729683e3e2d3050dd916be6d008ad3396a76b7f 100644 GIT binary patch delta 13 UcmX>iaYSOn8E!_m$!EFC0VniaYSOn8E!_G$!EFC0VnhYX8-^I diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/__init__.cpython-39.pyc index 17f0d381ae1c97b52c0db892e5b4584ec8daa93c..ff97a7009f97f378960c20bc3f2f85c41bf4362d 100644 GIT binary patch delta 13 Ucmey%@|R@;GZUlRWEQ4M03xge5dZ)H delta 13 Ucmey%@|R@;GZUlBWEQ4M03xCU4*&oF diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/_markupbase.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/_markupbase.cpython-39.pyc index b486d7d9132d8c11e01b719d164d0d2ad5a4969e..1786efeb991b109e52de31f4bde8229695c154b2 100644 GIT binary patch delta 14 Vcmez2`NMO=JWfWp&GR`Ur2#cs1@Hg> delta 14 Vcmez2`NMO=JWfWJ&GR`Ur2#cg1?~U< diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/datetime.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/datetime.cpython-39.pyc index 8726863dc55321609a9e4b203e12830cf9fcad9e..c71e3a5d178d7bc3fcb104cf82fcc769520274c4 100644 GIT binary patch delta 16 Xcmdnr$h^Oid4n@6quXW|*6Q5=H1-Af delta 16 Xcmdnr$h^Oid4n@6qswL&*6Q5=H0lNR diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/misc.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/misc.cpython-39.pyc index 73879ca7c3cb74226c7666989e72b188949d3a34..f271d02ab133a61f5234e985cbec460286c7efbd 100644 GIT binary patch delta 16 XcmaF*fbr=A#tl(yjBcBw*|@R*LmCEb delta 16 XcmaF*fbr=A#tl(yj4qp_*|@R*Lk069elN&o-= delta 16 YcmbQZj&b5T#tjR_8C^Cn63@2>0694ZNB{r; diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/total_ordering.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/__pycache__/total_ordering.cpython-39.pyc index dec3ad7e202245a3209aa841b304e322a1cbe3c7..0c6ce1c2d888301b7daa98feae8e5a90bfc4f6c0 100644 GIT binary patch delta 14 Wcmca7cu#P{dnQJ=%^#TFu>t@xS_WSL delta 14 Wcmca7cu#P{dnQJg%^#TFu>t@xP6k~7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/__init__.cpython-39.pyc index 0ff04051308b9fce199611c8047abf1068b48d09..045d317bf60bdc448f48da4ed6b3a9179177aab7 100644 GIT binary patch delta 14 Vcmey(|C@h97&D{W=5XdEEC4Lc1sVVV delta 14 Vcmey(|C@h97&D{G=5XdEEC4LQ1sDJT diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/_encoded_words.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/_encoded_words.cpython-39.pyc index 9f412242892700237e062a6b1b1c33f4b3258a1d..dccc661f24974a85adc9a0c44fe1ee8f2b10ec94 100644 GIT binary patch delta 14 VcmbPYFvVbl4>P0NW?$yxA^;^r1g!u7 delta 14 VcmbPYFvVbl4>P07W?$yxA^;^f1gii5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/_header_value_parser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/_header_value_parser.cpython-39.pyc index 7b73fda9ce54e15cd5d9bc497d70734900be1851..92972d4177c2e0d09ef6840e603a5a56279a462f 100644 GIT binary patch delta 20 ccmaF$k>%A#mJQ3r8Qq#!h;LsZ&gi5F0BmIlkN^Mx delta 20 ccmaF$k>%A#mJQ3r8C{xJh;LsZ&gi5F0BlhRjsO4v diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/_parseaddr.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/_parseaddr.cpython-39.pyc index e1c0d2a64f7abf88a9a912eb89a8bdf406393580..87c41f7230f41215d6263fdf813eac9eca2bdd71 100644 GIT binary patch delta 13 UcmZ3Qv@~hMe`ZFvO)RRq04m)D5C8xG delta 13 UcmZ3Qv@~hMe`ZFPO)RRq04mc34gdfE diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/_policybase.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/_policybase.cpython-39.pyc index 11cded215bef7c00d99d0e77b1b21d0117fb82b8..77be82020f5aa997f2756115942536c57aa03d94 100644 GIT binary patch delta 14 Vcmdm7w7F=*QFcbR&Bxet4FNP$1}p#o delta 14 Vcmdm7w7F=*QFca`&Bxet4FNPq1}Xpm diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/base64mime.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/base64mime.cpython-39.pyc index 32781b17ff40551e2bd4bae2d78f72f6862ee134..93d0364818dc9a897ecd9b8200af7a03b8c8540c 100644 GIT binary patch delta 14 VcmbO$Jy&{z5F4Z0W?{B2b^svV1Kj`s delta 14 VcmbO$Jy&{z5F4Y*W?{B2b^svJ1KR)q diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/charset.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/charset.cpython-39.pyc index ca125f5ebafeef7670caec9fbb2b74ed3f4b018b..f84aa322033084a1336139d50e2146f8cd4b0afd 100644 GIT binary patch delta 14 VcmaDC^Dbt?6HZ3A%}+TyRRB5_2FCyZ delta 14 VcmaDC^Dbt?6HZ2#%}+TyRRB5(2E_mX diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/encoders.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/encoders.cpython-39.pyc index 64e940d57fc846f1698345d7c33322f7f22703c4..ab8c6b6b7c0dbb008c0733170059496570a092f5 100644 GIT binary patch delta 14 VcmZn=Y!KYQ%f#rmnUAT64FDWn17rXI delta 14 VcmZn=Y!KYQ%f#rinUAT64FDWb17ZLG diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/errors.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/errors.cpython-39.pyc index dfe491592baf36e477a0d08be89fd669858384ed..50ee9bfca0e5a443fa3494c6b8156e8ae761fccd 100644 GIT binary patch delta 14 Vcmdm}w^47yFD6E}&A*wjhI1!DjJ delta 14 VcmdlVygzuuQg%j{&CA#&l>jh61z`XH diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/generator.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/generator.cpython-39.pyc index 4bb2494ae92b9819c776e425f13fdd8106262af3..36b2aa5b57a71a5caf29a8b540fa6f0222f90f2e 100644 GIT binary patch delta 14 Vcmewx{Wp5U0v1NM%?nv#Gyyk*1}Ojl delta 14 Vcmewx{Wp5U0v1M>%?nv#Gyykv1}6Xj diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/header.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/header.cpython-39.pyc index 46377e25795153e4d3ba8eb3f979d0c76f48edb3..08d84d4ae51f224c93eafa3cd55112c4bb78aa11 100644 GIT binary patch delta 16 YcmeyVv@)O07mWyD*ylh delta 16 Ycmcb0pYhgx#tjFV7+p3WVv@)O07l{mDF6Tf diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/parser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/parser.cpython-39.pyc index 478d8395c5c440c830d40e51836a43ab056efb5c..dae693711fdbb9ec59f577dfadc32f9ec39f87b8 100644 GIT binary patch delta 14 VcmX@6e@uUa6C0!3W@ol$K>#UJ1iAnK delta 14 VcmX@6e@uUa6C0z;W@ol$K>#U71h@bI diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/policy.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/policy.cpython-39.pyc index caeef5244332857a4a8eb2b3e324e6094c2af8fc..36b58355ece2aff01fffefd82bc913a3e31bf7f0 100644 GIT binary patch delta 14 VcmZ4KxYBV$I5(r)<_PXUQ2;3U1gZc4 delta 14 VcmZ4KxYBV$I5(rq<_PXUQ2;3I1gHQ2 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/quoprimime.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/quoprimime.cpython-39.pyc index 8679e4fb00338dfb785421fe6ec13675a7d832f5..517aec200927443594fa3d9da66b052d4cbac641 100644 GIT binary patch delta 14 VcmaFj@x)_8G&`f)<`{MkSpY8`1nmF- delta 14 VcmaFj@x)_8G&`fq<`{MkSpY8)1nU3* diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/utils.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/__pycache__/utils.cpython-39.pyc index ebf13526d6505a1e62784054715eab41734630a9..cd76ce7f2e6878b16fa0c780002a6473b9980e7b 100644 GIT binary patch delta 14 VcmeAR>E diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/audio.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/audio.cpython-39.pyc index 7f25151fceab35dd98390d448e759480986bfa93..aea520831937069c78903c25bd35cac5fa07d78d 100644 GIT binary patch delta 14 VcmaDa`d)NHGBcyw<`m{`b^t7&1rh)N delta 14 VcmaDa`d)NHGBcyg<`m{`b^t7s1rPuL diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/base.cpython-39.pyc index b3081ab637ce8d37a8757c11b7e8ae6a62f87eec..bed9f67ddd865e3f797c09e5aec663178e04c693 100644 GIT binary patch delta 14 VcmaFN@t9-7UnWMk&HtEE838e*1?B(% delta 14 VcmaFN@t9-7UnWME&HtEE838ev1>^t# diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/image.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/image.cpython-39.pyc index 75aa798df8688f93ae4747301fe4995c2343c600..46e88e06578f9599e57b51b13592071d5460b096 100644 GIT binary patch delta 14 VcmbO)FkfIp3LB%_=2W&_i~uB!1epK; delta 14 VcmbO)FkfIp3LB%#=2W&_i~uBo1eX8+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/message.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/message.cpython-39.pyc index 6d6ee87b4fd78928dfd0e8c864f6d39d6ae90c87..5a17b2b5a2fce094af02f5a227ee0d612325c87a 100644 GIT binary patch delta 14 VcmdnVy_0)`2n(azW>JJ1xEk? delta 14 VcmZqRZQ$MTlZDY`^DmY*MgS-#1w{Y= diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/nonmultipart.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/email/mime/__pycache__/nonmultipart.cpython-39.pyc index 140da24abc77293447e74a9a89aafea68420b5a6..75a1a938c86a121aa149bd15fd085335b266e4a9 100644 GIT binary patch delta 14 VcmX@lex7}U5fh`^W@Dx~i~uF01YH0C delta 14 VcmX@lex7}U5fh`!W@Dx~i~uE<1X}PyTr3N4X delta 14 WcmX?*bs%fQQVvF!&C57u=>PyTnFbyJ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/__init__.cpython-39.pyc index f7092276b139efe7447ceabcacb355e6aed68a9c..a75f4a9c553cebcbc827f107bdbd56b8e8b6d10c 100644 GIT binary patch delta 11 ScmdnVxRY^$2cz3W&jJ7#0|VXw delta 11 ScmdnVxRY^$2cyeG&jJ7!`vcqn diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/client.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/client.cpython-39.pyc index 94e8496b3cee7cc887cce91f75aa48e0a6e0de6e..7e2ca33917b155be3c296b7725904ee1ce3fbb0d 100644 GIT binary patch delta 16 YcmZ4RfpNhH#tqNJ8QnHN7q?6R07WDRVE_OC delta 16 YcmZ4RfpNhH#tqNJ8C^C%7q?6R07V!FUjP6A diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/cookiejar.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/cookiejar.cpython-39.pyc index 3e98cffbe6da9b1201cdd2f0ea878cbc16a9d507..88c95d331b98e1d210d747714d205717b75c3cc7 100644 GIT binary patch delta 16 Ycmcb=g!%pw<_*!DjBcA_IGIlZ06fVCOaK4? delta 16 Ycmcb=g!%pw<_*!Dj4qpFIGIlZ06e`0N&o-= diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/cookies.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/cookies.cpython-39.pyc index 0c359841c3ac4b09e8bab00925cc35a5e316f29e..3995a985bd6e0abb9465c80f18dd1f421d0a0f5d 100644 GIT binary patch delta 14 VcmX?Af2w|iCm*BRW-q=5LjW=e1)Tr@ delta 14 VcmX?Af2w|iCm*BBW-q=5LjW=S1)Bf> diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/server.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/http/__pycache__/server.cpython-39.pyc index 5802127b6dbf142b637d7e6c14b67398f58cb134..cc41e53dd9f1206467f1401386777fb6d4e59182 100644 GIT binary patch delta 16 XcmbQx%QT^vX@eRkquXY6&dgc>FCPUi delta 16 XcmbQx%QT^vX@eRkqswM>&dgc>FB1hU diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/test/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/test/__pycache__/__init__.cpython-39.pyc index 78c24cbc50c665aab3b753d6f9315f55a75ee076..62b2f2d7318523eed5d2cf329753e110a468334b 100644 GIT binary patch delta 13 UcmX@fe3E%X1S6x{03k~RMgRZ+ delta 13 UcmX@fe3E%X1S6x%03ksHL;wH) diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/test/__pycache__/pystone.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/test/__pycache__/pystone.cpython-39.pyc index 5f7ebc9de0e49202b2cceba226f3c93793640ef2..18dc8670fd568e195ff26803e187505b45f4338a 100644 GIT binary patch delta 14 WcmaE9^3r6(S$0OZ&F9!>3jqK$qy{?x delta 14 WcmaE9^3r6(S$0O3&F9!>3jqK$m^uXd1gkp%@>$gvjG4zdIlc= delta 14 Wcmew@@>^uXd1gkJ%@>$gvjG4zZU!9y diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/urllib/__pycache__/parse.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/urllib/__pycache__/parse.cpython-39.pyc index ee811c81e978f3bad58bb4c9b6d078e07a71cd8c..75b7f63403b5ddd6e87193f394837422d8645114 100644 GIT binary patch delta 16 YcmX^1knz|<#tm{jjBcCdd6uUD06rWBTL1t6 delta 16 YcmX^1knz|<#tm{jj4qqyd6uUD06q`~SpWb4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/urllib/__pycache__/request.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/urllib/__pycache__/request.cpython-39.pyc index 383bbf5d3f1c66e56617f768b339387f3aa75d26..d90e801116f58a0714f71f298207feadde07ae07 100644 GIT binary patch delta 16 YcmeylfaT``mJP*XjBcAt#8`g;06}C1_W%F@ delta 16 YcmeylfaT``mJP*Xj4qo?#8`g;06|y=^#A|> diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/urllib/__pycache__/response.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/urllib/__pycache__/response.cpython-39.pyc index e66794574281ea6d3eda54b216a17423792da3c5..8a826916ef5df0ca76bacff39c963af091728a4f 100644 GIT binary patch delta 14 Vcmca6cTH|XFf*gu<`8Bk9sns21Wo_| delta 14 Vcmca6cTH|XFf*ge<`8Bk9snr>1WW(` diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/urllib/__pycache__/robotparser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/urllib/__pycache__/robotparser.cpython-39.pyc index 26277303e68fecef10e68dab8dc84efb0e78b64d..0f64136f036e19b78bb5e0edde45f7732c6ff3c9 100644 GIT binary patch delta 14 VcmaE_|6YH?VJ1em%}1EDMFBH11+oAD delta 14 VcmaE_|6YH?VJ1eG%}1EDMFBG=1+V}B diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/__init__.cpython-39.pyc index 80bcf4d79c039260a30c5caedf9969a013ed7174..0f5ea5cf598451419acdfe2db13be0f61163bbc2 100644 GIT binary patch delta 11 ScmdnZxSMf;2cz3W&msUAEd%5L delta 11 ScmdnZxSMf;2cyeG&msUAB?ICB diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/client.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/client.cpython-39.pyc index 14d722bcf4abd1b9e0f1e9c08f85e2a2826dc306..af86bf3ee297c7f8e8d4409f0a953197d87044d8 100644 GIT binary patch delta 16 YcmccC&UCGvX~Q)xMz_t^x&BuG06>igp#T5? delta 16 YcmccC&UCGvX~Q)xMwiXkx&BuG06>8Up8x;= diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/server.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/backports/xmlrpc/__pycache__/server.cpython-39.pyc index ae3f3030206a6edf105590c1925ed0b43fa9d1fc..aa637fd68a8c02a666910feef6cba6e189f4d9cf 100644 GIT binary patch delta 16 Ycmdn{l5y`##tn-F8QnH75tK{@07J?K-T(jq delta 16 Ycmdn{l5y`##tn-F8C^Cn5tK{@07Je8+yDRo diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/__init__.cpython-39.pyc index 4928d69f22b4d6852685cccd4ff68d882dc9e727..db70b4a38fd4df40e3a992e3af1fb88dabdc50a0 100644 GIT binary patch delta 13 Ucmcc5d7pDb01Knr delta 14 Vcmew_{$G4U3@4+@=2*@}OaLx(1w;S< diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/new_min_max.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/new_min_max.cpython-39.pyc index 908a02b84996d8be839ca45785ba28428c4eeb6a..34986d23d093a5b570f60e6fc22dc6434826bdd9 100644 GIT binary patch delta 14 VcmdnMvw>%W7$c+GW^qPIRsbM;18@KU delta 14 VcmdnMvw>%W7$c+0W^qPIRsbMy18x8S diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/newnext.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/newnext.cpython-39.pyc index cf62aff48f4650aa9fdfc15e3234abdd7177f1ec..a46f92550485fc0d60699b20754ea2cfc00585c4 100644 GIT binary patch delta 13 Ucmeyy|BZhG6FZ~ZWM=ly03(tFn*aa+ delta 13 Ucmeyy|BZhG6FZ~JWM=ly03(P5nE(I) diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/newround.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/newround.cpython-39.pyc index 6a461ffc02fae367db7edf57a7e6c7089950e729..0f2df8dc73b7739fe05f83eeeb49016926fb2781 100644 GIT binary patch delta 14 VcmZn_YZcqjz{2RZxsj!X4FDr(1atrZ delta 14 VcmZn_YZcqjz{2RVxsj!X4FDrt1abfX diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/newsuper.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/builtins/__pycache__/newsuper.cpython-39.pyc index 5f886b45df97a3884aa9f887fdc81816e142a9a0..2ee1c97042f430145e854bf335250df4fb62823d 100644 GIT binary patch delta 14 VcmZ23wp?rjGbf|lW)@CmCIBDw17iRH delta 14 VcmZ23wp?rjGbf|VW)@CmCIBDk17QFF diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/__init__.cpython-39.pyc index ca1f26e5dc949e391a8a7cda7d5d9fc5e773e578..a3561eff113dba567ee82e1c79b8ff38c7cd154b 100644 GIT binary patch delta 13 Ucmeyz^p9x+4jjVi diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/_markupbase.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/_markupbase.cpython-39.pyc index c940dd31738ed263dedc708f6cb1ca779e3d0772..13df3eca67da3ec91c7ee08f9a4aadd668c56a7d 100644 GIT binary patch delta 11 ScmaFJ^pI)78%DQ@Z%Y6mSp|Fm delta 11 ScmaFJ^pI)78%CFjZ%Y6mQ3ZMc diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/_thread.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/_thread.cpython-39.pyc index de10243de962f1b29dbd6ca7c3b217df9f72ef78..f1250dd2277c08b3ee715bd7d6f6b570a4ea00c7 100644 GIT binary patch delta 11 Scmcc0bd_ns6Gpd*PYVDaB?V9b delta 11 Scmcc0bd_ns6GoSbPYVDa9R*GR diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/builtins.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/builtins.cpython-39.pyc index f2bb7faad8929ecfe25952a680c773d155915bb2..24347bc419f9a0e287cc2a3cc256c677ebcd1f2e 100644 GIT binary patch delta 13 Ucmey)^qpw~Gb5whWERF^03qQ6`2YX_ delta 13 Ucmey)^qpw~Gb5wRWERF^03p`{_W%F@ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/collections.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/collections.cpython-39.pyc index 113a642187ed4a66fa7002ef4e49a82faa05ad36..01deb537b014bdaa15a3338187e360ce08c754ca 100644 GIT binary patch delta 13 Ucmeyy@{MJ~XGTW1$zK?o04!7m>Hq)$ delta 13 Ucmeyy@{MJ~XGTVs$zK?o04z!c=l}o! diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/configparser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/configparser.cpython-39.pyc index fd46f2992dc973d145bcca8e3fa20f91f154f67a..655c6b2811165161a313058f35d7e46d490fe1c4 100644 GIT binary patch delta 11 ScmX@jbed_xbw;;|H;Mrr_yr{Z delta 11 ScmX@jbed_xbw-zoH;Mrr@C73P diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/copyreg.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/copyreg.cpython-39.pyc index 571cd4e7854dbdaf018b44216170e16a88d88b5a..45a93f413a5f07bf2fc3c9d4a8d3fd7ebc702a50 100644 GIT binary patch delta 13 UcmeBY?q}X0!^r41S(dQ~02xUGTmS$7 delta 13 UcmeBY?q}X0!^r3|S(dQ~02x06S^xk5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/itertools.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/itertools.cpython-39.pyc index 799d8b23d69a123b30466680f092b20c089032c9..ea55f54fc09610644ec4f7afb149f8bf0107da0d 100644 GIT binary patch delta 11 ScmaFC^nz)^XGXV)UrGQW9R-*G delta 11 ScmaFC^nz)^XGWKaUrGQW6$O?6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/pickle.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/pickle.cpython-39.pyc index 407418d683eca095a0a870ecbaa949cd32085b28..460719b69e4b8dd27607f8b6eb846c5b50956dd5 100644 GIT binary patch delta 13 UcmZo?ZfD*g$jIn6S%|R|02mVkIRF3v delta 13 UcmZo?ZfD*g$jIn2S%|R|02m1aHvj+t diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/queue.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/queue.cpython-39.pyc index da96b354c3fd10dc8dde4f0d2925c9cd63299748..252e27e507b49323b2aaee7217c3a1cb71ab9f35 100644 GIT binary patch delta 11 Scmcb>bb)EYLq@lWkMaN>rv*L$ delta 11 Scmcb>bb)EYLq?a0kMaN>p9MSs diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/reprlib.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/__pycache__/reprlib.cpython-39.pyc index 0067877b87a6fa1f9c5c209525259f4734147350..594e82e3f17dd80c333dcfb419e337a2a95a0264 100644 GIT binary patch delta 11 Scmcc2beUk delta 13 Ucmcb`e2aNQ5+kF_n+a diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/dbm/__pycache__/dumb.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/dbm/__pycache__/dumb.cpython-39.pyc index 7c92a6c60171d7fca5356678db3ca34746b61998..c76308b111da80c3bf44db954e1e0a1915063b71 100644 GIT binary patch delta 11 Scmcb?bc1QaGe)<{9 delta 13 Ucmeyv^oMB!3nQb;WLCy<03u!l2LJ#7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/http/__pycache__/server.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/http/__pycache__/server.cpython-39.pyc index abd06b422c494fe60c277861a86942c8220346de..63e6e3ca97a1f6951e29fc1a3ddbb48d92b64a08 100644 GIT binary patch delta 13 UcmdnVvXf=QCPqfL$(tG503+1|@&Et; delta 13 UcmdnVvXf=QCPqe=$(tG503*u;@Bjb+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/test/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/test/__pycache__/__init__.cpython-39.pyc index 1269690430428ab4688250081e5f2b22156845d2..19e9916fc3da223c8878e95c8ce0c3303c720b5a 100644 GIT binary patch delta 11 ScmZ3_w4Q0g9!9r`dy4=X?*z60 delta 11 ScmZ3_w4Q0g9!8gmdy4=X=LEC> diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/test/__pycache__/support.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/test/__pycache__/support.cpython-39.pyc index 05f833d9ac183ab9610ae3eb3e99daaf1d9553df..229c536a62ead971038b1af7da62c25c2e97cc5d 100644 GIT binary patch delta 13 UcmX@le4cqjC?liWqQvd(} diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/tkinter/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/tkinter/__pycache__/__init__.cpython-39.pyc index 80ee1baeba29c1d64f05d24a520bbccf89cf9a85..8625947618c399265c712a8a1314fd32cb6041ff 100644 GIT binary patch delta 13 UcmX@idYE;CJ`QAQA(^b delta 13 UcmX@ie3*HICnKZFWG}`_03a0vBLDyZ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/tkinter/__pycache__/messagebox.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/tkinter/__pycache__/messagebox.cpython-39.pyc index 99116bd338d4301ca46a2970becf626bb36135bf..b5617bb5774d3271e65cc1ff32bdcb9d3ecc3ee5 100644 GIT binary patch delta 13 Ucmcc3e4BYgG$W(iP+G$uy3$P+G$uxu$^C+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/moves/xmlrpc/__pycache__/server.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/moves/xmlrpc/__pycache__/server.cpython-39.pyc index 1b60eac5e4b7e39fcd892e5d64812f0771b4c20a..b35876a1c7960f861ff3e865eacbb30a8e7980f4 100644 GIT binary patch delta 11 ScmX@bbc$)hRYtdo*Gd2#)de5` delta 11 ScmX@bbc$)hRYsSI*Gd2#%>^C+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/standard_library/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/standard_library/__pycache__/__init__.cpython-39.pyc index 04a9fec8e34b04c084eb699ac8abb2fc9c6a8185..fa2f112e0361219c7be2bf6f1424670f0218c21c 100644 GIT binary patch delta 16 XcmaFe&-l8ZaYG?Lqub^p{z?k~J$D9E delta 16 XcmaFe&-l8ZaYG?Lqs!(Z{z?k~J!=M0 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/tests/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/tests/__pycache__/__init__.cpython-39.pyc index b3131aed1c3deb74582094a93c0efd96d68ed56d..5c4a2e84a8eebd246fb999bfe4a47cf7c930aae6 100644 GIT binary patch delta 11 ScmdnMxPftk2cz3W&vXD6MgzkD delta 11 ScmdnMxPftk2cyeG&vXD6J_Er3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/tests/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/tests/__pycache__/base.cpython-39.pyc index a1ed181815f0ae17b4b6341ad61fe344a7c79f29..d1fb12b6d5c711befacbbbaaf84ef38f61a88e02 100644 GIT binary patch delta 16 XcmZ3{#JHk~al=z4Mz_t+n4IhYIc^3} delta 16 XcmZ3{#JHk~al=z4MwiXcn4IhYIbsG* diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/__init__.cpython-39.pyc index 8ca04c84815e8acb3231d5b74928500657fe0a63..48ccca3c114d6c04ac14b46e586ebab8f650ff23 100644 GIT binary patch delta 14 VcmeyO_eF2R4}M0s%|H38*#S3h27mwn delta 14 VcmeyO_eF2R4}M0M%|H38*#S3V27Ukl diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newbytes.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newbytes.cpython-39.pyc index 9b60cd348d463ec0f79afe23ea3fb0712f21122d..00956f08915de0204889631b99a9ff6db3268d20 100644 GIT binary patch delta 14 VcmZoHXe`+9j)~E2^Lr*CQvfhK1+@SG delta 14 VcmZoHXe`+9j)~D_^Lr*CQvfh81+xGE diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newdict.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newdict.cpython-39.pyc index 5c500155ae2f858d3ea8728d45293af9bb748cf7..3dc1cd35ecdbbd7d13794cf4f5596843fd26e43a 100644 GIT binary patch delta 14 VcmbOwGfQSeGc%*x<`(8@TmU9s1jGOU delta 14 VcmbOwGfQSeGc%*h<`(8@TmU9g1i}CS diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newint.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newint.cpython-39.pyc index c302148ca53c0573841420dd1542459885915425..37cdd24bff748fe79c02f40acc31b18a8fe51a2a 100644 GIT binary patch delta 14 VcmbQ5G&O0%VJ1em%}1C5^#CtB1)~4} delta 14 VcmbQ5G&O0%VJ1eG%}1C5^#Cs~1)%@{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newlist.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newlist.cpython-39.pyc index d7f9b4b0f70d2c5a3acac2d07b18eb578d914579..01d9134e37f249be4e3f5d61d3f889ebc6e3527c 100644 GIT binary patch delta 14 VcmbOvF-c;>E+$5|&AXYxIRPhc1lRxo delta 14 VcmbOvF-c;>E+$5o&AXYxIRPhQ1l9lm diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newmemoryview.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newmemoryview.cpython-39.pyc index 111810781ec5d9a33aeeaef05cb5285137a53df9..744cafe5b56580253fbed09f59cf74d5e3d2f90a 100644 GIT binary patch delta 14 VcmaFN{+NA(F%zTPW)r6Mi~uLz1eyQ< delta 14 VcmaFN{+NA(F%zT9W)r6Mi~uLn1egE- diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newobject.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newobject.cpython-39.pyc index 281629258051ec87c7b88a77dfd8b4516c8794a5..711b204657af169f33ca7ee6ca36738b50b4b7bb 100644 GIT binary patch delta 14 VcmaDR@=Rm{KO3XlW&yS^762y=1S9|e delta 14 VcmaDR@=Rm{KO3XVW&yS^762y!1R?+c diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newopen.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newopen.cpython-39.pyc index a13f5a9845ea4cbf8a0653682215bc89a6b4bd5f..01ee94b0d10cc15764efeba3b795c7c2f4872a46 100644 GIT binary patch delta 14 Vcmdnbv!7=}5)-4_=47Tj%m62C1nB?( delta 14 Vcmdnbv!7=}5)-4#=47Tj%m6201m^$% diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newrange.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newrange.cpython-39.pyc index bfbfd2b7731e4885018c9f55d114fd2bfd35c69e..88e687d4e2aa0576c798b235f053aa2b21702ea3 100644 GIT binary patch delta 14 WcmaE_|6YH?CpJd6&7ax+2mk;#UIyd< delta 14 WcmaE_|6YH?CpJcx&7ax+2mk;#QU>Ax diff --git a/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newstr.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/future/types/__pycache__/newstr.cpython-39.pyc index d745dc7f3de0bb76f05a8bd1ac4153a0364085e7..69abfb5807449a496e83fc10238d560361064afa 100644 GIT binary patch delta 14 Vcmcapc&BiKC_AIuW-<0-h5#@p1$6)b delta 14 Vcmcapc&BiKC_AIeW-<0-h5#@d1#8RRDF?2xR~O diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_compat.cpython-39.pyc index 6f05de6c53c9867a53a5a4a4dc832ae13a297ce4..1ab3bacb2f259ccd74137aec9949bb6ef5374ef8 100644 GIT binary patch delta 27 hcmdn3xm%Mvk(ZZ?0SGjVyf$)su`;@C4r5K_2LM#21xpYgb8&@l4a$i0u1(QWf7)_xpYgb8aJ%fVk$WF2qs!(~tp7X#gIx(n diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_fileobjectcommon.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_fileobjectcommon.cpython-39.pyc index 2ce17127f8f5d52b2e1ac58697d91a2cf018952e..a18dd765b98e5af0afa115d16e8db19b49c3627f 100644 GIT binary patch delta 29 jcmZpi!q_;4kvox>mx}=iG>p79a+@$Sx@~q~KIjGjVDko; delta 29 jcmZpi!q_;4kvox>mx}=i+%7w8vc3zA-k(ZZ?0SGjVyf$*zF)_Mr?qWL10RUJ$295v# delta 27 hcmX>vc3zA-k(ZZ?0SMeKJ8a~xV`6mK+{JX10{~%(2SES; diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_hub_local.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_hub_local.cpython-39.pyc index 862048c180a17a15858145f5c1aa954107d60e2e..93284850e375f24408a8ff0bc020ad5ea262be5a 100644 GIT binary patch delta 27 hcmew<`csrUk(ZZ?0SGjVyf$)sFfqDq4q;l#0RUZ;22=n5 delta 27 hcmew<`csrUk(ZZ?0SMeKJ8b0kU}ALH9Ky7e0{~{>2L}KE diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_hub_primitives.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_hub_primitives.cpython-39.pyc index 0c12103636f281eb92271b38194a45f5186decf1..3c65b481fa290d42ce6290eaca04650a5defd69f 100644 GIT binary patch delta 27 hcmeB+>x<(~x<(~FF*n=#+e1^`}l2HyYx diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_ident.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_ident.cpython-39.pyc index 0c4b7ec7d4bf780c0304ea29b42419ac52122fcd..e8091c5f69b0496ccba2a1ad7be395b67ea3e4f8 100644 GIT binary patch delta 27 hcmdlluwQ^Xk(ZZ?0SGjVyf$+GU}SXL%)(^N1^`s#1<3#a delta 27 hcmdlluwQ^Xk(ZZ?0SMeKJ8b0s!N};cnT5%k4FFy-27CYj diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_imap.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_imap.cpython-39.pyc index b5a274f0420133b1869b5e28ee5d67b4d71d183c..42b104adbda9d7df1ad7a77183b5161192ca0304 100644 GIT binary patch delta 27 hcmaE9@X~-gk(ZZ?0SGjVyf$)&FfqDqPGI5`0{~wP1@r&_ delta 27 hcmaE9@X~-gk(ZZ?0SMeKJ8a|*VPbUIoWR5>1^{ST2B!c3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_interfaces.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_interfaces.cpython-39.pyc index 4378ef9f744dc4e72d0814c70e575f6c421adb4b..0277cf7c773b337aa5c19ed57732b4f0988f8041 100644 GIT binary patch delta 27 hcmeB(?uh12@Cz2O9tY delta 27 hcmeB(?uh12FF*moN*-003B01~>o! diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_patcher.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_patcher.cpython-39.pyc index 36fc4508f9cfa60cff721275411df641924f7cb1..11345241c557895733a816af00df6765185453c7 100644 GIT binary patch delta 27 hcmbPYF~x#Ak(ZZ?0SGjVyf$+0XJK^Pe452m8~{~b26X@c delta 27 hcmbPYF~x#Ak(ZZ?0SMeKJ8b0M&%)@k`812CH~?O&2Pgml diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_semaphore.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_semaphore.cpython-39.pyc index b53144e1b1838bbd8e056e8110aacc3dc2e07c60..e480f93adf380cf8fc5d77b0d21e95bdb2bf05fb 100644 GIT binary patch delta 27 hcmeyL`ahLBk(ZZ?0SGjVyf$(hF)_MrwqrVI003>S2N(bV delta 27 hcmeyL`ahLBk(ZZ?0SMeKJ8a}OVq$dJY{zua004IT2g?8e diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_socket2.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_socket2.cpython-39.pyc index c3d4be507da6c33ef31a06be6c00355dc0b142b8..3114cb3f5963ed4ca4f6a2c7824d69cbf55bc50c 100644 GIT binary patch delta 27 hcmaE1_ri`lk(ZZ?0SGjVyf$+GXJT~Q%*`At0{~|92EPCR delta 27 hcmaE1_ri`lk(ZZ?0SMeKJ8b0s&&24mnVUIQ1^{qD2XX)a diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_socket3.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_socket3.cpython-39.pyc index f517a2f6cbb01623defe79a89074ff028fa2ea30..41d81725b687a7601ee8f96c3bfc849b13c776df 100644 GIT binary patch delta 44 xcmZpxZ>#4{#4{mx}=iG>p79a;tJOx@|V()U*TuZv+N& delta 29 jcmccB!g#BNkvox>mx}=i+%7w8b8&@l4a$gRM}=(bshE!7hMWfBHc delta 29 jcmbO@pK;=RM(#vjUM>b8aJ%fVkz0X{(Pgs^TdF4jZeIrm diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_sslgte279.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_sslgte279.cpython-39.pyc index 626423f3369b464b41aeaf9683efef7bec43c1aa..e9ce0c4e3e6ceecd3c673803ea48bb62ce4d7a01 100644 GIT binary patch delta 29 jcmeB}#Mm*3kvox>mx}=iG>p79a(`!Gblc3#%IX3DW`zcA delta 29 jcmeB}#Mm*3kvox>mx}=i+%7w8@cU2N(bV delta 27 hcmX@Ux2Soq? diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_util_py2.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/_util_py2.cpython-39.pyc index f30756587d09528b7e2732ace850e46487829c8a..f022ba6632ad9386a3f4d959600d672271c9deb0 100644 GIT binary patch delta 27 gcmZo=ZDr+7bpQYW diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/backdoor.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/backdoor.cpython-39.pyc index b58ba6714d2c7f46a666df8c9318740844566502..60551ee75aa0d61d11970f918e5ac6468137f9d1 100644 GIT binary patch delta 27 hcmbPWJHeJak(ZZ?0SGjVyf$)QXJK^P{Fr5}Bmh^62MquK delta 27 hcmbPWJHeJak(ZZ?0SMeKJ8a~>&cf)j`7z5{NdREi2fzRT diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/baseserver.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/baseserver.cpython-39.pyc index 41e9a6244d97a022b6851c802ee471d1df71a7f9..93ecba43131e942724fc854a4c8923b2e4270ffb 100644 GIT binary patch delta 27 hcmbQ7HaU$uk(ZZ?0SGjVyf$)kFfqDq7Ge5t0034>1}p#o delta 27 hcmbQ7HaU$uk(ZZ?0SMeKJ8b0UU}ALHEW-5P003W?2HyYx diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/builtins.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/builtins.cpython-39.pyc index 80523ad2378bfdc2b392b22c11d04a3ca7f1dbce..0bd99a0d208326ee5bacaf70b5b64c0dae145544 100644 GIT binary patch delta 27 hcmdlcx=oZjk(ZZ?0SGjVyf$*zF)_Mr?qbs6002?M1;GFS delta 27 hcmdlcx=oZjk(ZZ?0SMeKJ8a~xV`6mK+{L8B0RUSO26O-b diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/contextvars.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/contextvars.cpython-39.pyc index 36f0814fabc78ef4afaa159eafb7f030d3e0a90c..5e24f4297d4f614118a177cdd7dc8382ccbaec21 100644 GIT binary patch delta 27 hcmbQ^GslNJk(ZZ?0SGjVyf$)+b27SZR_6RE0{~O{1{?qY delta 27 hcmbQ^GslNJk(ZZ?0SMeKJ8a|@=VWx*tjzgS1^``02G0Nh diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/core.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/core.cpython-39.pyc index af6ec0facd907f0ab63bdcf023b343c3769edda0..7f45a5cb59c405d8170b5344ec6e6bbfb34dd392 100644 GIT binary patch delta 26 gcmdnUvXO;5k(ZZ?0SGjVyf$+0Vq|oie2g(007@eUA^-pY delta 26 gcmdnUvXO;5k(ZZ?0SMeKJ8b0M#mML~`50q108+gM)c^nh diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/event.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/event.cpython-39.pyc index 611c9b81fef317ad8d98eb9026d887cdff808513..0f7fda6a1920bb6ac178c9d92832bdb88d700c56 100644 GIT binary patch delta 27 hcmbPUKE0efk(ZZ?0SGjVyf$)wV`OyO%)~U+5&&VZ2G9Ti delta 27 hcmbPUKE0efk(ZZ?0SMeKJ8b0s#>nWhnTcttB>-yt2ZI0r diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/events.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/events.cpython-39.pyc index 5fbaf1df70912d41bb0d7525554cbdd984dcc893..a931ebc52adc60f6b20a3c5dc05526c749fbee13 100644 GIT binary patch delta 27 hcmX?Je!QGJk(ZZ?0SGjVyf$**;be5%{DSkoApmav2u%P0 delta 27 hcmX?Je!QGJk(ZZ?0SMeKJ8a~>!^!Bf`32{FLjZV72><{9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/exceptions.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/exceptions.cpython-39.pyc index e7dae5c3f0aae367d29f9033db624c78b644d6a4..d434c8ca68a8b6af4beedc67215a5f174aa4ca1c 100644 GIT binary patch delta 27 hcmX@Ca#)2sk(ZZ?0SGjVyf$**WnpyN{E{V#7XVzK2JQd= delta 27 hcmX@Ca#)2sk(ZZ?0SMeKJ8a~>%fjfg`6WvfF92oj2cZA} diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/fileobject.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/fileobject.cpython-39.pyc index 5ab1609c94a65f70ce9cd26a62bc62e79c77d3a5..c1a3030dbb4849709024790479815df3259d1f9f 100644 GIT binary patch delta 26 gcmX>ic0`Ojk(ZZ?0SGjVyf$+0ic0`Ojk(ZZ?0SMeKJ8b0M%f;w2`6O3009sWCM*si- diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/greenlet.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/greenlet.cpython-39.pyc index dc744cd76d9fed7ff26b697be7bd98a573118151..fcc7c26c0f762c8eea8ee0a890c6087412d2279b 100644 GIT binary patch delta 29 jcmdnf%(SPOi93;(mx}=iG>p79a(`fEbld!g`9LiIbPoue delta 29 jcmdnf%(SPOi93;(mx}=i+%7w8|S=(70_^MP6beOw7o diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/hub.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/hub.cpython-39.pyc index 83a2547e620f8d54356ce92a113bd65d1f8cec10..342e9f26a94dd081cbb2b7f1afe40d56d5b5c29c 100644 GIT binary patch delta 29 jcmX@VneqH)M(#vjUM>b8&@l4a$X(0L=(f3&+szLEdp`%E delta 29 jcmX@VneqH)M(#vjUM>b8aJ%fVk-L_g(PeWdx0@dTgp3GO diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/local.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/local.cpython-39.pyc index 3431f45e33a95ccb28562c00ee957f3c0bc717fc..b49480907f5de85bab86bdcbf3606250e450aafa 100644 GIT binary patch delta 264 zcmdmyx+9f4k(ZZ?0SGjVyf$*r5Mp%OyhKP@VDb|smC4%5GS;`a<8$(p6LaEADhpC? zamL3dXXa&=#K+$fKoXBHODrnBC5xHvw3a<%dbwg8|_MLwG~ zRpc2}{6K6^5a9(P{6T~_khsNMoLX{=IVH2G$aiv%syn04<}Iqf7)3#HMZ6%w7eqj` vZ$7O4nUNbwYV$!&TSh6cJqmEOU<;f;T<^^i+D{mPM*h_aX9iNC2FXkSJatP4 delta 250 zcmdmyx+9f4k(ZZ?0SMeKJ8a~hA;jpid5Ms+z+@w3naRhLRFyd6f~2SvXlLkl?4Tm1mnvRi;5>#E3aVl0h(Rpy;)O5o>9dU z#P$LaejvghMEC-UTg=6&CAXMUGK-1=Cg-TSGkR~{qWX(b6eL%~3nBtQ1VsDh!|Ib8&@l4a$Zaad=(gEWtgjdVa##me delta 29 jcmX>b8aJ%fVk=s;^(PguvSYI&!d!+~o diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/os.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/os.cpython-39.pyc index 31981d6070b839dcd30d0cda7361ba1b94affd69..5759a12c0069cc69a727d0e150a3628b6daf88f7 100644 GIT binary patch delta 27 gcmZq7ZOr9Pb8&@l4a$SuLn=(bsfohuvwa7hMi delta 29 jcmZ3thjHB=M(#vjUM>b8aJ%fVkz0bD(Pgs=J6AXWd6ows diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/pywsgi.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/pywsgi.cpython-39.pyc index c03230dd0a71610609faa4c92200714ac6aef8ed..b0aa6b6ca30b136504554d92b578f8eccbe6a246 100644 GIT binary patch delta 29 jcmdnJg=zN|ChkODUM>b8&@l4a$UT9b(QWe__W6?lc^n8h delta 29 kcmdnJg=zN|ChkODUM>b8aJ%fVk$VC=qs!(w?DHo90D@@<>i_@% diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/queue.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/queue.cpython-39.pyc index 19c3b8b70d8f7fe205c73b03c8fc457a6db47920..c6f6bd7a11e1ad03621a86a07670dbff81e5c2a8 100644 GIT binary patch delta 29 jcmdnDlyTouM(#vjUM>b8&@l4a$lb}t=(c$(o2Cx{blV3~ delta 29 jcmdnDlyTouM(#vjUM>b8aJ%fVk-L+P(Pi^gHccM@ekce9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/resolver_ares.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/resolver_ares.cpython-39.pyc index f60030c867282a8773e517ee1eb4b939b2701b04..1864d8f3749c2e7b9ae530cdbdb4c3bc67a95c2b 100644 GIT binary patch delta 26 gcmcc1a+ifWk(ZZ?0SGjVyf$)QWn^@l{E)E*08{k_!2kdN delta 26 gcmcc1a+ifWk(ZZ?0SMeKJ8a~>%E;(4`5|Ks09=m;bN~PV diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/resolver_thread.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/resolver_thread.cpython-39.pyc index 59325cd57683157baa3ccd6ca300aec04b1766a1..96e787a60c42b4337625d073ce31133492e0106f 100644 GIT binary patch delta 26 gcmaFM@|J}=k(ZZ?0SGjVyf$(_W@L1m{GPE609UaF{{R30 delta 26 gcmaFM@|J}=k(ZZ?0SMeKJ8a~B%*g06`8{JD0ANc8vH$=8 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/select.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/select.cpython-39.pyc index d18891bd00dc54acbe2d18304e70d828663f6ff7..383deadd129660c6eb6d0bd883835f2ebb1c8531 100644 GIT binary patch delta 27 hcmexp{n45`k(ZZ?0SGjVyf$*5Wny&Oe3MB+8USe;2Ot0d delta 27 hcmexp{n45`k(ZZ?0SMeKJ8a}W%f#ri`6iQuGyrmE2h#um diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/selectors.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/selectors.cpython-39.pyc index ce13585ee3888d2788eea682ddfb565e38009933..956961e464505152448fd6beed7edb835e97b492 100644 GIT binary patch delta 27 hcmeyY{aKqkk(ZZ?0SGjVyf$*XvNO7E4rE`%2LNEW273Si delta 27 hcmeyY{aKqkk(ZZ?0SMeKJ8a~3WoLBR9LT@D71`YrK delta 27 hcmaDY|5~0qk(ZZ?0SMeKJ8b0UXJd5PEX{U-698kI2EhOT diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/socket.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/socket.cpython-39.pyc index bd4a5eba9dfaf90623e837395b432897abdee66f..52817fb77285a4bb13bd3ae3ab5f791ba0684765 100644 GIT binary patch delta 27 hcmeB_?3CnAJzR-(z0Q0RT?52ABW< delta 27 hcmeB_?3CnAb8&@l4a$lc4&=(c$#ztAiIdo~B# delta 29 jcmZ2|nQ8T9ChkODUM>b8aJ%fVk-L|l(Pi^YexX?ago6l< diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/thread.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/thread.cpython-39.pyc index f21a45fe7e55fc7007b5650f2b9ed3bad8182126..077beb0e14dca5c97d353771aac9714f467b4d10 100644 GIT binary patch delta 27 hcmaDQ@k)X_k(ZZ?0SGjVyf$(_WnpyN{E?-S9ROm~2TcF~ delta 27 hcmaDQ@k)X_k(ZZ?0SMeKJ8a~B%EIWf`6EjuI{<7U2mk;8 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/threading.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/threading.cpython-39.pyc index 313ab6abf62720117ef76a4665d6467704823167..061c7c2f29a728b97b7e4b6c31c68dd5a84dae1e 100644 GIT binary patch delta 27 hcmbQMGgpT@k(ZZ?0SGjVyf$(_WMg#O{Fcpt9{^Tx29^K- delta 27 hcmbQMGgpT@k(ZZ?0SMeKJ8a~B$j0ch`7N6PKLB672T1?` diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/threadpool.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/threadpool.cpython-39.pyc index d4d8cd2f152495be8c774c72525a2b48c421e2d5..9818f7ab247cf61daf4bbd537b20a7b7ad0bb41f 100644 GIT binary patch delta 29 jcmeynh4JqeM(#vjUM>b8&@l4a$j!sT=(bscB{d8Hf073_ delta 29 jcmeynh4JqeM(#vjUM>b8aJ%fVk(-Bw(Pgs)OKKPZh~Ee4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/time.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/time.cpython-39.pyc index 7e329ef1714b8440a8e1688b4234adf960d8aebb..2c3853cdbf5c6543eb31daa8e45aa541f0a69387 100644 GIT binary patch delta 26 gcmdnWvXzB9k(ZZ?0SGjVyf$)gV`Oxje2B3a07}OODgXcg delta 26 gcmdnWvXzB9k(ZZ?0SMeKJ8b0M#>nV0`4D3<08?QG-2eap diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/timeout.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/timeout.cpython-39.pyc index 351aa55fa0a1819726ffa2ef3296563310bf25e5..23b50a513570430f9cfb17ae3c7a016226be9f04 100644 GIT binary patch delta 27 hcmcZ?elMImk(ZZ?0SGjVyf$**V`g;Q{EGRDIsk2A2tEJ+ delta 27 hcmcZ?elMImk(ZZ?0SMeKJ8a~>$IR%m`4#gQbpUp+2=M>_ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/util.cpython-39.pyc index 3ac57d714a1acb847078c94f9cc250a414a2819a..ad866085a025ddc2bc8dae8bf7b18519d1d616f5 100644 GIT binary patch delta 29 jcmdlxgK_T+M(#vjUM>b8&@l4a$X&(6=(f3yX}c!?avcYo delta 29 jcmdlxgK_T+M(#vjUM>b8aJ%fVk-LhC(PeWR({@h)duj+y diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/win32util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/__pycache__/win32util.cpython-39.pyc index 8da9410aec37081ff5a98e45ec111dee6c32507d..6e7d72e9c5fcf2c01d9562d64bbb59109799de76 100644 GIT binary patch delta 27 hcmew=@>PU8k(ZZ?0SGjVyf$)kvM{=B7G+6b0{~d*1&IIv delta 27 hcmew=@>PU8k(ZZ?0SMeKJ8b0UWMOpKEXtC=1^{9<20Q=& diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/_ffi/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/_ffi/__pycache__/__init__.cpython-39.pyc index 0ac33a09861d15a835d26afd557eb581ba34a639..dcdca1a38cfaff9c8a5369256d10c21ec33e0eca 100644 GIT binary patch delta 27 hcmZ3;wvdfGk(ZZ?0SGjVyf$)cFfzJrHer0r2mnW<1%&_r delta 27 hcmZ3;wvdfGk(ZZ?0SMeKJ8b0EU}SXJY{K}K5dcu}1~>o! diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/_ffi/__pycache__/callback.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/_ffi/__pycache__/callback.cpython-39.pyc index bb46d666a5f1cbadce0291e73e8bc1614a0301ff..0584a4883504567a97382d5394995ebc084a8ccb 100644 GIT binary patch delta 27 hcmcc5bDxJhk(ZZ?0SGjVyf$)AWn^^QypVAp3jkV{2D<*mGSIUM(#vjUM>b8&@l4a$bE{5(QWfJrtj_md3*?y delta 29 jcmX>*mGSIUM(#vjUM>b8aJ%fVk^2-Aqs!)NOyAuBg2@R+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/_ffi/__pycache__/watcher.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/_ffi/__pycache__/watcher.cpython-39.pyc index 927819eca967f33102a715c0456f69f2c6ce8f61..8787af18cd2a1b0d5fc1ec26d68a69fe95aeae72 100644 GIT binary patch delta 29 jcmX>$o$=UoM(#vjUM>b8&@l4a$Q{AV=(ah9ImrV6aeW69 delta 29 jcmX>$o$=UoM(#vjUM>b8aJ%fVkvoE!(PeWAbCL%DdddgJ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/libev/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/libev/__pycache__/__init__.cpython-39.pyc index dac44e13b861fbe3a156c127ff6216803913e009..97145111e60f97c66804457dbc0eece38ebccca3 100644 GIT binary patch delta 24 ecmdnWw3UfFk(ZZ?0SGjVye4w*VRV~#A{PKZyaosW delta 24 ecmdnWw3UfFk(ZZ?0SMeKJ51!>!{{>cL@oeE?gqO6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/libev/__pycache__/_corecffi_build.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/libev/__pycache__/_corecffi_build.cpython-39.pyc index da1a8784dd26e70583fb2a4e6f79747f6acbbf12..3360698814185c65afd7e2bfb021e9ea70190b30 100644 GIT binary patch delta 27 hcmZ3*zlxtbk(ZZ?0SGjVyf$+GW@2>P%+9=+1prZQ1`7ZH delta 27 hcmZ3*zlxtbk(ZZ?0SMeKJ8b0s&BW-knVoqt3jkWX2EG6Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/libev/__pycache__/corecffi.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/libev/__pycache__/corecffi.cpython-39.pyc index 31f0e3cd3b354b8c896ee499f861467022e79bd8..97e3688ef63c438e437add3df4141890e275c088 100644 GIT binary patch delta 27 hcmZq8YR%$K` diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/libev/__pycache__/watcher.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/libev/__pycache__/watcher.cpython-39.pyc index c6e6ef9fa55a552e152b16c29ad6b5bed4cf3309..a1f8d7319d47f5e63d6361fc128e3bb405e641dc 100644 GIT binary patch delta 27 hcmaFn_RNhtk(ZZ?0SGjVyf$)QW@2>Pe4nXZ0RU<>2cQ4| delta 27 hcmaFn_RNhtk(ZZ?0SMeKJ8a~>%*5!j`94#-0swP@2vYz6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/libuv/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/libuv/__pycache__/__init__.cpython-39.pyc index ff8b6bf3322d771cf83a5c916bf71a233d43c23d..c58c96c89bd51235490fc799bbb31f62d6cbb189 100644 GIT binary patch delta 24 ecmdnWw3UfFk(ZZ?0SGjVye4w*VRV~#A{PKZyaosW delta 24 ecmdnWw3UfFk(ZZ?0SMeKJ51!>!{{>cL@oeE?gqO6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/libuv/__pycache__/_corecffi_build.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/libuv/__pycache__/_corecffi_build.cpython-39.pyc index 43295e69984f8d810a731ea05d6318dcf7bfad14..25581da11b56a045ce0daf2f5cfd3506ce7b03a3 100644 GIT binary patch delta 27 hcmZ3jvs#Bck(ZZ?0SGjVyf$*Hb1=GXHs<)j3jk4i1_%HE delta 27 hcmZ3jvs#Bck(ZZ?0SMeKJ8a}u=U{Z%Y|Qb47XVtv2D<ax8^Ak(ZZ?0SGjVyf$*jF*CYt&SJi!2LNPa2NwVU delta 27 hcmX?>ax8^Ak(ZZ?0SMeKJ8a~RV`g;OoW*=c4*+ej2g(2d diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/libuv/__pycache__/watcher.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/libuv/__pycache__/watcher.cpython-39.pyc index 5567e90c9fa7b8984af81a45817538112fd5ba82..deabbb193b46b0c09bc757bd0478cac03a22983c 100644 GIT binary patch delta 29 jcmew}jq%SkM(#vjUM>b8&@l4a$i0}E(QWg3=Ckeqfrbcu delta 29 jcmew}jq%SkM(#vjUM>b8aJ%fVk$W*Sqs!*?%xB#Jiqi=& diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/__init__.cpython-39.pyc index dbf71368397c4eb853bebb5fa9a11c576126ce67..0b810b419a6fb6db928725dbbde5550d45ca9f9d 100644 GIT binary patch delta 27 hcmX?Ve$<>hk(ZZ?0SGjVyf$)wXJvHT%*=L36aZfK2EPCR delta 27 hcmX?Ve$<>hk(ZZ?0SMeKJ8b0s&dTVrnVId7C;(_f2XX)a diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/_addresses.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/_addresses.cpython-39.pyc index dc06d7ef72ea9ff2ab4f85cb4dd3159df91a45d4..2a3a1ea4c4efa6dc6672494307e9e873e24478f9 100644 GIT binary patch delta 27 hcmZ1@zDArok(ZZ?0SGjVyf$(#VPtgMyn*o#Cje8V2Fw5e delta 27 hcmZ1@zDArok(ZZ?0SMeKJ8a}$!pP{dc?07gP5@l-2Y&zn diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/_hostsfile.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/_hostsfile.cpython-39.pyc index 311ce60dfa011f454779db11c6a14391c200b1e8..c75ec90dd87935363b3ff202d8fc8476991e33f4 100644 GIT binary patch delta 27 hcmdlfwo{Bdk(ZZ?0SGjVyf$**VrF#P{ERu69ROFB2B`o5 delta 27 hcmdlfwo{Bdk(ZZ?0SMeKJ8a~>#mwlk`5ALCI{;wg2V4LE diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/ares.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/ares.cpython-39.pyc index 35b5f576df1092d45824976de0d47e34b29fc55d..eb2cd125591a0826c8b0e4f62da46f3f5b3b7d5f 100644 GIT binary patch delta 27 hcmccQdC8MIk(ZZ?0SGjVyf$)s3NgBE4i%~u0svq~266xZ delta 27 hcmccQdC8MIk(ZZ?0SMeKJ8b0k6k>GQ94b^R1ORE22PFUi diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/blocking.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/resolver/__pycache__/blocking.cpython-39.pyc index f1f03c3e56ffca7544fb7406a5d2c2da372f66b8..758a419e889c7956b5d4114af24809c26604e7e9 100644 GIT binary patch delta 27 hcmeC+>EPi`EPi`k{Kmk{Km0;qd0;qd?@y1>*n! diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/hub.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/hub.cpython-39.pyc index 391dfb8b36eb85289c48834b02317d8d882a43e0..2284607d1d66659483920e25659d96f6bfd30e9b 100644 GIT binary patch delta 27 hcmbQjKZTz=k(ZZ?0SGjVyf$(_VrF#P{Em4UGXPJ%2Cx7C delta 27 hcmbQjKZTz=k(ZZ?0SMeKJ8a~B#LVcj`5p5zW&l|W2V(#L diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/leakcheck.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/leakcheck.cpython-39.pyc index 8435b4d74bfb56512c3b614576d350eacf69f38a..b13c107709fc4cdb2babf564bc60ffca81ac4d7b 100644 GIT binary patch delta 27 hcmeyU`B9TQk(ZZ?0SGjVyf$(RF*CYtmSesw2moD<1~~u# delta 27 hcmeyU`B9TQk(ZZ?0SMeKJ8a|@VrF#NEXRCV5CCS|2J8R; diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/modules.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/modules.cpython-39.pyc index 7733ce2e135ac643f5d8c350469e35b6f9f6df59..d6d2bcb9d266db0cc55b904d1d89125ac06593b3 100644 GIT binary patch delta 160 zcmew({70BOk(ZZ?0SGjVye4x05EV&JElbTS(aXt9N-fhXPb^8!NG+P&z$iAEiBX4D zFR>`KcycbI%w#o2=@2^(puQ-MJcEJ@BtEt(w9D3b^jDTRyJaR5!c#gd#~lp4hu52BLO(lVns;4FT)V0=<( zW=={J3&{8=uK42A+{A(mkUrM<(vr-aTO9H6nR%Hd@$s8qG1js%x@^win8FAETXjLW diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/monkey_test.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/monkey_test.cpython-39.pyc index 1b135cd73a6dfaec83768fbf7a233c82f3d1a7c3..9eb898cff9a7e2e5a5c1060ec5246eacf9da78c5 100644 GIT binary patch delta 27 hcmaDR@JxU^k(ZZ?0SGjVyf$*PurRu97GMcu0RU9K1x)|| delta 27 hcmaDR@JxU^k(ZZ?0SMeKJ8a};VPSOHEWi@R0svkM1^@s6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/openfiles.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/openfiles.cpython-39.pyc index f8dc6a5b0de38e9ef785e0bf16c51b8d101ed85f..8515319c6ca400ab2a8a7c1d4dc1dc8b61d82717 100644 GIT binary patch delta 27 hcmaE*_DYRAk(ZZ?0SGjVyf$)sFfqDq4q*}#1OQyc1=0Wj delta 27 hcmaE*_DYRAk(ZZ?0SMeKJ8b0kU}ALH9Ks|f2modh2893s diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/params.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/params.cpython-39.pyc index b08de84ccae8cdc97306949f14cd061faaf48369..c5e2d6937da9e8463b9de449d834f6322052a2fa 100644 GIT binary patch delta 26 gcmZ3@wwjGQk(ZZ?0SGjVyf$)AVq$cgJdddt07uFN?f?J) delta 26 gcmZ3@wwjGQk(ZZ?0SMeKJ8a~h#Kh<_c^*?Q08nHGp#T5? diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/patched_tests_setup.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/patched_tests_setup.cpython-39.pyc index 3488e5f91e6e178b54a8d44459c667bcd52f22e9..b824bbe7cba08ce13869cc78c38fe26f2c8c6721 100644 GIT binary patch delta 29 jcmZp;!q{+ykvox>mx}=iG>p79a(D7Gx^14ypB)7NaybW< delta 29 jcmZp;!q{+ykvox>mx}=i+%7w8NJe}z_Cje>R2fP3P diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/six.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/six.cpython-39.pyc index 86c94bbbd48b09e3d5267918c05328e680c37575..59e89bc88280357c07f0abf3eac8bdfde39f4798 100644 GIT binary patch delta 27 hcmeC@=;z>00$HeHe`4v+aHvn#?2p<3d diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/sockets.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/sockets.cpython-39.pyc index fe716897818bd7ccafbf50adf7feaff2e24b2e2d..9319b9cbde66dee9a30a16789ecc6b158dda876b 100644 GIT binary patch delta 27 hcmZ3-wT_EBk(ZZ?0SGjVyf$*PFfqDq7GRQN1^`E^1e5>( delta 27 hcmZ3-wT_EBk(ZZ?0SMeKJ8a};VPbUIEWjkk3;?>f22}t6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/sysinfo.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/sysinfo.cpython-39.pyc index 58506d367283b60159e9c5b87beb3887c1a2abad..b2fd681df913cd857d1e840c0f0ad7fe20fae631 100644 GIT binary patch delta 27 gcmZpaZItCs(Ap((Ap(b8&@l4a$X(6C=(f3?#U~U1d&dW) delta 29 jcmcb-nep;wM(#vjUM>b8aJ%fVk-M6O(PeWxi%%#3g%k)^ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/timing.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/timing.cpython-39.pyc index f6d480054de35f122290ab953b38f67abbb380af..c289a187f7f4dd630d74ccf9024ab8353611341b 100644 GIT binary patch delta 27 gcmZpYZ<6Ou69)t1!j!0su|01&aUx diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/travis.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/__pycache__/travis.cpython-39.pyc index 62410569a481f24a0d9c8a6da01c2f1c07270e18..6436a6de7c2db065cf53c7ac507f0cc1a85031fe 100644 GIT binary patch delta 27 hcmcc3d7G0vk(ZZ?0SGjVyf$(NGcvkuj%Tc41^`u21?B(% delta 27 hcmcc3d7G0vk(ZZ?0SMeKJ8a|*W@L2P9M4$83;H2`SI2k-y@ delta 27 hcmZ2nzqp<|k(ZZ?0SMeKJ8a~>%gpGq`6cr%YXEW<2%`W1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/coveragesite/__pycache__/sitecustomize.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/testing/coveragesite/__pycache__/sitecustomize.cpython-39.pyc index f1a3a2952cbade6d05d153625511b74480fc4912..4c5ebeefa4090438bffc88716c3d7775fd3d6743 100644 GIT binary patch delta 26 gcmeys{DGM}k(ZZ?0SGjVyf$(NGBUbNj%Az-08!=z^Z)<= delta 26 gcmeys{DGM}k(ZZ?0SMeKJ8a|*WMp)i9LqQv09t?srvLx| diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/__init__.cpython-39.pyc index 7db021e814f05f43150aa799ba261dcacb8752a6..559d073713b24a30c9c048e7ef204f0b97bd6ff8 100644 GIT binary patch delta 24 ecmdnMxPg&7k(ZZ?0SGjVye4wnGP+IlOa}lutOWP~ delta 24 ecmdnMxPg&7k(ZZ?0SMeKJ51!ZWptV7nGOI!-UX`w diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/__main__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/__main__.cpython-39.pyc index f30f551b61bb8c2e892f86aaeae0548bab9d4b2d..38eb3670238baa69f4abb7f41e4dd6bbe0059164 100644 GIT binary patch delta 24 ecmaFM^p=S`k(ZZ?0SGjVye4vgVRW0smuI diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/_blocks_at_top_level.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/_blocks_at_top_level.cpython-39.pyc index 0e3a17aefb0588840293f78393efe0fa2f461cc3..755c6d6f130bd88824db34309f1f54fdbb265273 100644 GIT binary patch delta 24 dcmZo-YGUF}I|jG_ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/_import_wait.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/_import_wait.cpython-39.pyc index fd9c62f564536071dc8a9263dded97226ce8dfcb..e19f9df8438a52c931646d09d1786dcd19ba24c4 100644 GIT binary patch delta 25 fcmcc4dYzR!k(ZZ?0SGjVye4wrV|3g2>MbJxPlE?H delta 25 fcmcc4dYzR!k(ZZ?0SMeKJ51!h$LO;0)mugYS7-<7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/_imports_at_top_level.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/_imports_at_top_level.cpython-39.pyc index 701d3f2df5bf58243cd0e613698f6ebeade7fc9e..5d74866db2363694f3dd283e1160890eeb60517f 100644 GIT binary patch delta 24 ecmcc0c$JYmk(ZZ?0SGjVye4voGP+GnECB#Q9|eB^ delta 24 ecmcc0c$JYmk(ZZ?0SMeKJ51ybWptUCSONe^Q3f&q diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/_imports_imports_at_top_level.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/_imports_imports_at_top_level.cpython-39.pyc index a6fb91a6fe7ced54e319fa9d1335ecc2d2ba7ce2..9ce39a52aba660392cfd261befea1698a54439f1 100644 GIT binary patch delta 24 ecmZo+Zeiw5_N_N^_8~}Kt2xb5P diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/lock_tests.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/lock_tests.cpython-39.pyc index 5549bc7bc97e6c9de345e24fffecd941afaf2d7d..e19445e5a3ad8e8a7f2f44558cbc2bd308e0e414 100644 GIT binary patch delta 29 jcmaF5o$={*M(#vjUM>b8&@l4a$Zf*J=(gE`X=x+?eSQa< delta 29 jcmaF5o$={*M(#vjUM>b8aJ%fVk=ulc(Pgs()6z%)hRX;} diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__GreenletExit.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__GreenletExit.cpython-39.pyc index 622f5bed0298193769e4c1767fc425d3b7125d6c..adf1412e73e0e8af0e0be140a19a64e2de513fe6 100644 GIT binary patch delta 24 ecmZ3@w3>-Kk(ZZ?0SGjVye4w5Vsx9htrP$~Xa(2+ delta 24 ecmZ3@w3>-Kk(ZZ?0SMeKJ51zW#pp6|TPXlUng)vi diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test___config.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test___config.cpython-39.pyc index 81e04ba654363f0ee37f262fbe8753ca56fa28dd..f642545212cd52d96012b2763e9b3112eb53a702 100644 GIT binary patch delta 27 hcmZ3izgV9;k(ZZ?0SGjVyf$+0XJmBSe46owC;(TZ2M7QF delta 27 hcmZ3izgV9;k(ZZ?0SMeKJ8b0M&&cSq`84AVQ2=1@2fF|O diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test___ident.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test___ident.cpython-39.pyc index 29c8a41c56578f5bc00feab3ea5fd807cc007d85..7fd359ce5debde3142c89413d320838e56fc2614 100644 GIT binary patch delta 27 hcmZ20v{r~ak(ZZ?0SGjVyf$(-FfzJr?qOWW4ggS61|I+b delta 27 hcmZ20v{r~ak(ZZ?0SMeKJ8a}`U}SXJ+{3t#9ROLM2GRfk diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test___monitor.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test___monitor.cpython-39.pyc index 2dda2aa6115c73aef7eb2b29362c9a8f133064a5..7d7ed9d446d15fb15258fbbd439ebcf197b9a971 100644 GIT binary patch delta 27 hcmcbSbR&s7k(ZZ?0SGjVyf$)gVq$dLypL&?9sp}x2b%x@ delta 27 hcmcbSbR&s7k(ZZ?0SMeKJ8b0M#Kh>bc^}g(Jpgp62u=V1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test___monkey_patching.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test___monkey_patching.cpython-39.pyc index 1e5e5564cd28d98f2241ddd526088827526459e6..a3869aeadf0a04ff98e9d45a3867fe28f5256356 100644 GIT binary patch delta 27 hcmdlgzEzw%k(ZZ?0SGjVyf$*zGBUbt?qt;A0sv9o1;GFS delta 27 hcmdlgzEzw%k(ZZ?0SMeKJ8a~xWn^^O+{viJ1pr$s26O-b diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__all__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__all__.cpython-39.pyc index 246fa7b975ace2c7184d3693b50ce874014c8f2f..5ed357dd24422b9ac17448ac0a24ba29c7de1792 100644 GIT binary patch delta 190 zcmca>dDoIVk(ZZ?0SGjVyf$(NGcmetj%V7zIQcb;3@=Z5YFTPtiC%nZNoLOEd={z6 znk+JtJ6YuGxnVMCX_-|La871UYJO5yYH~?(er|4lUKKw~rXaB-IU}{GN&qTQl2MeJ qn39>7UL^ukQkdDoIVk(ZZ?0SMeKJ8a|*W@2>N9M80aQBWW~wJbHSL@z!$zbG|1EiH3$B#W#7 zKTNbBu_QSowP^A}7U{{3ERvJUSmdR6V3MUJnK@P5Fdj(nJr;S@l8mC%#FWgu^eQQ+ dR8eYieok3xkzRa8esM{0T4qk_W;WLA;sB|iG)e#f diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__api.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__api.cpython-39.pyc index b86a7fae268c34035562397e654e2ce3bc9e5985..eb4f9ab843f6b5825486301c32add5fe327ea6e2 100644 GIT binary patch delta 27 hcmew_|6iUvk(ZZ?0SGjVyf$+8F)_Mrp2d{P3jkx&2E_mX delta 27 hcmew_|6iUvk(ZZ?0SMeKJ8b0cV`6mKJc}un7XWP_2Y3Jg diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__api_timeout.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__api_timeout.cpython-39.pyc index b43f34d2471e36d3765005508dfc68d9a48920d3..871dff2199a8f61a3f656362fc36bf39b81a2447 100644 GIT binary patch delta 27 hcmcbsb61Buk(ZZ?0SGjVyf$)AXJmBSyqIy92moM^2L}KE delta 27 hcmcbsb61Buk(ZZ?0SMeKJ8a~h&dBJpc`@TI5ddl32f6?N diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__ares_host_result.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__ares_host_result.cpython-39.pyc index 04d35355b7c76d67b89254a5162b109ffd62e9ac..9069aed6fbf50d1767222c2fbd25ba9eaacca6c2 100644 GIT binary patch delta 27 hcmZqWYUSci delta 27 hcmZqWYUSci69)+c6zy0su@)1^EB~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__ares_timeout.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__ares_timeout.cpython-39.pyc index 198b99209de4b8d8e4d124f0bcb15b9319a00c84..42e34c91f56e39d8a22392e77889edf7fa988a9f 100644 GIT binary patch delta 27 hcmdnYy_uUkk(ZZ?0SGjVyf$)|F)_MrZelWI1^`ac1(yH- delta 27 hcmdnYy_uUkk(ZZ?0SMeKJ8a}GV`6mK+{9$a3;ra#n;pk(ZZ?0SGjVyf$)AWn^^QypVAX2LM=J2AKc= delta 27 hcmX>ra#n;pk(ZZ?0SMeKJ8a~h%E;)lc_HH(4gg`R2TT9} diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__contextvars.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__contextvars.cpython-39.pyc index 116bd231d9f5d54d41abfd8bc1eabfb6c80ee176..9054f49db0da9ee33ce9a8973ea612bf499d1f40 100644 GIT binary patch delta 27 hcmZ1*x;B(Mk(ZZ?0SGjVyf$(lWMp*Pe3tQn1^{7H2ZsOv delta 27 hcmZ1*x;B(Mk(ZZ?0SMeKJ8a}W$jIoj`7GlD4FGDP2s!`& diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core.cpython-39.pyc index 62a265624b4c77c57c84239b103832e08145101c..9364331eb99f0aa9152a414c208d9376cb1bee76 100644 GIT binary patch delta 27 hcmeCu>(b*+(b*+F*3Ss_G2ty1prS%1&9Cu delta 27 hcmdnTyN{PUk(ZZ?0SMeKJ8a~3Vq|pL?8jKZ3IJG-20H)% diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core_loop_run.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core_loop_run.cpython-39.pyc index 98400f4b890239b5061c53f36e9287db862f5cde..e2145b494bd75f0767cd8de576ee757a5d03774e 100644 GIT binary patch delta 27 hcmey$`jwSCk(ZZ?0SGjVyf$+0U}SXLe1y@E5ddCV29E#$ delta 27 hcmey$`jwSCk(ZZ?0SMeKJ8b0M!N};c`3R#SBLHWo2SNY< diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core_stat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core_stat.cpython-39.pyc index c120b088a4adf47b16287126f15ed5e215a607cd..1b452e1173a7318b38ddc76a4b55df39ce348e19 100644 GIT binary patch delta 27 hcmca7bx(>rk(ZZ?0SGjVyf$(-F)_Mr?qj;Z1pr)J2FU;b delta 27 hcmca7bx(>rk(ZZ?0SMeKJ8a}`Vq$dJ+{bi*3jk%Q2Ydhk diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core_timer.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core_timer.cpython-39.pyc index 659d9df32233ece17f056adb82157f7cc8b999b9..fba0253b5a08a4b14f32eb42102c6c114c86fffa 100644 GIT binary patch delta 27 hcmew+|4p7dk(ZZ?0SGjVyf$+8GBLVsp2-x;3jkr_2B`o5 delta 27 hcmew+|4p7dk(ZZ?0SMeKJ8b0cWny&MJd-Jw7XWK72V4LE diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core_watcher.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__core_watcher.cpython-39.pyc index ec90797f908930bb74d10accc2da80982d1cf0c6..a7bf085b68f77f7efee5162635606cfcf73e1d5f 100644 GIT binary patch delta 27 hcmaDP{YaWSk(ZZ?0SGjVyf$*HFfqDqHelMs4FFhO1^NI0 delta 27 hcmaDP{YaWSk(ZZ?0SMeKJ8a}uVPbUIY{0aM8vtRd2CV=9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__destroy.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__destroy.cpython-39.pyc index b01ac20dcaff12684a5ebeaf67026194869ebedf..dbee73c38dc15fd9e3852fa82c99edb2cf3e0489 100644 GIT binary patch delta 27 hcmZ3@v6_QBk(ZZ?0SGjVyf$)AW@2>PJfEqD5dcoe1{44Q delta 27 hcmZ3@v6_QBk(ZZ?0SMeKJ8a~h%*5!jc|KDQBLG+x2FCyZ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__destroy_default_loop.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__destroy_default_loop.cpython-39.pyc index 42117ec122b583a763dbad82f3e72ca8cc75e6f9..763520182ceb6f71572bf0b9d492b653ba34272c 100644 GIT binary patch delta 27 hcmX@YdxV!ek(ZZ?0SGjVyf$(tGcvku&Swl|1pra;1-k$M delta 27 hcmX@YdxV!ek(ZZ?0SMeKJ8a}mW@L2PoX;4_3IJO^25tZV diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__doctests.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__doctests.cpython-39.pyc index 32ec95798d35980703e4f25ebc63a6ad18f24614..448b1452100d7100b63a9a516523e14220cd1d9b 100644 GIT binary patch delta 27 hcmZ1?yF`{dk(ZZ?0SGjVyf$)kFfzJr7Ga#g3jj)R1ta)E_Ak(ZZ?0SGjVyf$(lU}SWge1@?F08oqug#Z8m delta 26 gcmcb>a)E_Ak(ZZ?0SMeKJ8a}Wz{uz_`3z$V09hsnH~;_u diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__event.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__event.cpython-39.pyc index 1dafcba6e113be7ed9589c73baa7e2ea8f0d5b37..8fa973dcd199244a53ae0e598a6adf00bb92e2fb 100644 GIT binary patch delta 27 hcmX?Fd$g82k(ZZ?0SGjVyf$(tGc&qv&Sws@1^{SN2G{@q delta 27 hcmX?Fd$g82k(ZZ?0SMeKJ8a}mW@dERoX;F)4FGYV2a5mz diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__events.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__events.cpython-39.pyc index a3af375d874702b58cc8e6341689a7c91dd75ca9..618cc9e258203c0cca59753bab6cb53a3d8853a8 100644 GIT binary patch delta 27 gcmeC@@8{=EnHb$RA7-*+1prA510susP1m*w$ delta 27 hcmbQjIfauuk(ZZ?0SMeKJ8a}uXJT~OY|NC%1OQFS1(^T< diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__example_udp_server.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__example_udp_server.cpython-39.pyc index 7434cf280e1675c93cc15bd47a5397af2ec1ace8..72f433c14728d259305ff90f4ecd1d10897353f8 100644 GIT binary patch delta 27 hcmeyy_Kl4@k(ZZ?0SGjVyf$+GU}SXL%)(T}2moG%22}t6 delta 27 hcmeyy_Kl4@k(ZZ?0SMeKJ8b0s!N};cnT4r{5dde>2M7QF diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__example_webproxy.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__example_webproxy.cpython-39.pyc index e86c2cf6c3b4274ef0d878ec6d88fcb899b04971..62695e0e5de57063343137bf2d7379f8dad3e9d9 100644 GIT binary patch delta 27 hcmcb~d6Sbnk(ZZ?0SGjVyf$*jF)_Mr&SJ`E0svKL1?&I- delta 27 hcmcb~d6Sbnk(ZZ?0SMeKJ8a~RV`6mKoW+#S1OQ&O2A==` diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__example_wsgiserver.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__example_wsgiserver.cpython-39.pyc index 3db11749ec9d27429afc418bea64f775d16eb175..c1c62a1c4d9ef48cce59f3d5ddc11f04af323499 100644 GIT binary patch delta 26 gcmca5a!Z6ek(ZZ?0SGjVyf$+CF*CX?j$&p908noQYybcN delta 26 gcmca5a!Z6ek(ZZ?0SMeKJ8b0kV`g+&9L3BI09gqJ9{>OV diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__example_wsgiserver_ssl.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__example_wsgiserver_ssl.cpython-39.pyc index 862238d4605b9b5da57589ab0ac1133e2528beaa..261175805954a725089f7c65f88b9d2cd0178758 100644 GIT binary patch delta 27 hcmcb`c8iTWk(ZZ?0SGjVyf$*HF)_MrHe%9X1OQQ=1uy^r delta 27 hcmcb`c8iTWk(ZZ?0SMeKJ8a}uV`6mKY{aC&2mo5_1>*n! diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__examples.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__examples.cpython-39.pyc index 3db82dfb1c4c6bafe78cd9f3c97151624f138935..89eb7f1a41f343d1078496df417a89c5dae5ae2a 100644 GIT binary patch delta 27 hcmdlhwO5Kek(ZZ?0SGjVyf$*5VPD8d`4f{RGXPw02P6Oh diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__fileobject.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__fileobject.cpython-39.pyc index 63dd5edb00e11be18d92c823efacb1f80a6480f2..601ec768938bf9b84551eedbd6d9802d4654e664 100644 GIT binary patch delta 29 jcmX@o#(1QSkvox>mx}=iG>p79a_cfPx^1>(=5_!8YNZA^ delta 29 jcmX@o#(1QSkvox>mx}=i+%7w8;_=~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__greenio.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__greenio.cpython-39.pyc index 2ffd9916ae67acf303f24a5808aa20fe8e5075cf..362f6d936278c4181d8adced49954fa3937a1810 100644 GIT binary patch delta 27 hcmZ1?wM2?Lk(ZZ?0SGjVyf$)gVq|pNypJ)B8vs%!21)<` delta 27 hcmZ1?wM2?Lk(ZZ?0SMeKJ8b0M#K`Efc^_jMHvn662K@j4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__greenlet.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__greenlet.cpython-39.pyc index ebc95c690ded297723da12bb40a9ae25ee6113b6..c6b5f2f5eeeab283713acac12e1643309ed41423 100644 GIT binary patch delta 29 jcmcaPo9X6kChkODUM>b8&@l4a$gRb~=(gF6WpO6}brA<^ delta 29 jcmcaPo9X6kChkODUM>b8aJ%fVkz0#}(Pgt4%i>M|eqIP3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__greenletset.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__greenletset.cpython-39.pyc index eb937b9c5e9b78a17d21e2971f475cf4deeadc05..8a94fbdfe6256b5a7dbc5ce2bc2dc0de20994219 100644 GIT binary patch delta 27 hcmX?Tc+ikLk(ZZ?0SGjVyf$)AV`OyOyoga=8~|FH20s7* delta 27 hcmX?Tc+ikLk(ZZ?0SMeKJ8a~h#>nWhc@d+$H~?ek2J!#^ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__greenness.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__greenness.cpython-39.pyc index 911fb5a7678dad351c6eb5ec70f7248ee003e091..81a76dae7e94c039498a2fb5e4b7a0346cb5d39c 100644 GIT binary patch delta 27 hcmZ1^v`C0Mk(ZZ?0SGjVyf$*5WMXvNe3i+U4FFLs21oz^ delta 27 hcmZ1^v`C0Mk(ZZ?0SMeKJ8a}W$;9Zg`6`ny8vt5*2KxX2 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__hub.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__hub.cpython-39.pyc index 543e7d34e5c6a9e866ab448510e4a1598b9d732d..d3c2f467a3e21bba0d3acdcfe0f101ee74edd5ab 100644 GIT binary patch delta 27 hcmZ3SusDG`k(ZZ?0SGjVyf$(hGc&qvwr75#0{~iH26+Gg delta 27 hcmZ3SusDG`k(ZZ?0SMeKJ8a}OW@dERY|s2e2LNNM2P^;p diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__hub_join.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__hub_join.cpython-39.pyc index 9c2ea573fee91f83a54807b31b06291a4cc063d9..d39f3cb691aa85bcab670ac62bce09d88385a4a6 100644 GIT binary patch delta 27 hcmX>kdq|c$k(ZZ?0SGjVyf$*bWn^^Q{FCt{4**=62W9{O delta 27 hcmX>kdq|c$k(ZZ?0SMeKJ8a~B%gE@m`6uH^9sp(M2pIqX diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__hub_join_timeout.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__hub_join_timeout.cpython-39.pyc index 85beb51d2a35f91795cbf49fc9f78ba9f629bdbc..d73368c0078b7f7ee5d1971908f03e84b72d95c8 100644 GIT binary patch delta 27 gcmeB@?~>eHlk(ZZ?0SGjVye4wbV04?fqznK#%LS7F delta 24 ecmbQmG>eHlk(ZZ?0SMeKJ51!B!RRt^Nf`h@{RTz= diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issue112.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issue112.cpython-39.pyc index 0ce1ca558d5530774f71c193997558e55e57fd0a..9127508f11b7d656b852b030500fc97c8910ecdd 100644 GIT binary patch delta 27 hcmaFQ`ks|Lk(ZZ?0SGjVyf$*jF*3Ss&SGq31OQn$1|t9f delta 27 hcmaFQ`ks|Lk(ZZ?0SMeKJ8a~RV`OyMoWpd{US@k(ZZ?0SGjVye4u#W^~*5{uT!SPkIM6 delta 25 fcmX>pd{US@k(ZZ?0SMeKJ51z$%;>W5{VfgvS6>I{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issue467.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issue467.cpython-39.pyc index 17cf403a2925a47048ac5cb7f0ef1af56da8dc8d..330699f40028344635211983215a1105d63e1c0d 100644 GIT binary patch delta 25 fcmbQsIhT_=k(ZZ?0SGjVye4v=V|3ei>o79_L}>dqk(ZZ?0SGjVyf$)QWMXvNe3xl9BLHEr2RQ%$ delta 27 hcmeyt@q>dqk(ZZ?0SMeKJ8a~>$i(Qf`7YCJMgVI42kZa< diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issue600.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issue600.cpython-39.pyc index 99f939776ca973d7117600475a2fc94aa19180a6..8b08c8c2077939d56aa7362b7463a641648dd88c 100644 GIT binary patch delta 27 gcmZqYZs+Dsc1&#m! diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issue_728.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issue_728.cpython-39.pyc index ce6a36bd18519c3171779953720e656c6fd501ed..aa505083534a1dea09930b2ba5edcc93f8f84d10 100644 GIT binary patch delta 24 ecmX@ebdZTVk(ZZ?0SGjVye4uVWOSQ&wgdn|69zE= delta 24 ecmX@ebdZTVk(ZZ?0SMeKJ51z0$mlZhYzY8KMF!*m diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issues461_471.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__issues461_471.cpython-39.pyc index bcd858e4b9171331bfeaec0e5b74b0f653389a2a..a0a52564c65fdf5bf5ed50a0a51d14b399e053bd 100644 GIT binary patch delta 27 hcmZn^Y82v5AtQUt-c{0{}`E1>yhz delta 27 hcmZn^Y82v50su-}1zi9D delta 27 hcmbQuJ)4_5k(ZZ?0SMeKJ8a}`Wn^^OJdu%$1prg21`q%M diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__joinall.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__joinall.cpython-39.pyc index de82892b124546af8085adff0bc41a4627c51406..ba9455e2bbf2568c187966f9a2ec4adf8271aa06 100644 GIT binary patch delta 27 hcmcc5dY_d$k(ZZ?0SGjVyf$(hGcvkuwr5D8d`4UsL2>^AG2wwmI diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__lock.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__lock.cpython-39.pyc index 67e95a94e0eb4720d1fc98f514cb460a90ea8b76..5028e612f4e71a8a5f246c0e8ab05ad3fa0af5e9 100644 GIT binary patch delta 27 hcmeys{(+r4k(ZZ?0SGjVyf$*zGcvku?q*D70svb+2220| delta 27 hcmeys{(+r4k(ZZ?0SMeKJ8a~xXJmBQ+|8KE1OQ}<2LAv6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__loop_callback.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__loop_callback.cpython-39.pyc index 9a2fd7a27f48af3660aff009cef7254c325d4c90..32f1bb6f4949c5d3eca3d12f7c8ec6d97666de13 100644 GIT binary patch delta 27 hcmX@Xc7lyNk(ZZ?0SGjVyf$(dF*3Ssu46pK2mn(I21Eb= delta 27 hcmX@Xc7lyNk(ZZ?0SMeKJ8a}GVq|pLT*r8d5dd6S2KN8} diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__makefile_ref.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__makefile_ref.cpython-39.pyc index cebbfd3e6d4ed75bc99304c22cc388dc3adaa5f0..6bb6f19684bc0fb465037a05df3ad63cb6003050 100644 GIT binary patch delta 27 hcmX?*cOZ{Dk(ZZ?0SGjVyf$)&Gc&qvPG-Jq3;<-y2NwVU delta 27 hcmX?*cOZ{Dk(ZZ?0SMeKJ8a|*XJ&NSoXmXJ7yxb<2g(2d diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__memleak.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__memleak.cpython-39.pyc index ef2e256f06ef09596f3345e2a8c642c6bd04d2d3..9d73c736f5d4b9d116caa27235307db2b1adb10e 100644 GIT binary patch delta 27 hcmX@jd76_uk(ZZ?0SGjVyf$)kF*CYt7GvJZ2mnsv1#bWV delta 27 hcmX@jd76_uk(ZZ?0SMeKJ8b0UVrF#NEXKT*5dc^(1|k3e diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey.cpython-39.pyc index 57de6236e89e2ceb9864503d8af953eb982569bf..7bc24010784493177cd553e3b5d7a6b54f778187 100644 GIT binary patch delta 27 hcmaE^^<0ZPk(ZZ?0SGjVyf$)MF)_Mrc4JZ$1^`@B1;qdW delta 27 hcmaE^^<0ZPk(ZZ?0SMeKJ8a~(Vq$dJ?8c-h3;<=I26zAf diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_builtins_future.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_builtins_future.cpython-39.pyc index 8b87d6a96525baefdc6bcc52b331e921dfc50bf3..81d975f716fd5789988501d3ebf375207bb68adb 100644 GIT binary patch delta 26 gcmZ3%vVw&>k(ZZ?0SGjVye4x0VszWg#;C*y07x|jM*si- delta 26 gcmZ3%vVw&>k(ZZ?0SMeKJ51#M#ptq`jZuja08q^Z`Tzg` diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_futures_thread.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_futures_thread.cpython-39.pyc index 73cbc8487888e15e4333aaf2c3406412a3fc929e..761ef913daddd38ff3c442ff7c8d30d024e0e8c0 100644 GIT binary patch delta 27 hcmZ3_wVsPRk(ZZ?0SGjVyf$*jF*CYt&SE~w2mnpU1@Qm? delta 27 hcmZ3_wVsPRk(ZZ?0SMeKJ8a~RV`g;OoW*>U5dc>e2BZK0 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_hub_in_thread.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_hub_in_thread.cpython-39.pyc index f02d513fb03dc52d806dff12bccf7bdce0324cb1..54d2cb5b27f5cab7fd9a10baf0f300c9ea659c58 100644 GIT binary patch delta 25 fcmX@XdV-ZZk(ZZ?0SGjVye4u#W^~*5{w5;;OuYvW delta 25 fcmX@XdV-ZZk(ZZ?0SMeKJ51z$%;>W5{Y^#yRH6sM diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_logging.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_logging.cpython-39.pyc index 518c4462aac11c72031d95abed39cd9598278e5b..3cf54bec73f3309d8ade40110cc2c26314b7aea2 100644 GIT binary patch delta 27 hcmaFN^_Yu0k(ZZ?0SGjVyf$(hGcvkuwr5mf0RU9g1z`XH delta 27 hcmaFN^_Yu0k(ZZ?0SMeKJ8a}OW@L2PY|p5|0svki1{44Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_module_run.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_module_run.cpython-39.pyc index fedae8b3be7dc2dd8b89a7b7c957c87b63ef4dd7..754b7335b610f022e9355d8d8fbe35ffa86eca52 100644 GIT binary patch delta 27 hcmca2e?^` delta 27 hcmca2e?^`*!3EO* delta 24 ecmaFE_=b@?k(ZZ?0SMeKJ51zGVRV^TPy+x>^9F_h diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_queue.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_queue.cpython-39.pyc index 40b25d167aed56d97497c92d0c85a7c2e9688d8f..8f3c6ba30de697c47a4048af9d8aea6422d79381 100644 GIT binary patch delta 27 hcmdnsy1|t@k(ZZ?0SGjVyf$*1FfqDqc3>({0036X1>FDu delta 27 hcmdnsy1|t@k(ZZ?0SMeKJ8a}OVPbUI?7&o@003YY29N*% diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_select.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_select.cpython-39.pyc index 1a9a602d56aa5fd827c9f337ba2c379ab239a3a0..9d4c7c81e9bb139bb44c608b529be7b850792690 100644 GIT binary patch delta 27 hcmaFC{(_x5k(ZZ?0SGjVyf$)gV`OyOe27tv2>@H`25SHS delta 27 hcmaFC{(_x5k(ZZ?0SMeKJ8b0M#>nWh`4FQT698p62OaJs8kJs8k?@t1@Zs@ delta 27 hcmX@eevq9zk(ZZ?0SMeKJ8b0M#K`Efc^@M)698P&2BiQ1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_sigchld_3.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_sigchld_3.cpython-39.pyc index e0bc8832b4620f0c49d6b9320185e2d1b948873b..3e0e3de0338893cb36c97376bfc698ba1059d2b9 100644 GIT binary patch delta 27 gcmeC>?B(Q6?B(Q6CIU0RT&i1#$oY diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_ssl_warning.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_ssl_warning.cpython-39.pyc index 7479528e5bc6d87d85f7c18f284cdd408a1fc9cc..97b0a6b03d066d1fb59c6b8de8a72b4855a083aa 100644 GIT binary patch delta 27 hcmcb{d5x1hk(ZZ?0SGjVyf$+4GBLVsmSoz?1OQP>1(E;& delta 27 hcmcb{d5x1hk(ZZ?0SMeKJ8b0UWny&MEXlN&2>@D{21Nh> diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_ssl_warning2.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_ssl_warning2.cpython-39.pyc index 35c200be3139a89c29097e798ea1b796e988c905..49dad26450ce8d1117dc11e1f2a491245afba60a 100644 GIT binary patch delta 26 gcmbQhGl7RYk(ZZ?0SGjVycTjZGP-T%VPs(i06o0~DgXcg delta 26 gcmbQhGl7RYk(ZZ?0SMeKJ1pd8WOUig!^px407g{=-2eap diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_ssl_warning3.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__monkey_ssl_warning3.cpython-39.pyc index 919b558f89347b28f24b36439ae93dc8435a69c7..e04f1d82565abd96bde5b834af79254c90e1b83c 100644 GIT binary patch delta 25 fcmZ3^vz&)Jk(ZZ?0SGjVye4vgV07E~N1GJ@M)?Ly delta 25 fcmZ3^vz&)Jk(ZZ?0SMeKJ51#M!058^k2Wg+PTmIo diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__nondefaultloop.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__nondefaultloop.cpython-39.pyc index 7503b8504938533eea77d321ff38883eda908221..3f2571e688f30c94742241f8fc263e5a27363e37 100644 GIT binary patch delta 26 gcmbQtJeiq0k(ZZ?0SGjVyf$*PF*3SM7Gi7!06cL7k^lez delta 26 gcmbQtJeiq0k(ZZ?0SMeKJ8a};V`OxhEX3Fd07VN0MF0Q* diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__order.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__order.cpython-39.pyc index 43b29b5d98ab729a6edbbcc200cd9686d43a9cf7..08aca5ce35327ff7df666f13b7f630b5f18dd254 100644 GIT binary patch delta 27 hcmdllxL=Svk(ZZ?0SGjVyf$)|FfzJrZeX-$2LMuN1;+pY delta 27 hcmdllxL=Svk(ZZ?0SMeKJ8a}GVPtgK+`wqh4gg!V26_Mh diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__os.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__os.cpython-39.pyc index 2ed305eb21cdda4e7727973a05f6aa7a771b2f8a..15d4f0cd095ba4600b949317848711dbecbfc58c 100644 GIT binary patch delta 27 hcmews@GXElk(ZZ?0SGjVyf$*@GBLVsu4MYF3IJ;?2ZI0r delta 27 hcmews@GXElk(ZZ?0SMeKJ8b06Wny&MT*>rT6##U32sQu! diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__pool.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__pool.cpython-39.pyc index 7315f04e0eecc46e4722e43caca574e009850691..7fb1b919208051559f432165e1241f62ada969ab 100644 GIT binary patch delta 29 jcmeyqhVlCvM(#vjUM>b8&@l4a$i1GK(QWf?<~>0Gg@y>R delta 29 jcmeyqhVlCvM(#vjUM>b8aJ%fVk$XKeqs!*q%zJ_Wj?)Qb diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__pywsgi.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__pywsgi.cpython-39.pyc index f68acbb58cd8792bf0285aa2a41354d56f294483..361835388b805f94f4c3775d6faeaa311d6862dc 100644 GIT binary patch delta 29 jcmbRBgL&2uX6{5@UM>b8&@l4a$Q{qd=(ahVZT(jOen$w8 delta 29 jcmbRBgL&2uX6{5@UM>b8aJ%fVkvpD^(PeWs+xo8nhm;9I diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__queue.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__queue.cpython-39.pyc index c3ee31cfba48e7d00ab829511a4a1005350caea8..f8fe7cad8e90c4ec4f81cbe0c2d911b25c29e2b1 100644 GIT binary patch delta 29 jcmX@w$au7okvox>mx}=iG>p79a(6H@x^14qY-kGrZo3Bw delta 29 jcmX@w$au7okvox>mx}=i+%7w8nHXI*=Q7DM0RT=c1+@SG diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__refcount.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__refcount.cpython-39.pyc index d298f30053c25a265a5db5fb909d8154a18f687e..88d1c25d11f1a9a008a9a0f830592eb8aca14163 100644 GIT binary patch delta 27 hcmZ3ev`~pVk(ZZ?0SGjVyf$)gW@2>Pyq_tF4**jw23G(8 delta 27 hcmZ3ev`~pVk(ZZ?0SMeKJ8b0M%*5!jc|TJU9{^l>2MPcH diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__refcount_core.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__refcount_core.cpython-39.pyc index 450a34f2b10ea9ce7ad57d650ad50d0ff1d1f5c5..186df1d1ceec29ad2778d2622ea92f2d34cbb7c4 100644 GIT binary patch delta 27 hcmeyv@rQ#uk(ZZ?0SGjVyf$)&F*3SsPGXc|1^`<&1ne@>n|k(ZZ?0SGjVyf$(lU}SXLe1?&U4**-424esK delta 27 hcmX>ne@>n|k(ZZ?0SMeKJ8a}Wz{u#b`3xfy9{^b8&@l4a$i0t+(QWf7mOys^ZHotc delta 29 jcmbO|gK_o@M(#vjUM>b8aJ%fVk$WEtqs!(~EP?I-cGw6m diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__server_pywsgi.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__server_pywsgi.cpython-39.pyc index b5fe6ac6a0cd0b0df7ce1d95ea402856292b6323..86d9fe35f1d1e6c3816c69007dd4be775bca0ac9 100644 GIT binary patch delta 26 fcmeB|?U&_F@a}23Y_A diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__sleep0.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__sleep0.cpython-39.pyc index a20120f21b02559b2c9dd0de32e14827c27e11c0..255cb9066b1fe7a8a0e35c4cc80d5a0dea2d5685 100644 GIT binary patch delta 24 ecmcb^bccyMk(ZZ?0SGjVye4wrWptbPvKRnI%m$tS delta 24 ecmcb^bccyMk(ZZ?0SMeKJ51!h%jh!kWibFw{s&P2 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket.cpython-39.pyc index 8e60e1d0c74f75bbdf1a3c6f5942dfd47402d021..450787f28337e9907a6741c7d64d08b90aefb17c 100644 GIT binary patch delta 29 jcmcaLiSgDXM(#vjUM>b8&@l4a$UU2x(QWf`=FP4Ec*Y0? delta 29 jcmcaLiSgDXM(#vjUM>b8aJ%fVk$W~Xqs!*y%$r>Sf)fb1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_close.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_close.cpython-39.pyc index 11b202b0052ab7efb8fa97306ae6a6ce95950cb1..29143701636b93613388a7ac7506830838c87cd4 100644 GIT binary patch delta 26 gcmeyt|AU`9k(ZZ?0SGjVye4x0VszWg#`uX109%R%(f|Me delta 26 gcmeyt|AU`9k(ZZ?0SMeKJ51#M#ptq`jqwv30AwNug#Z8m diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_dns.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_dns.cpython-39.pyc index 8517dd39e9bcfb977754a8a55aee332c01cde5da..9b58c3e6f6561c6122a1cf668f035970eafc8be3 100644 GIT binary patch delta 29 jcmeA^&)9vQkvox>mx}=iG>p79a$jI$blZG~ZG8d&cT)&x delta 29 jcmeA^&)9vQkvox>mx}=i+%7w8@i$2KxX2 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_errors.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_errors.cpython-39.pyc index 77ae4d630b47ab25694e13c14ce5b55c432c59e4..175139b25dbe1c95be34ddaed9c68e029deb19b3 100644 GIT binary patch delta 27 hcmZ3@xtfzZk(ZZ?0SGjVyf$*5U}ALJe1+*cBLGrC2Fm~d delta 27 hcmZ3@xtfzZk(ZZ?0SMeKJ8a}W!NlmY`3lo@MgUum2Yvtm diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_ex.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_ex.cpython-39.pyc index a5e57ff86f95a138dc2e470b511b7399b5283b81..9c7b22ba8cded2fbe15a9ed66c54fa7c1ffac896 100644 GIT binary patch delta 27 hcmdnXwU>)Kk(ZZ?0SGjVyf$*{FfqDqwqRmq1^`Tr1nB?( delta 27 hcmdnXwU>)Kk(ZZ?0SMeKJ8b0EVPbUIY{A6J3;vzCWDk(ZZ?0SGjVyf$*{Gcvkuwr2dq0su>>1-}3Q delta 27 hcmZ3>vzCWDk(ZZ?0SMeKJ8b0EXJmBQY|Z$I1prj_266xZ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_ssl.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_ssl.cpython-39.pyc index dec2219fef87b5593a142df6fa868462d390cd93..d5847c96c21d29a6b0525b975881b43513c2a2f5 100644 GIT binary patch delta 27 hcmZ3;wUCQDk(ZZ?0SGjVyf$(RGBLVsmStjL1^`8T1bP4f delta 27 hcmZ3;wUCQDk(ZZ?0SMeKJ8a|@WMXvLEX%~g3;<5a1uXyo diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_timeout.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__socket_timeout.cpython-39.pyc index 6855028e98f5b05eca5ead0d9f902963c06b0441..2f173518ff55c8d92ced9687a3c3674c52180e79 100644 GIT binary patch delta 27 hcmZqTYvSWhGXP-F2VwvK diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__ssl.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__ssl.cpython-39.pyc index 730a57f147b72d6211069fe0abee668cd8510c07..01c4caf67cd1eeddf665ee2a45b0a65bdb28a3d7 100644 GIT binary patch delta 27 hcmaDQ`AU*Ik(ZZ?0SGjVyf$**WMp*P{FITE8vtQt2EhOT delta 27 hcmaDQ`AU*Ik(ZZ?0SMeKJ8a~>$;jxk`6(kSHvnp~2Xp`c diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__subprocess.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__subprocess.cpython-39.pyc index 164673e84c4bb444e564176de9b95928cb5f43d7..1e915e9a1fad0fc07a0ec005495bde8c0e81a5b8 100644 GIT binary patch delta 27 hcmZ2fy{MWyk(ZZ?0SGjVyf$*bU}kjN{Dpa)B>-qb2krm> delta 27 hcmZ2fy{MWyk(ZZ?0SMeKJ8a~B!OZBg`3v(pO8{|?2%!J~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__subprocess_interrupted.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__subprocess_interrupted.cpython-39.pyc index b31c0dc484f8bf7e23d30b07c1dc933065dbf27e..3fece3c0e2733390fe906ab5f4c8f76650b8e105 100644 GIT binary patch delta 26 gcmZ3%wt|g2k(ZZ?0SGjVyf$*zGBLVM?qr$|07hR0&;S4c delta 26 gcmZ3%wt|g2k(ZZ?0SMeKJ8a~xWny%h+{rW_08aS^g8%>k diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__subprocess_poll.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__subprocess_poll.cpython-39.pyc index 170e7069a63afbf7113014d496d5a4002bb9d15e..de784600ad63061df2b7357bf7057c6c4411df3b 100644 GIT binary patch delta 26 gcmcb|e2pb5e#ok(ZZ?0SGjVye4wLXLQ^6+m9CjP<;m2 delta 25 fcmX>pb5e#ok(ZZ?0SMeKJ51z$&*-x8w;wM6SYii@ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__thread.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__thread.cpython-39.pyc index d2af73ae68cbbdeb3850f4ac18cd27606ae78c30..728c78d2cec95f327e2ee1c32f3e04a437892eb3 100644 GIT binary patch delta 27 hcmcb>ae;$7k(ZZ?0SGjVyf$*@GBLVsu4KB-2mn;{23-IE delta 27 hcmcb>ae;$7k(ZZ?0SMeKJ8b06Wny&MT*-8u5ddC62M_=N diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading.cpython-39.pyc index ac8a2c07448d01d3333585ad3b22b2037a7a3698..d0686e1990b7ea43a84087070ed2aa29313365e8 100644 GIT binary patch delta 27 hcmaDP`bd;Jk(ZZ?0SGjVyf$+0U}SXLe1uVs698R+27Ukl delta 27 hcmaDP`bd;Jk(ZZ?0SMeKJ8b0M!N};c`3R#NCje&62QdHu diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading_2.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading_2.cpython-39.pyc index 285a7bb9ef5fc3b124dde8addb4f5b829b8e2544..38ef82a71aa4479518707c1cf6c961d9a7247607 100644 GIT binary patch delta 29 jcmZ27opH%@M(#vjUM>b8&@l4a$X&b8aJ%fVk-LtS(PeWNtCSl6bnXX; diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading_before_monkey.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading_before_monkey.cpython-39.pyc index 79d2ee0a0ec79ab5889a9ebec48364afd5a610e5..03d0ae288381f31deee6225a91e826a5adfbc91e 100644 GIT binary patch delta 27 hcmX@bc8ZNVk(ZZ?0SGjVyf$*LVPtgMyn}HPBLG$Q27~|r delta 27 hcmX@bc8ZNVk(ZZ?0SMeKJ8a}$!^r5ec?aVpMgU(!2R8r! diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading_holding_lock_while_monkey.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading_holding_lock_while_monkey.cpython-39.pyc index 498ce7982c436cbdbf327502b4ab2f88e57cd716..b0ee947d8ea81cc5b05865657faa8756822c1448 100644 GIT binary patch delta 24 ecmcb}bdiZWk(ZZ?0SGjVye4vQXLOr*xDNnCy#`kR delta 24 ecmcb}bdiZWk(ZZ?0SMeKJ51!>&ge4na326m?*|G1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading_monkey_in_thread.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threading_monkey_in_thread.cpython-39.pyc index 25d6b26e820f05fdf00883caf01deb6a4e5b9853..378a47a022ef97e7d5da6b027d7430250c33eb1e 100644 GIT binary patch delta 27 hcmX@be~Ob8&@l4a$UT#p(QWfm=2gi6g2xDW delta 29 jcmX?qj`93CM(#vjUM>b8aJ%fVk$WaHqs!){%&U?Cj1&ng diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threadpool_executor_patched.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__threadpool_executor_patched.cpython-39.pyc index 53e4b81dca48d727af3eab5f9aab054b8ed4b422..dab20b52def806e9e1d514d89216a36ea5e98087 100644 GIT binary patch delta 27 hcmX@idYF|vk(ZZ?0SGjVyf$)IGcvkuZfCS%1OQPl1-t+N delta 27 hcmX@idYF|vk(ZZ?0SMeKJ8a~xW@L2P+|Fpj2mo4q25$fW diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__timeout.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__timeout.cpython-39.pyc index 7ffcc4fda9ac3c6fcdddf4bcf0a5a1fdaecc706c..db0922f03e8b792d2a3bca9159cd04d003277ac2 100644 GIT binary patch delta 27 hcmZ3lxn7eyk(ZZ?0SGjVyf$+0V`OyOe2Vd@5CB;52OIzZ delta 27 hcmZ3lxn7eyk(ZZ?0SMeKJ8b0M$H?fi`4r<*Apl}N2hRWi diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/__pycache__/test__util.cpython-39.pyc index 18c4f6147f924e8aa16a6e88c130510c071eae86..bece02a45d093eb73f995d80a4cb77294612094c 100644 GIT binary patch delta 27 hcmccXb=QkKk(ZZ?0SGjVyf$)wXJmBS%*+&}3;<@H2D1PF delta 27 hcmccXb=QkKk(ZZ?0SMeKJ8b0s&dBJpnVBg{831qV2W9{O diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/__init__.cpython-39.pyc index 419feff3982d0f3b2923b12cc4e9399538ad36d2..08b4768e437da78bd220e8bc32e39e9df60d93b6 100644 GIT binary patch delta 26 fcmZo>X=dS0X=dS0oN07o4L3;+NC diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/__main__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/__main__.cpython-39.pyc index e0622a8db8ed52cd40f7fd5a6ed7559388a7f26c..6fe29331b30fc5fa0a8a8271d4d88b1e94d38325 100644 GIT binary patch delta 24 ecmX@hbe4%bk(ZZ?0SGjVye4uVWptZ(u?7G{V+L6O delta 24 ecmX@hbe4%bk(ZZ?0SMeKJ51z0%IGrjVhsRGl?My} diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/issue1526_no_monkey.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/issue1526_no_monkey.cpython-39.pyc index 8db5518cbbca281a31360eb49067d2d9f6531852..362e92f148fd0d55e2d99c482d80c93878e1c1a7 100644 GIT binary patch delta 26 gcmeBS?P29k(TN08P*b6#xJL diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/issue1526_with_monkey.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/issue1526_with_monkey.cpython-39.pyc index 8e048e41bcebacfaa384edd214a0bc265ef6521b..b24b8a07db39e8aa96bc6081266c69cf1f42524c 100644 GIT binary patch delta 26 gcmbQnHjRxtk(ZZ?0SGjVyf$*DGcmeNE@oN`072~qga7~l delta 26 gcmbQnHjRxtk(ZZ?0SMeKJ8a}mXJT}jT+Fl>07{1jHvj+t diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/issue302monkey.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/issue302monkey.cpython-39.pyc index 4470f54beded9d7cd838a7e80fd6626ed92cf877..9bb90413975fbfa9dd6b06d5e33836fdbc0ec04d 100644 GIT binary patch delta 26 gcmcb?a)X6Ck(ZZ?0SGjVyf$)gV`Oxje28%x08zjOlK=n! delta 26 gcmcb?a)X6Ck(ZZ?0SMeKJ8b0M#>nV0`4HnY09slHMgRZ+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/script.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/gevent/tests/monkey_package/__pycache__/script.cpython-39.pyc index 830ed110af791353ad30fa34d9f16dba21c65cf1..3b3fe9558d205c24545216f75e9727a6c12760b4 100644 GIT binary patch delta 27 hcmbQpI+2w-k(ZZ?0SGjVyf$(NGBUbtj%74q1OP69)=P}J?1OQJu1~vcy diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/__init__.cpython-39.pyc index eb212fcc31f9531a407bbae8d3d5c46bb47ea748..c566444cd60663c6c03749f202869a415035f997 100644 GIT binary patch delta 27 gcmZo;ZDZw5Hq)$ delta 27 hcmZo;ZDZw5yf$*nF*3Ss)?!@C2mn!%1)cx^ delta 27 hcmcc4dYzR!k(ZZ?0SG)UJ8a~ZV`OyMti`yN5dd1z22cP1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/exceptions.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/exceptions.cpython-39.pyc index 684037f0ab0e0f2b2db46df17fb83dd9bc98df26..7cd4d1d2f3befc4e6b5020db68e0f0173690e66b 100644 GIT binary patch delta 27 hcmaFD_JoZ)k(ZZ?0SL5>yf$(xGBUbt)@3wj0svE_1xo+` delta 27 hcmaFD_JoZ)k(ZZ?0SG)UJ8a}uWMp*NtjlQ51OQy)1^oa3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/handler.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/handler.cpython-39.pyc index dd984926d9ad8d313ca36aab773299d887c61894..c28c2edd10eb02dfcd155d0ebe2ff6238c11b76c 100644 GIT binary patch delta 27 hcmdmJz0sOGk(ZZ?0SL5>yf$)YGcvkuE@!lo0RUHo1^@s6 delta 27 hcmdmJz0sOGk(ZZ?0SG)UJ8b06W@L2PT+V1E0{~#d2C@JE diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/logging.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/logging.cpython-39.pyc index a5948b6913b65ecead7da8d5c4351e1e0c223046..24f22706cb9f6856871d74ae0d0bc8da0320ca0f 100644 GIT binary patch delta 27 hcmZ3>y_TChk(ZZ?0SL5>yf$*{GBLVswqz<{1^`Nw1wQ}) delta 27 hcmZ3>y_TChk(ZZ?0SG)UJ8b0EWny&MY{^u@3;yf$*XGBUbt4rFZM1^`yY1@Qm? delta 27 hcmcaAc~z1-k(ZZ?0SG)UJ8a~3Wn^^O9LU(h4FF&S2BQD~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/server.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/server.cpython-39.pyc index b80e7bb3b9c28a8cb2a2562727f9a8fc748e5f00..4bdc7f74567fbbfc0766539d35eddc14af15c975 100644 GIT binary patch delta 27 hcmZ3*y^5PVk(ZZ?0SL5>yf$(lVPbUKe1Yi}697_f2Fw5e delta 27 hcmZ3*y^5PVk(ZZ?0SG)UJ8a}W!o=vZ`2y1|CIDNl2Yvtm diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/utf8validator.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/utf8validator.cpython-39.pyc index 4a0ecb985dc73bf0e4f496d9c2f2a1837394ade1..4b97470638e4cea35e9f564c26ee0dc4065f6e1b 100644 GIT binary patch delta 27 hcmaE?|5%?pk(ZZ?0SL5>yf$)saxuDX4(00O1pr=_244UG delta 27 hcmaE?|5%?pk(ZZ?0SG)UJ8b0kyf$*PFfqDq7GT=J1OQGR1!4dI delta 27 hcmX@Xd4iKWk(ZZ?0SG)UJ8a};VPbUIEWosb2>@4J1{44Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/websocket.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/__pycache__/websocket.cpython-39.pyc index 81e6341c235c0bfe4e372f985a4af112823ea82d..7ce62e6caee7831a5fe0d0cefdec81e930867bea 100644 GIT binary patch delta 27 hcmbQ0IxCesk(ZZ?0SL5>yf$((vogAE=4b8J1pro~1;79R delta 27 hcmbQ0IxCesk(ZZ?0SG)UJ8a};W@U8Q%+K1b3jkl@266xZ diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/gunicorn/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/gunicorn/__pycache__/__init__.cpython-39.pyc index de97d5f5b78cd926903311852a721c3ea960a1d1..96ca6d70ab0a74448adcd563236eda5a77f96417 100644 GIT binary patch delta 24 ecmdnPxQCHDk(ZZ?0SL5>ye4wnGP+IlECv8Q0Ryf$+4GcvkOmS%hc08(}Z;s5{u delta 26 gcmey*{GXXSk(ZZ?0SG)UJ8b0UXJmAlEY0`?09ykFlmGw# diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/protocols/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/protocols/__pycache__/__init__.cpython-39.pyc index 109d77ecb4f9db695e979170a7a40fd1abc90d90..80ae1445100f9e79b856f55ac0e088d7cde19366 100644 GIT binary patch delta 24 ecmdnXxR;STk(ZZ?0SL5>ye4wnGP+IlECB#LFa;t2 delta 24 ecmdnXxR;STk(ZZ?0SG)UJ51!ZWptV7Spon=R|V7n diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/protocols/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/protocols/__pycache__/base.cpython-39.pyc index be3e0da35e883c87b975c2f5d6a67593aaca444e..cc6f141dc011ba810fd70030687b985053e482c5 100644 GIT binary patch delta 27 hcmcc1eV3a%k(ZZ?0SL5>yf$)kFfzJr7GXTe0svDJ1*rf4 delta 27 hcmcc1eV3a%k(ZZ?0SG)UJ8b0UU}SXJEW&t_1pr)923r6C diff --git a/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/protocols/__pycache__/wamp.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/geventwebsocket/protocols/__pycache__/wamp.cpython-39.pyc index 99b759fc6dae2310f87ee4f266574b2ea3c18e5c..1dedf3ad8d1401d30b62acbb5faa968dac22a73d 100644 GIT binary patch delta 26 gcmaE8`OuO(k(ZZ?0SL5>yf$)QWn^?){E$%^0A8~O%E;)l_#vY-0B1l4mjD0& diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/__pycache__/__init__.cpython-39.pyc index 25661c7064ea24877fe9b4b9f38cc1b323e221fb..9907d1bf7a08d2a11720f84dcea5f3009a78d7e6 100644 GIT binary patch delta 26 gcmX@ic9@Mjk(ZZ?0SMHMyf$)gU}AKeyoaeB08Oz5Qvd(} delta 26 gcmX@ic9@Mjk(ZZ?0SMeKJ8b0Mz{Kb>c@I-N09IHB2LJ#7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/__init__.cpython-39.pyc index 7966ae902013c6ffc72a488b0acdc5cff298273d..7f0320ae833ae8b48364fa33c12d9112987baf3e 100644 GIT binary patch delta 24 ecmdnQxQUTFk(ZZ?0SMHMye4wnGP+Il%me^B{{;O2 delta 24 ecmdnQxQUTFk(ZZ?0SMeKJ51!ZWptV7nF#N9M6;>1ps0=2EG6Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_cpp.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_cpp.cpython-39.pyc index 7266c392694aa86ba86b61126cb0eb2a399c4e26..10a5157af6a0cf9cbb68fe871d93c37acbb5ec32 100644 GIT binary patch delta 27 hcmX@Zc7}~Rk(ZZ?0SMHMyf$*bW@L2R{GBnB5dc{U2FL&a delta 27 hcmX@Zc7}~Rk(ZZ?0SMeKJ8a~B&B*Ao`8#7MBLHG#2Ydhk diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_extension_interface.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_extension_interface.cpython-39.pyc index 456ab84463612f73a5308ea11a3152e79bd261e5..17ad6f2b221df5611642ec50482b0cb700100af3 100644 GIT binary patch delta 27 hcmcaDeOsD4k(ZZ?0SMHMyf$(lVPtgMe1Vah2LN5G27>?q delta 27 hcmcaDeOsD4k(ZZ?0SMeKJ8a}W!pP{d`2r(14*+Kd2R8r! diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_gc.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_gc.cpython-39.pyc index f921fab1f579a55269cd1a64ac81b2f728a72d05..935ec1427138faf838526d81d0e6407cb7a0c832 100644 GIT binary patch delta 27 hcmca2c14Ukk(ZZ?0SMHMyf$*rU}SXLyo7NBCjeSd2DJbH delta 27 hcmca2c14Ukk(ZZ?0SMeKJ8a~h!N};cc?shNP5@)82WbER diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_generator.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_generator.cpython-39.pyc index e1795692df7205374e8ac6eb9c263b247f17c7df..b301f12db41d0d8f208167bce1291218d5e526e6 100644 GIT binary patch delta 27 hcmZ1@xJHmWk(ZZ?0SMHMyf$(hGcvkuwr9*`2LMZr1xx?{ delta 27 hcmZ1@xJHmWk(ZZ?0SMeKJ8a}OW@L2PY|og>4ggf>1^@s6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_generator_nested.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_generator_nested.cpython-39.pyc index bb6b38d97418fb03d639fbb3d6504bd63bcc0a74..1a03ceed6768a660b95f188b78fa4a1cf9edc60c 100644 GIT binary patch delta 27 hcmX@Fd0vw{k(ZZ?0SMHMyf$+0Vq|pNe2kG(7yw;(26zAf delta 27 hcmX@Fd0vw{k(ZZ?0SMeKJ8b0M#mMNg`4}UoFaT!L2P^;p diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_greenlet.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_greenlet.cpython-39.pyc index ece919beb1b6b837847dd5582f598ad7748f27f9..47c3d673bdae19dcb97a1ed83fcf31959d3d42f7 100644 GIT binary patch delta 29 jcmcb0i1F4TM(#vjUM>b8P&e}0$Q{MV=(ahH@k=}af8hu@ delta 29 jcmcb0i1F4TM(#vjUM>b8aJ%fVkvoc!(PeWQZxQECZxQEC@c)2EYIS diff --git a/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_weakref.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/greenlet/tests/__pycache__/test_weakref.cpython-39.pyc index a01f7b8db607f23a79963fc3c134defc0f87bd30..3675fdfba3cfb6c2f691b989db7aca09d7b437b6 100644 GIT binary patch delta 27 hcmdnax1EnWk(ZZ?0SMHMyf$)|GBUbtZe-lX3II_Z1}6Xj delta 27 hcmdnax1EnWk(ZZ?0SMeKJ8a}GWn^^O+{n0%6#!az2HOAt diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/INSTALLER b/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/LICENSE.txt b/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/LICENSE.txt deleted file mode 100644 index 8f080eae..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Nathaniel J. Smith and other contributors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/METADATA b/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/METADATA deleted file mode 100644 index 5478c3cc..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/METADATA +++ /dev/null @@ -1,194 +0,0 @@ -Metadata-Version: 2.1 -Name: h11 -Version: 0.12.0 -Summary: A pure-Python, bring-your-own-I/O implementation of HTTP/1.1 -Home-page: https://github.com/python-hyper/h11 -Author: Nathaniel J. Smith -Author-email: njs@pobox.com -License: MIT -Platform: UNKNOWN -Classifier: Development Status :: 3 - Alpha -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Topic :: Internet :: WWW/HTTP -Classifier: Topic :: System :: Networking -Requires-Python: >=3.6 - -h11 -=== - -.. image:: https://travis-ci.org/python-hyper/h11.svg?branch=master - :target: https://travis-ci.org/python-hyper/h11 - :alt: Automated test status - -.. image:: https://codecov.io/gh/python-hyper/h11/branch/master/graph/badge.svg - :target: https://codecov.io/gh/python-hyper/h11 - :alt: Test coverage - -.. image:: https://readthedocs.org/projects/h11/badge/?version=latest - :target: http://h11.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status - -This is a little HTTP/1.1 library written from scratch in Python, -heavily inspired by `hyper-h2 `_. - -It's a "bring-your-own-I/O" library; h11 contains no IO code -whatsoever. This means you can hook h11 up to your favorite network -API, and that could be anything you want: synchronous, threaded, -asynchronous, or your own implementation of `RFC 6214 -`_ -- h11 won't judge you. -(Compare this to the current state of the art, where every time a `new -network API `_ comes along then someone -gets to start over reimplementing the entire HTTP protocol from -scratch.) Cory Benfield made an `excellent blog post describing the -benefits of this approach -`_, or if you like video -then here's his `PyCon 2016 talk on the same theme -`_. - -This also means that h11 is not immediately useful out of the box: -it's a toolkit for building programs that speak HTTP, not something -that could directly replace ``requests`` or ``twisted.web`` or -whatever. But h11 makes it much easier to implement something like -``requests`` or ``twisted.web``. - -At a high level, working with h11 goes like this: - -1) First, create an ``h11.Connection`` object to track the state of a - single HTTP/1.1 connection. - -2) When you read data off the network, pass it to - ``conn.receive_data(...)``; you'll get back a list of objects - representing high-level HTTP "events". - -3) When you want to send a high-level HTTP event, create the - corresponding "event" object and pass it to ``conn.send(...)``; - this will give you back some bytes that you can then push out - through the network. - -For example, a client might instantiate and then send a -``h11.Request`` object, then zero or more ``h11.Data`` objects for the -request body (e.g., if this is a POST), and then a -``h11.EndOfMessage`` to indicate the end of the message. Then the -server would then send back a ``h11.Response``, some ``h11.Data``, and -its own ``h11.EndOfMessage``. If either side violates the protocol, -you'll get a ``h11.ProtocolError`` exception. - -h11 is suitable for implementing both servers and clients, and has a -pleasantly symmetric API: the events you send as a client are exactly -the ones that you receive as a server and vice-versa. - -`Here's an example of a tiny HTTP client -`_ - -It also has `a fine manual `_. - -FAQ ---- - -*Whyyyyy?* - -I wanted to play with HTTP in `Curio -`__ and `Trio -`__, which at the time didn't have any -HTTP libraries. So I thought, no big deal, Python has, like, a dozen -different implementations of HTTP, surely I can find one that's -reusable. I didn't find one, but I did find Cory's call-to-arms -blog-post. So I figured, well, fine, if I have to implement HTTP from -scratch, at least I can make sure no-one *else* has to ever again. - -*Should I use it?* - -Maybe. You should be aware that it's a very young project. But, it's -feature complete and has an exhaustive test-suite and complete docs, -so the next step is for people to try using it and see how it goes -:-). If you do then please let us know -- if nothing else we'll want -to talk to you before making any incompatible changes! - -*What are the features/limitations?* - -Roughly speaking, it's trying to be a robust, complete, and non-hacky -implementation of the first "chapter" of the HTTP/1.1 spec: `RFC 7230: -HTTP/1.1 Message Syntax and Routing -`_. That is, it mostly focuses on -implementing HTTP at the level of taking bytes on and off the wire, -and the headers related to that, and tries to be anal about spec -conformance. It doesn't know about higher-level concerns like URL -routing, conditional GETs, cross-origin cookie policies, or content -negotiation. But it does know how to take care of framing, -cross-version differences in keep-alive handling, and the "obsolete -line folding" rule, so you can focus your energies on the hard / -interesting parts for your application, and it tries to support the -full specification in the sense that any useful HTTP/1.1 conformant -application should be able to use h11. - -It's pure Python, and has no dependencies outside of the standard -library. - -It has a test suite with 100.0% coverage for both statements and -branches. - -Currently it supports Python 3 (testing on 3.6-3.9) and PyPy 3. -The last Python 2-compatible version was h11 0.11.x. -(Originally it had a Cython wrapper for `http-parser -`_ and a beautiful nested state -machine implemented with ``yield from`` to postprocess the output. But -I had to take these out -- the new *parser* needs fewer lines-of-code -than the old *parser wrapper*, is written in pure Python, uses no -exotic language syntax, and has more features. It's sad, really; that -old state machine was really slick. I just need a few sentences here -to mourn that.) - -I don't know how fast it is. I haven't benchmarked or profiled it yet, -so it's probably got a few pointless hot spots, and I've been trying -to err on the side of simplicity and robustness instead of -micro-optimization. But at the architectural level I tried hard to -avoid fundamentally bad decisions, e.g., I believe that all the -parsing algorithms remain linear-time even in the face of pathological -input like slowloris, and there are no byte-by-byte loops. (I also -believe that it maintains bounded memory usage in the face of -arbitrary/pathological input.) - -The whole library is ~800 lines-of-code. You can read and understand -the whole thing in less than an hour. Most of the energy invested in -this so far has been spent on trying to keep things simple by -minimizing special-cases and ad hoc state manipulation; even though it -is now quite small and simple, I'm still annoyed that I haven't -figured out how to make it even smaller and simpler. (Unfortunately, -HTTP does not lend itself to simplicity.) - -The API is ~feature complete and I don't expect the general outlines -to change much, but you can't judge an API's ergonomics until you -actually document and use it, so I'd expect some changes in the -details. - -*How do I try it?* - -.. code-block:: sh - - $ pip install h11 - $ git clone git@github.com:python-hyper/h11 - $ cd h11/examples - $ python basic-client.py - -and go from there. - -*License?* - -MIT - -*Code of conduct?* - -Contributors are requested to follow our `code of conduct -`_ in -all project spaces. - - diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/RECORD deleted file mode 100644 index aa6f50d2..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/RECORD +++ /dev/null @@ -1,51 +0,0 @@ -h11-0.12.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -h11-0.12.0.dist-info/LICENSE.txt,sha256=N9tbuFkm2yikJ6JYZ_ELEjIAOuob5pzLhRE4rbjm82E,1124 -h11-0.12.0.dist-info/METADATA,sha256=_X-4TWqWCxSJ_mDyAbZPzdxHqP290_yVu09nelJOk04,8109 -h11-0.12.0.dist-info/RECORD,, -h11-0.12.0.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92 -h11-0.12.0.dist-info/top_level.txt,sha256=F7dC4jl3zeh8TGHEPaWJrMbeuoWbS379Gwdi-Yvdcis,4 -h11/__init__.py,sha256=3gYpvQiX8_6-dyXaAxQt_sIYREVTz1T-zB5Lf4hjKt0,909 -h11/__pycache__/__init__.cpython-39.pyc,, -h11/__pycache__/_abnf.cpython-39.pyc,, -h11/__pycache__/_connection.cpython-39.pyc,, -h11/__pycache__/_events.cpython-39.pyc,, -h11/__pycache__/_headers.cpython-39.pyc,, -h11/__pycache__/_readers.cpython-39.pyc,, -h11/__pycache__/_receivebuffer.cpython-39.pyc,, -h11/__pycache__/_state.cpython-39.pyc,, -h11/__pycache__/_util.cpython-39.pyc,, -h11/__pycache__/_version.cpython-39.pyc,, -h11/__pycache__/_writers.cpython-39.pyc,, -h11/_abnf.py,sha256=tMKqgOEkTHHp8sPd_gmU9Qowe_yXXrihct63RX2zJsg,4637 -h11/_connection.py,sha256=XFZ-LPb3C2vgF4v5ifmcJqX-a2tHkItucJ7uIGvPYZA,24964 -h11/_events.py,sha256=IJtM7i2TxKv0S-givq2b-oehPVsmsbsIelTW6NHcIvg,9834 -h11/_headers.py,sha256=P2h8Q39SIFiRS9CpYjAwo_99XKJUvLHjn0U3tnm4qHE,9130 -h11/_readers.py,sha256=DmJKQwH9Iu7U3WNljKB09d6iJIO6P2_WtylJEY3HvPY,7280 -h11/_receivebuffer.py,sha256=pMOLWjS53haaCm73O6tSWKFD_6BQQWzVLqLCm2ouvcE,5029 -h11/_state.py,sha256=Upg0_uiO_C_QNXHxLB4YUprEeoeso0i_ma12SOrrA54,12167 -h11/_util.py,sha256=Lw_CoIUMR8wjnvgKwo94FCdmFcIbRQsokmxpBV7LcTI,4387 -h11/_version.py,sha256=14wRZqPo0n2t5kFKCQLsldnyZAfOZoKPJbbwJnbGPcc,686 -h11/_writers.py,sha256=dj8HQ4Pnzq5SjkUZrgh3RKQ6-8Ecy9RKC1MjSo27y4s,4173 -h11/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -h11/tests/__pycache__/__init__.cpython-39.pyc,, -h11/tests/__pycache__/helpers.cpython-39.pyc,, -h11/tests/__pycache__/test_against_stdlib_http.cpython-39.pyc,, -h11/tests/__pycache__/test_connection.cpython-39.pyc,, -h11/tests/__pycache__/test_events.cpython-39.pyc,, -h11/tests/__pycache__/test_headers.cpython-39.pyc,, -h11/tests/__pycache__/test_helpers.cpython-39.pyc,, -h11/tests/__pycache__/test_io.cpython-39.pyc,, -h11/tests/__pycache__/test_receivebuffer.cpython-39.pyc,, -h11/tests/__pycache__/test_state.cpython-39.pyc,, -h11/tests/__pycache__/test_util.cpython-39.pyc,, -h11/tests/data/test-file,sha256=ZJ03Rqs98oJw29OHzJg7LlMzyGQaRAY0r3AqBeM2wVU,65 -h11/tests/helpers.py,sha256=nKheRzldPf278C81d_9_Mb9yWsYJ5udwKg_oq-fAz-U,2528 -h11/tests/test_against_stdlib_http.py,sha256=aA4oDd3_jXkapvW0ER9dbGxIiNt6Ytsfs3U2Rd5XtUc,3700 -h11/tests/test_connection.py,sha256=1WybI9IQROZ0QPtR2wQjetPIR_Jwsvw5i5j2fO7XtcI,36375 -h11/tests/test_events.py,sha256=RTPFBIg81Muc7ZoDhsLwaZxthD76R1UCzHF5nzsbM-Q,5182 -h11/tests/test_headers.py,sha256=pa-WMjCk8ZXJFABkojr2db7ZKrgNKiwl-D-hjjt6-Eg,5390 -h11/tests/test_helpers.py,sha256=mPOAiv4HtyG0_T23K_ihh1JUs0y71ykD47c9r3iVtz0,573 -h11/tests/test_io.py,sha256=oaIEAy3ktA_e1xuyP09fX_GiSlS7GKMlFhQIdkg-EhI,15494 -h11/tests/test_receivebuffer.py,sha256=nZ9_LXj3wfyOn4dkgvjnDjZeNTEtxO8-lNphAB0FVF0,3399 -h11/tests/test_state.py,sha256=JMKqA2d2wtskf7FbsAr1s9qsIul4WtwdXVAOCUJgalk,8551 -h11/tests/test_util.py,sha256=j28tMloUSuhlpUxmgvS1PRurRFSbyzWb7yCTp6qy9_Q,2710 diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/WHEEL b/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/WHEEL deleted file mode 100644 index 385faab0..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.36.2) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/top_level.txt b/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/top_level.txt deleted file mode 100644 index 0d24def7..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11-0.12.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -h11 diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/h11/__init__.py deleted file mode 100644 index ae39e012..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# A highish-level implementation of the HTTP/1.1 wire protocol (RFC 7230), -# containing no networking code at all, loosely modelled on hyper-h2's generic -# implementation of HTTP/2 (and in particular the h2.connection.H2Connection -# class). There's still a bunch of subtle details you need to get right if you -# want to make this actually useful, because it doesn't implement all the -# semantics to check that what you're asking to write to the wire is sensible, -# but at least it gets you out of dealing with the wire itself. - -from ._connection import * -from ._events import * -from ._state import * -from ._util import LocalProtocolError, ProtocolError, RemoteProtocolError -from ._version import __version__ - -PRODUCT_ID = "python-h11/" + __version__ - - -__all__ = ["ProtocolError", "LocalProtocolError", "RemoteProtocolError"] -__all__ += _events.__all__ -__all__ += _connection.__all__ -__all__ += _state.__all__ diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 84f9f8220bdb0845070217424cc46c11e1545855..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 485 zcmY*U(N4lJ6m2&)#*h~@@f&6Wh9?taj6`@K5+#5y&61nCH8AW}(iIZ?2YA5(sIU@)zo7i@`~_|39HRW?7UFs3t!NMe@3>9{4s0CVs}D<>IcQZfEM&5 zu#4tUMO==wGAdHCueH)eV_zPQMXHS0J4AaOU@df>s0`q#zTB9(%3AYI=QOZ&1rs!W znrH{%HmKutq_Rvz2IpB7#9Cw~FI>nCH-b5^GKt(dw%*cKc)tPKMalfp_^x+*RG!!|~*!(s9e=7|xl sC66BYOypttbbusF3_yFiDZGnR#VaW;Yj}6wMDS=?NA$q*Y>)a_-?Q+4I{*Lx diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_abnf.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_abnf.cpython-39.pyc deleted file mode 100644 index 988037bae58100038695c46ba0fa72fa20d2a118..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1214 zcmZ8h%Wl&^6m^n`>%96fj}0KTD$qE=X;K!5wn`eQg;tMP1si^crB_J&1VX4~Y$t6JTb`MF&YijUo@*OrGD(hIzpkq2k;rksePi+h%-CU% z^^*;lgB*^)2#LTbj=~s@K|lbEWAKS@acz#wedWGKzD1yb<1NHV1Rfff)V%6!I(`u6rRtHTDnQlH? z*$ht0Ps37hy110>hO8 z7b-ZT=yY}em8)v_rFs%`UiKzxI9v^lC&QCYMOHaxV(_^;N z)`^#z&=6*(G=pQ#cZ7VXmY2Mh117>Xs~@JrWth(o&P=e+JsAET>~1PY7n*J8iivb= zbd}?#W*8mi;LToDwVEdC5mPA)h(1u>wi}Aowu#(B&2w}{EJZ7o)>YKdTZP_*Cv0~O z-0zUG;Qvv|Yyb%WzzT@?w+KWa0Pqi7M@42uKy+kfm=zTS@P{#Jz>7R%qTmW#{|AZl BfKUJc diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_connection.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_connection.cpython-39.pyc deleted file mode 100644 index f31278d691b5d6b5845ae1f7e400ffd9309fbd58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14438 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 T-(VlJU?3N}l$k7y6~6etu!}tj diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_events.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_events.cpython-39.pyc deleted file mode 100644 index 113bdd6d41ad1cbf1488594481fbdaae20826d60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8972 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 G%zprqFN#9| diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_headers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_headers.cpython-39.pyc deleted file mode 100644 index c062a0923a86ca2717a32eca02deb2f6e0ecd90f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4618 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_receivebuffer.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_receivebuffer.cpython-39.pyc deleted file mode 100644 index 69f4bf6c7aada792be6167f7c89aa293c27f5442..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2968 zcmb7G&2tY^ z7|MTtelPj{0%QN9&dK7Va~-vK9Yit3GuEnF-r`EE^On%;z*C-PoBp9_1s^fxEAcf` zVqdgsir;0;;0SBkYT3A>J38IbHwN9VHU(`RHQtRnG<&iLbgrWoZ4k{MhqZ))w69qU zl9Z3uSAnXb4OCr)XlrUtMQH14UM-*vRYNVJol{S!CA5(`r_Q6DR~OVpv4f}AeQa3F_Tb28Vv zR%U6gWr3;AM!76|gUqJenRdg)Wc)ra{X%Em`^=Ch{(t9#zqdafZrFa_Hc77fz4qPC zM!%o6Z+&v}Jy~>2vaL;fWk=^b?c3>EyGX76^LEnNO4fDJ-ne@8HEAj{uQ@ZXY!Ay& z$}~@{l&{gDY9NeaYlgw{2^N-e^ise|1296-vT(;wuv^!fvP+C>N*lXUD2@E0yUiABC3YP=>+ zA$G$0+e*jS#Hq=rN{eEd^3s?cVC;}Glo;KJ;z_w#36GPwo9=2A=Y!swHgUfjI|IdC z)9=N0L&uZ&nl4-g_?`DDYnV$!Ncj`kztl^HYg$fpmWh?UeqnEesUWN}f06s#7o$JS zy5`JPGa#Wm|F!L51vC`rR~FRaB8ln|_sB&Q}Rl7B(>!iB0L<*8Dd9(V%)rsbHrB#ftJ^ z@R%T{#3AQw9cgni@4NW`^Vi+He>`vDGU7qS)e0x#4jM3HEUrFVqnUlKd~z@%&v%gK z2X$3DjpCjbsDmZk{ANwD$e_z}S#=*gy3Jo5T7?>ygv@ia38ib?z1vA%2E}%k+A`F+D*lt&jb?3fY9h=<|@5sA_BkAt1t zaRzc^49XlX?kPQwmMTyIaAJ#n36S}?BZn_?M&G{x!@KM+NZ@dvUp-%rp2xBeC#kE9 zZc#YhG^TIPyu@BjixV%K{@PC39~9XTQMi+2slwCa-ar@C!{=LUT;(+`aN-3%dUN)4 zzhke}W`kZ1dD7ETmXSo_R0F)EWVs;ay+M*yGlpIThQisLBSOy=bCHP4$yex)&TCeP zTqW`_MY}(Gqqs*QaTK&PgEMwebOEK1z#NrneSS*P@uX1bjF l=jXRSyLJ24>P-Pa8Sd_xot+)+>dSI$$4OWM#NNax7*ZT4L&ZpIS&qDN?QW9FmZ+)8c1s$0 zG%NSCY$Vnf>?-&LoF#6)@+-(6;4lZOfD;#Pq$r9aJa5mgzK~KBGd1ti{r1OnzaLL` zRI3FH&!7H%H~Q84jQxcwC!b5Ge26dm4QEU;$rIKk6bauJJ+bZd9L_eFbbiZwu5zUN zg7-?m63_#Bz%sB5^npIG0;~W7U;vx|P5`UGDzFBu0Vjczz$xGqa2hxboKYoJRbRO1VReL)F;i3cYB7s_Iy#6T~X7} zO`$wP7`y+|KaS>)MenMbR8tsR!f1{^1t@!J!j{WN<=P2-psKb%^(mhy2dXyK$K~F& zB_?O&>`NwRUx?o8@=}L2=Kc!bum;chyA6@gt_=E7@<gqq}k5h<;9g|Uh6bli($Ljd9>Q`hC9G9@ zB+4Xw5)~2@hKNG`=o)^j9673j*6^nfKKEK0J%jMjo=%iPOo5!oxAyO~PXUom|R z>VH01{L$K@y-hPn*L0N1!S-6Gzd0BrYs()s?}k}lM>|Td%|BJ?)3ufO^R+BC>bpBp z|8caTvbD|Ix8D!##Pd6QxgUmc8k;cu0yAgyS61>|U+iB!V~Y84$G)IWqle1m5^Iy! zP%yB?79a9Ezyoo}IC!PQUh!7LDV$H8@^6Ogu}19D_CllMjSZ!hL@7$KSXe)62z`}$ zx_Xc(yX``}PRbfA)>l~;DoTVuK$VeW7!UaVn`hU3s_%a}lr~@&KZ`=)P%NB}7Y-NR z!%~Pa^_wKFkRUIdSkCqFFOD4@$~cQYPn68jb+kB-@4t7^;?5a)v7N~KXeZ|nZuPB$ zFaqQ@SP&wi5{U5YdUm;gz zJyZIr()C|FuUmW7k*%A9T~m+hqXe$QVm5OdK|y|Gb?rdp-uggqM<(~%D%(LkD?LZ* zQQ+J8&JX;&+*VI^Rb~n@prC8GHW&0;G(#{NySJlymx>jRJ$0^Ek8_25{%1^Kxr=e1 zSCKD*yIg!FzH&=GpC+9{`suIBBbujAn;bvnO5%Cz&K?RBoI`$%J$Lr!41)9;9E?vu z<9^E0TP`zV?*RunaAq7h*By$j5}Y;~cj%C#KVzx*9vixa_KqbIYJdx zM2%cyU=DKBvrU!Oi86kS3Odv+#h}vgv}K;_%};PdhTZn^(o(aHldRjm+v+TLmvK1e z{zq!ho~_o0`diov5o8)|t1xVoj=i97P*cfH-m9eQSwUrIGD?33y}rbkk?)C}1fPR- z$>x)=c~IKFeKw5>V*Hx;IK^OO`J*H0cc>Kf`+`3wTMB&>k{j6GrpQfGD(XbeTOzx6 z)LKH4+%sfp^tP>Drg5O*QnSc@_6CxTNFDyO^K^}0)bFq--SHe2%hwoE(=nBUVCcl` zP&~JD9!w0~f~e?dcr3K_PFQ@*0@WL>ioC4^*2;y@{19MXl!8n7rE2^;{0?!7~$KS$WhwdNC&1Kr}e0=)vi69isYCF&n4^gg=HvHDuowlA;tC0 znw=8fW<+rqTBfr%mGe%-Y0L&|r|Rb>?C}k1T-z`8)n3wh#J0@ls8YR#1eGT3pbV`wxV>B{Em|{}LWinoI2{pXm2D Q@pt!~s-Ur>_e*#3KOyXJLjV8( diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_util.cpython-39.pyc deleted file mode 100644 index 3443e8224f69df9dcef160b85cf9a2a913a226c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3212 zcmai1&vO$u6qa_^j%^YeXrVu*2QlqTYYL{!Fg>^(CO~P+l%`CRlP5EavXX7V+G`{^ zA&j{Y&Yk`V&>R2K-a0+?U+AIJ?`h)@Cz*DGWJxQ%_r3SN_g2W2l@`PE$3M5^C+8UZ zlO{)>1d}y1*GD&Civ7-e?0crTie54mX}%x#BFtlzV4mm*^BD7*s$*Uc^F*Cf4b^ zyT9mB;q~HTV@KvjNw3S5k$kLEr^numbzU~M_q=wdzn8&~g(t>r4b6RoPO~0YtQRTX zi&Z_C#e0dW0oIb`*dTv`OYT0+^u(KDEX-J$OhUy#NU>vz9AhjOec^{%{II$C;M(=h zbul@xrqgN(Jexz~gv7tGklW5%nR&4-ofcUxox37-jUNiXTZpU}XI6WC}>9|Cxg7PcJ1b#l)MKs0%-2Qt3` zph{EyJ6Rqv(2r7WbwO8UQ1Rb%Vwdh*i?>^MTh^s?D%7Ol& z=oeNf?WM`xfqU=4txA~?2^dQl#)Tcp{J@68@ZqqQerh#*ZoC*GB*j<@>EWpDsn^{q zT%FF5rLG77Qs;5frSPDycFp5DFgvhb3O5}LvfdMi6YCU)*^C{Gm+L4y(HZFWD5BQHsi#1aD@ENFa?yPB@h;>? zF-MNXLsC!mTd$SXJESVUm=MG&N)6)3iKy zg8J>aOq|a9Wjt~Ny9}&vn0*I7f8YDIyY*mi=!@}|MXna3t&MD06#3S@AMf5uU1lY; zZgqC_cxUUr+1_%->#Gx)J(kFtEkx&9I`t;+O!n*<$om}4HPA7>%o}LWE-o0-nS)$! zbGw9X?HU0e%aI1~R+^3qHO*({Gl-|hDe{qfFhmp8GC`R&<1c4IhUzeZ%bvR*u0eFQrynX`D`_!;n6W>709Mh}+jV6^vj@_13c+Co`_|zarLQ z1g;6po~Q0z>OP>3B7UR`ej~fOXpROAUKx+!!b1*NLvuu(w_YP62fNqX@o|Nx=^_{X zOkxgn(fseTsQ9Q4BP2I&1acw8YS=)VzNbT1(9PH@N+$k1nI-PiS!_R^MUVI_{*^tC zd^C$FE$Ajk5p#m>n;0A^&Z{%H4QydP-jD33;8dcBQ`K4xYhU@g3S9C?@_is|$LnQH zy3CkopXjF(lxxs6+*PmU=CKyV_9Lua!374Now3I)l!{g`kf`|Vc6W1{@FgylvkO3o*;{e3P96%z4A&Mb|F_=M9wt7Cj| za#3PIYEg_{S!!Ncj8A4#OmSvOs%}AIa&}^RYH>`4p`kv^V7-FMTO2mI`6;D2sdfTD J3qAue0|4XKGW`Gm diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_writers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/__pycache__/_writers.cpython-39.pyc deleted file mode 100644 index a539149c90dcc913af9c3337b83dbc0bac019582..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3479 zcmbtXO>^7E8O8!22+<@>QL@v6+j7z-6IxU<0bBWWd&7U=04svzQikd*FUoOHD3M7;?+|-xDKku>!9l5`l%B%Kwsw# z&<#T`gI?xM&`m=(g)2&jwx|i;yz6+ELDz*RmPJD}`N}_>p&P95)qSgd<68zX+O~GL zqb$m2#crFAso&<<`vTDPlQ+%!m4 zrhI&?se7$8RjYhQjMXY_=p;NG$8k8!#7MP0T^@*t3#oMJbBQs%B%{xZN$t~T5{-m* zO<#H*#ba@1$rYUS{qFX?-lLO2mL@$JB|IJV_WOf0je9#EcRmPJUq;75_ST<^YxgM)CpEakwyn(R`Ad_4q zu>twF_#lu0sUw>iAU$PYG6D#rHkvboH*-Oia&~G=+5q>RgWa3!o8PbQw9+I#X(^HL z)`NqCM|Uu4*jZBmb3Oz(JzX7S*>U(B2oBRkl4EIaB(g!uwUdKoqOTLCqmm<|44vq9PCBXOsH2;X%?mtB`4u**IPJBnILAMX)HCF z{1wLfXcr!`j{9he@D*0TxE0tOc7Y(|aEJ7+D<7u(Vl>$aILhq2k)wq+Y@v{#Vl z#4rvA@rTJU3&RI=khy_PZe4LZKr0q5wvY`Rk;5CGSQ#SDDZ2{}! zQ_+do&6)Bk!sLi=MKmf32?Tp%Zx}~5oR$erQ6{W?QLD%*Hn*94A1_G>^qhFc%}MUh z(2AJixXeXV@!90H3(T!AwjBy+##1S)5PQT1v6$QQ^lNt&E!&_HrN|T%Szcv@(0`0( zY8;E0xOoK=h??EA(yKcBarIHq{M+ngsBcNq$p59h>H|~;n;Q#sH+Lw4f2JeSpQJ!i z2);-g17eg8umHgMTYf|d^ZTf*g1c5TR7rDpwY!ry`w=-9sqv-LW$CQi*=Y6SA?2PW z?3as_^AwX)<-pBuT;`2*BY#gv7}t5(8B@E5iKE#OpcIa?VO-QO diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_abnf.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_abnf.py deleted file mode 100644 index e6d49e1e..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_abnf.py +++ /dev/null @@ -1,129 +0,0 @@ -# We use native strings for all the re patterns, to take advantage of string -# formatting, and then convert to bytestrings when compiling the final re -# objects. - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#whitespace -# OWS = *( SP / HTAB ) -# ; optional whitespace -OWS = r"[ \t]*" - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.token.separators -# token = 1*tchar -# -# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" -# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" -# / DIGIT / ALPHA -# ; any VCHAR, except delimiters -token = r"[-!#$%&'*+.^_`|~0-9a-zA-Z]+" - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#header.fields -# field-name = token -field_name = token - -# The standard says: -# -# field-value = *( field-content / obs-fold ) -# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] -# field-vchar = VCHAR / obs-text -# obs-fold = CRLF 1*( SP / HTAB ) -# ; obsolete line folding -# ; see Section 3.2.4 -# -# https://tools.ietf.org/html/rfc5234#appendix-B.1 -# -# VCHAR = %x21-7E -# ; visible (printing) characters -# -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.quoted-string -# obs-text = %x80-FF -# -# However, the standard definition of field-content is WRONG! It disallows -# fields containing a single visible character surrounded by whitespace, -# e.g. "foo a bar". -# -# See: https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4189 -# -# So our definition of field_content attempts to fix it up... -# -# Also, we allow lots of control characters, because apparently people assume -# that they're legal in practice (e.g., google analytics makes cookies with -# \x01 in them!): -# https://github.com/python-hyper/h11/issues/57 -# We still don't allow NUL or whitespace, because those are often treated as -# meta-characters and letting them through can lead to nasty issues like SSRF. -vchar = r"[\x21-\x7e]" -vchar_or_obs_text = r"[^\x00\s]" -field_vchar = vchar_or_obs_text -field_content = r"{field_vchar}+(?:[ \t]+{field_vchar}+)*".format(**globals()) - -# We handle obs-fold at a different level, and our fixed-up field_content -# already grows to swallow the whole value, so ? instead of * -field_value = r"({field_content})?".format(**globals()) - -# header-field = field-name ":" OWS field-value OWS -header_field = ( - r"(?P{field_name})" - r":" - r"{OWS}" - r"(?P{field_value})" - r"{OWS}".format(**globals()) -) - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#request.line -# -# request-line = method SP request-target SP HTTP-version CRLF -# method = token -# HTTP-version = HTTP-name "/" DIGIT "." DIGIT -# HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive -# -# request-target is complicated (see RFC 7230 sec 5.3) -- could be path, full -# URL, host+port (for connect), or even "*", but in any case we are guaranteed -# that it contists of the visible printing characters. -method = token -request_target = r"{vchar}+".format(**globals()) -http_version = r"HTTP/(?P[0-9]\.[0-9])" -request_line = ( - r"(?P{method})" - r" " - r"(?P{request_target})" - r" " - r"{http_version}".format(**globals()) -) - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#status.line -# -# status-line = HTTP-version SP status-code SP reason-phrase CRLF -# status-code = 3DIGIT -# reason-phrase = *( HTAB / SP / VCHAR / obs-text ) -status_code = r"[0-9]{3}" -reason_phrase = r"([ \t]|{vchar_or_obs_text})*".format(**globals()) -status_line = ( - r"{http_version}" - r" " - r"(?P{status_code})" - # However, there are apparently a few too many servers out there that just - # leave out the reason phrase: - # https://github.com/scrapy/scrapy/issues/345#issuecomment-281756036 - # https://github.com/seanmonstar/httparse/issues/29 - # so make it optional. ?: is a non-capturing group. - r"(?: (?P{reason_phrase}))?".format(**globals()) -) - -HEXDIG = r"[0-9A-Fa-f]" -# Actually -# -# chunk-size = 1*HEXDIG -# -# but we impose an upper-limit to avoid ridiculosity. len(str(2**64)) == 20 -chunk_size = r"({HEXDIG}){{1,20}}".format(**globals()) -# Actually -# -# chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) -# -# but we aren't parsing the things so we don't really care. -chunk_ext = r";.*" -chunk_header = ( - r"(?P{chunk_size})" - r"(?P{chunk_ext})?" - r"\r\n".format(**globals()) -) diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_connection.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_connection.py deleted file mode 100644 index 6f796ef5..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_connection.py +++ /dev/null @@ -1,585 +0,0 @@ -# This contains the main Connection class. Everything in h11 revolves around -# this. - -from ._events import * # Import all event types -from ._headers import get_comma_header, has_expect_100_continue, set_comma_header -from ._readers import READERS -from ._receivebuffer import ReceiveBuffer -from ._state import * # Import all state sentinels -from ._state import _SWITCH_CONNECT, _SWITCH_UPGRADE, ConnectionState -from ._util import ( # Import the internal things we need - LocalProtocolError, - make_sentinel, - RemoteProtocolError, -) -from ._writers import WRITERS - -# Everything in __all__ gets re-exported as part of the h11 public API. -__all__ = ["Connection", "NEED_DATA", "PAUSED"] - -NEED_DATA = make_sentinel("NEED_DATA") -PAUSED = make_sentinel("PAUSED") - -# If we ever have this much buffered without it making a complete parseable -# event, we error out. The only time we really buffer is when reading the -# request/reponse line + headers together, so this is effectively the limit on -# the size of that. -# -# Some precedents for defaults: -# - node.js: 80 * 1024 -# - tomcat: 8 * 1024 -# - IIS: 16 * 1024 -# - Apache: <8 KiB per line> -DEFAULT_MAX_INCOMPLETE_EVENT_SIZE = 16 * 1024 - -# RFC 7230's rules for connection lifecycles: -# - If either side says they want to close the connection, then the connection -# must close. -# - HTTP/1.1 defaults to keep-alive unless someone says Connection: close -# - HTTP/1.0 defaults to close unless both sides say Connection: keep-alive -# (and even this is a mess -- e.g. if you're implementing a proxy then -# sending Connection: keep-alive is forbidden). -# -# We simplify life by simply not supporting keep-alive with HTTP/1.0 peers. So -# our rule is: -# - If someone says Connection: close, we will close -# - If someone uses HTTP/1.0, we will close. -def _keep_alive(event): - connection = get_comma_header(event.headers, b"connection") - if b"close" in connection: - return False - if getattr(event, "http_version", b"1.1") < b"1.1": - return False - return True - - -def _body_framing(request_method, event): - # Called when we enter SEND_BODY to figure out framing information for - # this body. - # - # These are the only two events that can trigger a SEND_BODY state: - assert type(event) in (Request, Response) - # Returns one of: - # - # ("content-length", count) - # ("chunked", ()) - # ("http/1.0", ()) - # - # which are (lookup key, *args) for constructing body reader/writer - # objects. - # - # Reference: https://tools.ietf.org/html/rfc7230#section-3.3.3 - # - # Step 1: some responses always have an empty body, regardless of what the - # headers say. - if type(event) is Response: - if ( - event.status_code in (204, 304) - or request_method == b"HEAD" - or (request_method == b"CONNECT" and 200 <= event.status_code < 300) - ): - return ("content-length", (0,)) - # Section 3.3.3 also lists another case -- responses with status_code - # < 200. For us these are InformationalResponses, not Responses, so - # they can't get into this function in the first place. - assert event.status_code >= 200 - - # Step 2: check for Transfer-Encoding (T-E beats C-L): - transfer_encodings = get_comma_header(event.headers, b"transfer-encoding") - if transfer_encodings: - assert transfer_encodings == [b"chunked"] - return ("chunked", ()) - - # Step 3: check for Content-Length - content_lengths = get_comma_header(event.headers, b"content-length") - if content_lengths: - return ("content-length", (int(content_lengths[0]),)) - - # Step 4: no applicable headers; fallback/default depends on type - if type(event) is Request: - return ("content-length", (0,)) - else: - return ("http/1.0", ()) - - -################################################################ -# -# The main Connection class -# -################################################################ - - -class Connection: - """An object encapsulating the state of an HTTP connection. - - Args: - our_role: If you're implementing a client, pass :data:`h11.CLIENT`. If - you're implementing a server, pass :data:`h11.SERVER`. - - max_incomplete_event_size (int): - The maximum number of bytes we're willing to buffer of an - incomplete event. In practice this mostly sets a limit on the - maximum size of the request/response line + headers. If this is - exceeded, then :meth:`next_event` will raise - :exc:`RemoteProtocolError`. - - """ - - def __init__( - self, our_role, max_incomplete_event_size=DEFAULT_MAX_INCOMPLETE_EVENT_SIZE - ): - self._max_incomplete_event_size = max_incomplete_event_size - # State and role tracking - if our_role not in (CLIENT, SERVER): - raise ValueError("expected CLIENT or SERVER, not {!r}".format(our_role)) - self.our_role = our_role - if our_role is CLIENT: - self.their_role = SERVER - else: - self.their_role = CLIENT - self._cstate = ConnectionState() - - # Callables for converting data->events or vice-versa given the - # current state - self._writer = self._get_io_object(self.our_role, None, WRITERS) - self._reader = self._get_io_object(self.their_role, None, READERS) - - # Holds any unprocessed received data - self._receive_buffer = ReceiveBuffer() - # If this is true, then it indicates that the incoming connection was - # closed *after* the end of whatever's in self._receive_buffer: - self._receive_buffer_closed = False - - # Extra bits of state that don't fit into the state machine. - # - # These two are only used to interpret framing headers for figuring - # out how to read/write response bodies. their_http_version is also - # made available as a convenient public API. - self.their_http_version = None - self._request_method = None - # This is pure flow-control and doesn't at all affect the set of legal - # transitions, so no need to bother ConnectionState with it: - self.client_is_waiting_for_100_continue = False - - @property - def states(self): - """A dictionary like:: - - {CLIENT: , SERVER: } - - See :ref:`state-machine` for details. - - """ - return dict(self._cstate.states) - - @property - def our_state(self): - """The current state of whichever role we are playing. See - :ref:`state-machine` for details. - """ - return self._cstate.states[self.our_role] - - @property - def their_state(self): - """The current state of whichever role we are NOT playing. See - :ref:`state-machine` for details. - """ - return self._cstate.states[self.their_role] - - @property - def they_are_waiting_for_100_continue(self): - return self.their_role is CLIENT and self.client_is_waiting_for_100_continue - - def start_next_cycle(self): - """Attempt to reset our connection state for a new request/response - cycle. - - If both client and server are in :data:`DONE` state, then resets them - both to :data:`IDLE` state in preparation for a new request/response - cycle on this same connection. Otherwise, raises a - :exc:`LocalProtocolError`. - - See :ref:`keepalive-and-pipelining`. - - """ - old_states = dict(self._cstate.states) - self._cstate.start_next_cycle() - self._request_method = None - # self.their_http_version gets left alone, since it presumably lasts - # beyond a single request/response cycle - assert not self.client_is_waiting_for_100_continue - self._respond_to_state_changes(old_states) - - def _process_error(self, role): - old_states = dict(self._cstate.states) - self._cstate.process_error(role) - self._respond_to_state_changes(old_states) - - def _server_switch_event(self, event): - if type(event) is InformationalResponse and event.status_code == 101: - return _SWITCH_UPGRADE - if type(event) is Response: - if ( - _SWITCH_CONNECT in self._cstate.pending_switch_proposals - and 200 <= event.status_code < 300 - ): - return _SWITCH_CONNECT - return None - - # All events go through here - def _process_event(self, role, event): - # First, pass the event through the state machine to make sure it - # succeeds. - old_states = dict(self._cstate.states) - if role is CLIENT and type(event) is Request: - if event.method == b"CONNECT": - self._cstate.process_client_switch_proposal(_SWITCH_CONNECT) - if get_comma_header(event.headers, b"upgrade"): - self._cstate.process_client_switch_proposal(_SWITCH_UPGRADE) - server_switch_event = None - if role is SERVER: - server_switch_event = self._server_switch_event(event) - self._cstate.process_event(role, type(event), server_switch_event) - - # Then perform the updates triggered by it. - - # self._request_method - if type(event) is Request: - self._request_method = event.method - - # self.their_http_version - if role is self.their_role and type(event) in ( - Request, - Response, - InformationalResponse, - ): - self.their_http_version = event.http_version - - # Keep alive handling - # - # RFC 7230 doesn't really say what one should do if Connection: close - # shows up on a 1xx InformationalResponse. I think the idea is that - # this is not supposed to happen. In any case, if it does happen, we - # ignore it. - if type(event) in (Request, Response) and not _keep_alive(event): - self._cstate.process_keep_alive_disabled() - - # 100-continue - if type(event) is Request and has_expect_100_continue(event): - self.client_is_waiting_for_100_continue = True - if type(event) in (InformationalResponse, Response): - self.client_is_waiting_for_100_continue = False - if role is CLIENT and type(event) in (Data, EndOfMessage): - self.client_is_waiting_for_100_continue = False - - self._respond_to_state_changes(old_states, event) - - def _get_io_object(self, role, event, io_dict): - # event may be None; it's only used when entering SEND_BODY - state = self._cstate.states[role] - if state is SEND_BODY: - # Special case: the io_dict has a dict of reader/writer factories - # that depend on the request/response framing. - framing_type, args = _body_framing(self._request_method, event) - return io_dict[SEND_BODY][framing_type](*args) - else: - # General case: the io_dict just has the appropriate reader/writer - # for this state - return io_dict.get((role, state)) - - # This must be called after any action that might have caused - # self._cstate.states to change. - def _respond_to_state_changes(self, old_states, event=None): - # Update reader/writer - if self.our_state != old_states[self.our_role]: - self._writer = self._get_io_object(self.our_role, event, WRITERS) - if self.their_state != old_states[self.their_role]: - self._reader = self._get_io_object(self.their_role, event, READERS) - - @property - def trailing_data(self): - """Data that has been received, but not yet processed, represented as - a tuple with two elements, where the first is a byte-string containing - the unprocessed data itself, and the second is a bool that is True if - the receive connection was closed. - - See :ref:`switching-protocols` for discussion of why you'd want this. - """ - return (bytes(self._receive_buffer), self._receive_buffer_closed) - - def receive_data(self, data): - """Add data to our internal receive buffer. - - This does not actually do any processing on the data, just stores - it. To trigger processing, you have to call :meth:`next_event`. - - Args: - data (:term:`bytes-like object`): - The new data that was just received. - - Special case: If *data* is an empty byte-string like ``b""``, - then this indicates that the remote side has closed the - connection (end of file). Normally this is convenient, because - standard Python APIs like :meth:`file.read` or - :meth:`socket.recv` use ``b""`` to indicate end-of-file, while - other failures to read are indicated using other mechanisms - like raising :exc:`TimeoutError`. When using such an API you - can just blindly pass through whatever you get from ``read`` - to :meth:`receive_data`, and everything will work. - - But, if you have an API where reading an empty string is a - valid non-EOF condition, then you need to be aware of this and - make sure to check for such strings and avoid passing them to - :meth:`receive_data`. - - Returns: - Nothing, but after calling this you should call :meth:`next_event` - to parse the newly received data. - - Raises: - RuntimeError: - Raised if you pass an empty *data*, indicating EOF, and then - pass a non-empty *data*, indicating more data that somehow - arrived after the EOF. - - (Calling ``receive_data(b"")`` multiple times is fine, - and equivalent to calling it once.) - - """ - if data: - if self._receive_buffer_closed: - raise RuntimeError("received close, then received more data?") - self._receive_buffer += data - else: - self._receive_buffer_closed = True - - def _extract_next_receive_event(self): - state = self.their_state - # We don't pause immediately when they enter DONE, because even in - # DONE state we can still process a ConnectionClosed() event. But - # if we have data in our buffer, then we definitely aren't getting - # a ConnectionClosed() immediately and we need to pause. - if state is DONE and self._receive_buffer: - return PAUSED - if state is MIGHT_SWITCH_PROTOCOL or state is SWITCHED_PROTOCOL: - return PAUSED - assert self._reader is not None - event = self._reader(self._receive_buffer) - if event is None: - if not self._receive_buffer and self._receive_buffer_closed: - # In some unusual cases (basically just HTTP/1.0 bodies), EOF - # triggers an actual protocol event; in that case, we want to - # return that event, and then the state will change and we'll - # get called again to generate the actual ConnectionClosed(). - if hasattr(self._reader, "read_eof"): - event = self._reader.read_eof() - else: - event = ConnectionClosed() - if event is None: - event = NEED_DATA - return event - - def next_event(self): - """Parse the next event out of our receive buffer, update our internal - state, and return it. - - This is a mutating operation -- think of it like calling :func:`next` - on an iterator. - - Returns: - : One of three things: - - 1) An event object -- see :ref:`events`. - - 2) The special constant :data:`NEED_DATA`, which indicates that - you need to read more data from your socket and pass it to - :meth:`receive_data` before this method will be able to return - any more events. - - 3) The special constant :data:`PAUSED`, which indicates that we - are not in a state where we can process incoming data (usually - because the peer has finished their part of the current - request/response cycle, and you have not yet called - :meth:`start_next_cycle`). See :ref:`flow-control` for details. - - Raises: - RemoteProtocolError: - The peer has misbehaved. You should close the connection - (possibly after sending some kind of 4xx response). - - Once this method returns :class:`ConnectionClosed` once, then all - subsequent calls will also return :class:`ConnectionClosed`. - - If this method raises any exception besides :exc:`RemoteProtocolError` - then that's a bug -- if it happens please file a bug report! - - If this method raises any exception then it also sets - :attr:`Connection.their_state` to :data:`ERROR` -- see - :ref:`error-handling` for discussion. - - """ - - if self.their_state is ERROR: - raise RemoteProtocolError("Can't receive data when peer state is ERROR") - try: - event = self._extract_next_receive_event() - if event not in [NEED_DATA, PAUSED]: - self._process_event(self.their_role, event) - if event is NEED_DATA: - if len(self._receive_buffer) > self._max_incomplete_event_size: - # 431 is "Request header fields too large" which is pretty - # much the only situation where we can get here - raise RemoteProtocolError( - "Receive buffer too long", error_status_hint=431 - ) - if self._receive_buffer_closed: - # We're still trying to complete some event, but that's - # never going to happen because no more data is coming - raise RemoteProtocolError("peer unexpectedly closed connection") - return event - except BaseException as exc: - self._process_error(self.their_role) - if isinstance(exc, LocalProtocolError): - exc._reraise_as_remote_protocol_error() - else: - raise - - def send(self, event): - """Convert a high-level event into bytes that can be sent to the peer, - while updating our internal state machine. - - Args: - event: The :ref:`event ` to send. - - Returns: - If ``type(event) is ConnectionClosed``, then returns - ``None``. Otherwise, returns a :term:`bytes-like object`. - - Raises: - LocalProtocolError: - Sending this event at this time would violate our - understanding of the HTTP/1.1 protocol. - - If this method raises any exception then it also sets - :attr:`Connection.our_state` to :data:`ERROR` -- see - :ref:`error-handling` for discussion. - - """ - data_list = self.send_with_data_passthrough(event) - if data_list is None: - return None - else: - return b"".join(data_list) - - def send_with_data_passthrough(self, event): - """Identical to :meth:`send`, except that in situations where - :meth:`send` returns a single :term:`bytes-like object`, this instead - returns a list of them -- and when sending a :class:`Data` event, this - list is guaranteed to contain the exact object you passed in as - :attr:`Data.data`. See :ref:`sendfile` for discussion. - - """ - if self.our_state is ERROR: - raise LocalProtocolError("Can't send data when our state is ERROR") - try: - if type(event) is Response: - self._clean_up_response_headers_for_sending(event) - # We want to call _process_event before calling the writer, - # because if someone tries to do something invalid then this will - # give a sensible error message, while our writers all just assume - # they will only receive valid events. But, _process_event might - # change self._writer. So we have to do a little dance: - writer = self._writer - self._process_event(self.our_role, event) - if type(event) is ConnectionClosed: - return None - else: - # In any situation where writer is None, process_event should - # have raised ProtocolError - assert writer is not None - data_list = [] - writer(event, data_list.append) - return data_list - except: - self._process_error(self.our_role) - raise - - def send_failed(self): - """Notify the state machine that we failed to send the data it gave - us. - - This causes :attr:`Connection.our_state` to immediately become - :data:`ERROR` -- see :ref:`error-handling` for discussion. - - """ - self._process_error(self.our_role) - - # When sending a Response, we take responsibility for a few things: - # - # - Sometimes you MUST set Connection: close. We take care of those - # times. (You can also set it yourself if you want, and if you do then - # we'll respect that and close the connection at the right time. But you - # don't have to worry about that unless you want to.) - # - # - The user has to set Content-Length if they want it. Otherwise, for - # responses that have bodies (e.g. not HEAD), then we will automatically - # select the right mechanism for streaming a body of unknown length, - # which depends on depending on the peer's HTTP version. - # - # This function's *only* responsibility is making sure headers are set up - # right -- everything downstream just looks at the headers. There are no - # side channels. It mutates the response event in-place (but not the - # response.headers list object). - def _clean_up_response_headers_for_sending(self, response): - assert type(response) is Response - - headers = response.headers - need_close = False - - # HEAD requests need some special handling: they always act like they - # have Content-Length: 0, and that's how _body_framing treats - # them. But their headers are supposed to match what we would send if - # the request was a GET. (Technically there is one deviation allowed: - # we're allowed to leave out the framing headers -- see - # https://tools.ietf.org/html/rfc7231#section-4.3.2 . But it's just as - # easy to get them right.) - method_for_choosing_headers = self._request_method - if method_for_choosing_headers == b"HEAD": - method_for_choosing_headers = b"GET" - framing_type, _ = _body_framing(method_for_choosing_headers, response) - if framing_type in ("chunked", "http/1.0"): - # This response has a body of unknown length. - # If our peer is HTTP/1.1, we use Transfer-Encoding: chunked - # If our peer is HTTP/1.0, we use no framing headers, and close the - # connection afterwards. - # - # Make sure to clear Content-Length (in principle user could have - # set both and then we ignored Content-Length b/c - # Transfer-Encoding overwrote it -- this would be naughty of them, - # but the HTTP spec says that if our peer does this then we have - # to fix it instead of erroring out, so we'll accord the user the - # same respect). - headers = set_comma_header(headers, b"content-length", []) - if self.their_http_version is None or self.their_http_version < b"1.1": - # Either we never got a valid request and are sending back an - # error (their_http_version is None), so we assume the worst; - # or else we did get a valid HTTP/1.0 request, so we know that - # they don't understand chunked encoding. - headers = set_comma_header(headers, b"transfer-encoding", []) - # This is actually redundant ATM, since currently we - # unconditionally disable keep-alive when talking to HTTP/1.0 - # peers. But let's be defensive just in case we add - # Connection: keep-alive support later: - if self._request_method != b"HEAD": - need_close = True - else: - headers = set_comma_header(headers, b"transfer-encoding", ["chunked"]) - - if not self._cstate.keep_alive or need_close: - # Make sure Connection: close is set - connection = set(get_comma_header(headers, b"connection")) - connection.discard(b"keep-alive") - connection.add(b"close") - headers = set_comma_header(headers, b"connection", sorted(connection)) - - response.headers = headers diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_events.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_events.py deleted file mode 100644 index 18279301..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_events.py +++ /dev/null @@ -1,302 +0,0 @@ -# High level events that make up HTTP/1.1 conversations. Loosely inspired by -# the corresponding events in hyper-h2: -# -# http://python-hyper.org/h2/en/stable/api.html#events -# -# Don't subclass these. Stuff will break. - -import re - -from . import _headers -from ._abnf import request_target -from ._util import bytesify, LocalProtocolError, validate - -# Everything in __all__ gets re-exported as part of the h11 public API. -__all__ = [ - "Request", - "InformationalResponse", - "Response", - "Data", - "EndOfMessage", - "ConnectionClosed", -] - -request_target_re = re.compile(request_target.encode("ascii")) - - -class _EventBundle: - _fields = [] - _defaults = {} - - def __init__(self, **kwargs): - _parsed = kwargs.pop("_parsed", False) - allowed = set(self._fields) - for kwarg in kwargs: - if kwarg not in allowed: - raise TypeError( - "unrecognized kwarg {} for {}".format( - kwarg, self.__class__.__name__ - ) - ) - required = allowed.difference(self._defaults) - for field in required: - if field not in kwargs: - raise TypeError( - "missing required kwarg {} for {}".format( - field, self.__class__.__name__ - ) - ) - self.__dict__.update(self._defaults) - self.__dict__.update(kwargs) - - # Special handling for some fields - - if "headers" in self.__dict__: - self.headers = _headers.normalize_and_validate( - self.headers, _parsed=_parsed - ) - - if not _parsed: - for field in ["method", "target", "http_version", "reason"]: - if field in self.__dict__: - self.__dict__[field] = bytesify(self.__dict__[field]) - - if "status_code" in self.__dict__: - if not isinstance(self.status_code, int): - raise LocalProtocolError("status code must be integer") - # Because IntEnum objects are instances of int, but aren't - # duck-compatible (sigh), see gh-72. - self.status_code = int(self.status_code) - - self._validate() - - def _validate(self): - pass - - def __repr__(self): - name = self.__class__.__name__ - kwarg_strs = [ - "{}={}".format(field, self.__dict__[field]) for field in self._fields - ] - kwarg_str = ", ".join(kwarg_strs) - return "{}({})".format(name, kwarg_str) - - # Useful for tests - def __eq__(self, other): - return self.__class__ == other.__class__ and self.__dict__ == other.__dict__ - - # This is an unhashable type. - __hash__ = None - - -class Request(_EventBundle): - """The beginning of an HTTP request. - - Fields: - - .. attribute:: method - - An HTTP method, e.g. ``b"GET"`` or ``b"POST"``. Always a byte - string. :term:`Bytes-like objects ` and native - strings containing only ascii characters will be automatically - converted to byte strings. - - .. attribute:: target - - The target of an HTTP request, e.g. ``b"/index.html"``, or one of the - more exotic formats described in `RFC 7320, section 5.3 - `_. Always a byte - string. :term:`Bytes-like objects ` and native - strings containing only ascii characters will be automatically - converted to byte strings. - - .. attribute:: headers - - Request headers, represented as a list of (name, value) pairs. See - :ref:`the header normalization rules ` for details. - - .. attribute:: http_version - - The HTTP protocol version, represented as a byte string like - ``b"1.1"``. See :ref:`the HTTP version normalization rules - ` for details. - - """ - - _fields = ["method", "target", "headers", "http_version"] - _defaults = {"http_version": b"1.1"} - - def _validate(self): - # "A server MUST respond with a 400 (Bad Request) status code to any - # HTTP/1.1 request message that lacks a Host header field and to any - # request message that contains more than one Host header field or a - # Host header field with an invalid field-value." - # -- https://tools.ietf.org/html/rfc7230#section-5.4 - host_count = 0 - for name, value in self.headers: - if name == b"host": - host_count += 1 - if self.http_version == b"1.1" and host_count == 0: - raise LocalProtocolError("Missing mandatory Host: header") - if host_count > 1: - raise LocalProtocolError("Found multiple Host: headers") - - validate(request_target_re, self.target, "Illegal target characters") - - -class _ResponseBase(_EventBundle): - _fields = ["status_code", "headers", "http_version", "reason"] - _defaults = {"http_version": b"1.1", "reason": b""} - - -class InformationalResponse(_ResponseBase): - """An HTTP informational response. - - Fields: - - .. attribute:: status_code - - The status code of this response, as an integer. For an - :class:`InformationalResponse`, this is always in the range [100, - 200). - - .. attribute:: headers - - Request headers, represented as a list of (name, value) pairs. See - :ref:`the header normalization rules ` for - details. - - .. attribute:: http_version - - The HTTP protocol version, represented as a byte string like - ``b"1.1"``. See :ref:`the HTTP version normalization rules - ` for details. - - .. attribute:: reason - - The reason phrase of this response, as a byte string. For example: - ``b"OK"``, or ``b"Not Found"``. - - """ - - def _validate(self): - if not (100 <= self.status_code < 200): - raise LocalProtocolError( - "InformationalResponse status_code should be in range " - "[100, 200), not {}".format(self.status_code) - ) - - -class Response(_ResponseBase): - """The beginning of an HTTP response. - - Fields: - - .. attribute:: status_code - - The status code of this response, as an integer. For an - :class:`Response`, this is always in the range [200, - 600). - - .. attribute:: headers - - Request headers, represented as a list of (name, value) pairs. See - :ref:`the header normalization rules ` for details. - - .. attribute:: http_version - - The HTTP protocol version, represented as a byte string like - ``b"1.1"``. See :ref:`the HTTP version normalization rules - ` for details. - - .. attribute:: reason - - The reason phrase of this response, as a byte string. For example: - ``b"OK"``, or ``b"Not Found"``. - - """ - - def _validate(self): - if not (200 <= self.status_code < 600): - raise LocalProtocolError( - "Response status_code should be in range [200, 600), not {}".format( - self.status_code - ) - ) - - -class Data(_EventBundle): - """Part of an HTTP message body. - - Fields: - - .. attribute:: data - - A :term:`bytes-like object` containing part of a message body. Or, if - using the ``combine=False`` argument to :meth:`Connection.send`, then - any object that your socket writing code knows what to do with, and for - which calling :func:`len` returns the number of bytes that will be - written -- see :ref:`sendfile` for details. - - .. attribute:: chunk_start - - A marker that indicates whether this data object is from the start of a - chunked transfer encoding chunk. This field is ignored when when a Data - event is provided to :meth:`Connection.send`: it is only valid on - events emitted from :meth:`Connection.next_event`. You probably - shouldn't use this attribute at all; see - :ref:`chunk-delimiters-are-bad` for details. - - .. attribute:: chunk_end - - A marker that indicates whether this data object is the last for a - given chunked transfer encoding chunk. This field is ignored when when - a Data event is provided to :meth:`Connection.send`: it is only valid - on events emitted from :meth:`Connection.next_event`. You probably - shouldn't use this attribute at all; see - :ref:`chunk-delimiters-are-bad` for details. - - """ - - _fields = ["data", "chunk_start", "chunk_end"] - _defaults = {"chunk_start": False, "chunk_end": False} - - -# XX FIXME: "A recipient MUST ignore (or consider as an error) any fields that -# are forbidden to be sent in a trailer, since processing them as if they were -# present in the header section might bypass external security filters." -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#chunked.trailer.part -# Unfortunately, the list of forbidden fields is long and vague :-/ -class EndOfMessage(_EventBundle): - """The end of an HTTP message. - - Fields: - - .. attribute:: headers - - Default value: ``[]`` - - Any trailing headers attached to this message, represented as a list of - (name, value) pairs. See :ref:`the header normalization rules - ` for details. - - Must be empty unless ``Transfer-Encoding: chunked`` is in use. - - """ - - _fields = ["headers"] - _defaults = {"headers": []} - - -class ConnectionClosed(_EventBundle): - """This event indicates that the sender has closed their outgoing - connection. - - Note that this does not necessarily mean that they can't *receive* further - data, because TCP connections are composed to two one-way channels which - can be closed independently. See :ref:`closing` for details. - - No fields. - """ - - pass diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_headers.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_headers.py deleted file mode 100644 index 7ed39bc1..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_headers.py +++ /dev/null @@ -1,242 +0,0 @@ -import re - -from ._abnf import field_name, field_value -from ._util import bytesify, LocalProtocolError, validate - -# Facts -# ----- -# -# Headers are: -# keys: case-insensitive ascii -# values: mixture of ascii and raw bytes -# -# "Historically, HTTP has allowed field content with text in the ISO-8859-1 -# charset [ISO-8859-1], supporting other charsets only through use of -# [RFC2047] encoding. In practice, most HTTP header field values use only a -# subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD -# limit their field values to US-ASCII octets. A recipient SHOULD treat other -# octets in field content (obs-text) as opaque data." -# And it deprecates all non-ascii values -# -# Leading/trailing whitespace in header names is forbidden -# -# Values get leading/trailing whitespace stripped -# -# Content-Disposition actually needs to contain unicode semantically; to -# accomplish this it has a terrifically weird way of encoding the filename -# itself as ascii (and even this still has lots of cross-browser -# incompatibilities) -# -# Order is important: -# "a proxy MUST NOT change the order of these field values when forwarding a -# message" -# (and there are several headers where the order indicates a preference) -# -# Multiple occurences of the same header: -# "A sender MUST NOT generate multiple header fields with the same field name -# in a message unless either the entire field value for that header field is -# defined as a comma-separated list [or the header is Set-Cookie which gets a -# special exception]" - RFC 7230. (cookies are in RFC 6265) -# -# So every header aside from Set-Cookie can be merged by b", ".join if it -# occurs repeatedly. But, of course, they can't necessarily be split by -# .split(b","), because quoting. -# -# Given all this mess (case insensitive, duplicates allowed, order is -# important, ...), there doesn't appear to be any standard way to handle -# headers in Python -- they're almost like dicts, but... actually just -# aren't. For now we punt and just use a super simple representation: headers -# are a list of pairs -# -# [(name1, value1), (name2, value2), ...] -# -# where all entries are bytestrings, names are lowercase and have no -# leading/trailing whitespace, and values are bytestrings with no -# leading/trailing whitespace. Searching and updating are done via naive O(n) -# methods. -# -# Maybe a dict-of-lists would be better? - -_content_length_re = re.compile(br"[0-9]+") -_field_name_re = re.compile(field_name.encode("ascii")) -_field_value_re = re.compile(field_value.encode("ascii")) - - -class Headers: - """ - A list-like interface that allows iterating over headers as byte-pairs - of (lowercased-name, value). - - Internally we actually store the representation as three-tuples, - including both the raw original casing, in order to preserve casing - over-the-wire, and the lowercased name, for case-insensitive comparisions. - - r = Request( - method="GET", - target="/", - headers=[("Host", "example.org"), ("Connection", "keep-alive")], - http_version="1.1", - ) - assert r.headers == [ - (b"host", b"example.org"), - (b"connection", b"keep-alive") - ] - assert r.headers.raw_items() == [ - (b"Host", b"example.org"), - (b"Connection", b"keep-alive") - ] - """ - - __slots__ = "_full_items" - - def __init__(self, full_items): - self._full_items = full_items - - def __iter__(self): - for _, name, value in self._full_items: - yield name, value - - def __bool__(self): - return bool(self._full_items) - - def __eq__(self, other): - return list(self) == list(other) - - def __len__(self): - return len(self._full_items) - - def __repr__(self): - return "" % repr(list(self)) - - def __getitem__(self, idx): - _, name, value = self._full_items[idx] - return (name, value) - - def raw_items(self): - return [(raw_name, value) for raw_name, _, value in self._full_items] - - -def normalize_and_validate(headers, _parsed=False): - new_headers = [] - seen_content_length = None - saw_transfer_encoding = False - for name, value in headers: - # For headers coming out of the parser, we can safely skip some steps, - # because it always returns bytes and has already run these regexes - # over the data: - if not _parsed: - name = bytesify(name) - value = bytesify(value) - validate(_field_name_re, name, "Illegal header name {!r}", name) - validate(_field_value_re, value, "Illegal header value {!r}", value) - raw_name = name - name = name.lower() - if name == b"content-length": - lengths = {length.strip() for length in value.split(b",")} - if len(lengths) != 1: - raise LocalProtocolError("conflicting Content-Length headers") - value = lengths.pop() - validate(_content_length_re, value, "bad Content-Length") - if seen_content_length is None: - seen_content_length = value - new_headers.append((raw_name, name, value)) - elif seen_content_length != value: - raise LocalProtocolError("conflicting Content-Length headers") - elif name == b"transfer-encoding": - # "A server that receives a request message with a transfer coding - # it does not understand SHOULD respond with 501 (Not - # Implemented)." - # https://tools.ietf.org/html/rfc7230#section-3.3.1 - if saw_transfer_encoding: - raise LocalProtocolError( - "multiple Transfer-Encoding headers", error_status_hint=501 - ) - # "All transfer-coding names are case-insensitive" - # -- https://tools.ietf.org/html/rfc7230#section-4 - value = value.lower() - if value != b"chunked": - raise LocalProtocolError( - "Only Transfer-Encoding: chunked is supported", - error_status_hint=501, - ) - saw_transfer_encoding = True - new_headers.append((raw_name, name, value)) - else: - new_headers.append((raw_name, name, value)) - return Headers(new_headers) - - -def get_comma_header(headers, name): - # Should only be used for headers whose value is a list of - # comma-separated, case-insensitive values. - # - # The header name `name` is expected to be lower-case bytes. - # - # Connection: meets these criteria (including cast insensitivity). - # - # Content-Length: technically is just a single value (1*DIGIT), but the - # standard makes reference to implementations that do multiple values, and - # using this doesn't hurt. Ditto, case insensitivity doesn't things either - # way. - # - # Transfer-Encoding: is more complex (allows for quoted strings), so - # splitting on , is actually wrong. For example, this is legal: - # - # Transfer-Encoding: foo; options="1,2", chunked - # - # and should be parsed as - # - # foo; options="1,2" - # chunked - # - # but this naive function will parse it as - # - # foo; options="1 - # 2" - # chunked - # - # However, this is okay because the only thing we are going to do with - # any Transfer-Encoding is reject ones that aren't just "chunked", so - # both of these will be treated the same anyway. - # - # Expect: the only legal value is the literal string - # "100-continue". Splitting on commas is harmless. Case insensitive. - # - out = [] - for _, found_name, found_raw_value in headers._full_items: - if found_name == name: - found_raw_value = found_raw_value.lower() - for found_split_value in found_raw_value.split(b","): - found_split_value = found_split_value.strip() - if found_split_value: - out.append(found_split_value) - return out - - -def set_comma_header(headers, name, new_values): - # The header name `name` is expected to be lower-case bytes. - # - # Note that when we store the header we use title casing for the header - # names, in order to match the conventional HTTP header style. - # - # Simply calling `.title()` is a blunt approach, but it's correct - # here given the cases where we're using `set_comma_header`... - # - # Connection, Content-Length, Transfer-Encoding. - new_headers = [] - for found_raw_name, found_name, found_raw_value in headers._full_items: - if found_name != name: - new_headers.append((found_raw_name, found_raw_value)) - for new_value in new_values: - new_headers.append((name.title(), new_value)) - return normalize_and_validate(new_headers) - - -def has_expect_100_continue(request): - # https://tools.ietf.org/html/rfc7231#section-5.1.1 - # "A server that receives a 100-continue expectation in an HTTP/1.0 request - # MUST ignore that expectation." - if request.http_version < b"1.1": - return False - expect = get_comma_header(request.headers, b"expect") - return b"100-continue" in expect diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_readers.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_readers.py deleted file mode 100644 index 0ead0bec..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_readers.py +++ /dev/null @@ -1,222 +0,0 @@ -# Code to read HTTP data -# -# Strategy: each reader is a callable which takes a ReceiveBuffer object, and -# either: -# 1) consumes some of it and returns an Event -# 2) raises a LocalProtocolError (for consistency -- e.g. we call validate() -# and it might raise a LocalProtocolError, so simpler just to always use -# this) -# 3) returns None, meaning "I need more data" -# -# If they have a .read_eof attribute, then this will be called if an EOF is -# received -- but this is optional. Either way, the actual ConnectionClosed -# event will be generated afterwards. -# -# READERS is a dict describing how to pick a reader. It maps states to either: -# - a reader -# - or, for body readers, a dict of per-framing reader factories - -import re - -from ._abnf import chunk_header, header_field, request_line, status_line -from ._events import * -from ._state import * -from ._util import LocalProtocolError, RemoteProtocolError, validate - -__all__ = ["READERS"] - -header_field_re = re.compile(header_field.encode("ascii")) - -# Remember that this has to run in O(n) time -- so e.g. the bytearray cast is -# critical. -obs_fold_re = re.compile(br"[ \t]+") - - -def _obsolete_line_fold(lines): - it = iter(lines) - last = None - for line in it: - match = obs_fold_re.match(line) - if match: - if last is None: - raise LocalProtocolError("continuation line at start of headers") - if not isinstance(last, bytearray): - last = bytearray(last) - last += b" " - last += line[match.end() :] - else: - if last is not None: - yield last - last = line - if last is not None: - yield last - - -def _decode_header_lines(lines): - for line in _obsolete_line_fold(lines): - matches = validate(header_field_re, line, "illegal header line: {!r}", line) - yield (matches["field_name"], matches["field_value"]) - - -request_line_re = re.compile(request_line.encode("ascii")) - - -def maybe_read_from_IDLE_client(buf): - lines = buf.maybe_extract_lines() - if lines is None: - if buf.is_next_line_obviously_invalid_request_line(): - raise LocalProtocolError("illegal request line") - return None - if not lines: - raise LocalProtocolError("no request line received") - matches = validate( - request_line_re, lines[0], "illegal request line: {!r}", lines[0] - ) - return Request( - headers=list(_decode_header_lines(lines[1:])), _parsed=True, **matches - ) - - -status_line_re = re.compile(status_line.encode("ascii")) - - -def maybe_read_from_SEND_RESPONSE_server(buf): - lines = buf.maybe_extract_lines() - if lines is None: - if buf.is_next_line_obviously_invalid_request_line(): - raise LocalProtocolError("illegal request line") - return None - if not lines: - raise LocalProtocolError("no response line received") - matches = validate(status_line_re, lines[0], "illegal status line: {!r}", lines[0]) - # Tolerate missing reason phrases - if matches["reason"] is None: - matches["reason"] = b"" - status_code = matches["status_code"] = int(matches["status_code"]) - class_ = InformationalResponse if status_code < 200 else Response - return class_( - headers=list(_decode_header_lines(lines[1:])), _parsed=True, **matches - ) - - -class ContentLengthReader: - def __init__(self, length): - self._length = length - self._remaining = length - - def __call__(self, buf): - if self._remaining == 0: - return EndOfMessage() - data = buf.maybe_extract_at_most(self._remaining) - if data is None: - return None - self._remaining -= len(data) - return Data(data=data) - - def read_eof(self): - raise RemoteProtocolError( - "peer closed connection without sending complete message body " - "(received {} bytes, expected {})".format( - self._length - self._remaining, self._length - ) - ) - - -chunk_header_re = re.compile(chunk_header.encode("ascii")) - - -class ChunkedReader: - def __init__(self): - self._bytes_in_chunk = 0 - # After reading a chunk, we have to throw away the trailing \r\n; if - # this is >0 then we discard that many bytes before resuming regular - # de-chunkification. - self._bytes_to_discard = 0 - self._reading_trailer = False - - def __call__(self, buf): - if self._reading_trailer: - lines = buf.maybe_extract_lines() - if lines is None: - return None - return EndOfMessage(headers=list(_decode_header_lines(lines))) - if self._bytes_to_discard > 0: - data = buf.maybe_extract_at_most(self._bytes_to_discard) - if data is None: - return None - self._bytes_to_discard -= len(data) - if self._bytes_to_discard > 0: - return None - # else, fall through and read some more - assert self._bytes_to_discard == 0 - if self._bytes_in_chunk == 0: - # We need to refill our chunk count - chunk_header = buf.maybe_extract_next_line() - if chunk_header is None: - return None - matches = validate( - chunk_header_re, - chunk_header, - "illegal chunk header: {!r}", - chunk_header, - ) - # XX FIXME: we discard chunk extensions. Does anyone care? - self._bytes_in_chunk = int(matches["chunk_size"], base=16) - if self._bytes_in_chunk == 0: - self._reading_trailer = True - return self(buf) - chunk_start = True - else: - chunk_start = False - assert self._bytes_in_chunk > 0 - data = buf.maybe_extract_at_most(self._bytes_in_chunk) - if data is None: - return None - self._bytes_in_chunk -= len(data) - if self._bytes_in_chunk == 0: - self._bytes_to_discard = 2 - chunk_end = True - else: - chunk_end = False - return Data(data=data, chunk_start=chunk_start, chunk_end=chunk_end) - - def read_eof(self): - raise RemoteProtocolError( - "peer closed connection without sending complete message body " - "(incomplete chunked read)" - ) - - -class Http10Reader: - def __call__(self, buf): - data = buf.maybe_extract_at_most(999999999) - if data is None: - return None - return Data(data=data) - - def read_eof(self): - return EndOfMessage() - - -def expect_nothing(buf): - if buf: - raise LocalProtocolError("Got data when expecting EOF") - return None - - -READERS = { - (CLIENT, IDLE): maybe_read_from_IDLE_client, - (SERVER, IDLE): maybe_read_from_SEND_RESPONSE_server, - (SERVER, SEND_RESPONSE): maybe_read_from_SEND_RESPONSE_server, - (CLIENT, DONE): expect_nothing, - (CLIENT, MUST_CLOSE): expect_nothing, - (CLIENT, CLOSED): expect_nothing, - (SERVER, DONE): expect_nothing, - (SERVER, MUST_CLOSE): expect_nothing, - (SERVER, CLOSED): expect_nothing, - SEND_BODY: { - "chunked": ChunkedReader, - "content-length": ContentLengthReader, - "http/1.0": Http10Reader, - }, -} diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_receivebuffer.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_receivebuffer.py deleted file mode 100644 index a3737f35..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_receivebuffer.py +++ /dev/null @@ -1,152 +0,0 @@ -import re -import sys - -__all__ = ["ReceiveBuffer"] - - -# Operations we want to support: -# - find next \r\n or \r\n\r\n (\n or \n\n are also acceptable), -# or wait until there is one -# - read at-most-N bytes -# Goals: -# - on average, do this fast -# - worst case, do this in O(n) where n is the number of bytes processed -# Plan: -# - store bytearray, offset, how far we've searched for a separator token -# - use the how-far-we've-searched data to avoid rescanning -# - while doing a stream of uninterrupted processing, advance offset instead -# of constantly copying -# WARNING: -# - I haven't benchmarked or profiled any of this yet. -# -# Note that starting in Python 3.4, deleting the initial n bytes from a -# bytearray is amortized O(n), thanks to some excellent work by Antoine -# Martin: -# -# https://bugs.python.org/issue19087 -# -# This means that if we only supported 3.4+, we could get rid of the code here -# involving self._start and self.compress, because it's doing exactly the same -# thing that bytearray now does internally. -# -# BUT unfortunately, we still support 2.7, and reading short segments out of a -# long buffer MUST be O(bytes read) to avoid DoS issues, so we can't actually -# delete this code. Yet: -# -# https://pythonclock.org/ -# -# (Two things to double-check first though: make sure PyPy also has the -# optimization, and benchmark to make sure it's a win, since we do have a -# slightly clever thing where we delay calling compress() until we've -# processed a whole event, which could in theory be slightly more efficient -# than the internal bytearray support.) -blank_line_regex = re.compile(b"\n\r?\n", re.MULTILINE) - - -class ReceiveBuffer: - def __init__(self): - self._data = bytearray() - self._next_line_search = 0 - self._multiple_lines_search = 0 - - def __iadd__(self, byteslike): - self._data += byteslike - return self - - def __bool__(self): - return bool(len(self)) - - def __len__(self): - return len(self._data) - - # for @property unprocessed_data - def __bytes__(self): - return bytes(self._data) - - def _extract(self, count): - # extracting an initial slice of the data buffer and return it - out = self._data[:count] - del self._data[:count] - - self._next_line_search = 0 - self._multiple_lines_search = 0 - - return out - - def maybe_extract_at_most(self, count): - """ - Extract a fixed number of bytes from the buffer. - """ - out = self._data[:count] - if not out: - return None - - return self._extract(count) - - def maybe_extract_next_line(self): - """ - Extract the first line, if it is completed in the buffer. - """ - # Only search in buffer space that we've not already looked at. - search_start_index = max(0, self._next_line_search - 1) - partial_idx = self._data.find(b"\r\n", search_start_index) - - if partial_idx == -1: - self._next_line_search = len(self._data) - return None - - # + 2 is to compensate len(b"\r\n") - idx = partial_idx + 2 - - return self._extract(idx) - - def maybe_extract_lines(self): - """ - Extract everything up to the first blank line, and return a list of lines. - """ - # Handle the case where we have an immediate empty line. - if self._data[:1] == b"\n": - self._extract(1) - return [] - - if self._data[:2] == b"\r\n": - self._extract(2) - return [] - - # Only search in buffer space that we've not already looked at. - match = blank_line_regex.search(self._data, self._multiple_lines_search) - if match is None: - self._multiple_lines_search = max(0, len(self._data) - 2) - return None - - # Truncate the buffer and return it. - idx = match.span(0)[-1] - out = self._extract(idx) - lines = out.split(b"\n") - - for line in lines: - if line.endswith(b"\r"): - del line[-1] - - assert lines[-2] == lines[-1] == b"" - - del lines[-2:] - - return lines - - # In theory we should wait until `\r\n` before starting to validate - # incoming data. However it's interesting to detect (very) invalid data - # early given they might not even contain `\r\n` at all (hence only - # timeout will get rid of them). - # This is not a 100% effective detection but more of a cheap sanity check - # allowing for early abort in some useful cases. - # This is especially interesting when peer is messing up with HTTPS and - # sent us a TLS stream where we were expecting plain HTTP given all - # versions of TLS so far start handshake with a 0x16 message type code. - def is_next_line_obviously_invalid_request_line(self): - try: - # HTTP header line must not contain non-printable characters - # and should not start with a space - return self._data[0] < 0x21 - except IndexError: - return False diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_state.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_state.py deleted file mode 100644 index 0f08a090..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_state.py +++ /dev/null @@ -1,307 +0,0 @@ -################################################################ -# The core state machine -################################################################ -# -# Rule 1: everything that affects the state machine and state transitions must -# live here in this file. As much as possible goes into the table-based -# representation, but for the bits that don't quite fit, the actual code and -# state must nonetheless live here. -# -# Rule 2: this file does not know about what role we're playing; it only knows -# about HTTP request/response cycles in the abstract. This ensures that we -# don't cheat and apply different rules to local and remote parties. -# -# -# Theory of operation -# =================== -# -# Possibly the simplest way to think about this is that we actually have 5 -# different state machines here. Yes, 5. These are: -# -# 1) The client state, with its complicated automaton (see the docs) -# 2) The server state, with its complicated automaton (see the docs) -# 3) The keep-alive state, with possible states {True, False} -# 4) The SWITCH_CONNECT state, with possible states {False, True} -# 5) The SWITCH_UPGRADE state, with possible states {False, True} -# -# For (3)-(5), the first state listed is the initial state. -# -# (1)-(3) are stored explicitly in member variables. The last -# two are stored implicitly in the pending_switch_proposals set as: -# (state of 4) == (_SWITCH_CONNECT in pending_switch_proposals) -# (state of 5) == (_SWITCH_UPGRADE in pending_switch_proposals) -# -# And each of these machines has two different kinds of transitions: -# -# a) Event-triggered -# b) State-triggered -# -# Event triggered is the obvious thing that you'd think it is: some event -# happens, and if it's the right event at the right time then a transition -# happens. But there are somewhat complicated rules for which machines can -# "see" which events. (As a rule of thumb, if a machine "sees" an event, this -# means two things: the event can affect the machine, and if the machine is -# not in a state where it expects that event then it's an error.) These rules -# are: -# -# 1) The client machine sees all h11.events objects emitted by the client. -# -# 2) The server machine sees all h11.events objects emitted by the server. -# -# It also sees the client's Request event. -# -# And sometimes, server events are annotated with a _SWITCH_* event. For -# example, we can have a (Response, _SWITCH_CONNECT) event, which is -# different from a regular Response event. -# -# 3) The keep-alive machine sees the process_keep_alive_disabled() event -# (which is derived from Request/Response events), and this event -# transitions it from True -> False, or from False -> False. There's no way -# to transition back. -# -# 4&5) The _SWITCH_* machines transition from False->True when we get a -# Request that proposes the relevant type of switch (via -# process_client_switch_proposals), and they go from True->False when we -# get a Response that has no _SWITCH_* annotation. -# -# So that's event-triggered transitions. -# -# State-triggered transitions are less standard. What they do here is couple -# the machines together. The way this works is, when certain *joint* -# configurations of states are achieved, then we automatically transition to a -# new *joint* state. So, for example, if we're ever in a joint state with -# -# client: DONE -# keep-alive: False -# -# then the client state immediately transitions to: -# -# client: MUST_CLOSE -# -# This is fundamentally different from an event-based transition, because it -# doesn't matter how we arrived at the {client: DONE, keep-alive: False} state -# -- maybe the client transitioned SEND_BODY -> DONE, or keep-alive -# transitioned True -> False. Either way, once this precondition is satisfied, -# this transition is immediately triggered. -# -# What if two conflicting state-based transitions get enabled at the same -# time? In practice there's only one case where this arises (client DONE -> -# MIGHT_SWITCH_PROTOCOL versus DONE -> MUST_CLOSE), and we resolve it by -# explicitly prioritizing the DONE -> MIGHT_SWITCH_PROTOCOL transition. -# -# Implementation -# -------------- -# -# The event-triggered transitions for the server and client machines are all -# stored explicitly in a table. Ditto for the state-triggered transitions that -# involve just the server and client state. -# -# The transitions for the other machines, and the state-triggered transitions -# that involve the other machines, are written out as explicit Python code. -# -# It'd be nice if there were some cleaner way to do all this. This isn't -# *too* terrible, but I feel like it could probably be better. -# -# WARNING -# ------- -# -# The script that generates the state machine diagrams for the docs knows how -# to read out the EVENT_TRIGGERED_TRANSITIONS and STATE_TRIGGERED_TRANSITIONS -# tables. But it can't automatically read the transitions that are written -# directly in Python code. So if you touch those, you need to also update the -# script to keep it in sync! - -from ._events import * -from ._util import LocalProtocolError, make_sentinel - -# Everything in __all__ gets re-exported as part of the h11 public API. -__all__ = [ - "CLIENT", - "SERVER", - "IDLE", - "SEND_RESPONSE", - "SEND_BODY", - "DONE", - "MUST_CLOSE", - "CLOSED", - "MIGHT_SWITCH_PROTOCOL", - "SWITCHED_PROTOCOL", - "ERROR", -] - -CLIENT = make_sentinel("CLIENT") -SERVER = make_sentinel("SERVER") - -# States -IDLE = make_sentinel("IDLE") -SEND_RESPONSE = make_sentinel("SEND_RESPONSE") -SEND_BODY = make_sentinel("SEND_BODY") -DONE = make_sentinel("DONE") -MUST_CLOSE = make_sentinel("MUST_CLOSE") -CLOSED = make_sentinel("CLOSED") -ERROR = make_sentinel("ERROR") - -# Switch types -MIGHT_SWITCH_PROTOCOL = make_sentinel("MIGHT_SWITCH_PROTOCOL") -SWITCHED_PROTOCOL = make_sentinel("SWITCHED_PROTOCOL") - -_SWITCH_UPGRADE = make_sentinel("_SWITCH_UPGRADE") -_SWITCH_CONNECT = make_sentinel("_SWITCH_CONNECT") - -EVENT_TRIGGERED_TRANSITIONS = { - CLIENT: { - IDLE: {Request: SEND_BODY, ConnectionClosed: CLOSED}, - SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, - DONE: {ConnectionClosed: CLOSED}, - MUST_CLOSE: {ConnectionClosed: CLOSED}, - CLOSED: {ConnectionClosed: CLOSED}, - MIGHT_SWITCH_PROTOCOL: {}, - SWITCHED_PROTOCOL: {}, - ERROR: {}, - }, - SERVER: { - IDLE: { - ConnectionClosed: CLOSED, - Response: SEND_BODY, - # Special case: server sees client Request events, in this form - (Request, CLIENT): SEND_RESPONSE, - }, - SEND_RESPONSE: { - InformationalResponse: SEND_RESPONSE, - Response: SEND_BODY, - (InformationalResponse, _SWITCH_UPGRADE): SWITCHED_PROTOCOL, - (Response, _SWITCH_CONNECT): SWITCHED_PROTOCOL, - }, - SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, - DONE: {ConnectionClosed: CLOSED}, - MUST_CLOSE: {ConnectionClosed: CLOSED}, - CLOSED: {ConnectionClosed: CLOSED}, - SWITCHED_PROTOCOL: {}, - ERROR: {}, - }, -} - -# NB: there are also some special-case state-triggered transitions hard-coded -# into _fire_state_triggered_transitions below. -STATE_TRIGGERED_TRANSITIONS = { - # (Client state, Server state) -> new states - # Protocol negotiation - (MIGHT_SWITCH_PROTOCOL, SWITCHED_PROTOCOL): {CLIENT: SWITCHED_PROTOCOL}, - # Socket shutdown - (CLOSED, DONE): {SERVER: MUST_CLOSE}, - (CLOSED, IDLE): {SERVER: MUST_CLOSE}, - (ERROR, DONE): {SERVER: MUST_CLOSE}, - (DONE, CLOSED): {CLIENT: MUST_CLOSE}, - (IDLE, CLOSED): {CLIENT: MUST_CLOSE}, - (DONE, ERROR): {CLIENT: MUST_CLOSE}, -} - - -class ConnectionState: - def __init__(self): - # Extra bits of state that don't quite fit into the state model. - - # If this is False then it enables the automatic DONE -> MUST_CLOSE - # transition. Don't set this directly; call .keep_alive_disabled() - self.keep_alive = True - - # This is a subset of {UPGRADE, CONNECT}, containing the proposals - # made by the client for switching protocols. - self.pending_switch_proposals = set() - - self.states = {CLIENT: IDLE, SERVER: IDLE} - - def process_error(self, role): - self.states[role] = ERROR - self._fire_state_triggered_transitions() - - def process_keep_alive_disabled(self): - self.keep_alive = False - self._fire_state_triggered_transitions() - - def process_client_switch_proposal(self, switch_event): - self.pending_switch_proposals.add(switch_event) - self._fire_state_triggered_transitions() - - def process_event(self, role, event_type, server_switch_event=None): - if server_switch_event is not None: - assert role is SERVER - if server_switch_event not in self.pending_switch_proposals: - raise LocalProtocolError( - "Received server {} event without a pending proposal".format( - server_switch_event - ) - ) - event_type = (event_type, server_switch_event) - if server_switch_event is None and event_type is Response: - self.pending_switch_proposals = set() - self._fire_event_triggered_transitions(role, event_type) - # Special case: the server state does get to see Request - # events. - if event_type is Request: - assert role is CLIENT - self._fire_event_triggered_transitions(SERVER, (Request, CLIENT)) - self._fire_state_triggered_transitions() - - def _fire_event_triggered_transitions(self, role, event_type): - state = self.states[role] - try: - new_state = EVENT_TRIGGERED_TRANSITIONS[role][state][event_type] - except KeyError: - raise LocalProtocolError( - "can't handle event type {} when role={} and state={}".format( - event_type.__name__, role, self.states[role] - ) - ) - self.states[role] = new_state - - def _fire_state_triggered_transitions(self): - # We apply these rules repeatedly until converging on a fixed point - while True: - start_states = dict(self.states) - - # It could happen that both these special-case transitions are - # enabled at the same time: - # - # DONE -> MIGHT_SWITCH_PROTOCOL - # DONE -> MUST_CLOSE - # - # For example, this will always be true of a HTTP/1.0 client - # requesting CONNECT. If this happens, the protocol switch takes - # priority. From there the client will either go to - # SWITCHED_PROTOCOL, in which case it's none of our business when - # they close the connection, or else the server will deny the - # request, in which case the client will go back to DONE and then - # from there to MUST_CLOSE. - if self.pending_switch_proposals: - if self.states[CLIENT] is DONE: - self.states[CLIENT] = MIGHT_SWITCH_PROTOCOL - - if not self.pending_switch_proposals: - if self.states[CLIENT] is MIGHT_SWITCH_PROTOCOL: - self.states[CLIENT] = DONE - - if not self.keep_alive: - for role in (CLIENT, SERVER): - if self.states[role] is DONE: - self.states[role] = MUST_CLOSE - - # Tabular state-triggered transitions - joint_state = (self.states[CLIENT], self.states[SERVER]) - changes = STATE_TRIGGERED_TRANSITIONS.get(joint_state, {}) - self.states.update(changes) - - if self.states == start_states: - # Fixed point reached - return - - def start_next_cycle(self): - if self.states != {CLIENT: DONE, SERVER: DONE}: - raise LocalProtocolError( - "not in a reusable state. self.states={}".format(self.states) - ) - # Can't reach DONE/DONE with any of these active, but still, let's be - # sure. - assert self.keep_alive - assert not self.pending_switch_proposals - self.states = {CLIENT: IDLE, SERVER: IDLE} diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_util.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_util.py deleted file mode 100644 index eb1a5cd9..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_util.py +++ /dev/null @@ -1,122 +0,0 @@ -__all__ = [ - "ProtocolError", - "LocalProtocolError", - "RemoteProtocolError", - "validate", - "make_sentinel", - "bytesify", -] - - -class ProtocolError(Exception): - """Exception indicating a violation of the HTTP/1.1 protocol. - - This as an abstract base class, with two concrete base classes: - :exc:`LocalProtocolError`, which indicates that you tried to do something - that HTTP/1.1 says is illegal, and :exc:`RemoteProtocolError`, which - indicates that the remote peer tried to do something that HTTP/1.1 says is - illegal. See :ref:`error-handling` for details. - - In addition to the normal :exc:`Exception` features, it has one attribute: - - .. attribute:: error_status_hint - - This gives a suggestion as to what status code a server might use if - this error occurred as part of a request. - - For a :exc:`RemoteProtocolError`, this is useful as a suggestion for - how you might want to respond to a misbehaving peer, if you're - implementing a server. - - For a :exc:`LocalProtocolError`, this can be taken as a suggestion for - how your peer might have responded to *you* if h11 had allowed you to - continue. - - The default is 400 Bad Request, a generic catch-all for protocol - violations. - - """ - - def __init__(self, msg, error_status_hint=400): - if type(self) is ProtocolError: - raise TypeError("tried to directly instantiate ProtocolError") - Exception.__init__(self, msg) - self.error_status_hint = error_status_hint - - -# Strategy: there are a number of public APIs where a LocalProtocolError can -# be raised (send(), all the different event constructors, ...), and only one -# public API where RemoteProtocolError can be raised -# (receive_data()). Therefore we always raise LocalProtocolError internally, -# and then receive_data will translate this into a RemoteProtocolError. -# -# Internally: -# LocalProtocolError is the generic "ProtocolError". -# Externally: -# LocalProtocolError is for local errors and RemoteProtocolError is for -# remote errors. -class LocalProtocolError(ProtocolError): - def _reraise_as_remote_protocol_error(self): - # After catching a LocalProtocolError, use this method to re-raise it - # as a RemoteProtocolError. This method must be called from inside an - # except: block. - # - # An easy way to get an equivalent RemoteProtocolError is just to - # modify 'self' in place. - self.__class__ = RemoteProtocolError - # But the re-raising is somewhat non-trivial -- you might think that - # now that we've modified the in-flight exception object, that just - # doing 'raise' to re-raise it would be enough. But it turns out that - # this doesn't work, because Python tracks the exception type - # (exc_info[0]) separately from the exception object (exc_info[1]), - # and we only modified the latter. So we really do need to re-raise - # the new type explicitly. - # On py3, the traceback is part of the exception object, so our - # in-place modification preserved it and we can just re-raise: - raise self - - -class RemoteProtocolError(ProtocolError): - pass - - -def validate(regex, data, msg="malformed data", *format_args): - match = regex.fullmatch(data) - if not match: - if format_args: - msg = msg.format(*format_args) - raise LocalProtocolError(msg) - return match.groupdict() - - -# Sentinel values -# -# - Inherit identity-based comparison and hashing from object -# - Have a nice repr -# - Have a *bonus property*: type(sentinel) is sentinel -# -# The bonus property is useful if you want to take the return value from -# next_event() and do some sort of dispatch based on type(event). -class _SentinelBase(type): - def __repr__(self): - return self.__name__ - - -def make_sentinel(name): - cls = _SentinelBase(name, (_SentinelBase,), {}) - cls.__class__ = cls - return cls - - -# Used for methods, request targets, HTTP versions, header names, and header -# values. Accepts ascii-strings, or bytes/bytearray/memoryview/..., and always -# returns bytes. -def bytesify(s): - # Fast-path: - if type(s) is bytes: - return s - if isinstance(s, str): - s = s.encode("ascii") - if isinstance(s, int): - raise TypeError("expected bytes-like object, not int") - return bytes(s) diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_version.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_version.py deleted file mode 100644 index cb5c2c32..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# This file must be kept very simple, because it is consumed from several -# places -- it is imported by h11/__init__.py, execfile'd by setup.py, etc. - -# We use a simple scheme: -# 1.0.0 -> 1.0.0+dev -> 1.1.0 -> 1.1.0+dev -# where the +dev versions are never released into the wild, they're just what -# we stick into the VCS in between releases. -# -# This is compatible with PEP 440: -# http://legacy.python.org/dev/peps/pep-0440/ -# via the use of the "local suffix" "+dev", which is disallowed on index -# servers and causes 1.0.0+dev to sort after plain 1.0.0, which is what we -# want. (Contrast with the special suffix 1.0.0.dev, which sorts *before* -# 1.0.0.) - -__version__ = "0.12.0" diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/_writers.py b/IKEA_scraper/.venv/Lib/site-packages/h11/_writers.py deleted file mode 100644 index cb5e8a8c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/_writers.py +++ /dev/null @@ -1,123 +0,0 @@ -# Code to read HTTP data -# -# Strategy: each writer takes an event + a write-some-bytes function, which is -# calls. -# -# WRITERS is a dict describing how to pick a reader. It maps states to either: -# - a writer -# - or, for body writers, a dict of framin-dependent writer factories - -from ._events import Data, EndOfMessage -from ._state import CLIENT, IDLE, SEND_BODY, SEND_RESPONSE, SERVER -from ._util import LocalProtocolError - -__all__ = ["WRITERS"] - - -def write_headers(headers, write): - # "Since the Host field-value is critical information for handling a - # request, a user agent SHOULD generate Host as the first header field - # following the request-line." - RFC 7230 - raw_items = headers._full_items - for raw_name, name, value in raw_items: - if name == b"host": - write(b"%s: %s\r\n" % (raw_name, value)) - for raw_name, name, value in raw_items: - if name != b"host": - write(b"%s: %s\r\n" % (raw_name, value)) - write(b"\r\n") - - -def write_request(request, write): - if request.http_version != b"1.1": - raise LocalProtocolError("I only send HTTP/1.1") - write(b"%s %s HTTP/1.1\r\n" % (request.method, request.target)) - write_headers(request.headers, write) - - -# Shared between InformationalResponse and Response -def write_any_response(response, write): - if response.http_version != b"1.1": - raise LocalProtocolError("I only send HTTP/1.1") - status_bytes = str(response.status_code).encode("ascii") - # We don't bother sending ascii status messages like "OK"; they're - # optional and ignored by the protocol. (But the space after the numeric - # status code is mandatory.) - # - # XX FIXME: could at least make an effort to pull out the status message - # from stdlib's http.HTTPStatus table. Or maybe just steal their enums - # (either by import or copy/paste). We already accept them as status codes - # since they're of type IntEnum < int. - write(b"HTTP/1.1 %s %s\r\n" % (status_bytes, response.reason)) - write_headers(response.headers, write) - - -class BodyWriter: - def __call__(self, event, write): - if type(event) is Data: - self.send_data(event.data, write) - elif type(event) is EndOfMessage: - self.send_eom(event.headers, write) - else: # pragma: no cover - assert False - - -# -# These are all careful not to do anything to 'data' except call len(data) and -# write(data). This allows us to transparently pass-through funny objects, -# like placeholder objects referring to files on disk that will be sent via -# sendfile(2). -# -class ContentLengthWriter(BodyWriter): - def __init__(self, length): - self._length = length - - def send_data(self, data, write): - self._length -= len(data) - if self._length < 0: - raise LocalProtocolError("Too much data for declared Content-Length") - write(data) - - def send_eom(self, headers, write): - if self._length != 0: - raise LocalProtocolError("Too little data for declared Content-Length") - if headers: - raise LocalProtocolError("Content-Length and trailers don't mix") - - -class ChunkedWriter(BodyWriter): - def send_data(self, data, write): - # if we encoded 0-length data in the naive way, it would look like an - # end-of-message. - if not data: - return - write(b"%x\r\n" % len(data)) - write(data) - write(b"\r\n") - - def send_eom(self, headers, write): - write(b"0\r\n") - write_headers(headers, write) - - -class Http10Writer(BodyWriter): - def send_data(self, data, write): - write(data) - - def send_eom(self, headers, write): - if headers: - raise LocalProtocolError("can't send trailers to HTTP/1.0 client") - # no need to close the socket ourselves, that will be taken care of by - # Connection: close machinery - - -WRITERS = { - (CLIENT, IDLE): write_request, - (SERVER, IDLE): write_any_response, - (SERVER, SEND_RESPONSE): write_any_response, - SEND_BODY: { - "chunked": ChunkedWriter, - "content-length": ContentLengthWriter, - "http/1.0": Http10Writer, - }, -} diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 36953e6d915f917c533aaa33f4d7ed20c739b265..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmYe~<>g`kf`|Vc6G8N25P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_ei&acOWkyMU zUQAJ9UP^v$OmK2Wetu4jr?;zPd~tG7VnJ$Aj9yu4URjJ!W>QRXW=X1UL1J=tVtQ(E qOopMMeo1O^NwI!>d}dx|NqoFsLFFwDo80`A(wtN~kX@gFm;nHECoJv& diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/helpers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/helpers.cpython-39.pyc deleted file mode 100644 index 6f8121a536ab830e5601a8e93cbaa4e57c439e30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1969 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_connection.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_connection.cpython-39.pyc deleted file mode 100644 index 64c4e8ed54060ec7c2c3f34d54a99f0b616150cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32093 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 F{{effQDguB diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_events.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_events.cpython-39.pyc deleted file mode 100644 index 7edcce997e20c9b4390a5b743babead4ee221070..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3895 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 MVl&&YKe5mJ4-voh7XSbN diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_helpers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_helpers.cpython-39.pyc deleted file mode 100644 index ac436bc5074321938a3c2dde95cbb19d7e5492fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 648 zcmZuu&1w`u5bo}oHM5&tQPGPJ5Evnm%`b?G!Q^0~QH*#P28Pa5XJ^Um%+l2ftf!F8 zH4oyO_zZIsPdO(LFc7V&T}T8A>Z`7=zpkpO(Vb39ko~+_*RPZizv|?!5hvb|<6{C4 zAan6WfCBGSL=ya65jM^xU4^oe&r&-4V{OXblH)0X6HYn>ax6ieNhiVM=z-r8&^S}X z+?(FaaP-IY0)i>moW@oid(ClOVV1eO723>9UUpd7I8b=JB~By=n)d$AMLlkp=Ji24 z&DrAl58^^q&7#xp5Rkxt7~B+dQy~j zp!5DWlhln8b7TsKk-tGn)!Z97qpj7WD)?-0SQcoa_GSSe_dgg!-80{XeL%Gset+F~ z5q}zGt}J4!3n&NiZkm;49>3e(Tu(5ydT4CCKpl?a_x-&X`_9Y{b$URBFwVN&=gy!* z#w0U2sc~UAs-D(#^4~#yYL0URLMqjkfozcn(q{~=)F0KEaKv1zOZ$kFJE4kbYh0d* Z+fSIB9+IdEUJgn)%+2fiNATVP?=P3qoqzxU diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_io.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_io.cpython-39.pyc deleted file mode 100644 index 1e1e76202ac90ea0a9176727b259c35a784d8637..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11687 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-39.pyc deleted file mode 100644 index 2a855b6a4b4a548741f44d806cfbaa33d0e0bfc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2241 zcmZ`)&2Jk;6rY*3oy{hjxcO+>B2|{)P#>DaNk1S$RZD{SXca0_aabA5+A~SES?`*e zO{kG0A({h1Ldppt#3A7X{{Z4oK>P`NL!7K~GY7<>;=P$ox=vuFc{A_5-}{<*GwZvq zL*V=U`91$Fmykb@$$z83+=Zc*qG$l8`?QNjznctE^@ppT13C0>Gg zgpY8WkABVc+TmlT>v8VlddoUye1cCNkf+qMIo%-Dav$Q5^*#eyrK$VAXo+A?ys^8v zDP#+ECm$j#7^^VUcfcj&DcL7IA}8J@U(kg1z$>RaOkLGH(>w!y9{C>O)@_YfcXIdw z=+|?23;2)D@R6}UvUu^B@)96EHxl)wMw-YYApbUJX#@Y`8U7bz2cAa36C!@gAu!i; z2tjs<`qN0{UuNcxsp6<`O!(LiJEY3gZ|WV_l1k9^E2* z<_9?KLpD_Ztd^YA4_JQ{dH}5r6OZpul>+^de+N(bZnspT<;(Et# z?f6?l)wgT41;{Q@nl_|)rkeVhn(uVeDO3)N@kCS|2%#lv(=shHJDbaFD!0;H$p+b! z9yZ05rUgxrFQKhQpoYy*N9*Ji_)iPmPyA|8T>$3oM~@yZ)aGlIrNza{d-q*ua0R5R zag>NCxt?@8Vx^M6?k#jeKZu|;rj0rhtt5z}l}am&l>j+*DOh6*Zp3X-X~w+kO@A6B z+l`hCHyd1pK^rzn!n@4^UM&uApU;GM)MexTKchPXOdoO^4(<%_RycANsCQ9Egm`fj zc5^|Cat_pT2FWEP7$|Sj4xR{ZQibzwgqtn&dh%f(WAClPP-{T+?*yLmHS*#3KI_pQ zgDX!zaeDNK!joh5EO>G#J~?VJyZRJLaYL{N(rf42v9TG;MiA}!VZdK(;|GA&&jER* z1dZh|o0W_5C6HD}QznI1>fo(RyourFHffpWYx{D?8|(PeZ;M0*pNX`n8SN&Q8McSi o>DjNhW4;@TJ9r}M8W0--k6ZS7i85B8Y=r$?aL&xn*mL&szajY-9smFU diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_state.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_state.cpython-39.pyc deleted file mode 100644 index f0294ac118673cba1b3e13aeab53f529a5706f19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5084 zcmbtYO>Y~=8J=0L$Q4D36!j6waUC^HozSV>C@6Xef*_8_BuZsT5SauaWGrazN}{|X zshN=)0TfU)JrqHa8fcG2AqBY@2zu(FDEb@v0~Wm$J>>_qhah$PyfaI3NzsVVO4ym% z*>}F)=XpPd^=vlH@b~v8ck6rKW$YjH68}r$DcPKpO@qpEsXL*T$S50l{+77J4 zL@jY>*X+ZI+61R>6G8GYRZF3r^iscIHOF(jNz{{G+M7b1_A*`;^^|Y>89(7?J?>|l ziQ2R`?d8y)^YY#d>bzI*W>L?0bKX4ag16v3gL>9m^p;T1dA!1k*S^9I*~V8E$|4W> ztzsg~xs?yss;lq1tD74e<<;t-f$qS43 zBvO!Yw8R@Ep(fAMYU+aj`Z`Grq(6kZZTx?d;H;HjVe;S=#`XV4D5KQ|bA8%h%~qMQ zt9==h$c{*)^nU)@m$1~dk-&cJUR$3phxeS8{-!T&t9)#}8AudJ;t`k2B;&CPd(1bA zvx3+ZCM79ahRN0Swem(awAV`O7y{Ko7?5e*5*b9BRi*wI{j9r z-10Ve?_s6-o*&w!&5d%HACO@+XiMJ<)A!!5RNd9}%}Tk3{h}&8=AqS)kC}KD>wH}; zy|%M;y06-;9Z_$2?Zcf)W53-FcGiAUzU#_{sCRs^a|dTR*;#Ks*pW@;-|o~K53#D; z*V?2sM8(nMpJW=__mCK@uaV*l%q7ZB zpi@(}g+`CE=bEw+)b@oYmhPK~08N6tDdnh14f*R4wI=5J)B11)f;q%<3yT4@_-j8z&b(2kS^OJ8CtdCcT1k)l#Y zr3dDVgD>w5D`j$=Qex*`z`EiF6GMkQ`;RPIDEaQFX z*a>uy3F%|!wR=;1*DA3`{65^A$4l(~zs_)MI6bRtohQ2Ng2N$M=eC-N9Gz*Wv|6kK z@Iy^1I62Lss!>hXI>?+b`9QyM(bePA$~Y!`6J7nq%w(Jq7hhl$&6dM#hLN9>)KMYo z&-YjPbANPN&BXRGkoa3nqPObs+)s=I_EIpb96995iq=Nas=i$;2x5mIyE2aLMvuyk zpb6jQ%AYn>W8Xz@r!DKjDD&-7UDXY{b2LYv-L=Jz-}0KRz0nz@;k~vBB1SlWZ|$9T ztGyt%wY^#0T-{t3v-nm_)TW{hsMC&*VC%O|UB51ZQ*n)!8!?>c$FeAz0b`rK_ZEi9 zAE97;8q`Vhw5HL5HEr3jp)_2Q%@^_D|4DixLv_?z;Nk_08zLG7Y6=LNXn#RNF+;Tb ze>h{BUcAfu^x`pknYN)9AEB4FFN`BHnmA}AvVCd<8dj1>N0Dt*;tG%YkKjEkEwY|y-*qY0!`Yy@}lJoRa(HVnJ5`tQ+K0x(>1MHIGNLeND# ziwF_Un6#!`a(kE;ty(4mO9#%e7~dX?G5D!7ogUljjfUS*zDIFFlGkB?c>s1V+7!5W z5#OE;=@`~a z-!REb+Vqn>8|d;^fo>3wG)#Sq72n5Mh4$4N)0=oLT47fD;>7QvHWreX$3o(@j}iaK zbHtJP8D^DayDTxS0g3DnR+j#cop4}#g5ui{B*aA`+bSOUD-?TxWY^)Or#Hn= z<9*i#P`f+U8S6WEhMwuOgm&}^g6inixT{yGb0i1IUT;Jp0B*j^$y(z1>(Mgu*KRz2 zJz5^9J~QG-$6Cz{wk`@(P;fHNlCprJUCRymTV#MQkpwBKmL2*u>ho5{D!M80;D z?mhk5(O1XFk)ijc=#rovTl8+?&GgV4&4Fvg4>0S~ZSYNe9kD_4Ye)aeaLEo|jbk@( zRjF~hHJa3_qdVnTz1+}xi2|}PKPtFQ={AGF->V1z#5hSQ8%xmTNZdxNI4=mpTFU$u zfnO}l4SghB)h66y)eKBrqN}&QN{VG_QPQikIg`2TG=Z`v9jA4)(B4a{Pp=sZQ941_ ums;ob!?t%E_-{}&ku;|RojZJvXA;h`lXWuAO`U81+fF$JXV%G~y!&5FTqjom diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/__pycache__/test_util.cpython-39.pyc deleted file mode 100644 index 0c6334af9bb2647ba23ce3d30b50f07f87dca465..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3061 zcmZ`*&uw zZCcnOi#8*2Vg#)%@}ht?D@MgJv^l}&SgE*!71-GzE zvf^~J9r-GX)6%OeU&Yz^cGJHlWhmpq9T`SpEo^A@C6lxhE&iFid9`|{y&Q!>ReFI4 z*Q#^1MmBe7QSy?qAQ;bcN!k!SX&A_;>3PZ->*OOitH&Sndo1|W0$uG{&Ne|qXENel z*5iV&8tUTb>@lGvCQ|c@KNTUT^BX{tH|Kd%Y+!TV`Z!rK0p!W}6B7UAE1)`KH-5w(M;^ zL+{pjXz1OdrQHJO5pc54dHWHNEFdjLxvtgYQMSdNb9Gkl(OMZ1*;NDj9B1x%Bp5T$}Vh9)+VOfpYBYbC4)ah7t+ zUqFb**~L(%n5^oOY$J^UU=Wx@%$NyUpDsb2UHC@w?hQ^ii=D zAt__alS_ma2=$;IEtk?U_a#x~SXiOrjE1tl^y|%%ONshVb6pgMH|n-v;OCXw1&4 zbNHI`AK#f-l3}Y^x%So6rH{V8P^y;uw&^{a4!fzcGBIPSTzQQcW>Z>LN`{k80CwAH zl}bi!Z0O2|@j1BKkba!0g=@`v!&Xy6_^uWW=epHXM(HkJ$@KU- zQ+J0PxQ}BUit}&?#~Q%-aR}#Be?JJ69_rzN9sMzclo>$!i;%Rd?OE+O6tvgGm1Bir zQ*|;VC%)P2 zeK$VjJ2xpZQ9W3i!7OzG0&X<&e3Fm#y}n>L-Zg$V5KwACTkp@mFcNsjFRb!x+N2jbZ9-2*z!cusli`mAIro$|cpnA^K=&zo5NWl3-OFd6Yue~3q@z|F^y%q}pR-h#v;F9iK1H5X6HMvP` z*#mSiOwobKz~%{FL`a^)BP+0!Mv|-`+9d_9UeZbFo1nhs>2pNaARWKj3wr9IE88<` dp=dSyYgAWtCfIPGZQyU(Df^Ut%r4ra{{te=nOy(? diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/data/test-file b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/data/test-file deleted file mode 100644 index d0be0a6c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/data/test-file +++ /dev/null @@ -1 +0,0 @@ -92b12bc045050b55b848d37167a1a63947c364579889ce1d39788e45e9fac9e5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/helpers.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/helpers.py deleted file mode 100644 index 9d2cf380..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/helpers.py +++ /dev/null @@ -1,77 +0,0 @@ -from .._connection import * -from .._events import * -from .._state import * - - -def get_all_events(conn): - got_events = [] - while True: - event = conn.next_event() - if event in (NEED_DATA, PAUSED): - break - got_events.append(event) - if type(event) is ConnectionClosed: - break - return got_events - - -def receive_and_get(conn, data): - conn.receive_data(data) - return get_all_events(conn) - - -# Merges adjacent Data events, converts payloads to bytestrings, and removes -# chunk boundaries. -def normalize_data_events(in_events): - out_events = [] - for event in in_events: - if type(event) is Data: - event.data = bytes(event.data) - event.chunk_start = False - event.chunk_end = False - if out_events and type(out_events[-1]) is type(event) is Data: - out_events[-1].data += event.data - else: - out_events.append(event) - return out_events - - -# Given that we want to write tests that push some events through a Connection -# and check that its state updates appropriately... we might as make a habit -# of pushing them through two Connections with a fake network link in -# between. -class ConnectionPair: - def __init__(self): - self.conn = {CLIENT: Connection(CLIENT), SERVER: Connection(SERVER)} - self.other = {CLIENT: SERVER, SERVER: CLIENT} - - @property - def conns(self): - return self.conn.values() - - # expect="match" if expect=send_events; expect=[...] to say what expected - def send(self, role, send_events, expect="match"): - if not isinstance(send_events, list): - send_events = [send_events] - data = b"" - closed = False - for send_event in send_events: - new_data = self.conn[role].send(send_event) - if new_data is None: - closed = True - else: - data += new_data - # send uses b"" to mean b"", and None to mean closed - # receive uses b"" to mean closed, and None to mean "try again" - # so we have to translate between the two conventions - if data: - self.conn[self.other[role]].receive_data(data) - if closed: - self.conn[self.other[role]].receive_data(b"") - got_events = get_all_events(self.conn[self.other[role]]) - if expect == "match": - expect = send_events - if not isinstance(expect, list): - expect = [expect] - assert got_events == expect - return data diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_against_stdlib_http.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_against_stdlib_http.py deleted file mode 100644 index e6c5db44..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_against_stdlib_http.py +++ /dev/null @@ -1,111 +0,0 @@ -import json -import os.path -import socket -import socketserver -import threading -from contextlib import closing, contextmanager -from http.server import SimpleHTTPRequestHandler -from urllib.request import urlopen - -import h11 - - -@contextmanager -def socket_server(handler): - httpd = socketserver.TCPServer(("127.0.0.1", 0), handler) - thread = threading.Thread( - target=httpd.serve_forever, kwargs={"poll_interval": 0.01} - ) - thread.daemon = True - try: - thread.start() - yield httpd - finally: - httpd.shutdown() - - -test_file_path = os.path.join(os.path.dirname(__file__), "data/test-file") -with open(test_file_path, "rb") as f: - test_file_data = f.read() - - -class SingleMindedRequestHandler(SimpleHTTPRequestHandler): - def translate_path(self, path): - return test_file_path - - -def test_h11_as_client(): - with socket_server(SingleMindedRequestHandler) as httpd: - with closing(socket.create_connection(httpd.server_address)) as s: - c = h11.Connection(h11.CLIENT) - - s.sendall( - c.send( - h11.Request( - method="GET", target="/foo", headers=[("Host", "localhost")] - ) - ) - ) - s.sendall(c.send(h11.EndOfMessage())) - - data = bytearray() - while True: - event = c.next_event() - print(event) - if event is h11.NEED_DATA: - # Use a small read buffer to make things more challenging - # and exercise more paths :-) - c.receive_data(s.recv(10)) - continue - if type(event) is h11.Response: - assert event.status_code == 200 - if type(event) is h11.Data: - data += event.data - if type(event) is h11.EndOfMessage: - break - assert bytes(data) == test_file_data - - -class H11RequestHandler(socketserver.BaseRequestHandler): - def handle(self): - with closing(self.request) as s: - c = h11.Connection(h11.SERVER) - request = None - while True: - event = c.next_event() - if event is h11.NEED_DATA: - # Use a small read buffer to make things more challenging - # and exercise more paths :-) - c.receive_data(s.recv(10)) - continue - if type(event) is h11.Request: - request = event - if type(event) is h11.EndOfMessage: - break - info = json.dumps( - { - "method": request.method.decode("ascii"), - "target": request.target.decode("ascii"), - "headers": { - name.decode("ascii"): value.decode("ascii") - for (name, value) in request.headers - }, - } - ) - s.sendall(c.send(h11.Response(status_code=200, headers=[]))) - s.sendall(c.send(h11.Data(data=info.encode("ascii")))) - s.sendall(c.send(h11.EndOfMessage())) - - -def test_h11_as_server(): - with socket_server(H11RequestHandler) as httpd: - host, port = httpd.server_address - url = "http://{}:{}/some-path".format(host, port) - with closing(urlopen(url)) as f: - assert f.getcode() == 200 - data = f.read() - info = json.loads(data.decode("ascii")) - print(info) - assert info["method"] == "GET" - assert info["target"] == "/some-path" - assert "urllib" in info["headers"]["user-agent"] diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_connection.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_connection.py deleted file mode 100644 index baadec8d..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_connection.py +++ /dev/null @@ -1,1078 +0,0 @@ -import pytest - -from .._connection import _body_framing, _keep_alive, Connection, NEED_DATA, PAUSED -from .._events import * -from .._state import * -from .._util import LocalProtocolError, RemoteProtocolError -from .helpers import ConnectionPair, get_all_events, receive_and_get - - -def test__keep_alive(): - assert _keep_alive( - Request(method="GET", target="/", headers=[("Host", "Example.com")]) - ) - assert not _keep_alive( - Request( - method="GET", - target="/", - headers=[("Host", "Example.com"), ("Connection", "close")], - ) - ) - assert not _keep_alive( - Request( - method="GET", - target="/", - headers=[("Host", "Example.com"), ("Connection", "a, b, cLOse, foo")], - ) - ) - assert not _keep_alive( - Request(method="GET", target="/", headers=[], http_version="1.0") - ) - - assert _keep_alive(Response(status_code=200, headers=[])) - assert not _keep_alive(Response(status_code=200, headers=[("Connection", "close")])) - assert not _keep_alive( - Response(status_code=200, headers=[("Connection", "a, b, cLOse, foo")]) - ) - assert not _keep_alive(Response(status_code=200, headers=[], http_version="1.0")) - - -def test__body_framing(): - def headers(cl, te): - headers = [] - if cl is not None: - headers.append(("Content-Length", str(cl))) - if te: - headers.append(("Transfer-Encoding", "chunked")) - return headers - - def resp(status_code=200, cl=None, te=False): - return Response(status_code=status_code, headers=headers(cl, te)) - - def req(cl=None, te=False): - h = headers(cl, te) - h += [("Host", "example.com")] - return Request(method="GET", target="/", headers=h) - - # Special cases where the headers are ignored: - for kwargs in [{}, {"cl": 100}, {"te": True}, {"cl": 100, "te": True}]: - for meth, r in [ - (b"HEAD", resp(**kwargs)), - (b"GET", resp(status_code=204, **kwargs)), - (b"GET", resp(status_code=304, **kwargs)), - ]: - assert _body_framing(meth, r) == ("content-length", (0,)) - - # Transfer-encoding - for kwargs in [{"te": True}, {"cl": 100, "te": True}]: - for meth, r in [(None, req(**kwargs)), (b"GET", resp(**kwargs))]: - assert _body_framing(meth, r) == ("chunked", ()) - - # Content-Length - for meth, r in [(None, req(cl=100)), (b"GET", resp(cl=100))]: - assert _body_framing(meth, r) == ("content-length", (100,)) - - # No headers - assert _body_framing(None, req()) == ("content-length", (0,)) - assert _body_framing(b"GET", resp()) == ("http/1.0", ()) - - -def test_Connection_basics_and_content_length(): - with pytest.raises(ValueError): - Connection("CLIENT") - - p = ConnectionPair() - assert p.conn[CLIENT].our_role is CLIENT - assert p.conn[CLIENT].their_role is SERVER - assert p.conn[SERVER].our_role is SERVER - assert p.conn[SERVER].their_role is CLIENT - - data = p.send( - CLIENT, - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Content-Length", "10")], - ), - ) - assert data == ( - b"GET / HTTP/1.1\r\n" b"Host: example.com\r\n" b"Content-Length: 10\r\n\r\n" - ) - - for conn in p.conns: - assert conn.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - assert p.conn[CLIENT].our_state is SEND_BODY - assert p.conn[CLIENT].their_state is SEND_RESPONSE - assert p.conn[SERVER].our_state is SEND_RESPONSE - assert p.conn[SERVER].their_state is SEND_BODY - - assert p.conn[CLIENT].their_http_version is None - assert p.conn[SERVER].their_http_version == b"1.1" - - data = p.send(SERVER, InformationalResponse(status_code=100, headers=[])) - assert data == b"HTTP/1.1 100 \r\n\r\n" - - data = p.send(SERVER, Response(status_code=200, headers=[("Content-Length", "11")])) - assert data == b"HTTP/1.1 200 \r\nContent-Length: 11\r\n\r\n" - - for conn in p.conns: - assert conn.states == {CLIENT: SEND_BODY, SERVER: SEND_BODY} - - assert p.conn[CLIENT].their_http_version == b"1.1" - assert p.conn[SERVER].their_http_version == b"1.1" - - data = p.send(CLIENT, Data(data=b"12345")) - assert data == b"12345" - data = p.send( - CLIENT, Data(data=b"67890"), expect=[Data(data=b"67890"), EndOfMessage()] - ) - assert data == b"67890" - data = p.send(CLIENT, EndOfMessage(), expect=[]) - assert data == b"" - - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: SEND_BODY} - - data = p.send(SERVER, Data(data=b"1234567890")) - assert data == b"1234567890" - data = p.send(SERVER, Data(data=b"1"), expect=[Data(data=b"1"), EndOfMessage()]) - assert data == b"1" - data = p.send(SERVER, EndOfMessage(), expect=[]) - assert data == b"" - - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: DONE} - - -def test_chunked(): - p = ConnectionPair() - - p.send( - CLIENT, - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Transfer-Encoding", "chunked")], - ), - ) - data = p.send(CLIENT, Data(data=b"1234567890", chunk_start=True, chunk_end=True)) - assert data == b"a\r\n1234567890\r\n" - data = p.send(CLIENT, Data(data=b"abcde", chunk_start=True, chunk_end=True)) - assert data == b"5\r\nabcde\r\n" - data = p.send(CLIENT, Data(data=b""), expect=[]) - assert data == b"" - data = p.send(CLIENT, EndOfMessage(headers=[("hello", "there")])) - assert data == b"0\r\nhello: there\r\n\r\n" - - p.send( - SERVER, Response(status_code=200, headers=[("Transfer-Encoding", "chunked")]) - ) - p.send(SERVER, Data(data=b"54321", chunk_start=True, chunk_end=True)) - p.send(SERVER, Data(data=b"12345", chunk_start=True, chunk_end=True)) - p.send(SERVER, EndOfMessage()) - - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: DONE} - - -def test_chunk_boundaries(): - conn = Connection(our_role=SERVER) - - request = ( - b"POST / HTTP/1.1\r\n" - b"Host: example.com\r\n" - b"Transfer-Encoding: chunked\r\n" - b"\r\n" - ) - conn.receive_data(request) - assert conn.next_event() == Request( - method="POST", - target="/", - headers=[("Host", "example.com"), ("Transfer-Encoding", "chunked")], - ) - assert conn.next_event() is NEED_DATA - - conn.receive_data(b"5\r\nhello\r\n") - assert conn.next_event() == Data(data=b"hello", chunk_start=True, chunk_end=True) - - conn.receive_data(b"5\r\nhel") - assert conn.next_event() == Data(data=b"hel", chunk_start=True, chunk_end=False) - - conn.receive_data(b"l") - assert conn.next_event() == Data(data=b"l", chunk_start=False, chunk_end=False) - - conn.receive_data(b"o\r\n") - assert conn.next_event() == Data(data=b"o", chunk_start=False, chunk_end=True) - - conn.receive_data(b"5\r\nhello") - assert conn.next_event() == Data(data=b"hello", chunk_start=True, chunk_end=True) - - conn.receive_data(b"\r\n") - assert conn.next_event() == NEED_DATA - - conn.receive_data(b"0\r\n\r\n") - assert conn.next_event() == EndOfMessage() - - -def test_client_talking_to_http10_server(): - c = Connection(CLIENT) - c.send(Request(method="GET", target="/", headers=[("Host", "example.com")])) - c.send(EndOfMessage()) - assert c.our_state is DONE - # No content-length, so Http10 framing for body - assert receive_and_get(c, b"HTTP/1.0 200 OK\r\n\r\n") == [ - Response(status_code=200, headers=[], http_version="1.0", reason=b"OK") - ] - assert c.our_state is MUST_CLOSE - assert receive_and_get(c, b"12345") == [Data(data=b"12345")] - assert receive_and_get(c, b"67890") == [Data(data=b"67890")] - assert receive_and_get(c, b"") == [EndOfMessage(), ConnectionClosed()] - assert c.their_state is CLOSED - - -def test_server_talking_to_http10_client(): - c = Connection(SERVER) - # No content-length, so no body - # NB: no host header - assert receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") == [ - Request(method="GET", target="/", headers=[], http_version="1.0"), - EndOfMessage(), - ] - assert c.their_state is MUST_CLOSE - - # We automatically Connection: close back at them - assert ( - c.send(Response(status_code=200, headers=[])) - == b"HTTP/1.1 200 \r\nConnection: close\r\n\r\n" - ) - - assert c.send(Data(data=b"12345")) == b"12345" - assert c.send(EndOfMessage()) == b"" - assert c.our_state is MUST_CLOSE - - # Check that it works if they do send Content-Length - c = Connection(SERVER) - # NB: no host header - assert receive_and_get(c, b"POST / HTTP/1.0\r\nContent-Length: 10\r\n\r\n1") == [ - Request( - method="POST", - target="/", - headers=[("Content-Length", "10")], - http_version="1.0", - ), - Data(data=b"1"), - ] - assert receive_and_get(c, b"234567890") == [Data(data=b"234567890"), EndOfMessage()] - assert c.their_state is MUST_CLOSE - assert receive_and_get(c, b"") == [ConnectionClosed()] - - -def test_automatic_transfer_encoding_in_response(): - # Check that in responses, the user can specify either Transfer-Encoding: - # chunked or no framing at all, and in both cases we automatically select - # the right option depending on whether the peer speaks HTTP/1.0 or - # HTTP/1.1 - for user_headers in [ - [("Transfer-Encoding", "chunked")], - [], - # In fact, this even works if Content-Length is set, - # because if both are set then Transfer-Encoding wins - [("Transfer-Encoding", "chunked"), ("Content-Length", "100")], - ]: - p = ConnectionPair() - p.send( - CLIENT, - [ - Request(method="GET", target="/", headers=[("Host", "example.com")]), - EndOfMessage(), - ], - ) - # When speaking to HTTP/1.1 client, all of the above cases get - # normalized to Transfer-Encoding: chunked - p.send( - SERVER, - Response(status_code=200, headers=user_headers), - expect=Response( - status_code=200, headers=[("Transfer-Encoding", "chunked")] - ), - ) - - # When speaking to HTTP/1.0 client, all of the above cases get - # normalized to no-framing-headers - c = Connection(SERVER) - receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") - assert ( - c.send(Response(status_code=200, headers=user_headers)) - == b"HTTP/1.1 200 \r\nConnection: close\r\n\r\n" - ) - assert c.send(Data(data=b"12345")) == b"12345" - - -def test_automagic_connection_close_handling(): - p = ConnectionPair() - # If the user explicitly sets Connection: close, then we notice and - # respect it - p.send( - CLIENT, - [ - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Connection", "close")], - ), - EndOfMessage(), - ], - ) - for conn in p.conns: - assert conn.states[CLIENT] is MUST_CLOSE - # And if the client sets it, the server automatically echoes it back - p.send( - SERVER, - # no header here... - [Response(status_code=204, headers=[]), EndOfMessage()], - # ...but oh look, it arrived anyway - expect=[ - Response(status_code=204, headers=[("connection", "close")]), - EndOfMessage(), - ], - ) - for conn in p.conns: - assert conn.states == {CLIENT: MUST_CLOSE, SERVER: MUST_CLOSE} - - -def test_100_continue(): - def setup(): - p = ConnectionPair() - p.send( - CLIENT, - Request( - method="GET", - target="/", - headers=[ - ("Host", "example.com"), - ("Content-Length", "100"), - ("Expect", "100-continue"), - ], - ), - ) - for conn in p.conns: - assert conn.client_is_waiting_for_100_continue - assert not p.conn[CLIENT].they_are_waiting_for_100_continue - assert p.conn[SERVER].they_are_waiting_for_100_continue - return p - - # Disabled by 100 Continue - p = setup() - p.send(SERVER, InformationalResponse(status_code=100, headers=[])) - for conn in p.conns: - assert not conn.client_is_waiting_for_100_continue - assert not conn.they_are_waiting_for_100_continue - - # Disabled by a real response - p = setup() - p.send( - SERVER, Response(status_code=200, headers=[("Transfer-Encoding", "chunked")]) - ) - for conn in p.conns: - assert not conn.client_is_waiting_for_100_continue - assert not conn.they_are_waiting_for_100_continue - - # Disabled by the client going ahead and sending stuff anyway - p = setup() - p.send(CLIENT, Data(data=b"12345")) - for conn in p.conns: - assert not conn.client_is_waiting_for_100_continue - assert not conn.they_are_waiting_for_100_continue - - -def test_max_incomplete_event_size_countermeasure(): - # Infinitely long headers are definitely not okay - c = Connection(SERVER) - c.receive_data(b"GET / HTTP/1.0\r\nEndless: ") - assert c.next_event() is NEED_DATA - with pytest.raises(RemoteProtocolError): - while True: - c.receive_data(b"a" * 1024) - c.next_event() - - # Checking that the same header is accepted / rejected depending on the - # max_incomplete_event_size setting: - c = Connection(SERVER, max_incomplete_event_size=5000) - c.receive_data(b"GET / HTTP/1.0\r\nBig: ") - c.receive_data(b"a" * 4000) - c.receive_data(b"\r\n\r\n") - assert get_all_events(c) == [ - Request( - method="GET", target="/", http_version="1.0", headers=[("big", "a" * 4000)] - ), - EndOfMessage(), - ] - - c = Connection(SERVER, max_incomplete_event_size=4000) - c.receive_data(b"GET / HTTP/1.0\r\nBig: ") - c.receive_data(b"a" * 4000) - with pytest.raises(RemoteProtocolError): - c.next_event() - - # Temporarily exceeding the size limit is fine, as long as its done with - # complete events: - c = Connection(SERVER, max_incomplete_event_size=5000) - c.receive_data(b"GET / HTTP/1.0\r\nContent-Length: 10000") - c.receive_data(b"\r\n\r\n" + b"a" * 10000) - assert get_all_events(c) == [ - Request( - method="GET", - target="/", - http_version="1.0", - headers=[("Content-Length", "10000")], - ), - Data(data=b"a" * 10000), - EndOfMessage(), - ] - - c = Connection(SERVER, max_incomplete_event_size=100) - # Two pipelined requests to create a way-too-big receive buffer... but - # it's fine because we're not checking - c.receive_data( - b"GET /1 HTTP/1.1\r\nHost: a\r\n\r\n" - b"GET /2 HTTP/1.1\r\nHost: b\r\n\r\n" + b"X" * 1000 - ) - assert get_all_events(c) == [ - Request(method="GET", target="/1", headers=[("host", "a")]), - EndOfMessage(), - ] - # Even more data comes in, still no problem - c.receive_data(b"X" * 1000) - # We can respond and reuse to get the second pipelined request - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - c.start_next_cycle() - assert get_all_events(c) == [ - Request(method="GET", target="/2", headers=[("host", "b")]), - EndOfMessage(), - ] - # But once we unpause and try to read the next message, and find that it's - # incomplete and the buffer is *still* way too large, then *that's* a - # problem: - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - c.start_next_cycle() - with pytest.raises(RemoteProtocolError): - c.next_event() - - -def test_reuse_simple(): - p = ConnectionPair() - p.send( - CLIENT, - [Request(method="GET", target="/", headers=[("Host", "a")]), EndOfMessage()], - ) - p.send(SERVER, [Response(status_code=200, headers=[]), EndOfMessage()]) - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: DONE} - conn.start_next_cycle() - - p.send( - CLIENT, - [ - Request(method="DELETE", target="/foo", headers=[("Host", "a")]), - EndOfMessage(), - ], - ) - p.send(SERVER, [Response(status_code=404, headers=[]), EndOfMessage()]) - - -def test_pipelining(): - # Client doesn't support pipelining, so we have to do this by hand - c = Connection(SERVER) - assert c.next_event() is NEED_DATA - # 3 requests all bunched up - c.receive_data( - b"GET /1 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" - b"12345" - b"GET /2 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" - b"67890" - b"GET /3 HTTP/1.1\r\nHost: a.com\r\n\r\n" - ) - assert get_all_events(c) == [ - Request( - method="GET", - target="/1", - headers=[("Host", "a.com"), ("Content-Length", "5")], - ), - Data(data=b"12345"), - EndOfMessage(), - ] - assert c.their_state is DONE - assert c.our_state is SEND_RESPONSE - - assert c.next_event() is PAUSED - - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - assert c.their_state is DONE - assert c.our_state is DONE - - c.start_next_cycle() - - assert get_all_events(c) == [ - Request( - method="GET", - target="/2", - headers=[("Host", "a.com"), ("Content-Length", "5")], - ), - Data(data=b"67890"), - EndOfMessage(), - ] - assert c.next_event() is PAUSED - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - c.start_next_cycle() - - assert get_all_events(c) == [ - Request(method="GET", target="/3", headers=[("Host", "a.com")]), - EndOfMessage(), - ] - # Doesn't pause this time, no trailing data - assert c.next_event() is NEED_DATA - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - - # Arrival of more data triggers pause - assert c.next_event() is NEED_DATA - c.receive_data(b"SADF") - assert c.next_event() is PAUSED - assert c.trailing_data == (b"SADF", False) - # If EOF arrives while paused, we don't see that either: - c.receive_data(b"") - assert c.trailing_data == (b"SADF", True) - assert c.next_event() is PAUSED - c.receive_data(b"") - assert c.next_event() is PAUSED - # Can't call receive_data with non-empty buf after closing it - with pytest.raises(RuntimeError): - c.receive_data(b"FDSA") - - -def test_protocol_switch(): - for (req, deny, accept) in [ - ( - Request( - method="CONNECT", - target="example.com:443", - headers=[("Host", "foo"), ("Content-Length", "1")], - ), - Response(status_code=404, headers=[]), - Response(status_code=200, headers=[]), - ), - ( - Request( - method="GET", - target="/", - headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], - ), - Response(status_code=200, headers=[]), - InformationalResponse(status_code=101, headers=[("Upgrade", "a")]), - ), - ( - Request( - method="CONNECT", - target="example.com:443", - headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], - ), - Response(status_code=404, headers=[]), - # Accept CONNECT, not upgrade - Response(status_code=200, headers=[]), - ), - ( - Request( - method="CONNECT", - target="example.com:443", - headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], - ), - Response(status_code=404, headers=[]), - # Accept Upgrade, not CONNECT - InformationalResponse(status_code=101, headers=[("Upgrade", "b")]), - ), - ]: - - def setup(): - p = ConnectionPair() - p.send(CLIENT, req) - # No switch-related state change stuff yet; the client has to - # finish the request before that kicks in - for conn in p.conns: - assert conn.states[CLIENT] is SEND_BODY - p.send(CLIENT, [Data(data=b"1"), EndOfMessage()]) - for conn in p.conns: - assert conn.states[CLIENT] is MIGHT_SWITCH_PROTOCOL - assert p.conn[SERVER].next_event() is PAUSED - return p - - # Test deny case - p = setup() - p.send(SERVER, deny) - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: SEND_BODY} - p.send(SERVER, EndOfMessage()) - # Check that re-use is still allowed after a denial - for conn in p.conns: - conn.start_next_cycle() - - # Test accept case - p = setup() - p.send(SERVER, accept) - for conn in p.conns: - assert conn.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} - conn.receive_data(b"123") - assert conn.next_event() is PAUSED - conn.receive_data(b"456") - assert conn.next_event() is PAUSED - assert conn.trailing_data == (b"123456", False) - - # Pausing in might-switch, then recovery - # (weird artificial case where the trailing data actually is valid - # HTTP for some reason, because this makes it easier to test the state - # logic) - p = setup() - sc = p.conn[SERVER] - sc.receive_data(b"GET / HTTP/1.0\r\n\r\n") - assert sc.next_event() is PAUSED - assert sc.trailing_data == (b"GET / HTTP/1.0\r\n\r\n", False) - sc.send(deny) - assert sc.next_event() is PAUSED - sc.send(EndOfMessage()) - sc.start_next_cycle() - assert get_all_events(sc) == [ - Request(method="GET", target="/", headers=[], http_version="1.0"), - EndOfMessage(), - ] - - # When we're DONE, have no trailing data, and the connection gets - # closed, we report ConnectionClosed(). When we're in might-switch or - # switched, we don't. - p = setup() - sc = p.conn[SERVER] - sc.receive_data(b"") - assert sc.next_event() is PAUSED - assert sc.trailing_data == (b"", True) - p.send(SERVER, accept) - assert sc.next_event() is PAUSED - - p = setup() - sc = p.conn[SERVER] - sc.receive_data(b"") == [] - assert sc.next_event() is PAUSED - sc.send(deny) - assert sc.next_event() == ConnectionClosed() - - # You can't send after switching protocols, or while waiting for a - # protocol switch - p = setup() - with pytest.raises(LocalProtocolError): - p.conn[CLIENT].send( - Request(method="GET", target="/", headers=[("Host", "a")]) - ) - p = setup() - p.send(SERVER, accept) - with pytest.raises(LocalProtocolError): - p.conn[SERVER].send(Data(data=b"123")) - - -def test_close_simple(): - # Just immediately closing a new connection without anything having - # happened yet. - for (who_shot_first, who_shot_second) in [(CLIENT, SERVER), (SERVER, CLIENT)]: - - def setup(): - p = ConnectionPair() - p.send(who_shot_first, ConnectionClosed()) - for conn in p.conns: - assert conn.states == { - who_shot_first: CLOSED, - who_shot_second: MUST_CLOSE, - } - return p - - # You can keep putting b"" into a closed connection, and you keep - # getting ConnectionClosed() out: - p = setup() - assert p.conn[who_shot_second].next_event() == ConnectionClosed() - assert p.conn[who_shot_second].next_event() == ConnectionClosed() - p.conn[who_shot_second].receive_data(b"") - assert p.conn[who_shot_second].next_event() == ConnectionClosed() - # Second party can close... - p = setup() - p.send(who_shot_second, ConnectionClosed()) - for conn in p.conns: - assert conn.our_state is CLOSED - assert conn.their_state is CLOSED - # But trying to receive new data on a closed connection is a - # RuntimeError (not ProtocolError, because the problem here isn't - # violation of HTTP, it's violation of physics) - p = setup() - with pytest.raises(RuntimeError): - p.conn[who_shot_second].receive_data(b"123") - # And receiving new data on a MUST_CLOSE connection is a ProtocolError - p = setup() - p.conn[who_shot_first].receive_data(b"GET") - with pytest.raises(RemoteProtocolError): - p.conn[who_shot_first].next_event() - - -def test_close_different_states(): - req = [ - Request(method="GET", target="/foo", headers=[("Host", "a")]), - EndOfMessage(), - ] - resp = [Response(status_code=200, headers=[]), EndOfMessage()] - - # Client before request - p = ConnectionPair() - p.send(CLIENT, ConnectionClosed()) - for conn in p.conns: - assert conn.states == {CLIENT: CLOSED, SERVER: MUST_CLOSE} - - # Client after request - p = ConnectionPair() - p.send(CLIENT, req) - p.send(CLIENT, ConnectionClosed()) - for conn in p.conns: - assert conn.states == {CLIENT: CLOSED, SERVER: SEND_RESPONSE} - - # Server after request -> not allowed - p = ConnectionPair() - p.send(CLIENT, req) - with pytest.raises(LocalProtocolError): - p.conn[SERVER].send(ConnectionClosed()) - p.conn[CLIENT].receive_data(b"") - with pytest.raises(RemoteProtocolError): - p.conn[CLIENT].next_event() - - # Server after response - p = ConnectionPair() - p.send(CLIENT, req) - p.send(SERVER, resp) - p.send(SERVER, ConnectionClosed()) - for conn in p.conns: - assert conn.states == {CLIENT: MUST_CLOSE, SERVER: CLOSED} - - # Both after closing (ConnectionClosed() is idempotent) - p = ConnectionPair() - p.send(CLIENT, req) - p.send(SERVER, resp) - p.send(CLIENT, ConnectionClosed()) - p.send(SERVER, ConnectionClosed()) - p.send(CLIENT, ConnectionClosed()) - p.send(SERVER, ConnectionClosed()) - - # In the middle of sending -> not allowed - p = ConnectionPair() - p.send( - CLIENT, - Request( - method="GET", target="/", headers=[("Host", "a"), ("Content-Length", "10")] - ), - ) - with pytest.raises(LocalProtocolError): - p.conn[CLIENT].send(ConnectionClosed()) - p.conn[SERVER].receive_data(b"") - with pytest.raises(RemoteProtocolError): - p.conn[SERVER].next_event() - - -# Receive several requests and then client shuts down their side of the -# connection; we can respond to each -def test_pipelined_close(): - c = Connection(SERVER) - # 2 requests then a close - c.receive_data( - b"GET /1 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" - b"12345" - b"GET /2 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" - b"67890" - ) - c.receive_data(b"") - assert get_all_events(c) == [ - Request( - method="GET", - target="/1", - headers=[("host", "a.com"), ("content-length", "5")], - ), - Data(data=b"12345"), - EndOfMessage(), - ] - assert c.states[CLIENT] is DONE - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - assert c.states[SERVER] is DONE - c.start_next_cycle() - assert get_all_events(c) == [ - Request( - method="GET", - target="/2", - headers=[("host", "a.com"), ("content-length", "5")], - ), - Data(data=b"67890"), - EndOfMessage(), - ConnectionClosed(), - ] - assert c.states == {CLIENT: CLOSED, SERVER: SEND_RESPONSE} - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - assert c.states == {CLIENT: CLOSED, SERVER: MUST_CLOSE} - c.send(ConnectionClosed()) - assert c.states == {CLIENT: CLOSED, SERVER: CLOSED} - - -def test_sendfile(): - class SendfilePlaceholder: - def __len__(self): - return 10 - - placeholder = SendfilePlaceholder() - - def setup(header, http_version): - c = Connection(SERVER) - receive_and_get( - c, "GET / HTTP/{}\r\nHost: a\r\n\r\n".format(http_version).encode("ascii") - ) - headers = [] - if header: - headers.append(header) - c.send(Response(status_code=200, headers=headers)) - return c, c.send_with_data_passthrough(Data(data=placeholder)) - - c, data = setup(("Content-Length", "10"), "1.1") - assert data == [placeholder] - # Raises an error if the connection object doesn't think we've sent - # exactly 10 bytes - c.send(EndOfMessage()) - - _, data = setup(("Transfer-Encoding", "chunked"), "1.1") - assert placeholder in data - data[data.index(placeholder)] = b"x" * 10 - assert b"".join(data) == b"a\r\nxxxxxxxxxx\r\n" - - c, data = setup(None, "1.0") - assert data == [placeholder] - assert c.our_state is SEND_BODY - - -def test_errors(): - # After a receive error, you can't receive - for role in [CLIENT, SERVER]: - c = Connection(our_role=role) - c.receive_data(b"gibberish\r\n\r\n") - with pytest.raises(RemoteProtocolError): - c.next_event() - # Now any attempt to receive continues to raise - assert c.their_state is ERROR - assert c.our_state is not ERROR - print(c._cstate.states) - with pytest.raises(RemoteProtocolError): - c.next_event() - # But we can still yell at the client for sending us gibberish - if role is SERVER: - assert ( - c.send(Response(status_code=400, headers=[])) - == b"HTTP/1.1 400 \r\nConnection: close\r\n\r\n" - ) - - # After an error sending, you can no longer send - # (This is especially important for things like content-length errors, - # where there's complex internal state being modified) - def conn(role): - c = Connection(our_role=role) - if role is SERVER: - # Put it into the state where it *could* send a response... - receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") - assert c.our_state is SEND_RESPONSE - return c - - for role in [CLIENT, SERVER]: - if role is CLIENT: - # This HTTP/1.0 request won't be detected as bad until after we go - # through the state machine and hit the writing code - good = Request(method="GET", target="/", headers=[("Host", "example.com")]) - bad = Request( - method="GET", - target="/", - headers=[("Host", "example.com")], - http_version="1.0", - ) - elif role is SERVER: - good = Response(status_code=200, headers=[]) - bad = Response(status_code=200, headers=[], http_version="1.0") - # Make sure 'good' actually is good - c = conn(role) - c.send(good) - assert c.our_state is not ERROR - # Do that again, but this time sending 'bad' first - c = conn(role) - with pytest.raises(LocalProtocolError): - c.send(bad) - assert c.our_state is ERROR - assert c.their_state is not ERROR - # Now 'good' is not so good - with pytest.raises(LocalProtocolError): - c.send(good) - - # And check send_failed() too - c = conn(role) - c.send_failed() - assert c.our_state is ERROR - assert c.their_state is not ERROR - # This is idempotent - c.send_failed() - assert c.our_state is ERROR - assert c.their_state is not ERROR - - -def test_idle_receive_nothing(): - # At one point this incorrectly raised an error - for role in [CLIENT, SERVER]: - c = Connection(role) - assert c.next_event() is NEED_DATA - - -def test_connection_drop(): - c = Connection(SERVER) - c.receive_data(b"GET /") - assert c.next_event() is NEED_DATA - c.receive_data(b"") - with pytest.raises(RemoteProtocolError): - c.next_event() - - -def test_408_request_timeout(): - # Should be able to send this spontaneously as a server without seeing - # anything from client - p = ConnectionPair() - p.send(SERVER, Response(status_code=408, headers=[])) - - -# This used to raise IndexError -def test_empty_request(): - c = Connection(SERVER) - c.receive_data(b"\r\n") - with pytest.raises(RemoteProtocolError): - c.next_event() - - -# This used to raise IndexError -def test_empty_response(): - c = Connection(CLIENT) - c.send(Request(method="GET", target="/", headers=[("Host", "a")])) - c.receive_data(b"\r\n") - with pytest.raises(RemoteProtocolError): - c.next_event() - - -@pytest.mark.parametrize( - "data", - [ - b"\x00", - b"\x20", - b"\x16\x03\x01\x00\xa5", # Typical start of a TLS Client Hello - ], -) -def test_early_detection_of_invalid_request(data): - c = Connection(SERVER) - # Early detection should occur before even receiving a `\r\n` - c.receive_data(data) - with pytest.raises(RemoteProtocolError): - c.next_event() - - -@pytest.mark.parametrize( - "data", - [ - b"\x00", - b"\x20", - b"\x16\x03\x03\x00\x31", # Typical start of a TLS Server Hello - ], -) -def test_early_detection_of_invalid_response(data): - c = Connection(CLIENT) - # Early detection should occur before even receiving a `\r\n` - c.receive_data(data) - with pytest.raises(RemoteProtocolError): - c.next_event() - - -# This used to give different headers for HEAD and GET. -# The correct way to handle HEAD is to put whatever headers we *would* have -# put if it were a GET -- even though we know that for HEAD, those headers -# will be ignored. -def test_HEAD_framing_headers(): - def setup(method, http_version): - c = Connection(SERVER) - c.receive_data( - method + b" / HTTP/" + http_version + b"\r\n" + b"Host: example.com\r\n\r\n" - ) - assert type(c.next_event()) is Request - assert type(c.next_event()) is EndOfMessage - return c - - for method in [b"GET", b"HEAD"]: - # No Content-Length, HTTP/1.1 peer, should use chunked - c = setup(method, b"1.1") - assert ( - c.send(Response(status_code=200, headers=[])) == b"HTTP/1.1 200 \r\n" - b"Transfer-Encoding: chunked\r\n\r\n" - ) - - # No Content-Length, HTTP/1.0 peer, frame with connection: close - c = setup(method, b"1.0") - assert ( - c.send(Response(status_code=200, headers=[])) == b"HTTP/1.1 200 \r\n" - b"Connection: close\r\n\r\n" - ) - - # Content-Length + Transfer-Encoding, TE wins - c = setup(method, b"1.1") - assert ( - c.send( - Response( - status_code=200, - headers=[ - ("Content-Length", "100"), - ("Transfer-Encoding", "chunked"), - ], - ) - ) - == b"HTTP/1.1 200 \r\n" - b"Transfer-Encoding: chunked\r\n\r\n" - ) - - -def test_special_exceptions_for_lost_connection_in_message_body(): - c = Connection(SERVER) - c.receive_data( - b"POST / HTTP/1.1\r\n" b"Host: example.com\r\n" b"Content-Length: 100\r\n\r\n" - ) - assert type(c.next_event()) is Request - assert c.next_event() is NEED_DATA - c.receive_data(b"12345") - assert c.next_event() == Data(data=b"12345") - c.receive_data(b"") - with pytest.raises(RemoteProtocolError) as excinfo: - c.next_event() - assert "received 5 bytes" in str(excinfo.value) - assert "expected 100" in str(excinfo.value) - - c = Connection(SERVER) - c.receive_data( - b"POST / HTTP/1.1\r\n" - b"Host: example.com\r\n" - b"Transfer-Encoding: chunked\r\n\r\n" - ) - assert type(c.next_event()) is Request - assert c.next_event() is NEED_DATA - c.receive_data(b"8\r\n012345") - assert c.next_event().data == b"012345" - c.receive_data(b"") - with pytest.raises(RemoteProtocolError) as excinfo: - c.next_event() - assert "incomplete chunked read" in str(excinfo.value) diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_events.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_events.py deleted file mode 100644 index e20f741c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_events.py +++ /dev/null @@ -1,179 +0,0 @@ -from http import HTTPStatus - -import pytest - -from .. import _events -from .._events import * -from .._util import LocalProtocolError - - -def test_event_bundle(): - class T(_events._EventBundle): - _fields = ["a", "b"] - _defaults = {"b": 1} - - def _validate(self): - if self.a == 0: - raise ValueError - - # basic construction and methods - t = T(a=1, b=0) - assert repr(t) == "T(a=1, b=0)" - assert t == T(a=1, b=0) - assert not (t == T(a=2, b=0)) - assert not (t != T(a=1, b=0)) - assert t != T(a=2, b=0) - with pytest.raises(TypeError): - hash(t) - - # check defaults - t = T(a=10) - assert t.a == 10 - assert t.b == 1 - - # no positional args - with pytest.raises(TypeError): - T(1) - - with pytest.raises(TypeError): - T(1, a=1, b=0) - - # unknown field - with pytest.raises(TypeError): - T(a=1, b=0, c=10) - - # missing required field - with pytest.raises(TypeError) as exc: - T(b=0) - # make sure we error on the right missing kwarg - assert "kwarg a" in str(exc.value) - - # _validate is called - with pytest.raises(ValueError): - T(a=0, b=0) - - -def test_events(): - with pytest.raises(LocalProtocolError): - # Missing Host: - req = Request( - method="GET", target="/", headers=[("a", "b")], http_version="1.1" - ) - # But this is okay (HTTP/1.0) - req = Request(method="GET", target="/", headers=[("a", "b")], http_version="1.0") - # fields are normalized - assert req.method == b"GET" - assert req.target == b"/" - assert req.headers == [(b"a", b"b")] - assert req.http_version == b"1.0" - - # This is also okay -- has a Host (with weird capitalization, which is ok) - req = Request( - method="GET", - target="/", - headers=[("a", "b"), ("hOSt", "example.com")], - http_version="1.1", - ) - # we normalize header capitalization - assert req.headers == [(b"a", b"b"), (b"host", b"example.com")] - - # Multiple host is bad too - with pytest.raises(LocalProtocolError): - req = Request( - method="GET", - target="/", - headers=[("Host", "a"), ("Host", "a")], - http_version="1.1", - ) - # Even for HTTP/1.0 - with pytest.raises(LocalProtocolError): - req = Request( - method="GET", - target="/", - headers=[("Host", "a"), ("Host", "a")], - http_version="1.0", - ) - - # Header values are validated - for bad_char in "\x00\r\n\f\v": - with pytest.raises(LocalProtocolError): - req = Request( - method="GET", - target="/", - headers=[("Host", "a"), ("Foo", "asd" + bad_char)], - http_version="1.0", - ) - - # But for compatibility we allow non-whitespace control characters, even - # though they're forbidden by the spec. - Request( - method="GET", - target="/", - headers=[("Host", "a"), ("Foo", "asd\x01\x02\x7f")], - http_version="1.0", - ) - - # Request target is validated - for bad_char in b"\x00\x20\x7f\xee": - target = bytearray(b"/") - target.append(bad_char) - with pytest.raises(LocalProtocolError): - Request( - method="GET", target=target, headers=[("Host", "a")], http_version="1.1" - ) - - ir = InformationalResponse(status_code=100, headers=[("Host", "a")]) - assert ir.status_code == 100 - assert ir.headers == [(b"host", b"a")] - assert ir.http_version == b"1.1" - - with pytest.raises(LocalProtocolError): - InformationalResponse(status_code=200, headers=[("Host", "a")]) - - resp = Response(status_code=204, headers=[], http_version="1.0") - assert resp.status_code == 204 - assert resp.headers == [] - assert resp.http_version == b"1.0" - - with pytest.raises(LocalProtocolError): - resp = Response(status_code=100, headers=[], http_version="1.0") - - with pytest.raises(LocalProtocolError): - Response(status_code="100", headers=[], http_version="1.0") - - with pytest.raises(LocalProtocolError): - InformationalResponse(status_code=b"100", headers=[], http_version="1.0") - - d = Data(data=b"asdf") - assert d.data == b"asdf" - - eom = EndOfMessage() - assert eom.headers == [] - - cc = ConnectionClosed() - assert repr(cc) == "ConnectionClosed()" - - -def test_intenum_status_code(): - # https://github.com/python-hyper/h11/issues/72 - - r = Response(status_code=HTTPStatus.OK, headers=[], http_version="1.0") - assert r.status_code == HTTPStatus.OK - assert type(r.status_code) is not type(HTTPStatus.OK) - assert type(r.status_code) is int - - -def test_header_casing(): - r = Request( - method="GET", - target="/", - headers=[("Host", "example.org"), ("Connection", "keep-alive")], - http_version="1.1", - ) - assert len(r.headers) == 2 - assert r.headers[0] == (b"host", b"example.org") - assert r.headers == [(b"host", b"example.org"), (b"connection", b"keep-alive")] - assert r.headers.raw_items() == [ - (b"Host", b"example.org"), - (b"Connection", b"keep-alive"), - ] diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_headers.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_headers.py deleted file mode 100644 index ff3dc8d7..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_headers.py +++ /dev/null @@ -1,151 +0,0 @@ -import pytest - -from .._headers import * - - -def test_normalize_and_validate(): - assert normalize_and_validate([("foo", "bar")]) == [(b"foo", b"bar")] - assert normalize_and_validate([(b"foo", b"bar")]) == [(b"foo", b"bar")] - - # no leading/trailing whitespace in names - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b"foo ", "bar")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b" foo", "bar")]) - - # no weird characters in names - with pytest.raises(LocalProtocolError) as excinfo: - normalize_and_validate([(b"foo bar", b"baz")]) - assert "foo bar" in str(excinfo.value) - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b"foo\x00bar", b"baz")]) - # Not even 8-bit characters: - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b"foo\xffbar", b"baz")]) - # And not even the control characters we allow in values: - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b"foo\x01bar", b"baz")]) - - # no return or NUL characters in values - with pytest.raises(LocalProtocolError) as excinfo: - normalize_and_validate([("foo", "bar\rbaz")]) - assert "bar\\rbaz" in str(excinfo.value) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "bar\nbaz")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "bar\x00baz")]) - # no leading/trailing whitespace - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "barbaz ")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", " barbaz")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "barbaz\t")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "\tbarbaz")]) - - # content-length - assert normalize_and_validate([("Content-Length", "1")]) == [ - (b"content-length", b"1") - ] - with pytest.raises(LocalProtocolError): - normalize_and_validate([("Content-Length", "asdf")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("Content-Length", "1x")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("Content-Length", "1"), ("Content-Length", "2")]) - assert normalize_and_validate( - [("Content-Length", "0"), ("Content-Length", "0")] - ) == [(b"content-length", b"0")] - assert normalize_and_validate([("Content-Length", "0 , 0")]) == [ - (b"content-length", b"0") - ] - with pytest.raises(LocalProtocolError): - normalize_and_validate( - [("Content-Length", "1"), ("Content-Length", "1"), ("Content-Length", "2")] - ) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("Content-Length", "1 , 1,2")]) - - # transfer-encoding - assert normalize_and_validate([("Transfer-Encoding", "chunked")]) == [ - (b"transfer-encoding", b"chunked") - ] - assert normalize_and_validate([("Transfer-Encoding", "cHuNkEd")]) == [ - (b"transfer-encoding", b"chunked") - ] - with pytest.raises(LocalProtocolError) as excinfo: - normalize_and_validate([("Transfer-Encoding", "gzip")]) - assert excinfo.value.error_status_hint == 501 # Not Implemented - with pytest.raises(LocalProtocolError) as excinfo: - normalize_and_validate( - [("Transfer-Encoding", "chunked"), ("Transfer-Encoding", "gzip")] - ) - assert excinfo.value.error_status_hint == 501 # Not Implemented - - -def test_get_set_comma_header(): - headers = normalize_and_validate( - [ - ("Connection", "close"), - ("whatever", "something"), - ("connectiON", "fOo,, , BAR"), - ] - ) - - assert get_comma_header(headers, b"connection") == [b"close", b"foo", b"bar"] - - headers = set_comma_header(headers, b"newthing", ["a", "b"]) - - with pytest.raises(LocalProtocolError): - set_comma_header(headers, b"newthing", [" a", "b"]) - - assert headers == [ - (b"connection", b"close"), - (b"whatever", b"something"), - (b"connection", b"fOo,, , BAR"), - (b"newthing", b"a"), - (b"newthing", b"b"), - ] - - headers = set_comma_header(headers, b"whatever", ["different thing"]) - - assert headers == [ - (b"connection", b"close"), - (b"connection", b"fOo,, , BAR"), - (b"newthing", b"a"), - (b"newthing", b"b"), - (b"whatever", b"different thing"), - ] - - -def test_has_100_continue(): - from .._events import Request - - assert has_expect_100_continue( - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Expect", "100-continue")], - ) - ) - assert not has_expect_100_continue( - Request(method="GET", target="/", headers=[("Host", "example.com")]) - ) - # Case insensitive - assert has_expect_100_continue( - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Expect", "100-Continue")], - ) - ) - # Doesn't work in HTTP/1.0 - assert not has_expect_100_continue( - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Expect", "100-continue")], - http_version="1.0", - ) - ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_helpers.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_helpers.py deleted file mode 100644 index 1477947a..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_helpers.py +++ /dev/null @@ -1,23 +0,0 @@ -from .helpers import * - - -def test_normalize_data_events(): - assert normalize_data_events( - [ - Data(data=bytearray(b"1")), - Data(data=b"2"), - Response(status_code=200, headers=[]), - Data(data=b"3"), - Data(data=b"4"), - EndOfMessage(), - Data(data=b"5"), - Data(data=b"6"), - Data(data=b"7"), - ] - ) == [ - Data(data=b"12"), - Response(status_code=200, headers=[]), - Data(data=b"34"), - EndOfMessage(), - Data(data=b"567"), - ] diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_io.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_io.py deleted file mode 100644 index 459a627d..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_io.py +++ /dev/null @@ -1,544 +0,0 @@ -import pytest - -from .._events import * -from .._headers import Headers, normalize_and_validate -from .._readers import ( - _obsolete_line_fold, - ChunkedReader, - ContentLengthReader, - Http10Reader, - READERS, -) -from .._receivebuffer import ReceiveBuffer -from .._state import * -from .._util import LocalProtocolError -from .._writers import ( - ChunkedWriter, - ContentLengthWriter, - Http10Writer, - write_any_response, - write_headers, - write_request, - WRITERS, -) -from .helpers import normalize_data_events - -SIMPLE_CASES = [ - ( - (CLIENT, IDLE), - Request( - method="GET", - target="/a", - headers=[("Host", "foo"), ("Connection", "close")], - ), - b"GET /a HTTP/1.1\r\nHost: foo\r\nConnection: close\r\n\r\n", - ), - ( - (SERVER, SEND_RESPONSE), - Response(status_code=200, headers=[("Connection", "close")], reason=b"OK"), - b"HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", - ), - ( - (SERVER, SEND_RESPONSE), - Response(status_code=200, headers=[], reason=b"OK"), - b"HTTP/1.1 200 OK\r\n\r\n", - ), - ( - (SERVER, SEND_RESPONSE), - InformationalResponse( - status_code=101, headers=[("Upgrade", "websocket")], reason=b"Upgrade" - ), - b"HTTP/1.1 101 Upgrade\r\nUpgrade: websocket\r\n\r\n", - ), - ( - (SERVER, SEND_RESPONSE), - InformationalResponse(status_code=101, headers=[], reason=b"Upgrade"), - b"HTTP/1.1 101 Upgrade\r\n\r\n", - ), -] - - -def dowrite(writer, obj): - got_list = [] - writer(obj, got_list.append) - return b"".join(got_list) - - -def tw(writer, obj, expected): - got = dowrite(writer, obj) - assert got == expected - - -def makebuf(data): - buf = ReceiveBuffer() - buf += data - return buf - - -def tr(reader, data, expected): - def check(got): - assert got == expected - # Headers should always be returned as bytes, not e.g. bytearray - # https://github.com/python-hyper/wsproto/pull/54#issuecomment-377709478 - for name, value in getattr(got, "headers", []): - print(name, value) - assert type(name) is bytes - assert type(value) is bytes - - # Simple: consume whole thing - buf = makebuf(data) - check(reader(buf)) - assert not buf - - # Incrementally growing buffer - buf = ReceiveBuffer() - for i in range(len(data)): - assert reader(buf) is None - buf += data[i : i + 1] - check(reader(buf)) - - # Trailing data - buf = makebuf(data) - buf += b"trailing" - check(reader(buf)) - assert bytes(buf) == b"trailing" - - -def test_writers_simple(): - for ((role, state), event, binary) in SIMPLE_CASES: - tw(WRITERS[role, state], event, binary) - - -def test_readers_simple(): - for ((role, state), event, binary) in SIMPLE_CASES: - tr(READERS[role, state], binary, event) - - -def test_writers_unusual(): - # Simple test of the write_headers utility routine - tw( - write_headers, - normalize_and_validate([("foo", "bar"), ("baz", "quux")]), - b"foo: bar\r\nbaz: quux\r\n\r\n", - ) - tw(write_headers, Headers([]), b"\r\n") - - # We understand HTTP/1.0, but we don't speak it - with pytest.raises(LocalProtocolError): - tw( - write_request, - Request( - method="GET", - target="/", - headers=[("Host", "foo"), ("Connection", "close")], - http_version="1.0", - ), - None, - ) - with pytest.raises(LocalProtocolError): - tw( - write_any_response, - Response( - status_code=200, headers=[("Connection", "close")], http_version="1.0" - ), - None, - ) - - -def test_readers_unusual(): - # Reading HTTP/1.0 - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.0\r\nSome: header\r\n\r\n", - Request( - method="HEAD", - target="/foo", - headers=[("Some", "header")], - http_version="1.0", - ), - ) - - # check no-headers, since it's only legal with HTTP/1.0 - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.0\r\n\r\n", - Request(method="HEAD", target="/foo", headers=[], http_version="1.0"), - ) - - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200 OK\r\nSome: header\r\n\r\n", - Response( - status_code=200, - headers=[("Some", "header")], - http_version="1.0", - reason=b"OK", - ), - ) - - # single-character header values (actually disallowed by the ABNF in RFC - # 7230 -- this is a bug in the standard that we originally copied...) - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200 OK\r\n" b"Foo: a a a a a \r\n\r\n", - Response( - status_code=200, - headers=[("Foo", "a a a a a")], - http_version="1.0", - reason=b"OK", - ), - ) - - # Empty headers -- also legal - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200 OK\r\n" b"Foo:\r\n\r\n", - Response( - status_code=200, headers=[("Foo", "")], http_version="1.0", reason=b"OK" - ), - ) - - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200 OK\r\n" b"Foo: \t \t \r\n\r\n", - Response( - status_code=200, headers=[("Foo", "")], http_version="1.0", reason=b"OK" - ), - ) - - # Tolerate broken servers that leave off the response code - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200\r\n" b"Foo: bar\r\n\r\n", - Response( - status_code=200, headers=[("Foo", "bar")], http_version="1.0", reason=b"" - ), - ) - - # Tolerate headers line endings (\r\n and \n) - # \n\r\b between headers and body - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.1 200 OK\r\nSomeHeader: val\n\r\n", - Response( - status_code=200, - headers=[("SomeHeader", "val")], - http_version="1.1", - reason="OK", - ), - ) - - # delimited only with \n - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.1 200 OK\nSomeHeader1: val1\nSomeHeader2: val2\n\n", - Response( - status_code=200, - headers=[("SomeHeader1", "val1"), ("SomeHeader2", "val2")], - http_version="1.1", - reason="OK", - ), - ) - - # mixed \r\n and \n - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.1 200 OK\r\nSomeHeader1: val1\nSomeHeader2: val2\n\r\n", - Response( - status_code=200, - headers=[("SomeHeader1", "val1"), ("SomeHeader2", "val2")], - http_version="1.1", - reason="OK", - ), - ) - - # obsolete line folding - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" - b"Host: example.com\r\n" - b"Some: multi-line\r\n" - b" header\r\n" - b"\tnonsense\r\n" - b" \t \t\tI guess\r\n" - b"Connection: close\r\n" - b"More-nonsense: in the\r\n" - b" last header \r\n\r\n", - Request( - method="HEAD", - target="/foo", - headers=[ - ("Host", "example.com"), - ("Some", "multi-line header nonsense I guess"), - ("Connection", "close"), - ("More-nonsense", "in the last header"), - ], - ), - ) - - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b" folded: line\r\n\r\n", - None, - ) - - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b"foo : line\r\n\r\n", - None, - ) - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b"foo\t: line\r\n\r\n", - None, - ) - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b"foo\t: line\r\n\r\n", - None, - ) - with pytest.raises(LocalProtocolError): - tr(READERS[CLIENT, IDLE], b"HEAD /foo HTTP/1.1\r\n" b": line\r\n\r\n", None) - - -def test__obsolete_line_fold_bytes(): - # _obsolete_line_fold has a defensive cast to bytearray, which is - # necessary to protect against O(n^2) behavior in case anyone ever passes - # in regular bytestrings... but right now we never pass in regular - # bytestrings. so this test just exists to get some coverage on that - # defensive cast. - assert list(_obsolete_line_fold([b"aaa", b"bbb", b" ccc", b"ddd"])) == [ - b"aaa", - bytearray(b"bbb ccc"), - b"ddd", - ] - - -def _run_reader_iter(reader, buf, do_eof): - while True: - event = reader(buf) - if event is None: - break - yield event - # body readers have undefined behavior after returning EndOfMessage, - # because this changes the state so they don't get called again - if type(event) is EndOfMessage: - break - if do_eof: - assert not buf - yield reader.read_eof() - - -def _run_reader(*args): - events = list(_run_reader_iter(*args)) - return normalize_data_events(events) - - -def t_body_reader(thunk, data, expected, do_eof=False): - # Simple: consume whole thing - print("Test 1") - buf = makebuf(data) - assert _run_reader(thunk(), buf, do_eof) == expected - - # Incrementally growing buffer - print("Test 2") - reader = thunk() - buf = ReceiveBuffer() - events = [] - for i in range(len(data)): - events += _run_reader(reader, buf, False) - buf += data[i : i + 1] - events += _run_reader(reader, buf, do_eof) - assert normalize_data_events(events) == expected - - is_complete = any(type(event) is EndOfMessage for event in expected) - if is_complete and not do_eof: - buf = makebuf(data + b"trailing") - assert _run_reader(thunk(), buf, False) == expected - - -def test_ContentLengthReader(): - t_body_reader(lambda: ContentLengthReader(0), b"", [EndOfMessage()]) - - t_body_reader( - lambda: ContentLengthReader(10), - b"0123456789", - [Data(data=b"0123456789"), EndOfMessage()], - ) - - -def test_Http10Reader(): - t_body_reader(Http10Reader, b"", [EndOfMessage()], do_eof=True) - t_body_reader(Http10Reader, b"asdf", [Data(data=b"asdf")], do_eof=False) - t_body_reader( - Http10Reader, b"asdf", [Data(data=b"asdf"), EndOfMessage()], do_eof=True - ) - - -def test_ChunkedReader(): - t_body_reader(ChunkedReader, b"0\r\n\r\n", [EndOfMessage()]) - - t_body_reader( - ChunkedReader, - b"0\r\nSome: header\r\n\r\n", - [EndOfMessage(headers=[("Some", "header")])], - ) - - t_body_reader( - ChunkedReader, - b"5\r\n01234\r\n" - + b"10\r\n0123456789abcdef\r\n" - + b"0\r\n" - + b"Some: header\r\n\r\n", - [ - Data(data=b"012340123456789abcdef"), - EndOfMessage(headers=[("Some", "header")]), - ], - ) - - t_body_reader( - ChunkedReader, - b"5\r\n01234\r\n" + b"10\r\n0123456789abcdef\r\n" + b"0\r\n\r\n", - [Data(data=b"012340123456789abcdef"), EndOfMessage()], - ) - - # handles upper and lowercase hex - t_body_reader( - ChunkedReader, - b"aA\r\n" + b"x" * 0xAA + b"\r\n" + b"0\r\n\r\n", - [Data(data=b"x" * 0xAA), EndOfMessage()], - ) - - # refuses arbitrarily long chunk integers - with pytest.raises(LocalProtocolError): - # Technically this is legal HTTP/1.1, but we refuse to process chunk - # sizes that don't fit into 20 characters of hex - t_body_reader(ChunkedReader, b"9" * 100 + b"\r\nxxx", [Data(data=b"xxx")]) - - # refuses garbage in the chunk count - with pytest.raises(LocalProtocolError): - t_body_reader(ChunkedReader, b"10\x00\r\nxxx", None) - - # handles (and discards) "chunk extensions" omg wtf - t_body_reader( - ChunkedReader, - b"5; hello=there\r\n" - + b"xxxxx" - + b"\r\n" - + b'0; random="junk"; some=more; canbe=lonnnnngg\r\n\r\n', - [Data(data=b"xxxxx"), EndOfMessage()], - ) - - -def test_ContentLengthWriter(): - w = ContentLengthWriter(5) - assert dowrite(w, Data(data=b"123")) == b"123" - assert dowrite(w, Data(data=b"45")) == b"45" - assert dowrite(w, EndOfMessage()) == b"" - - w = ContentLengthWriter(5) - with pytest.raises(LocalProtocolError): - dowrite(w, Data(data=b"123456")) - - w = ContentLengthWriter(5) - dowrite(w, Data(data=b"123")) - with pytest.raises(LocalProtocolError): - dowrite(w, Data(data=b"456")) - - w = ContentLengthWriter(5) - dowrite(w, Data(data=b"123")) - with pytest.raises(LocalProtocolError): - dowrite(w, EndOfMessage()) - - w = ContentLengthWriter(5) - dowrite(w, Data(data=b"123")) == b"123" - dowrite(w, Data(data=b"45")) == b"45" - with pytest.raises(LocalProtocolError): - dowrite(w, EndOfMessage(headers=[("Etag", "asdf")])) - - -def test_ChunkedWriter(): - w = ChunkedWriter() - assert dowrite(w, Data(data=b"aaa")) == b"3\r\naaa\r\n" - assert dowrite(w, Data(data=b"a" * 20)) == b"14\r\n" + b"a" * 20 + b"\r\n" - - assert dowrite(w, Data(data=b"")) == b"" - - assert dowrite(w, EndOfMessage()) == b"0\r\n\r\n" - - assert ( - dowrite(w, EndOfMessage(headers=[("Etag", "asdf"), ("a", "b")])) - == b"0\r\nEtag: asdf\r\na: b\r\n\r\n" - ) - - -def test_Http10Writer(): - w = Http10Writer() - assert dowrite(w, Data(data=b"1234")) == b"1234" - assert dowrite(w, EndOfMessage()) == b"" - - with pytest.raises(LocalProtocolError): - dowrite(w, EndOfMessage(headers=[("Etag", "asdf")])) - - -def test_reject_garbage_after_request_line(): - with pytest.raises(LocalProtocolError): - tr(READERS[SERVER, SEND_RESPONSE], b"HTTP/1.0 200 OK\x00xxxx\r\n\r\n", None) - - -def test_reject_garbage_after_response_line(): - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1 xxxxxx\r\n" b"Host: a\r\n\r\n", - None, - ) - - -def test_reject_garbage_in_header_line(): - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b"Host: foo\x00bar\r\n\r\n", - None, - ) - - -def test_reject_non_vchar_in_path(): - for bad_char in b"\x00\x20\x7f\xee": - message = bytearray(b"HEAD /") - message.append(bad_char) - message.extend(b" HTTP/1.1\r\nHost: foobar\r\n\r\n") - with pytest.raises(LocalProtocolError): - tr(READERS[CLIENT, IDLE], message, None) - - -# https://github.com/python-hyper/h11/issues/57 -def test_allow_some_garbage_in_cookies(): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" - b"Host: foo\r\n" - b"Set-Cookie: ___utmvafIumyLc=kUd\x01UpAt; path=/; Max-Age=900\r\n" - b"\r\n", - Request( - method="HEAD", - target="/foo", - headers=[ - ("Host", "foo"), - ("Set-Cookie", "___utmvafIumyLc=kUd\x01UpAt; path=/; Max-Age=900"), - ], - ), - ) - - -def test_host_comes_first(): - tw( - write_headers, - normalize_and_validate([("foo", "bar"), ("Host", "example.com")]), - b"Host: example.com\r\nfoo: bar\r\n\r\n", - ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_receivebuffer.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_receivebuffer.py deleted file mode 100644 index 3a61f9dc..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_receivebuffer.py +++ /dev/null @@ -1,134 +0,0 @@ -import re - -import pytest - -from .._receivebuffer import ReceiveBuffer - - -def test_receivebuffer(): - b = ReceiveBuffer() - assert not b - assert len(b) == 0 - assert bytes(b) == b"" - - b += b"123" - assert b - assert len(b) == 3 - assert bytes(b) == b"123" - - assert bytes(b) == b"123" - - assert b.maybe_extract_at_most(2) == b"12" - assert b - assert len(b) == 1 - assert bytes(b) == b"3" - - assert bytes(b) == b"3" - - assert b.maybe_extract_at_most(10) == b"3" - assert bytes(b) == b"" - - assert b.maybe_extract_at_most(10) is None - assert not b - - ################################################################ - # maybe_extract_until_next - ################################################################ - - b += b"123\n456\r\n789\r\n" - - assert b.maybe_extract_next_line() == b"123\n456\r\n" - assert bytes(b) == b"789\r\n" - - assert b.maybe_extract_next_line() == b"789\r\n" - assert bytes(b) == b"" - - b += b"12\r" - assert b.maybe_extract_next_line() is None - assert bytes(b) == b"12\r" - - b += b"345\n\r" - assert b.maybe_extract_next_line() is None - assert bytes(b) == b"12\r345\n\r" - - # here we stopped at the middle of b"\r\n" delimiter - - b += b"\n6789aaa123\r\n" - assert b.maybe_extract_next_line() == b"12\r345\n\r\n" - assert b.maybe_extract_next_line() == b"6789aaa123\r\n" - assert b.maybe_extract_next_line() is None - assert bytes(b) == b"" - - ################################################################ - # maybe_extract_lines - ################################################################ - - b += b"123\r\na: b\r\nfoo:bar\r\n\r\ntrailing" - lines = b.maybe_extract_lines() - assert lines == [b"123", b"a: b", b"foo:bar"] - assert bytes(b) == b"trailing" - - assert b.maybe_extract_lines() is None - - b += b"\r\n\r" - assert b.maybe_extract_lines() is None - - assert b.maybe_extract_at_most(100) == b"trailing\r\n\r" - assert not b - - # Empty body case (as happens at the end of chunked encoding if there are - # no trailing headers, e.g.) - b += b"\r\ntrailing" - assert b.maybe_extract_lines() == [] - assert bytes(b) == b"trailing" - - -@pytest.mark.parametrize( - "data", - [ - pytest.param( - ( - b"HTTP/1.1 200 OK\r\n", - b"Content-type: text/plain\r\n", - b"Connection: close\r\n", - b"\r\n", - b"Some body", - ), - id="with_crlf_delimiter", - ), - pytest.param( - ( - b"HTTP/1.1 200 OK\n", - b"Content-type: text/plain\n", - b"Connection: close\n", - b"\n", - b"Some body", - ), - id="with_lf_only_delimiter", - ), - pytest.param( - ( - b"HTTP/1.1 200 OK\n", - b"Content-type: text/plain\r\n", - b"Connection: close\n", - b"\n", - b"Some body", - ), - id="with_mixed_crlf_and_lf", - ), - ], -) -def test_receivebuffer_for_invalid_delimiter(data): - b = ReceiveBuffer() - - for line in data: - b += line - - lines = b.maybe_extract_lines() - - assert lines == [ - b"HTTP/1.1 200 OK", - b"Content-type: text/plain", - b"Connection: close", - ] - assert bytes(b) == b"Some body" diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_state.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_state.py deleted file mode 100644 index efe83f0a..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_state.py +++ /dev/null @@ -1,250 +0,0 @@ -import pytest - -from .._events import * -from .._state import * -from .._state import _SWITCH_CONNECT, _SWITCH_UPGRADE, ConnectionState -from .._util import LocalProtocolError - - -def test_ConnectionState(): - cs = ConnectionState() - - # Basic event-triggered transitions - - assert cs.states == {CLIENT: IDLE, SERVER: IDLE} - - cs.process_event(CLIENT, Request) - # The SERVER-Request special case: - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - # Illegal transitions raise an error and nothing happens - with pytest.raises(LocalProtocolError): - cs.process_event(CLIENT, Request) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, InformationalResponse) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, Response) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_BODY} - - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(SERVER, EndOfMessage) - assert cs.states == {CLIENT: DONE, SERVER: DONE} - - # State-triggered transition - - cs.process_event(SERVER, ConnectionClosed) - assert cs.states == {CLIENT: MUST_CLOSE, SERVER: CLOSED} - - -def test_ConnectionState_keep_alive(): - # keep_alive = False - cs = ConnectionState() - cs.process_event(CLIENT, Request) - cs.process_keep_alive_disabled() - cs.process_event(CLIENT, EndOfMessage) - assert cs.states == {CLIENT: MUST_CLOSE, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - assert cs.states == {CLIENT: MUST_CLOSE, SERVER: MUST_CLOSE} - - -def test_ConnectionState_keep_alive_in_DONE(): - # Check that if keep_alive is disabled when the CLIENT is already in DONE, - # then this is sufficient to immediately trigger the DONE -> MUST_CLOSE - # transition - cs = ConnectionState() - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - assert cs.states[CLIENT] is DONE - cs.process_keep_alive_disabled() - assert cs.states[CLIENT] is MUST_CLOSE - - -def test_ConnectionState_switch_denied(): - for switch_type in (_SWITCH_CONNECT, _SWITCH_UPGRADE): - for deny_early in (True, False): - cs = ConnectionState() - cs.process_client_switch_proposal(switch_type) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, Data) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - assert switch_type in cs.pending_switch_proposals - - if deny_early: - # before client reaches DONE - cs.process_event(SERVER, Response) - assert not cs.pending_switch_proposals - - cs.process_event(CLIENT, EndOfMessage) - - if deny_early: - assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} - else: - assert cs.states == { - CLIENT: MIGHT_SWITCH_PROTOCOL, - SERVER: SEND_RESPONSE, - } - - cs.process_event(SERVER, InformationalResponse) - assert cs.states == { - CLIENT: MIGHT_SWITCH_PROTOCOL, - SERVER: SEND_RESPONSE, - } - - cs.process_event(SERVER, Response) - assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} - assert not cs.pending_switch_proposals - - -_response_type_for_switch = { - _SWITCH_UPGRADE: InformationalResponse, - _SWITCH_CONNECT: Response, - None: Response, -} - - -def test_ConnectionState_protocol_switch_accepted(): - for switch_event in [_SWITCH_UPGRADE, _SWITCH_CONNECT]: - cs = ConnectionState() - cs.process_client_switch_proposal(switch_event) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, Data) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - cs.process_event(CLIENT, EndOfMessage) - assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, InformationalResponse) - assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, _response_type_for_switch[switch_event], switch_event) - assert cs.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} - - -def test_ConnectionState_double_protocol_switch(): - # CONNECT + Upgrade is legal! Very silly, but legal. So we support - # it. Because sometimes doing the silly thing is easier than not. - for server_switch in [None, _SWITCH_UPGRADE, _SWITCH_CONNECT]: - cs = ConnectionState() - cs.process_client_switch_proposal(_SWITCH_UPGRADE) - cs.process_client_switch_proposal(_SWITCH_CONNECT) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} - cs.process_event( - SERVER, _response_type_for_switch[server_switch], server_switch - ) - if server_switch is None: - assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} - else: - assert cs.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} - - -def test_ConnectionState_inconsistent_protocol_switch(): - for client_switches, server_switch in [ - ([], _SWITCH_CONNECT), - ([], _SWITCH_UPGRADE), - ([_SWITCH_UPGRADE], _SWITCH_CONNECT), - ([_SWITCH_CONNECT], _SWITCH_UPGRADE), - ]: - cs = ConnectionState() - for client_switch in client_switches: - cs.process_client_switch_proposal(client_switch) - cs.process_event(CLIENT, Request) - with pytest.raises(LocalProtocolError): - cs.process_event(SERVER, Response, server_switch) - - -def test_ConnectionState_keepalive_protocol_switch_interaction(): - # keep_alive=False + pending_switch_proposals - cs = ConnectionState() - cs.process_client_switch_proposal(_SWITCH_UPGRADE) - cs.process_event(CLIENT, Request) - cs.process_keep_alive_disabled() - cs.process_event(CLIENT, Data) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - # the protocol switch "wins" - cs.process_event(CLIENT, EndOfMessage) - assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} - - # but when the server denies the request, keep_alive comes back into play - cs.process_event(SERVER, Response) - assert cs.states == {CLIENT: MUST_CLOSE, SERVER: SEND_BODY} - - -def test_ConnectionState_reuse(): - cs = ConnectionState() - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - - cs.start_next_cycle() - assert cs.states == {CLIENT: IDLE, SERVER: IDLE} - - # No keepalive - - cs.process_event(CLIENT, Request) - cs.process_keep_alive_disabled() - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - # One side closed - - cs = ConnectionState() - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(CLIENT, ConnectionClosed) - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - # Succesful protocol switch - - cs = ConnectionState() - cs.process_client_switch_proposal(_SWITCH_UPGRADE) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(SERVER, InformationalResponse, _SWITCH_UPGRADE) - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - # Failed protocol switch - - cs = ConnectionState() - cs.process_client_switch_proposal(_SWITCH_UPGRADE) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - - cs.start_next_cycle() - assert cs.states == {CLIENT: IDLE, SERVER: IDLE} - - -def test_server_request_is_illegal(): - # There used to be a bug in how we handled the Request special case that - # made this allowed... - cs = ConnectionState() - with pytest.raises(LocalProtocolError): - cs.process_event(SERVER, Request) diff --git a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_util.py b/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_util.py deleted file mode 100644 index d851bdcb..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/h11/tests/test_util.py +++ /dev/null @@ -1,99 +0,0 @@ -import re -import sys -import traceback - -import pytest - -from .._util import * - - -def test_ProtocolError(): - with pytest.raises(TypeError): - ProtocolError("abstract base class") - - -def test_LocalProtocolError(): - try: - raise LocalProtocolError("foo") - except LocalProtocolError as e: - assert str(e) == "foo" - assert e.error_status_hint == 400 - - try: - raise LocalProtocolError("foo", error_status_hint=418) - except LocalProtocolError as e: - assert str(e) == "foo" - assert e.error_status_hint == 418 - - def thunk(): - raise LocalProtocolError("a", error_status_hint=420) - - try: - try: - thunk() - except LocalProtocolError as exc1: - orig_traceback = "".join(traceback.format_tb(sys.exc_info()[2])) - exc1._reraise_as_remote_protocol_error() - except RemoteProtocolError as exc2: - assert type(exc2) is RemoteProtocolError - assert exc2.args == ("a",) - assert exc2.error_status_hint == 420 - new_traceback = "".join(traceback.format_tb(sys.exc_info()[2])) - assert new_traceback.endswith(orig_traceback) - - -def test_validate(): - my_re = re.compile(br"(?P[0-9]+)\.(?P[0-9]+)") - with pytest.raises(LocalProtocolError): - validate(my_re, b"0.") - - groups = validate(my_re, b"0.1") - assert groups == {"group1": b"0", "group2": b"1"} - - # successful partial matches are an error - must match whole string - with pytest.raises(LocalProtocolError): - validate(my_re, b"0.1xx") - with pytest.raises(LocalProtocolError): - validate(my_re, b"0.1\n") - - -def test_validate_formatting(): - my_re = re.compile(br"foo") - - with pytest.raises(LocalProtocolError) as excinfo: - validate(my_re, b"", "oops") - assert "oops" in str(excinfo.value) - - with pytest.raises(LocalProtocolError) as excinfo: - validate(my_re, b"", "oops {}") - assert "oops {}" in str(excinfo.value) - - with pytest.raises(LocalProtocolError) as excinfo: - validate(my_re, b"", "oops {} xx", 10) - assert "oops 10 xx" in str(excinfo.value) - - -def test_make_sentinel(): - S = make_sentinel("S") - assert repr(S) == "S" - assert S == S - assert type(S).__name__ == "S" - assert S in {S} - assert type(S) is S - S2 = make_sentinel("S2") - assert repr(S2) == "S2" - assert S != S2 - assert S not in {S2} - assert type(S) is not type(S2) - - -def test_bytesify(): - assert bytesify(b"123") == b"123" - assert bytesify(bytearray(b"123")) == b"123" - assert bytesify("123") == b"123" - - with pytest.raises(UnicodeEncodeError): - bytesify("\u1234") - - with pytest.raises(TypeError): - bytesify(10) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/INSTALLER b/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/LICENSE.md b/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/LICENSE.md deleted file mode 100644 index 311b2b56..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/LICENSE.md +++ /dev/null @@ -1,27 +0,0 @@ -Copyright © 2020, [Encode OSS Ltd](https://www.encode.io/). -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may 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 HOLDER 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/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/METADATA b/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/METADATA deleted file mode 100644 index cf84d2a0..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/METADATA +++ /dev/null @@ -1,422 +0,0 @@ -Metadata-Version: 2.1 -Name: httpcore -Version: 0.13.7 -Summary: A minimal low-level HTTP client. -Home-page: https://github.com/encode/httpcore -Author: Tom Christie -Author-email: tom@tomchristie.com -License: BSD -Project-URL: Documentation, https://www.encode.io/httpcore -Project-URL: Source, https://github.com/encode/httpcore -Platform: UNKNOWN -Classifier: Development Status :: 3 - Alpha -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Topic :: Internet :: WWW/HTTP -Classifier: Framework :: AsyncIO -Classifier: Framework :: Trio -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3 :: Only -Requires-Python: >=3.6 -Description-Content-Type: text/markdown -License-File: LICENSE.md -Requires-Dist: h11 (<0.13,>=0.11) -Requires-Dist: sniffio (==1.*) -Requires-Dist: anyio (==3.*) -Provides-Extra: http2 -Requires-Dist: h2 (<5,>=3) ; extra == 'http2' - -# HTTP Core - -[![Test Suite](https://github.com/encode/httpcore/workflows/Test%20Suite/badge.svg)](https://github.com/encode/httpcore/actions) -[![Package version](https://badge.fury.io/py/httpcore.svg)](https://pypi.org/project/httpcore/) - -> *Do one thing, and do it well.* - -The HTTP Core package provides a minimal low-level HTTP client, which does -one thing only. Sending HTTP requests. - -It does not provide any high level model abstractions over the API, -does not handle redirects, multipart uploads, building authentication headers, -transparent HTTP caching, URL parsing, session cookie handling, -content or charset decoding, handling JSON, environment based configuration -defaults, or any of that Jazz. - -Some things HTTP Core does do: - -* Sending HTTP requests. -* Provides both sync and async interfaces. -* Supports HTTP/1.1 and HTTP/2. -* Async backend support for `asyncio`, `trio` and `curio`. -* Automatic connection pooling. -* HTTP(S) proxy support. - -## Installation - -For HTTP/1.1 only support, install with... - -```shell -$ pip install httpcore -``` - -For HTTP/1.1 and HTTP/2 support, install with... - -```shell -$ pip install httpcore[http2] -``` - -## Quickstart - -Here's an example of making an HTTP GET request using `httpcore`... - -```python -with httpcore.SyncConnectionPool() as http: - status_code, headers, stream, extensions = http.handle_request( - method=b'GET', - url=(b'https', b'example.org', 443, b'/'), - headers=[(b'host', b'example.org'), (b'user-agent', b'httpcore')], - stream=httpcore.ByteStream(b''), - extensions={} - ) - body = stream.read() - print(status_code, body) -``` - -Or, using async... - -```python -async with httpcore.AsyncConnectionPool() as http: - status_code, headers, stream, extensions = await http.handle_async_request( - method=b'GET', - url=(b'https', b'example.org', 443, b'/'), - headers=[(b'host', b'example.org'), (b'user-agent', b'httpcore')], - stream=httpcore.ByteStream(b''), - extensions={} - ) - body = await stream.aread() - print(status_code, body) -``` - -## Motivation - -You probably don't want to be using HTTP Core directly. It might make sense if -you're writing something like a proxy service in Python, and you just want -something at the lowest possible level, but more typically you'll want to use -a higher level client library, such as `httpx`. - -The motivation for `httpcore` is: - -* To provide a reusable low-level client library, that other packages can then build on top of. -* To provide a *really clear interface split* between the networking code and client logic, - so that each is easier to understand and reason about in isolation. - - -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -## 0.13.7 (September 13th, 2021) - -- Fix broken error messaging when URL scheme is missing, or a non HTTP(S) scheme is used. (Pull #403) - -## 0.13.6 (June 15th, 2021) - -### Fixed - -- Close sockets when read or write timeouts occur. (Pull #365) - -## 0.13.5 (June 14th, 2021) - -### Fixed - -- Resolved niggles with AnyIO EOF behaviours. (Pull #358, #362) - -## 0.13.4 (June 9th, 2021) - -### Added - -- Improved error messaging when URL scheme is missing, or a non HTTP(S) scheme is used. (Pull #354) - -### Fixed - -- Switched to `anyio` as the default backend implementation when running with `asyncio`. Resolves some awkward [TLS timeout issues](https://github.com/encode/httpx/discussions/1511). - -## 0.13.3 (May 6th, 2021) - -### Added - -- Support HTTP/2 prior knowledge, using `httpcore.SyncConnectionPool(http1=False)`. (Pull #333) - -### Fixed - -- Handle cases where environment does not provide `select.poll` support. (Pull #331) - -## 0.13.2 (April 29th, 2021) - -### Added - -- Improve error message for specific case of `RemoteProtocolError` where server disconnects without sending a response. (Pull #313) - -## 0.13.1 (April 28th, 2021) - -### Fixed - -- More resiliant testing for closed connections. (Pull #311) -- Don't raise exceptions on ungraceful connection closes. (Pull #310) - -## 0.13.0 (April 21st, 2021) - -The 0.13 release updates the core API in order to match the HTTPX Transport API, -introduced in HTTPX 0.18 onwards. - -An example of making requests with the new interface is: - -```python -with httpcore.SyncConnectionPool() as http: - status_code, headers, stream, extensions = http.handle_request( - method=b'GET', - url=(b'https', b'example.org', 443, b'/'), - headers=[(b'host', b'example.org'), (b'user-agent', b'httpcore')] - stream=httpcore.ByteStream(b''), - extensions={} - ) - body = stream.read() - print(status_code, body) -``` - -### Changed - -- The `.request()` method is now `handle_request()`. (Pull #296) -- The `.arequest()` method is now `.handle_async_request()`. (Pull #296) -- The `headers` argument is no longer optional. (Pull #296) -- The `stream` argument is no longer optional. (Pull #296) -- The `ext` argument is now named `extensions`, and is no longer optional. (Pull #296) -- The `"reason"` extension keyword is now named `"reason_phrase"`. (Pull #296) -- The `"reason_phrase"` and `"http_version"` extensions now use byte strings for their values. (Pull #296) -- The `httpcore.PlainByteStream()` class becomes `httpcore.ByteStream()`. (Pull #296) - -### Added - -- Streams now support a `.read()` interface. (Pull #296) - -### Fixed - -- Task cancelation no longer leaks connections from the connection pool. (Pull #305) - -## 0.12.3 (December 7th, 2020) - -### Fixed - -- Abort SSL connections on close rather than waiting for remote EOF when using `asyncio`. (Pull #167) -- Fix exception raised in case of connect timeouts when using the `anyio` backend. (Pull #236) -- Fix `Host` header precedence for `:authority` in HTTP/2. (Pull #241, #243) -- Handle extra edge case when detecting for socket readability when using `asyncio`. (Pull #242, #244) -- Fix `asyncio` SSL warning when using proxy tunneling. (Pull #249) - -## 0.12.2 (November 20th, 2020) - -### Fixed - -- Properly wrap connect errors on the asyncio backend. (Pull #235) -- Fix `ImportError` occurring on Python 3.9 when using the HTTP/1.1 sync client in a multithreaded context. (Pull #237) - -## 0.12.1 (November 7th, 2020) - -### Added - -- Add connect retries. (Pull #221) - -### Fixed - -- Tweak detection of dropped connections, resolving an issue with open files limits on Linux. (Pull #185) -- Avoid leaking connections when establishing an HTTP tunnel to a proxy has failed. (Pull #223) -- Properly wrap OS errors when using `trio`. (Pull #225) - -## 0.12.0 (October 6th, 2020) - -### Changed - -- HTTP header casing is now preserved, rather than always sent in lowercase. (#216 and python-hyper/h11#104) - -### Added - -- Add Python 3.9 to officially supported versions. - -### Fixed - -- Gracefully handle a stdlib asyncio bug when a connection is closed while it is in a paused-for-reading state. (#201) - -## 0.11.1 (September 28nd, 2020) - -### Fixed - -- Add await to async semaphore release() coroutine (#197) -- Drop incorrect curio classifier (#192) - -## 0.11.0 (September 22nd, 2020) - -The Transport API with 0.11.0 has a couple of significant changes. - -Firstly we've moved changed the request interface in order to allow extensions, which will later enable us to support features -such as trailing headers, HTTP/2 server push, and CONNECT/Upgrade connections. - -The interface changes from: - -```python -def request(method, url, headers, stream, timeout): - return (http_version, status_code, reason, headers, stream) -``` - -To instead including an optional dictionary of extensions on the request and response: - -```python -def request(method, url, headers, stream, ext): - return (status_code, headers, stream, ext) -``` - -Having an open-ended extensions point will allow us to add later support for various optional features, that wouldn't otherwise be supported without these API changes. - -In particular: - -* Trailing headers support. -* HTTP/2 Server Push -* sendfile. -* Exposing raw connection on CONNECT, Upgrade, HTTP/2 bi-di streaming. -* Exposing debug information out of the API, including template name, template context. - -Currently extensions are limited to: - -* request: `timeout` - Optional. Timeout dictionary. -* response: `http_version` - Optional. Include the HTTP version used on the response. -* response: `reason` - Optional. Include the reason phrase used on the response. Only valid with HTTP/1.*. - -See https://github.com/encode/httpx/issues/1274#issuecomment-694884553 for the history behind this. - -Secondly, the async version of `request` is now namespaced as `arequest`. - -This allows concrete transports to support both sync and async implementations on the same class. - -### Added - -- Add curio support. (Pull #168) -- Add anyio support, with `backend="anyio"`. (Pull #169) - -### Changed - -- Update the Transport API to use 'ext' for optional extensions. (Pull #190) -- Update the Transport API to use `.request` and `.arequest` so implementations can support both sync and async. (Pull #189) - -## 0.10.2 (August 20th, 2020) - -### Added - -- Added Unix Domain Socket support. (Pull #139) - -### Fixed - -- Always include the port on proxy CONNECT requests. (Pull #154) -- Fix `max_keepalive_connections` configuration. (Pull #153) -- Fixes behaviour in HTTP/1.1 where server disconnects can be used to signal the end of the response body. (Pull #164) - -## 0.10.1 (August 7th, 2020) - -- Include `max_keepalive_connections` on `AsyncHTTPProxy`/`SyncHTTPProxy` classes. - -## 0.10.0 (August 7th, 2020) - -The most notable change in the 0.10.0 release is that HTTP/2 support is now fully optional. - -Use either `pip install httpcore` for HTTP/1.1 support only, or `pip install httpcore[http2]` for HTTP/1.1 and HTTP/2 support. - -### Added - -- HTTP/2 support becomes optional. (Pull #121, #130) -- Add `local_address=...` support. (Pull #100, #134) -- Add `PlainByteStream`, `IteratorByteStream`, `AsyncIteratorByteStream`. The `AsyncByteSteam` and `SyncByteStream` classes are now pure interface classes. (#133) -- Add `LocalProtocolError`, `RemoteProtocolError` exceptions. (Pull #129) -- Add `UnsupportedProtocol` exception. (Pull #128) -- Add `.get_connection_info()` method. (Pull #102, #137) -- Add better TRACE logs. (Pull #101) - -### Changed - -- `max_keepalive` is deprecated in favour of `max_keepalive_connections`. (Pull #140) - -### Fixed - -- Improve handling of server disconnects. (Pull #112) - -## 0.9.1 (May 27th, 2020) - -### Fixed - -- Proper host resolution for sync case, including IPv6 support. (Pull #97) -- Close outstanding connections when connection pool is closed. (Pull #98) - -## 0.9.0 (May 21th, 2020) - -### Changed - -- URL port becomes an `Optional[int]` instead of `int`. (Pull #92) - -### Fixed - -- Honor HTTP/2 max concurrent streams settings. (Pull #89, #90) -- Remove incorrect debug log. (Pull #83) - -## 0.8.4 (May 11th, 2020) - -### Added - -- Logging via HTTPCORE_LOG_LEVEL and HTTPX_LOG_LEVEL environment variables -and TRACE level logging. (Pull #79) - -### Fixed - -- Reuse of connections on HTTP/2 in close concurrency situations. (Pull #81) - -## 0.8.3 (May 6rd, 2020) - -### Fixed - -- Include `Host` and `Accept` headers on proxy "CONNECT" requests. -- De-duplicate any headers also contained in proxy_headers. -- HTTP/2 flag not being passed down to proxy connections. - -## 0.8.2 (May 3rd, 2020) - -### Fixed - -- Fix connections using proxy forwarding requests not being added to the -connection pool properly. (Pull #70) - -## 0.8.1 (April 30th, 2020) - -### Changed - -- Allow inherintance of both `httpcore.AsyncByteStream`, `httpcore.SyncByteStream` without type conflicts. - -## 0.8.0 (April 30th, 2020) - -### Fixed - -- Fixed tunnel proxy support. - -### Added - -- New `TimeoutException` base class. - -## 0.7.0 (March 5th, 2020) - -- First integration with HTTPX. - - diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/RECORD deleted file mode 100644 index 653e92bc..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/RECORD +++ /dev/null @@ -1,67 +0,0 @@ -httpcore-0.13.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -httpcore-0.13.7.dist-info/LICENSE.md,sha256=_ctZFUx0y6uhahEkL3dAvqnyPW_rVUeRfYxflKgDkqU,1518 -httpcore-0.13.7.dist-info/METADATA,sha256=AD2A2icHFW5_CQo9WqHR3vmKaeTFXZkW2Zi_6gbFSJ8,13025 -httpcore-0.13.7.dist-info/RECORD,, -httpcore-0.13.7.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 -httpcore-0.13.7.dist-info/top_level.txt,sha256=kYeSB6l1hBNp7JwgSwLajcsxRlrSCVKOhYKSkdgx798,59 -httpcore/__init__.py,sha256=udEv1w02RmsdoGNMPCxH1hOcZTFiEBXsnnNUoizC4Po,1656 -httpcore/__pycache__/__init__.cpython-39.pyc,, -httpcore/__pycache__/_bytestreams.cpython-39.pyc,, -httpcore/__pycache__/_exceptions.cpython-39.pyc,, -httpcore/__pycache__/_threadlock.cpython-39.pyc,, -httpcore/__pycache__/_types.cpython-39.pyc,, -httpcore/__pycache__/_utils.cpython-39.pyc,, -httpcore/_async/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -httpcore/_async/__pycache__/__init__.cpython-39.pyc,, -httpcore/_async/__pycache__/base.cpython-39.pyc,, -httpcore/_async/__pycache__/connection.cpython-39.pyc,, -httpcore/_async/__pycache__/connection_pool.cpython-39.pyc,, -httpcore/_async/__pycache__/http.cpython-39.pyc,, -httpcore/_async/__pycache__/http11.cpython-39.pyc,, -httpcore/_async/__pycache__/http2.cpython-39.pyc,, -httpcore/_async/__pycache__/http_proxy.cpython-39.pyc,, -httpcore/_async/base.py,sha256=uhEgVbp_560r6-80PRxK6jjV4OSuzYdbWY26K_OARC8,3264 -httpcore/_async/connection.py,sha256=ORhAgJVzI5PrQNU9w0ecsSiDsF0IuIUwKLQSkmBUajY,8350 -httpcore/_async/connection_pool.py,sha256=s5Ff430j36OL3lnJNzEHShNgMhJoQ9cSO03s11Gvl6U,13146 -httpcore/_async/http.py,sha256=6CG3ZiBXXxR-kGCpdyOWHuMTcgfp-ajPxkdAdMFf8Og,1285 -httpcore/_async/http11.py,sha256=oGrRxz4DxT6PnjP8bfLmaWvQ5NzI6OcBfUiuZZ7U078,9396 -httpcore/_async/http2.py,sha256=av5Ee5yM3hnDjiMb2paN3ObENCebCmDKfYUmPjXAtno,17082 -httpcore/_async/http_proxy.py,sha256=yDD8hXHtVHU8gLT_9VBPhgHfF0ebB6DOPlbjiuH6Viw,10004 -httpcore/_backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -httpcore/_backends/__pycache__/__init__.cpython-39.pyc,, -httpcore/_backends/__pycache__/anyio.cpython-39.pyc,, -httpcore/_backends/__pycache__/asyncio.cpython-39.pyc,, -httpcore/_backends/__pycache__/auto.cpython-39.pyc,, -httpcore/_backends/__pycache__/base.cpython-39.pyc,, -httpcore/_backends/__pycache__/curio.cpython-39.pyc,, -httpcore/_backends/__pycache__/sync.cpython-39.pyc,, -httpcore/_backends/__pycache__/trio.cpython-39.pyc,, -httpcore/_backends/anyio.py,sha256=OL7llxbbOv2pkzA5hjQR4mW0SLgDUEuJK0x_mD97Nu0,6317 -httpcore/_backends/asyncio.py,sha256=rg9-BCdRqD65_4EC6U0D-jMXkK4oV_PbYfPBeYptYj0,10700 -httpcore/_backends/auto.py,sha256=DhL7k6Iww7qkugkpeBzPQq4mySCCb9G_PK-w_zOqVUc,2211 -httpcore/_backends/base.py,sha256=hmAUxgADI-fmWciRs4iBxa0A2E-avawuaOWocX_A9nM,3796 -httpcore/_backends/curio.py,sha256=Zr3mfo7q8wpfkzXv3atEyAkbB-4NtndYWw56gEh7kDQ,6230 -httpcore/_backends/sync.py,sha256=W9WQq2lLOqZ1IhirZATFDDvKVWAdSJjeNja_vwZIg8E,5494 -httpcore/_backends/trio.py,sha256=nwEuP6_xIIFy6vqBs0XXxfqROk99GnDyLhiOIsJHcsQ,6818 -httpcore/_bytestreams.py,sha256=aZQvmevkf27rgnwMwumkOpzK5GBSwbe1WTTnkNvS910,2430 -httpcore/_exceptions.py,sha256=xieninAoG-IeEIma6OIjNDlUfUAYyH_Hx652U2RVKws,1115 -httpcore/_sync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -httpcore/_sync/__pycache__/__init__.cpython-39.pyc,, -httpcore/_sync/__pycache__/base.cpython-39.pyc,, -httpcore/_sync/__pycache__/connection.cpython-39.pyc,, -httpcore/_sync/__pycache__/connection_pool.cpython-39.pyc,, -httpcore/_sync/__pycache__/http.cpython-39.pyc,, -httpcore/_sync/__pycache__/http11.cpython-39.pyc,, -httpcore/_sync/__pycache__/http2.cpython-39.pyc,, -httpcore/_sync/__pycache__/http_proxy.cpython-39.pyc,, -httpcore/_sync/base.py,sha256=HeUz5H5t_WN4GDpwhz6hCsgL75JJnXwo8Jn9Ms3m1NM,3167 -httpcore/_sync/connection.py,sha256=DeE7z9ky3CyQUl9lD72O2bcawzv-zKbZ7RTq6UrRe4A,8231 -httpcore/_sync/connection_pool.py,sha256=6cUbHjaK5cfs4rWVN7F4hOxk2IxIp1C5bfVHieSINlM,12866 -httpcore/_sync/http.py,sha256=Dhcrb6AqgHyh18QFq1NysUS-6W5z6-guFMwwC6lVwAg,1274 -httpcore/_sync/http11.py,sha256=hhlEv95rfDr-vJW5OSwTvqthkGNYH9a6jc6p1RrGoJ8,9209 -httpcore/_sync/http2.py,sha256=JdLSySBTzkOnZ4KQzfaQOZYrsinHeTScJnuKBEyfGP4,16727 -httpcore/_sync/http_proxy.py,sha256=p8zuucWqny1nhP3qVPmGdUwUF8jNq2Yf-IM6S5Bf-QE,9869 -httpcore/_threadlock.py,sha256=Xc-WeI8tDh2Ivt7Chblv3HmhbBgZXKMo5SMneXjZDCE,813 -httpcore/_types.py,sha256=97NJ04exPaPoYZB_y4eV4qYfqeyr9XE-zYqkGEAaGuI,331 -httpcore/_utils.py,sha256=goElgq6cnQR0HSJI32taOi-gAJKO3Lr_kCJ0VHPv-XM,3691 -httpcore/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/WHEEL b/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/WHEEL deleted file mode 100644 index 5bad85fd..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.0) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/top_level.txt b/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/top_level.txt deleted file mode 100644 index 613e4350..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore-0.13.7.dist-info/top_level.txt +++ /dev/null @@ -1,4 +0,0 @@ -httpcore -httpcore/_async -httpcore/_backends -httpcore/_sync diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/__init__.py deleted file mode 100644 index 3ddc6d61..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/__init__.py +++ /dev/null @@ -1,63 +0,0 @@ -from ._async.base import AsyncByteStream, AsyncHTTPTransport -from ._async.connection_pool import AsyncConnectionPool -from ._async.http_proxy import AsyncHTTPProxy -from ._bytestreams import AsyncIteratorByteStream, ByteStream, IteratorByteStream -from ._exceptions import ( - CloseError, - ConnectError, - ConnectTimeout, - LocalProtocolError, - NetworkError, - PoolTimeout, - ProtocolError, - ProxyError, - ReadError, - ReadTimeout, - RemoteProtocolError, - TimeoutException, - UnsupportedProtocol, - WriteError, - WriteTimeout, -) -from ._sync.base import SyncByteStream, SyncHTTPTransport -from ._sync.connection_pool import SyncConnectionPool -from ._sync.http_proxy import SyncHTTPProxy - -__all__ = [ - "AsyncByteStream", - "AsyncConnectionPool", - "AsyncHTTPProxy", - "AsyncHTTPTransport", - "AsyncIteratorByteStream", - "ByteStream", - "CloseError", - "ConnectError", - "ConnectTimeout", - "IteratorByteStream", - "LocalProtocolError", - "NetworkError", - "PoolTimeout", - "ProtocolError", - "ProxyError", - "ReadError", - "ReadTimeout", - "RemoteProtocolError", - "SyncByteStream", - "SyncConnectionPool", - "SyncHTTPProxy", - "SyncHTTPTransport", - "TimeoutException", - "UnsupportedProtocol", - "WriteError", - "WriteTimeout", -] -__version__ = "0.13.7" - -__locals = locals() - -for _name in __all__: - if not _name.startswith("__"): - # Save original source module, used by Sphinx. - __locals[_name].__source_module__ = __locals[_name].__module__ - # Override module for prettier repr(). - setattr(__locals[_name], "__module__", "httpcore") # noqa diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 89af5f5e90f3b436a9884103e14f05d06e5a1caa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1407 zcma)+OK;mo5XVVMmMH4|@H2MvXzf-ls-);4KoJCSZ38hH1WxRtz(B=fOU}FnOmDQle z>QHA5Xs{+USqoaM4Q25{N=)(IDpUT7v~Oa(mT7(uLIbkTYr8TS6{pGf^O2S zRp+;_@?X-YU*}d_i|gkF*ZKV-ZX7!O=0C1!yzlAeww$EVj}t`?m7pQh9UFLjbaZee z!c=BlsJ^SaHoC*pltyaI(*w>E6K-549|(Rn=@;~}jqEEbLdC`0eS^XYoOse_$_ zOS&fn7rHimRPHsV-qDy*exh{e36H|WJW}z9C(|8Isd~l5%iODCfwT1b)y%-wn&(xX z(=eWHL36gH`FVBDL^D)DcYjXhNroEHc$TY!U&L6=`mpwNpOL$9cvbB- z`q#zoVDJ;I>$6l_et%7P<^)9%fzvDs2s7)BC?hHed0x4XSkX9rDMU}!uS{X*`-AQb^-gRf! zEsg>&^jDxhz+>L{5B!ULLp=4BM;;32%zC}+#4ZU4Mw;==nala+%sJm4J9Bd;f%5Cq zE$6!mA;00ESacX{LXFzcc*LVV=~0{Z6kF-3wn~Yoc&e}UbX%8w%`f%JcA1ioh^Kp{ zN5m^}otMAYYy%`^&j5)5W7V#}xZ;^GHn|RC)2r^2M(qjcAq_Q|+lq#PyBl-i#Gy!x zZO8YWw$BqIlRcrhk|vks$`6Mz-;V`%dLX*A4|{Woi)R*#3WH6k(QRlrv8hLF#iO>$ zHN4Mb#nU|fk!I_>#IAv-*tr30{|kDXWbkZIRtnyVA_y_6mj2ox`CC!=mv+@AmSdN zvj8pL2RB&ZfgGkdnsWPILrKb``J@Dw9*DqIz`R+(KGtoh5jx#5Jtho%YM-3Yy%U-k zY_uIt(jx932yjSpLd0eG`Qx+O8?C#;P8`&7p>+4 z9z1A$(rve*Zp?4?9rvDd$fH(fs5cp2Ei-U`2ufKu=*EmakFX?OdbE(6vzg7GP=TOb zbh@lyA1nG-RD_6 zb`{T|Rt=j)Y|x$pEnB$z7>+Ptq6{^{jzP7#d9|)e>6w5X)6fnqEe5Pt$Q2`|aO zRb}An5T;UE2wVf^F^r2rTTAL0ndCNbet;*HF8%EIy+FKr{J=Wo0a6*yoP4d3haHCA zu*-eVYOn5a-w$tC4@2R5E34zk#3jwVV@aQ!gi>|hYMg#!aC>?0RCzJ)WA7G2lAnsK)}Z1#Xqn0}y0qWB6CjqRSVb;t(7lE! zP@A}d4Kkrv#zu0;i`c_gOnF68$|?@?cgWcUDGgC&Y_hPV)ir@qH19e!)YKY7vqo zo~4v{b|thzQU!3{fOS*pr<9uXD?BV^Wgx+8vk;|=XR{FE5~o;5rZa0ekv~w*La)HY zCe#Su404)9@~1)#sywZgfQ@i=5B@8Z;$a^?ZfSm`f>83EU1icwn{6lJq6A{wWSC~8 k0(>`_9Z6D?XHA2U81JRY+6QP^nQ1R7HCj{aOY=BFiET-A?A!o;&vzMRF z*suIIw!?l{ca3A?*wn_1&x{iTwrA#ypK!rm8PB(0;hW!K5s&%LJjPsfyuohZ6>KP{ zHa2&U0-5Mg#o1h_Wt3)in1*qx{Wy?A3ushiraTIq#uHGHM`tyy==g>~3-A7QuyfPh zpB`!zyWqz{Mec*(P^qzd@0;B_UK)U(NN}&cknsz5FMRB#==nJDgJ=FznYxEsCxHTa zol>5*B)yhQvo3a0;S#kY?P6et!EN5q&jX^R8d&4pE;uu-~ z+c=#hi2^OfJ}9jMH6Fb&vxeuzek46Fvpp|TVlt-lw&y*c_~X+%`QI%B$_~_~9=Qw* z4W4tQ26fI`u?wJJ1oM=YI<^pUQy;G_;eKu+u4L-pmyy!)eSPG*Q1B5~@-6PEz#qS_ zZW+_B7j(pxbT*ofre(djf@!x38sbWt-a!~iHPO50!}T2{TgBub7G%VgWUYPtkj{kf z@KBjPDtL%1dAfI19LqqLs|J|*dO<~8N!7Y9eNpbYh-1wgYj(9{Vup#e=dK+^!wHwyIi01a)RVFxrMfXW5bn?U~+wkZ71dXP0f cKV7D7(Q=nw#n9kOro}(7d)C>n{@=5I09MhrT>t<8 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_threadlock.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_threadlock.cpython-39.pyc deleted file mode 100644 index 200bc12a58273d0e531a455002964cbf9980937a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1436 zcmaJ=&2G~`5Z<*N$4Qg4rIbGj$=672kT@cQTA)IRDyo#6B1@~SciWgccDn0?B=klf zqX#(VId}`-5GP&%5Msto+NP1ZK;v9k zq9n@ag-&T^w<0QFR~Bnac2!XWyA@$Tvg>KN-Bpr{{n$U5d@j2%4pcl0gw$@5Xh5c`6x7uI1EHE8wQq5$+*uARs^25(nPo2zf(`Ja793Z@GSnH*AUT=!D5# zvXx(b8%1Tt_>6)lm$B$%bAh9|#ZvWmMcahyZq@}4!t=zRUIw!#iw`n0sGH3uv@b#h z`zYc)$yf^c_F^#zQLZp{I^f|0;JW~K>Oavm;EG&BZUv99w0nK zc!Y4pekNh>DC7?tO>Y4>)GE}>T7gjb{u+i&4gCI8oaM93vu>**_@xExC!GaNZIIzF Z%(BXiZi|~bFZ23dA-5VcaA<{A%>SAjK<)ql diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_types.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_types.cpython-39.pyc deleted file mode 100644 index 9e57a90e6342661230f9b187bac7b03df6c21fdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 532 zcmYk3zm5|z5XSBO&t4J&qDi-H3PO(%;?N<1E)Ya=6xK>B-+DH&Zg*|j&PloA8lHw% za)+pR1q#F%C>YB>`5VuCvc`NmEeXcAU+4Ui67oHW|06~53b(yS2*QY*-(%A zA;j37zg#uxZ_XRr8m__At6Lav>$SYD yt#t5I^Y(`C!PW=obgK+JYr>H1N}qi3Vo>7P!%O^cVrPgXsiJ~T=!`z0bNU;5uaMdR diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_utils.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/__pycache__/_utils.cpython-39.pyc deleted file mode 100644 index 34b6d39d12f94169b2dd77bdd44a3d643f2538ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3212 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/base.cpython-39.pyc deleted file mode 100644 index 8bdf68663b0664ada3006933cd8ac3027a7c56ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4398 zcmcIn&2JmW72jPhmmd--MX{SYAMFBZ>M)UH)h$}oFbpZOVhdGS!(tp{D|EHm8JUci zyY$Rbwg|U}+J|0y_aQm@zbMdKZ$W_`_Ez-db5H$1(BGTkEapUs_R+?C;vjwayJhi+f z%obS#vj%3%%-lCx&6nW8Xt&I)(Gfw&kAm<)=XAhZrL3_fPvdYmR>Co*yfM6lQ`yK+DqcQ z{Nb=CIBSD!)%W9|&wW3u`+h%R!-&Rwp?VG#pTdsR|XY1x?YKfMg$({9>k z{!@Er%tx$k62c91)8^wgFJHoyd~UK5v!5v=su^84+pF-hn$dN$Vc0T^TF;i$jrr&_ z<@>4NL4Wj>(nqJuU2-b77vnM=EbZ+9u}Ady_80` z6)O4MXFU$SkDwt5nFkOXLiOVN>eyT%N;eaIoa&Pa{hxGRTNxaT*pf%bQ+_}$kktwi zKg3ksUBez-nzPJ$0o6WNjz1GFxvY*=qhA*i{Bj7B9dS2=wm6BRSP!Ef1aZ>@HfFsL z7aGd}7NAY3e8KGo5_mj@ouE}V5lYJ=-ok0~!Z_LlKbn%{JM)rgkTX(H>VleuE znP0#ftn|!yVq7(zn!89cw~a5&Pci?({L;{K)7YPzZvYN9wA6`!Qt z`@kJ7|5#D})cCFW#QdZ6(Ecg#Uzl3RmX%rS8<{-_L^>~P{d&}sX_)i}H+~Lc>bz0w zjI_8{Z2fwaK>zXv200E$+n*=BSbUF=&r@bOAl#o3w<I1y*Jbf>ni85s(&ngEv_1xuvqd?KRmFU*gM`48F`?1LWd! zn>ASTS=n1rp=&u?Q7X9I>D)mX5aaTRbo4jn^sk6sxVVfiE}`V1?Ee?Hx(Jde0s>0V z{y0wLf$7_Zu$GfKI{0O!p@_0dcU-?X`le=e{y62aq)00+!4x57vAofkBAvQhWUdGyVL1lLPwitmW=Ywgq;#E zX)fW|K_-|JgU(`axd_%O^$A5G&x7s+VM_ORRo*+J_(IDP>3JyqFkyW5m_qd$!X=1R zWba)6S2s4MmH*B3)r-Su$dH1Pc&sj+GAB}h3w_O_PUN4J26-V zaJC~vB3h1k8y81hrjF`n(W34H>L_VX#Zi^gFPwM#KL()A?(dE+pABB?=i#))cY!sN z#PY&LUFWHU|A)e=+mx=AhKs67Rbi{{qizot9M@thtE2dW9}QF3Sx3jBuG6-Vs|8uA z`Uv^~=L0v0dM79;ipLNFsa7GBsI_rULQ{$7L7@h7T;$Be@O51sv@ET070pQGyqyvM z39_~LKDJ+ZEWODB6gyN!J_MjPf;oEU93xC1TXt6Ek3&Dj>oKd*=p=}S7^eBFQ-@kI zLEdOgMTWA?3I-@uj7h0Ng^6OdWhzy)Y%Sy!K#C3OsBW5fCaMql<6i3fDRwpU&gkt| zFs}exrFOgBdi~sL;5|B`LLKFImDe+yf{GySvl8OJSfd?PCDdrNP9433vc^Yv73@3? zxhlT}$ttc=cU~d!Lu}A1MbZF;M9o40qkqkRExy-umdi*?rtx3Pa`gIt1cA0*%WNJG z`&pTEFV!iTgE4Z9DrOX?njuHoM@|Vu9A~u&kCgGU%5I$QfTVg;DVfzt=dqntuj>c= W4RW>dyKK?CU|lFJ+beH0-})aSOCQYu diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/connection.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/connection.cpython-39.pyc deleted file mode 100644 index e7339e45a45eba40e61b6bef2a55f558e740d890..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7180 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/connection_pool.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/connection_pool.cpython-39.pyc deleted file mode 100644 index ef8f3d1d25ea165f528133eb9d4fa4d73165e2d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10892 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 LwY**}RgeA;P2jS> diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/http.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/http.cpython-39.pyc deleted file mode 100644 index c1032829bb8acca83fa79bcbe3802a0b4e7c7bf6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1938 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 MwMV|MeP28Ff5-Bv-~a#s diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/http_proxy.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/__pycache__/http_proxy.cpython-39.pyc deleted file mode 100644 index 3e2b6df6a824a5c9a1c56f1f461d85eca2e53ab4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6253 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 Ssb0>k AsyncIterator[bytes]: - """ - Yield bytes representing the request or response body. - """ - yield b"" # pragma: nocover - - async def aclose(self) -> None: - """ - Must be called by the client to indicate that the stream has been closed. - """ - pass # pragma: nocover - - async def aread(self) -> bytes: - try: - return b"".join([part async for part in self]) - finally: - await self.aclose() - - -class AsyncHTTPTransport: - """ - The base interface for sending HTTP requests. - - Concrete implementations should subclass this class, and implement - the :meth:`handle_async_request` method, and optionally the :meth:`aclose` method. - """ - - async def handle_async_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - """ - The interface for sending a single HTTP request, and returning a response. - - Parameters - ---------- - method: - The HTTP method, such as ``b'GET'``. - url: - The URL as a 4-tuple of (scheme, host, port, path). - headers: - Any HTTP headers to send with the request. - stream: - The body of the HTTP request. - extensions: - A dictionary of optional extensions. - - Returns - ------- - status_code: - The HTTP status code, such as ``200``. - headers: - Any HTTP headers included on the response. - stream: - The body of the HTTP response. - extensions: - A dictionary of optional extensions. - """ - raise NotImplementedError() # pragma: nocover - - async def aclose(self) -> None: - """ - Close the implementation, which should close any outstanding response streams, - and any keep alive connections. - """ - - async def __aenter__(self: T) -> T: - return self - - async def __aexit__( - self, - exc_type: Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - await self.aclose() diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/connection.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/connection.py deleted file mode 100644 index 2add4d85..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/connection.py +++ /dev/null @@ -1,220 +0,0 @@ -from ssl import SSLContext -from typing import List, Optional, Tuple, cast - -from .._backends.auto import AsyncBackend, AsyncLock, AsyncSocketStream, AutoBackend -from .._exceptions import ConnectError, ConnectTimeout -from .._types import URL, Headers, Origin, TimeoutDict -from .._utils import exponential_backoff, get_logger, url_to_origin -from .base import AsyncByteStream, AsyncHTTPTransport, NewConnectionRequired -from .http import AsyncBaseHTTPConnection -from .http11 import AsyncHTTP11Connection - -logger = get_logger(__name__) - -RETRIES_BACKOFF_FACTOR = 0.5 # 0s, 0.5s, 1s, 2s, 4s, etc. - - -class AsyncHTTPConnection(AsyncHTTPTransport): - def __init__( - self, - origin: Origin, - http1: bool = True, - http2: bool = False, - keepalive_expiry: float = None, - uds: str = None, - ssl_context: SSLContext = None, - socket: AsyncSocketStream = None, - local_address: str = None, - retries: int = 0, - backend: AsyncBackend = None, - ): - self.origin = origin - self._http1_enabled = http1 - self._http2_enabled = http2 - self._keepalive_expiry = keepalive_expiry - self._uds = uds - self._ssl_context = SSLContext() if ssl_context is None else ssl_context - self.socket = socket - self._local_address = local_address - self._retries = retries - - alpn_protocols: List[str] = [] - if http1: - alpn_protocols.append("http/1.1") - if http2: - alpn_protocols.append("h2") - - self._ssl_context.set_alpn_protocols(alpn_protocols) - - self.connection: Optional[AsyncBaseHTTPConnection] = None - self._is_http11 = False - self._is_http2 = False - self._connect_failed = False - self._expires_at: Optional[float] = None - self._backend = AutoBackend() if backend is None else backend - - def __repr__(self) -> str: - return f"" - - def info(self) -> str: - if self.connection is None: - return "Connection failed" if self._connect_failed else "Connecting" - return self.connection.info() - - def should_close(self) -> bool: - """ - Return `True` if the connection is in a state where it should be closed. - This occurs when any of the following occur: - - * There are no active requests on an HTTP/1.1 connection, and the underlying - socket is readable. The only valid state the socket can be readable in - if this occurs is when the b"" EOF marker is about to be returned, - indicating a server disconnect. - * There are no active requests being made and the keepalive timeout has passed. - """ - if self.connection is None: - return False - return self.connection.should_close() - - def is_idle(self) -> bool: - """ - Return `True` if the connection is currently idle. - """ - if self.connection is None: - return False - return self.connection.is_idle() - - def is_closed(self) -> bool: - if self.connection is None: - return self._connect_failed - return self.connection.is_closed() - - def is_available(self) -> bool: - """ - Return `True` if the connection is currently able to accept an outgoing request. - This occurs when any of the following occur: - - * The connection has not yet been opened, and HTTP/2 support is enabled. - We don't *know* at this point if we'll end up on an HTTP/2 connection or - not, but we *might* do, so we indicate availability. - * The connection has been opened, and is currently idle. - * The connection is open, and is an HTTP/2 connection. The connection must - also not currently be exceeding the maximum number of allowable concurrent - streams and must not have exhausted the maximum total number of stream IDs. - """ - if self.connection is None: - return self._http2_enabled and not self.is_closed - return self.connection.is_available() - - @property - def request_lock(self) -> AsyncLock: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_request_lock"): - self._request_lock = self._backend.create_lock() - return self._request_lock - - async def handle_async_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - assert url_to_origin(url) == self.origin - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - async with self.request_lock: - if self.connection is None: - if self._connect_failed: - raise NewConnectionRequired() - if not self.socket: - logger.trace( - "open_socket origin=%r timeout=%r", self.origin, timeout - ) - self.socket = await self._open_socket(timeout) - self._create_connection(self.socket) - elif not self.connection.is_available(): - raise NewConnectionRequired() - - assert self.connection is not None - logger.trace( - "connection.handle_async_request method=%r url=%r headers=%r", - method, - url, - headers, - ) - return await self.connection.handle_async_request( - method, url, headers, stream, extensions - ) - - async def _open_socket(self, timeout: TimeoutDict = None) -> AsyncSocketStream: - scheme, hostname, port = self.origin - timeout = {} if timeout is None else timeout - ssl_context = self._ssl_context if scheme == b"https" else None - - retries_left = self._retries - delays = exponential_backoff(factor=RETRIES_BACKOFF_FACTOR) - - while True: - try: - if self._uds is None: - return await self._backend.open_tcp_stream( - hostname, - port, - ssl_context, - timeout, - local_address=self._local_address, - ) - else: - return await self._backend.open_uds_stream( - self._uds, hostname, ssl_context, timeout - ) - except (ConnectError, ConnectTimeout): - if retries_left <= 0: - self._connect_failed = True - raise - retries_left -= 1 - delay = next(delays) - await self._backend.sleep(delay) - except Exception: # noqa: PIE786 - self._connect_failed = True - raise - - def _create_connection(self, socket: AsyncSocketStream) -> None: - http_version = socket.get_http_version() - logger.trace( - "create_connection socket=%r http_version=%r", socket, http_version - ) - if http_version == "HTTP/2" or ( - self._http2_enabled and not self._http1_enabled - ): - from .http2 import AsyncHTTP2Connection - - self._is_http2 = True - self.connection = AsyncHTTP2Connection( - socket=socket, - keepalive_expiry=self._keepalive_expiry, - backend=self._backend, - ) - else: - self._is_http11 = True - self.connection = AsyncHTTP11Connection( - socket=socket, keepalive_expiry=self._keepalive_expiry - ) - - async def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict = None - ) -> None: - if self.connection is not None: - logger.trace("start_tls hostname=%r timeout=%r", hostname, timeout) - self.socket = await self.connection.start_tls( - hostname, ssl_context, timeout - ) - logger.trace("start_tls complete hostname=%r timeout=%r", hostname, timeout) - - async def aclose(self) -> None: - async with self.request_lock: - if self.connection is not None: - await self.connection.aclose() diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/connection_pool.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/connection_pool.py deleted file mode 100644 index 0902ac2f..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/connection_pool.py +++ /dev/null @@ -1,362 +0,0 @@ -import warnings -from ssl import SSLContext -from typing import ( - AsyncIterator, - Callable, - Dict, - List, - Optional, - Set, - Tuple, - Union, - cast, -) - -from .._backends.auto import AsyncBackend, AsyncLock, AsyncSemaphore -from .._backends.base import lookup_async_backend -from .._exceptions import LocalProtocolError, PoolTimeout, UnsupportedProtocol -from .._threadlock import ThreadLock -from .._types import URL, Headers, Origin, TimeoutDict -from .._utils import get_logger, origin_to_url_string, url_to_origin -from .base import AsyncByteStream, AsyncHTTPTransport, NewConnectionRequired -from .connection import AsyncHTTPConnection - -logger = get_logger(__name__) - - -class NullSemaphore(AsyncSemaphore): - def __init__(self) -> None: - pass - - async def acquire(self, timeout: float = None) -> None: - return - - async def release(self) -> None: - return - - -class ResponseByteStream(AsyncByteStream): - def __init__( - self, - stream: AsyncByteStream, - connection: AsyncHTTPConnection, - callback: Callable, - ) -> None: - """ - A wrapper around the response stream that we return from - `.handle_async_request()`. - - Ensures that when `stream.aclose()` is called, the connection pool - is notified via a callback. - """ - self.stream = stream - self.connection = connection - self.callback = callback - - async def __aiter__(self) -> AsyncIterator[bytes]: - async for chunk in self.stream: - yield chunk - - async def aclose(self) -> None: - try: - # Call the underlying stream close callback. - # This will be a call to `AsyncHTTP11Connection._response_closed()` - # or `AsyncHTTP2Stream._response_closed()`. - await self.stream.aclose() - finally: - # Call the connection pool close callback. - # This will be a call to `AsyncConnectionPool._response_closed()`. - await self.callback(self.connection) - - -class AsyncConnectionPool(AsyncHTTPTransport): - """ - A connection pool for making HTTP requests. - - Parameters - ---------- - ssl_context: - An SSL context to use for verifying connections. - max_connections: - The maximum number of concurrent connections to allow. - max_keepalive_connections: - The maximum number of connections to allow before closing keep-alive - connections. - keepalive_expiry: - The maximum time to allow before closing a keep-alive connection. - http1: - Enable/Disable HTTP/1.1 support. Defaults to True. - http2: - Enable/Disable HTTP/2 support. Defaults to False. - uds: - Path to a Unix Domain Socket to use instead of TCP sockets. - local_address: - Local address to connect from. Can also be used to connect using a particular - address family. Using ``local_address="0.0.0.0"`` will connect using an - ``AF_INET`` address (IPv4), while using ``local_address="::"`` will connect - using an ``AF_INET6`` address (IPv6). - retries: - The maximum number of retries when trying to establish a connection. - backend: - A name indicating which concurrency backend to use. - """ - - def __init__( - self, - ssl_context: SSLContext = None, - max_connections: int = None, - max_keepalive_connections: int = None, - keepalive_expiry: float = None, - http1: bool = True, - http2: bool = False, - uds: str = None, - local_address: str = None, - retries: int = 0, - max_keepalive: int = None, - backend: Union[AsyncBackend, str] = "auto", - ): - if max_keepalive is not None: - warnings.warn( - "'max_keepalive' is deprecated. Use 'max_keepalive_connections'.", - DeprecationWarning, - ) - max_keepalive_connections = max_keepalive - - if isinstance(backend, str): - backend = lookup_async_backend(backend) - - self._ssl_context = SSLContext() if ssl_context is None else ssl_context - self._max_connections = max_connections - self._max_keepalive_connections = max_keepalive_connections - self._keepalive_expiry = keepalive_expiry - self._http1 = http1 - self._http2 = http2 - self._uds = uds - self._local_address = local_address - self._retries = retries - self._connections: Dict[Origin, Set[AsyncHTTPConnection]] = {} - self._thread_lock = ThreadLock() - self._backend = backend - self._next_keepalive_check = 0.0 - - if not (http1 or http2): - raise ValueError("Either http1 or http2 must be True.") - - if http2: - try: - import h2 # noqa: F401 - except ImportError: - raise ImportError( - "Attempted to use http2=True, but the 'h2' " - "package is not installed. Use 'pip install httpcore[http2]'." - ) - - @property - def _connection_semaphore(self) -> AsyncSemaphore: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_internal_semaphore"): - if self._max_connections is not None: - self._internal_semaphore = self._backend.create_semaphore( - self._max_connections, exc_class=PoolTimeout - ) - else: - self._internal_semaphore = NullSemaphore() - - return self._internal_semaphore - - @property - def _connection_acquiry_lock(self) -> AsyncLock: - if not hasattr(self, "_internal_connection_acquiry_lock"): - self._internal_connection_acquiry_lock = self._backend.create_lock() - return self._internal_connection_acquiry_lock - - def _create_connection( - self, - origin: Tuple[bytes, bytes, int], - ) -> AsyncHTTPConnection: - return AsyncHTTPConnection( - origin=origin, - http1=self._http1, - http2=self._http2, - keepalive_expiry=self._keepalive_expiry, - uds=self._uds, - ssl_context=self._ssl_context, - local_address=self._local_address, - retries=self._retries, - backend=self._backend, - ) - - async def handle_async_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - if not url[0]: - raise UnsupportedProtocol( - "Request URL missing either an 'http://' or 'https://' protocol." - ) - - if url[0] not in (b"http", b"https"): - protocol = url[0].decode("ascii") - raise UnsupportedProtocol( - f"Request URL has an unsupported protocol '{protocol}://'." - ) - - if not url[1]: - raise LocalProtocolError("Missing hostname in URL.") - - origin = url_to_origin(url) - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - await self._keepalive_sweep() - - connection: Optional[AsyncHTTPConnection] = None - while connection is None: - async with self._connection_acquiry_lock: - # We get-or-create a connection as an atomic operation, to ensure - # that HTTP/2 requests issued in close concurrency will end up - # on the same connection. - logger.trace("get_connection_from_pool=%r", origin) - connection = await self._get_connection_from_pool(origin) - - if connection is None: - connection = self._create_connection(origin=origin) - logger.trace("created connection=%r", connection) - await self._add_to_pool(connection, timeout=timeout) - else: - logger.trace("reuse connection=%r", connection) - - try: - response = await connection.handle_async_request( - method, url, headers=headers, stream=stream, extensions=extensions - ) - except NewConnectionRequired: - connection = None - except BaseException: # noqa: PIE786 - # See https://github.com/encode/httpcore/pull/305 for motivation - # behind catching 'BaseException' rather than 'Exception' here. - logger.trace("remove from pool connection=%r", connection) - await self._remove_from_pool(connection) - raise - - status_code, headers, stream, extensions = response - wrapped_stream = ResponseByteStream( - stream, connection=connection, callback=self._response_closed - ) - return status_code, headers, wrapped_stream, extensions - - async def _get_connection_from_pool( - self, origin: Origin - ) -> Optional[AsyncHTTPConnection]: - # Determine expired keep alive connections on this origin. - reuse_connection = None - connections_to_close = set() - - for connection in self._connections_for_origin(origin): - if connection.should_close(): - connections_to_close.add(connection) - await self._remove_from_pool(connection) - elif connection.is_available(): - reuse_connection = connection - - # Close any dropped connections. - for connection in connections_to_close: - await connection.aclose() - - return reuse_connection - - async def _response_closed(self, connection: AsyncHTTPConnection) -> None: - remove_from_pool = False - close_connection = False - - if connection.is_closed(): - remove_from_pool = True - elif connection.is_idle(): - num_connections = len(self._get_all_connections()) - if ( - self._max_keepalive_connections is not None - and num_connections > self._max_keepalive_connections - ): - remove_from_pool = True - close_connection = True - - if remove_from_pool: - await self._remove_from_pool(connection) - - if close_connection: - await connection.aclose() - - async def _keepalive_sweep(self) -> None: - """ - Remove any IDLE connections that have expired past their keep-alive time. - """ - if self._keepalive_expiry is None: - return - - now = await self._backend.time() - if now < self._next_keepalive_check: - return - - self._next_keepalive_check = now + min(1.0, self._keepalive_expiry) - connections_to_close = set() - - for connection in self._get_all_connections(): - if connection.should_close(): - connections_to_close.add(connection) - await self._remove_from_pool(connection) - - for connection in connections_to_close: - await connection.aclose() - - async def _add_to_pool( - self, connection: AsyncHTTPConnection, timeout: TimeoutDict - ) -> None: - logger.trace("adding connection to pool=%r", connection) - await self._connection_semaphore.acquire(timeout=timeout.get("pool", None)) - async with self._thread_lock: - self._connections.setdefault(connection.origin, set()) - self._connections[connection.origin].add(connection) - - async def _remove_from_pool(self, connection: AsyncHTTPConnection) -> None: - logger.trace("removing connection from pool=%r", connection) - async with self._thread_lock: - if connection in self._connections.get(connection.origin, set()): - await self._connection_semaphore.release() - self._connections[connection.origin].remove(connection) - if not self._connections[connection.origin]: - del self._connections[connection.origin] - - def _connections_for_origin(self, origin: Origin) -> Set[AsyncHTTPConnection]: - return set(self._connections.get(origin, set())) - - def _get_all_connections(self) -> Set[AsyncHTTPConnection]: - connections: Set[AsyncHTTPConnection] = set() - for connection_set in self._connections.values(): - connections |= connection_set - return connections - - async def aclose(self) -> None: - connections = self._get_all_connections() - for connection in connections: - await self._remove_from_pool(connection) - - # Close all connections - for connection in connections: - await connection.aclose() - - async def get_connection_info(self) -> Dict[str, List[str]]: - """ - Returns a dict of origin URLs to a list of summary strings for each connection. - """ - await self._keepalive_sweep() - - stats = {} - for origin, connections in self._connections.items(): - stats[origin_to_url_string(origin)] = sorted( - [connection.info() for connection in connections] - ) - return stats diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http.py deleted file mode 100644 index 06270f0f..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http.py +++ /dev/null @@ -1,42 +0,0 @@ -from ssl import SSLContext - -from .._backends.auto import AsyncSocketStream -from .._types import TimeoutDict -from .base import AsyncHTTPTransport - - -class AsyncBaseHTTPConnection(AsyncHTTPTransport): - def info(self) -> str: - raise NotImplementedError() # pragma: nocover - - def should_close(self) -> bool: - """ - Return `True` if the connection is in a state where it should be closed. - """ - raise NotImplementedError() # pragma: nocover - - def is_idle(self) -> bool: - """ - Return `True` if the connection is currently idle. - """ - raise NotImplementedError() # pragma: nocover - - def is_closed(self) -> bool: - """ - Return `True` if the connection has been closed. - """ - raise NotImplementedError() # pragma: nocover - - def is_available(self) -> bool: - """ - Return `True` if the connection is currently able to accept an outgoing request. - """ - raise NotImplementedError() # pragma: nocover - - async def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict = None - ) -> AsyncSocketStream: - """ - Upgrade the underlying socket to TLS. - """ - raise NotImplementedError() # pragma: nocover diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http11.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http11.py deleted file mode 100644 index a265657c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http11.py +++ /dev/null @@ -1,269 +0,0 @@ -import enum -import time -from ssl import SSLContext -from typing import AsyncIterator, List, Optional, Tuple, Union, cast - -import h11 - -from .._backends.auto import AsyncSocketStream -from .._bytestreams import AsyncIteratorByteStream -from .._exceptions import LocalProtocolError, RemoteProtocolError, map_exceptions -from .._types import URL, Headers, TimeoutDict -from .._utils import get_logger -from .base import AsyncByteStream, NewConnectionRequired -from .http import AsyncBaseHTTPConnection - -H11Event = Union[ - h11.Request, - h11.Response, - h11.InformationalResponse, - h11.Data, - h11.EndOfMessage, - h11.ConnectionClosed, -] - - -class ConnectionState(enum.IntEnum): - NEW = 0 - ACTIVE = 1 - IDLE = 2 - CLOSED = 3 - - -logger = get_logger(__name__) - - -class AsyncHTTP11Connection(AsyncBaseHTTPConnection): - READ_NUM_BYTES = 64 * 1024 - - def __init__(self, socket: AsyncSocketStream, keepalive_expiry: float = None): - self.socket = socket - - self._keepalive_expiry: Optional[float] = keepalive_expiry - self._should_expire_at: Optional[float] = None - self._h11_state = h11.Connection(our_role=h11.CLIENT) - self._state = ConnectionState.NEW - - def __repr__(self) -> str: - return f"" - - def _now(self) -> float: - return time.monotonic() - - def _server_disconnected(self) -> bool: - """ - Return True if the connection is idle, and the underlying socket is readable. - The only valid state the socket can be readable here is when the b"" - EOF marker is about to be returned, indicating a server disconnect. - """ - return self._state == ConnectionState.IDLE and self.socket.is_readable() - - def _keepalive_expired(self) -> bool: - """ - Return True if the connection is idle, and has passed it's keepalive - expiry time. - """ - return ( - self._state == ConnectionState.IDLE - and self._should_expire_at is not None - and self._now() >= self._should_expire_at - ) - - def info(self) -> str: - return f"HTTP/1.1, {self._state.name}" - - def should_close(self) -> bool: - """ - Return `True` if the connection is in a state where it should be closed. - """ - return self._server_disconnected() or self._keepalive_expired() - - def is_idle(self) -> bool: - """ - Return `True` if the connection is currently idle. - """ - return self._state == ConnectionState.IDLE - - def is_closed(self) -> bool: - """ - Return `True` if the connection has been closed. - """ - return self._state == ConnectionState.CLOSED - - def is_available(self) -> bool: - """ - Return `True` if the connection is currently able to accept an outgoing request. - """ - return self._state == ConnectionState.IDLE - - async def handle_async_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - """ - Send a single HTTP/1.1 request. - - Note that there is no kind of task/thread locking at this layer of interface. - Dealing with locking for concurrency is handled by the `AsyncHTTPConnection`. - """ - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - if self._state in (ConnectionState.NEW, ConnectionState.IDLE): - self._state = ConnectionState.ACTIVE - self._should_expire_at = None - else: - raise NewConnectionRequired() - - await self._send_request(method, url, headers, timeout) - await self._send_request_body(stream, timeout) - ( - http_version, - status_code, - reason_phrase, - headers, - ) = await self._receive_response(timeout) - response_stream = AsyncIteratorByteStream( - aiterator=self._receive_response_data(timeout), - aclose_func=self._response_closed, - ) - extensions = { - "http_version": http_version, - "reason_phrase": reason_phrase, - } - return (status_code, headers, response_stream, extensions) - - async def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict = None - ) -> AsyncSocketStream: - timeout = {} if timeout is None else timeout - self.socket = await self.socket.start_tls(hostname, ssl_context, timeout) - return self.socket - - async def _send_request( - self, method: bytes, url: URL, headers: Headers, timeout: TimeoutDict - ) -> None: - """ - Send the request line and headers. - """ - logger.trace("send_request method=%r url=%r headers=%s", method, url, headers) - _scheme, _host, _port, target = url - with map_exceptions({h11.LocalProtocolError: LocalProtocolError}): - event = h11.Request(method=method, target=target, headers=headers) - await self._send_event(event, timeout) - - async def _send_request_body( - self, stream: AsyncByteStream, timeout: TimeoutDict - ) -> None: - """ - Send the request body. - """ - # Send the request body. - async for chunk in stream: - logger.trace("send_data=Data(<%d bytes>)", len(chunk)) - event = h11.Data(data=chunk) - await self._send_event(event, timeout) - - # Finalize sending the request. - event = h11.EndOfMessage() - await self._send_event(event, timeout) - - async def _send_event(self, event: H11Event, timeout: TimeoutDict) -> None: - """ - Send a single `h11` event to the network, waiting for the data to - drain before returning. - """ - bytes_to_send = self._h11_state.send(event) - await self.socket.write(bytes_to_send, timeout) - - async def _receive_response( - self, timeout: TimeoutDict - ) -> Tuple[bytes, int, bytes, List[Tuple[bytes, bytes]]]: - """ - Read the response status and headers from the network. - """ - while True: - event = await self._receive_event(timeout) - if isinstance(event, h11.Response): - break - - http_version = b"HTTP/" + event.http_version - - # h11 version 0.11+ supports a `raw_items` interface to get the - # raw header casing, rather than the enforced lowercase headers. - headers = event.headers.raw_items() - - return http_version, event.status_code, event.reason, headers - - async def _receive_response_data( - self, timeout: TimeoutDict - ) -> AsyncIterator[bytes]: - """ - Read the response data from the network. - """ - while True: - event = await self._receive_event(timeout) - if isinstance(event, h11.Data): - logger.trace("receive_event=Data(<%d bytes>)", len(event.data)) - yield bytes(event.data) - elif isinstance(event, (h11.EndOfMessage, h11.PAUSED)): - logger.trace("receive_event=%r", event) - break - - async def _receive_event(self, timeout: TimeoutDict) -> H11Event: - """ - Read a single `h11` event, reading more data from the network if needed. - """ - while True: - with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}): - event = self._h11_state.next_event() - - if event is h11.NEED_DATA: - data = await self.socket.read(self.READ_NUM_BYTES, timeout) - - # If we feed this case through h11 we'll raise an exception like: - # - # httpcore.RemoteProtocolError: can't handle event type - # ConnectionClosed when role=SERVER and state=SEND_RESPONSE - # - # Which is accurate, but not very informative from an end-user - # perspective. Instead we handle messaging for this case distinctly. - if data == b"" and self._h11_state.their_state == h11.SEND_RESPONSE: - msg = "Server disconnected without sending a response." - raise RemoteProtocolError(msg) - - self._h11_state.receive_data(data) - else: - assert event is not h11.NEED_DATA - break - return event - - async def _response_closed(self) -> None: - logger.trace( - "response_closed our_state=%r their_state=%r", - self._h11_state.our_state, - self._h11_state.their_state, - ) - if ( - self._h11_state.our_state is h11.DONE - and self._h11_state.their_state is h11.DONE - ): - self._h11_state.start_next_cycle() - self._state = ConnectionState.IDLE - if self._keepalive_expiry is not None: - self._should_expire_at = self._now() + self._keepalive_expiry - else: - await self.aclose() - - async def aclose(self) -> None: - if self._state != ConnectionState.CLOSED: - self._state = ConnectionState.CLOSED - - if self._h11_state.our_state is h11.MUST_CLOSE: - event = h11.ConnectionClosed() - self._h11_state.send(event) - - await self.socket.aclose() diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http2.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http2.py deleted file mode 100644 index 35a4e091..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http2.py +++ /dev/null @@ -1,446 +0,0 @@ -import enum -import time -from ssl import SSLContext -from typing import AsyncIterator, Dict, List, Optional, Tuple, cast - -import h2.connection -import h2.events -from h2.config import H2Configuration -from h2.exceptions import NoAvailableStreamIDError -from h2.settings import SettingCodes, Settings - -from .._backends.auto import AsyncBackend, AsyncLock, AsyncSemaphore, AsyncSocketStream -from .._bytestreams import AsyncIteratorByteStream -from .._exceptions import LocalProtocolError, PoolTimeout, RemoteProtocolError -from .._types import URL, Headers, TimeoutDict -from .._utils import get_logger -from .base import AsyncByteStream, NewConnectionRequired -from .http import AsyncBaseHTTPConnection - -logger = get_logger(__name__) - - -class ConnectionState(enum.IntEnum): - IDLE = 0 - ACTIVE = 1 - CLOSED = 2 - - -class AsyncHTTP2Connection(AsyncBaseHTTPConnection): - READ_NUM_BYTES = 64 * 1024 - CONFIG = H2Configuration(validate_inbound_headers=False) - - def __init__( - self, - socket: AsyncSocketStream, - backend: AsyncBackend, - keepalive_expiry: float = None, - ): - self.socket = socket - - self._backend = backend - self._h2_state = h2.connection.H2Connection(config=self.CONFIG) - - self._sent_connection_init = False - self._streams: Dict[int, AsyncHTTP2Stream] = {} - self._events: Dict[int, List[h2.events.Event]] = {} - - self._keepalive_expiry: Optional[float] = keepalive_expiry - self._should_expire_at: Optional[float] = None - self._state = ConnectionState.ACTIVE - self._exhausted_available_stream_ids = False - - def __repr__(self) -> str: - return f"" - - def info(self) -> str: - return f"HTTP/2, {self._state.name}, {len(self._streams)} streams" - - def _now(self) -> float: - return time.monotonic() - - def should_close(self) -> bool: - """ - Return `True` if the connection is currently idle, and the keepalive - timeout has passed. - """ - return ( - self._state == ConnectionState.IDLE - and self._should_expire_at is not None - and self._now() >= self._should_expire_at - ) - - def is_idle(self) -> bool: - """ - Return `True` if the connection is currently idle. - """ - return self._state == ConnectionState.IDLE - - def is_closed(self) -> bool: - """ - Return `True` if the connection has been closed. - """ - return self._state == ConnectionState.CLOSED - - def is_available(self) -> bool: - """ - Return `True` if the connection is currently able to accept an outgoing request. - This occurs when any of the following occur: - - * The connection has not yet been opened, and HTTP/2 support is enabled. - We don't *know* at this point if we'll end up on an HTTP/2 connection or - not, but we *might* do, so we indicate availability. - * The connection has been opened, and is currently idle. - * The connection is open, and is an HTTP/2 connection. The connection must - also not have exhausted the maximum total number of stream IDs. - """ - return ( - self._state != ConnectionState.CLOSED - and not self._exhausted_available_stream_ids - ) - - @property - def init_lock(self) -> AsyncLock: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_initialization_lock"): - self._initialization_lock = self._backend.create_lock() - return self._initialization_lock - - @property - def read_lock(self) -> AsyncLock: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_read_lock"): - self._read_lock = self._backend.create_lock() - return self._read_lock - - @property - def max_streams_semaphore(self) -> AsyncSemaphore: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_max_streams_semaphore"): - max_streams = self._h2_state.local_settings.max_concurrent_streams - self._max_streams_semaphore = self._backend.create_semaphore( - max_streams, exc_class=PoolTimeout - ) - return self._max_streams_semaphore - - async def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict = None - ) -> AsyncSocketStream: - raise NotImplementedError("TLS upgrade not supported on HTTP/2 connections.") - - async def handle_async_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - async with self.init_lock: - if not self._sent_connection_init: - # The very first stream is responsible for initiating the connection. - self._state = ConnectionState.ACTIVE - await self.send_connection_init(timeout) - self._sent_connection_init = True - - await self.max_streams_semaphore.acquire() - try: - try: - stream_id = self._h2_state.get_next_available_stream_id() - except NoAvailableStreamIDError: - self._exhausted_available_stream_ids = True - raise NewConnectionRequired() - else: - self._state = ConnectionState.ACTIVE - self._should_expire_at = None - - h2_stream = AsyncHTTP2Stream(stream_id=stream_id, connection=self) - self._streams[stream_id] = h2_stream - self._events[stream_id] = [] - return await h2_stream.handle_async_request( - method, url, headers, stream, extensions - ) - except Exception: # noqa: PIE786 - await self.max_streams_semaphore.release() - raise - - async def send_connection_init(self, timeout: TimeoutDict) -> None: - """ - The HTTP/2 connection requires some initial setup before we can start - using individual request/response streams on it. - """ - # Need to set these manually here instead of manipulating via - # __setitem__() otherwise the H2Connection will emit SettingsUpdate - # frames in addition to sending the undesired defaults. - self._h2_state.local_settings = Settings( - client=True, - initial_values={ - # Disable PUSH_PROMISE frames from the server since we don't do anything - # with them for now. Maybe when we support caching? - SettingCodes.ENABLE_PUSH: 0, - # These two are taken from h2 for safe defaults - SettingCodes.MAX_CONCURRENT_STREAMS: 100, - SettingCodes.MAX_HEADER_LIST_SIZE: 65536, - }, - ) - - # Some websites (*cough* Yahoo *cough*) balk at this setting being - # present in the initial handshake since it's not defined in the original - # RFC despite the RFC mandating ignoring settings you don't know about. - del self._h2_state.local_settings[ - h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL - ] - - logger.trace("initiate_connection=%r", self) - self._h2_state.initiate_connection() - self._h2_state.increment_flow_control_window(2 ** 24) - data_to_send = self._h2_state.data_to_send() - await self.socket.write(data_to_send, timeout) - - def is_socket_readable(self) -> bool: - return self.socket.is_readable() - - async def aclose(self) -> None: - logger.trace("close_connection=%r", self) - if self._state != ConnectionState.CLOSED: - self._state = ConnectionState.CLOSED - - await self.socket.aclose() - - async def wait_for_outgoing_flow(self, stream_id: int, timeout: TimeoutDict) -> int: - """ - Returns the maximum allowable outgoing flow for a given stream. - If the allowable flow is zero, then waits on the network until - WindowUpdated frames have increased the flow rate. - https://tools.ietf.org/html/rfc7540#section-6.9 - """ - local_flow = self._h2_state.local_flow_control_window(stream_id) - connection_flow = self._h2_state.max_outbound_frame_size - flow = min(local_flow, connection_flow) - while flow == 0: - await self.receive_events(timeout) - local_flow = self._h2_state.local_flow_control_window(stream_id) - connection_flow = self._h2_state.max_outbound_frame_size - flow = min(local_flow, connection_flow) - return flow - - async def wait_for_event( - self, stream_id: int, timeout: TimeoutDict - ) -> h2.events.Event: - """ - Returns the next event for a given stream. - If no events are available yet, then waits on the network until - an event is available. - """ - async with self.read_lock: - while not self._events[stream_id]: - await self.receive_events(timeout) - return self._events[stream_id].pop(0) - - async def receive_events(self, timeout: TimeoutDict) -> None: - """ - Read some data from the network, and update the H2 state. - """ - data = await self.socket.read(self.READ_NUM_BYTES, timeout) - if data == b"": - raise RemoteProtocolError("Server disconnected") - - events = self._h2_state.receive_data(data) - for event in events: - event_stream_id = getattr(event, "stream_id", 0) - logger.trace("receive_event stream_id=%r event=%s", event_stream_id, event) - - if hasattr(event, "error_code"): - raise RemoteProtocolError(event) - - if event_stream_id in self._events: - self._events[event_stream_id].append(event) - - data_to_send = self._h2_state.data_to_send() - await self.socket.write(data_to_send, timeout) - - async def send_headers( - self, stream_id: int, headers: Headers, end_stream: bool, timeout: TimeoutDict - ) -> None: - logger.trace("send_headers stream_id=%r headers=%r", stream_id, headers) - self._h2_state.send_headers(stream_id, headers, end_stream=end_stream) - self._h2_state.increment_flow_control_window(2 ** 24, stream_id=stream_id) - data_to_send = self._h2_state.data_to_send() - await self.socket.write(data_to_send, timeout) - - async def send_data( - self, stream_id: int, chunk: bytes, timeout: TimeoutDict - ) -> None: - logger.trace("send_data stream_id=%r chunk=%r", stream_id, chunk) - self._h2_state.send_data(stream_id, chunk) - data_to_send = self._h2_state.data_to_send() - await self.socket.write(data_to_send, timeout) - - async def end_stream(self, stream_id: int, timeout: TimeoutDict) -> None: - logger.trace("end_stream stream_id=%r", stream_id) - self._h2_state.end_stream(stream_id) - data_to_send = self._h2_state.data_to_send() - await self.socket.write(data_to_send, timeout) - - async def acknowledge_received_data( - self, stream_id: int, amount: int, timeout: TimeoutDict - ) -> None: - self._h2_state.acknowledge_received_data(amount, stream_id) - data_to_send = self._h2_state.data_to_send() - await self.socket.write(data_to_send, timeout) - - async def close_stream(self, stream_id: int) -> None: - try: - logger.trace("close_stream stream_id=%r", stream_id) - del self._streams[stream_id] - del self._events[stream_id] - - if not self._streams: - if self._state == ConnectionState.ACTIVE: - if self._exhausted_available_stream_ids: - await self.aclose() - else: - self._state = ConnectionState.IDLE - if self._keepalive_expiry is not None: - self._should_expire_at = ( - self._now() + self._keepalive_expiry - ) - finally: - await self.max_streams_semaphore.release() - - -class AsyncHTTP2Stream: - def __init__(self, stream_id: int, connection: AsyncHTTP2Connection) -> None: - self.stream_id = stream_id - self.connection = connection - - async def handle_async_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - headers = [(k.lower(), v) for (k, v) in headers] - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - # Send the request. - seen_headers = set(key for key, value in headers) - has_body = ( - b"content-length" in seen_headers or b"transfer-encoding" in seen_headers - ) - - await self.send_headers(method, url, headers, has_body, timeout) - if has_body: - await self.send_body(stream, timeout) - - # Receive the response. - status_code, headers = await self.receive_response(timeout) - response_stream = AsyncIteratorByteStream( - aiterator=self.body_iter(timeout), aclose_func=self._response_closed - ) - - extensions = { - "http_version": b"HTTP/2", - } - return (status_code, headers, response_stream, extensions) - - async def send_headers( - self, - method: bytes, - url: URL, - headers: Headers, - has_body: bool, - timeout: TimeoutDict, - ) -> None: - scheme, hostname, port, path = url - - # In HTTP/2 the ':authority' pseudo-header is used instead of 'Host'. - # In order to gracefully handle HTTP/1.1 and HTTP/2 we always require - # HTTP/1.1 style headers, and map them appropriately if we end up on - # an HTTP/2 connection. - authority = None - - for k, v in headers: - if k == b"host": - authority = v - break - - if authority is None: - # Mirror the same error we'd see with `h11`, so that the behaviour - # is consistent. Although we're dealing with an `:authority` - # pseudo-header by this point, from an end-user perspective the issue - # is that the outgoing request needed to include a `host` header. - raise LocalProtocolError("Missing mandatory Host: header") - - headers = [ - (b":method", method), - (b":authority", authority), - (b":scheme", scheme), - (b":path", path), - ] + [ - (k, v) - for k, v in headers - if k - not in ( - b"host", - b"transfer-encoding", - ) - ] - end_stream = not has_body - - await self.connection.send_headers(self.stream_id, headers, end_stream, timeout) - - async def send_body(self, stream: AsyncByteStream, timeout: TimeoutDict) -> None: - async for data in stream: - while data: - max_flow = await self.connection.wait_for_outgoing_flow( - self.stream_id, timeout - ) - chunk_size = min(len(data), max_flow) - chunk, data = data[:chunk_size], data[chunk_size:] - await self.connection.send_data(self.stream_id, chunk, timeout) - - await self.connection.end_stream(self.stream_id, timeout) - - async def receive_response( - self, timeout: TimeoutDict - ) -> Tuple[int, List[Tuple[bytes, bytes]]]: - """ - Read the response status and headers from the network. - """ - while True: - event = await self.connection.wait_for_event(self.stream_id, timeout) - if isinstance(event, h2.events.ResponseReceived): - break - - status_code = 200 - headers = [] - for k, v in event.headers: - if k == b":status": - status_code = int(v.decode("ascii", errors="ignore")) - elif not k.startswith(b":"): - headers.append((k, v)) - - return (status_code, headers) - - async def body_iter(self, timeout: TimeoutDict) -> AsyncIterator[bytes]: - while True: - event = await self.connection.wait_for_event(self.stream_id, timeout) - if isinstance(event, h2.events.DataReceived): - amount = event.flow_controlled_length - await self.connection.acknowledge_received_data( - self.stream_id, amount, timeout - ) - yield event.data - elif isinstance(event, (h2.events.StreamEnded, h2.events.StreamReset)): - break - - async def _response_closed(self) -> None: - await self.connection.close_stream(self.stream_id) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http_proxy.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http_proxy.py deleted file mode 100644 index 275bf214..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_async/http_proxy.py +++ /dev/null @@ -1,290 +0,0 @@ -from http import HTTPStatus -from ssl import SSLContext -from typing import Tuple, cast - -from .._bytestreams import ByteStream -from .._exceptions import ProxyError -from .._types import URL, Headers, TimeoutDict -from .._utils import get_logger, url_to_origin -from .base import AsyncByteStream -from .connection import AsyncHTTPConnection -from .connection_pool import AsyncConnectionPool, ResponseByteStream - -logger = get_logger(__name__) - - -def get_reason_phrase(status_code: int) -> str: - try: - return HTTPStatus(status_code).phrase - except ValueError: - return "" - - -def merge_headers( - default_headers: Headers = None, override_headers: Headers = None -) -> Headers: - """ - Append default_headers and override_headers, de-duplicating if a key existing in - both cases. - """ - default_headers = [] if default_headers is None else default_headers - override_headers = [] if override_headers is None else override_headers - has_override = set([key.lower() for key, value in override_headers]) - default_headers = [ - (key, value) - for key, value in default_headers - if key.lower() not in has_override - ] - return default_headers + override_headers - - -class AsyncHTTPProxy(AsyncConnectionPool): - """ - A connection pool for making HTTP requests via an HTTP proxy. - - Parameters - ---------- - proxy_url: - The URL of the proxy service as a 4-tuple of (scheme, host, port, path). - proxy_headers: - A list of proxy headers to include. - proxy_mode: - A proxy mode to operate in. May be "DEFAULT", "FORWARD_ONLY", or "TUNNEL_ONLY". - ssl_context: - An SSL context to use for verifying connections. - max_connections: - The maximum number of concurrent connections to allow. - max_keepalive_connections: - The maximum number of connections to allow before closing keep-alive - connections. - http2: - Enable HTTP/2 support. - """ - - def __init__( - self, - proxy_url: URL, - proxy_headers: Headers = None, - proxy_mode: str = "DEFAULT", - ssl_context: SSLContext = None, - max_connections: int = None, - max_keepalive_connections: int = None, - keepalive_expiry: float = None, - http2: bool = False, - backend: str = "auto", - # Deprecated argument style: - max_keepalive: int = None, - ): - assert proxy_mode in ("DEFAULT", "FORWARD_ONLY", "TUNNEL_ONLY") - - self.proxy_origin = url_to_origin(proxy_url) - self.proxy_headers = [] if proxy_headers is None else proxy_headers - self.proxy_mode = proxy_mode - super().__init__( - ssl_context=ssl_context, - max_connections=max_connections, - max_keepalive_connections=max_keepalive_connections, - keepalive_expiry=keepalive_expiry, - http2=http2, - backend=backend, - max_keepalive=max_keepalive, - ) - - async def handle_async_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - if self._keepalive_expiry is not None: - await self._keepalive_sweep() - - if ( - self.proxy_mode == "DEFAULT" and url[0] == b"http" - ) or self.proxy_mode == "FORWARD_ONLY": - # By default HTTP requests should be forwarded. - logger.trace( - "forward_request proxy_origin=%r proxy_headers=%r method=%r url=%r", - self.proxy_origin, - self.proxy_headers, - method, - url, - ) - return await self._forward_request( - method, url, headers=headers, stream=stream, extensions=extensions - ) - else: - # By default HTTPS should be tunnelled. - logger.trace( - "tunnel_request proxy_origin=%r proxy_headers=%r method=%r url=%r", - self.proxy_origin, - self.proxy_headers, - method, - url, - ) - return await self._tunnel_request( - method, url, headers=headers, stream=stream, extensions=extensions - ) - - async def _forward_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - """ - Forwarded proxy requests include the entire URL as the HTTP target, - rather than just the path. - """ - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - origin = self.proxy_origin - connection = await self._get_connection_from_pool(origin) - - if connection is None: - connection = AsyncHTTPConnection( - origin=origin, - http2=self._http2, - keepalive_expiry=self._keepalive_expiry, - ssl_context=self._ssl_context, - ) - await self._add_to_pool(connection, timeout) - - # Issue a forwarded proxy request... - - # GET https://www.example.org/path HTTP/1.1 - # [proxy headers] - # [headers] - scheme, host, port, path = url - if port is None: - target = b"%b://%b%b" % (scheme, host, path) - else: - target = b"%b://%b:%d%b" % (scheme, host, port, path) - - url = self.proxy_origin + (target,) - headers = merge_headers(self.proxy_headers, headers) - - ( - status_code, - headers, - stream, - extensions, - ) = await connection.handle_async_request( - method, url, headers=headers, stream=stream, extensions=extensions - ) - - wrapped_stream = ResponseByteStream( - stream, connection=connection, callback=self._response_closed - ) - - return status_code, headers, wrapped_stream, extensions - - async def _tunnel_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: AsyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, AsyncByteStream, dict]: - """ - Tunnelled proxy requests require an initial CONNECT request to - establish the connection, and then send regular requests. - """ - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - origin = url_to_origin(url) - connection = await self._get_connection_from_pool(origin) - - if connection is None: - scheme, host, port = origin - - # First, create a connection to the proxy server - proxy_connection = AsyncHTTPConnection( - origin=self.proxy_origin, - http2=self._http2, - keepalive_expiry=self._keepalive_expiry, - ssl_context=self._ssl_context, - ) - - # Issue a CONNECT request... - - # CONNECT www.example.org:80 HTTP/1.1 - # [proxy-headers] - target = b"%b:%d" % (host, port) - connect_url = self.proxy_origin + (target,) - connect_headers = [(b"Host", target), (b"Accept", b"*/*")] - connect_headers = merge_headers(connect_headers, self.proxy_headers) - - try: - ( - proxy_status_code, - _, - proxy_stream, - _, - ) = await proxy_connection.handle_async_request( - b"CONNECT", - connect_url, - headers=connect_headers, - stream=ByteStream(b""), - extensions=extensions, - ) - - proxy_reason = get_reason_phrase(proxy_status_code) - logger.trace( - "tunnel_response proxy_status_code=%r proxy_reason=%r ", - proxy_status_code, - proxy_reason, - ) - # Read the response data without closing the socket - async for _ in proxy_stream: - pass - - # See if the tunnel was successfully established. - if proxy_status_code < 200 or proxy_status_code > 299: - msg = "%d %s" % (proxy_status_code, proxy_reason) - raise ProxyError(msg) - - # Upgrade to TLS if required - # We assume the target speaks TLS on the specified port - if scheme == b"https": - await proxy_connection.start_tls(host, self._ssl_context, timeout) - except Exception as exc: - await proxy_connection.aclose() - raise ProxyError(exc) - - # The CONNECT request is successful, so we have now SWITCHED PROTOCOLS. - # This means the proxy connection is now unusable, and we must create - # a new one for regular requests, making sure to use the same socket to - # retain the tunnel. - connection = AsyncHTTPConnection( - origin=origin, - http2=self._http2, - keepalive_expiry=self._keepalive_expiry, - ssl_context=self._ssl_context, - socket=proxy_connection.socket, - ) - await self._add_to_pool(connection, timeout) - - # Once the connection has been established we can send requests on - # it as normal. - ( - status_code, - headers, - stream, - extensions, - ) = await connection.handle_async_request( - method, - url, - headers=headers, - stream=stream, - extensions=extensions, - ) - - wrapped_stream = ResponseByteStream( - stream, connection=connection, callback=self._response_closed - ) - - return status_code, headers, wrapped_stream, extensions diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 97c5b4aeb404b536d8b8361e477da4765e2df5d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182 zcmYe~<>g`kf`|Vc6G8N25P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_?i&acOWkyMU zUQAJ9UP^v$OmK2Wetu4jr?;zPd~tG7VnJ$Aj9yu4URjJ!W>QRXW=X1UL1J=tVtQ(E yOh!pbL2`aks(ySDP$)GorC2{cJ~J<~BtBlRpz;=nO>TZlX-=vg$kNY1%m4sS)iC`4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/anyio.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/anyio.cpython-39.pyc deleted file mode 100644 index 7e5b55729697a53dcfce8a163ede6d87e570c369..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7045 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/auto.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/auto.cpython-39.pyc deleted file mode 100644 index ebbfd07f956ff7411109f7f17bad53e4701783a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2523 zcmZuzOK%)S5T2g*?##aII8I0a^JXD&as@>Y$B7^iIfxBH8m%-MPq(uh&x`KfC~K`H zgmdM}1tZ1cl;4qm(Ko~?{{ZCxRL$(fYs)QlZC6)U_gB?l^=#B?H8p5|{kswU>1x{F zs4O-Ul$+2+0fK6jBw9)WLU61ndTInlIW`hAFsVtc#7gbJhB=!$iIcj4n>K<*+6%uNQwnY6ygSKcJW|rBx(%zw6&{ja}(WOJ3F4J?MpQk-Y^NR8|CNiI=3KDE{CMP_L zF_U$(U|>Msgf4ytA+;Is;XoIAl04Iow0$yzfOd6$of_0kjMUuMi8j*@U|ncs-+lRq;#7>=kV9v~#Td#oC0c!$QHv!J_%yJh zYzm;30Tl0{IEP{d#d#E~Ae8_8B$L4BJDlgdZz)r-WJfvk^D5`k1y?`U_?z(a>c`uk z55Jp^WS$Lql+ipL4&qUsC&Rnn-q{F6%%g(w;re5iJs#d0Zx6*-va1CoFM7zta3p0B zLoHmZ^C_-Hz=-u?$}hw2ZRp|+5Srd3uI>^ae~+c!CVR^Z6k4BS?c2&7Ybf49@h%GVD^psD zw@`f_1kMY@p*3vM{BQ5lV!WsKhf6CWIjRmg-upycxE02TdzNusfC0w!>~&m6W*yUW zvUM_;2^DoPRu#+#;C}i*q{c!VAAx!uy1-{sbIyq2c-s@jk9UARo6rS*F)Ex#kZt}U zs5Le(hUZhV5Uz9gIjL}+!tgOH{|vV&F_690#XK&!_YKuZqbK3xD48(TU{B&OPNJF| z2JBEb9OHMY1cxa;CI`?$uL?g2@gh=miXc2Z%v&(Rm4#DFzp8IL1ts zFz~UdsdhvvAov|Wb)A+-7%L!YWwoq>)9JKagSlJK>$LP1K~>(X$_+z&0m4u;x4z{Y diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/base.cpython-39.pyc deleted file mode 100644 index 35cdaae41d81ba737a908efe76e8186b2245e40e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5284 zcmb_gTW=f372Z3SS5cSPx!BFd=#8x{H*MOYX`1R{)mH7&0VJddp<=Px8Ci^$TxMn| zTdIWuwhQ#Bzd#Qy&=>!X{DnO2ThS-~gCZ@0erI-9Bt^OkTCcE&bLO0xIdkTmZ_X;H z*DD&HzkjtFe9_Rfe-JbNm|#}$%D;gyjp>or(>uCOZ6h*zX2(=*GqQSi$L={Dr&sEf z&}T6_a(m@YS=YEN?l6ayqDrsYse-RDmz7TqR$b)nZZnQ z>j~WYSbwT*k;H=JJxFYF@`(Y7kxLv%+K`mU6eyknBTJj&KMk79>_KsX+1s zk}4g^i4BQOlBB|FPxU7{L%UUPr&cgbVo`=|@K|*fOtH;UK-=ub=x?YUch5vtB2<5M z8^49V9S*bJ+B!APx`Y0aQm(D`k2de;-N#oq`-ef)W!`S)RgawL{hsJM;-pm-b1+FX ziOdsOAhJkgiO6e2E)ls*qAx|mx_%7wAtgg{y#8cY@6z;8&* z_+x`v!7Bv_*E$HQj=}Vf$t`A_>da&oa@*z(FL9S?%s#aU6VO-Y74C9}xu+&8vkH2u z&~jOo)zFh+LJb_vLbyPP(NG-Wg4LO0RfO+iI8wpNnpYK$hGKqd>~*Ua}t~-b1iK-y5P^EgwV}-wzV5W-CJGx)%#? z53fuRfj5FE?sG5UGQnWU<+4(Kt_wi*WHb=a(5t|OjyutwYFT1G*V_QC#de%*_68B} zaahh&VxZfSJlZ=S0nGrq(DT(a7gK6y0QjriKwx>u*y9n)+zQ`h$?aD6|m_D!-(27-~VhFM7gBo`z#L8 zZ2~RCw=sQc?;ash1!akFiF}WGO@M>APV6#~o789R;!+VmAbu3NszvxK-Ugwul0eHpn>o;?g&Po2bTsloqRVAn+R+p)e#4Ft~*J z$?mwhUWUKroC5-5RD~J9*G5`ap1TJqJ$^UC)xHn6FWYjFK*|4BDvcM)!uw1MGnwYF`*L7_F|?8JDW^HMy$DuKfNg zcDY<6s0W=_6hw5!d;ew0BG>eGt28T)QhP6ogCq+R6)-A7Mnu8w8dmrntwI5ZSOLrm z>YIv-5;|A#%4Z-&TyT`PIi!~G>jGNKOg}{|Fq5DYg{^reFEi`ZW;Symsp6xz1YpL8 zFt|EqY4AB#LBX4WZj;X|c~<@|fJ5nv$jeIJMK(tzuc*NkeBMw!lv;yWB%`V*tw(Vf zM1H`S;8JF=MnyV36biK8i$lU0tGI4q#ApGrLF}YA(>c`AeLo2YepYKAKqm{C^6?b~ zZ233e@;SwpjSU3J{`uNYRX~N=m`tPg#b(=?*|(v5e#V&=51Gs@KE#mB;?gXOM~bsA zG%{_Srg&KmJM#*whA34M?&HV~{%~f1ew-Cah0Dg2P$rgp!K32#qKiy@ZDhx6Vv6FS z_Ju~Z^7{4HP!@EFodz8W-0E&6o$KL)ZLseP;wOGeGIHg!M9it7*QP$c~~rl!~QC8K6odd+OU(R3PD8kZaO{{W?t BS|x$#BsCGw5Mu!XFQip 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 UpD!Bf=CdVSI9RpwwWV6^KhH9EumAu6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/trio.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/__pycache__/trio.cpython-39.pyc deleted file mode 100644 index 053e78f2575499a304fad08987220b46cbf8797d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7260 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/anyio.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/anyio.py deleted file mode 100644 index b1332a27..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/anyio.py +++ /dev/null @@ -1,201 +0,0 @@ -from ssl import SSLContext -from typing import Optional - -import anyio.abc -from anyio import BrokenResourceError, EndOfStream -from anyio.abc import ByteStream, SocketAttribute -from anyio.streams.tls import TLSAttribute, TLSStream - -from .._exceptions import ( - ConnectError, - ConnectTimeout, - ReadError, - ReadTimeout, - WriteError, - WriteTimeout, - map_exceptions, -) -from .._types import TimeoutDict -from .._utils import is_socket_readable -from .base import AsyncBackend, AsyncLock, AsyncSemaphore, AsyncSocketStream - - -class SocketStream(AsyncSocketStream): - def __init__(self, stream: ByteStream) -> None: - self.stream = stream - self.read_lock = anyio.Lock() - self.write_lock = anyio.Lock() - - def get_http_version(self) -> str: - alpn_protocol = self.stream.extra(TLSAttribute.alpn_protocol, None) - return "HTTP/2" if alpn_protocol == "h2" else "HTTP/1.1" - - async def start_tls( - self, - hostname: bytes, - ssl_context: SSLContext, - timeout: TimeoutDict, - ) -> "SocketStream": - connect_timeout = timeout.get("connect") - try: - with anyio.fail_after(connect_timeout): - ssl_stream = await TLSStream.wrap( - self.stream, - ssl_context=ssl_context, - hostname=hostname.decode("ascii"), - standard_compatible=False, - ) - except TimeoutError: - raise ConnectTimeout from None - except BrokenResourceError as exc: - raise ConnectError from exc - - return SocketStream(ssl_stream) - - async def read(self, n: int, timeout: TimeoutDict) -> bytes: - read_timeout = timeout.get("read") - async with self.read_lock: - try: - with anyio.fail_after(read_timeout): - return await self.stream.receive(n) - except TimeoutError: - await self.stream.aclose() - raise ReadTimeout from None - except BrokenResourceError as exc: - raise ReadError from exc - except EndOfStream: - return b"" - - async def write(self, data: bytes, timeout: TimeoutDict) -> None: - if not data: - return - - write_timeout = timeout.get("write") - async with self.write_lock: - try: - with anyio.fail_after(write_timeout): - return await self.stream.send(data) - except TimeoutError: - await self.stream.aclose() - raise WriteTimeout from None - except BrokenResourceError as exc: - raise WriteError from exc - - async def aclose(self) -> None: - async with self.write_lock: - try: - await self.stream.aclose() - except BrokenResourceError: - pass - - def is_readable(self) -> bool: - sock = self.stream.extra(SocketAttribute.raw_socket) - return is_socket_readable(sock) - - -class Lock(AsyncLock): - def __init__(self) -> None: - self._lock = anyio.Lock() - - async def release(self) -> None: - self._lock.release() - - async def acquire(self) -> None: - await self._lock.acquire() - - -class Semaphore(AsyncSemaphore): - def __init__(self, max_value: int, exc_class: type): - self.max_value = max_value - self.exc_class = exc_class - - @property - def semaphore(self) -> anyio.abc.Semaphore: - if not hasattr(self, "_semaphore"): - self._semaphore = anyio.Semaphore(self.max_value) - return self._semaphore - - async def acquire(self, timeout: float = None) -> None: - with anyio.move_on_after(timeout): - await self.semaphore.acquire() - return - - raise self.exc_class() - - async def release(self) -> None: - self.semaphore.release() - - -class AnyIOBackend(AsyncBackend): - async def open_tcp_stream( - self, - hostname: bytes, - port: int, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - *, - local_address: Optional[str], - ) -> AsyncSocketStream: - connect_timeout = timeout.get("connect") - unicode_host = hostname.decode("utf-8") - exc_map = { - TimeoutError: ConnectTimeout, - OSError: ConnectError, - BrokenResourceError: ConnectError, - } - - with map_exceptions(exc_map): - with anyio.fail_after(connect_timeout): - stream: anyio.abc.ByteStream - stream = await anyio.connect_tcp( - unicode_host, port, local_host=local_address - ) - if ssl_context: - stream = await TLSStream.wrap( - stream, - hostname=unicode_host, - ssl_context=ssl_context, - standard_compatible=False, - ) - - return SocketStream(stream=stream) - - async def open_uds_stream( - self, - path: str, - hostname: bytes, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - ) -> AsyncSocketStream: - connect_timeout = timeout.get("connect") - unicode_host = hostname.decode("utf-8") - exc_map = { - TimeoutError: ConnectTimeout, - OSError: ConnectError, - BrokenResourceError: ConnectError, - } - - with map_exceptions(exc_map): - with anyio.fail_after(connect_timeout): - stream: anyio.abc.ByteStream = await anyio.connect_unix(path) - if ssl_context: - stream = await TLSStream.wrap( - stream, - hostname=unicode_host, - ssl_context=ssl_context, - standard_compatible=False, - ) - - return SocketStream(stream=stream) - - def create_lock(self) -> AsyncLock: - return Lock() - - def create_semaphore(self, max_value: int, exc_class: type) -> AsyncSemaphore: - return Semaphore(max_value, exc_class=exc_class) - - async def time(self) -> float: - return float(anyio.current_time()) - - async def sleep(self, seconds: float) -> None: - await anyio.sleep(seconds) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/asyncio.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/asyncio.py deleted file mode 100644 index 5142072e..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/asyncio.py +++ /dev/null @@ -1,303 +0,0 @@ -import asyncio -import socket -from ssl import SSLContext -from typing import Optional - -from .._exceptions import ( - ConnectError, - ConnectTimeout, - ReadError, - ReadTimeout, - WriteError, - WriteTimeout, - map_exceptions, -) -from .._types import TimeoutDict -from .._utils import is_socket_readable -from .base import AsyncBackend, AsyncLock, AsyncSemaphore, AsyncSocketStream - -SSL_MONKEY_PATCH_APPLIED = False - - -def ssl_monkey_patch() -> None: - """ - Monkey-patch for https://bugs.python.org/issue36709 - - This prevents console errors when outstanding HTTPS connections - still exist at the point of exiting. - - Clients which have been opened using a `with` block, or which have - had `close()` closed, will not exhibit this issue in the first place. - """ - MonkeyPatch = asyncio.selector_events._SelectorSocketTransport # type: ignore - - _write = MonkeyPatch.write - - def _fixed_write(self, data: bytes) -> None: # type: ignore - if self._loop and not self._loop.is_closed(): - _write(self, data) - - MonkeyPatch.write = _fixed_write - - -async def backport_start_tls( - transport: asyncio.BaseTransport, - protocol: asyncio.BaseProtocol, - ssl_context: SSLContext, - *, - server_side: bool = False, - server_hostname: str = None, - ssl_handshake_timeout: float = None, -) -> asyncio.Transport: # pragma: nocover (Since it's not used on all Python versions.) - """ - Python 3.6 asyncio doesn't have a start_tls() method on the loop - so we use this function in place of the loop's start_tls() method. - Adapted from this comment: - https://github.com/urllib3/urllib3/issues/1323#issuecomment-362494839 - """ - import asyncio.sslproto - - loop = asyncio.get_event_loop() - waiter = loop.create_future() - ssl_protocol = asyncio.sslproto.SSLProtocol( - loop, - protocol, - ssl_context, - waiter, - server_side=False, - server_hostname=server_hostname, - call_connection_made=False, - ) - - transport.set_protocol(ssl_protocol) - loop.call_soon(ssl_protocol.connection_made, transport) - loop.call_soon(transport.resume_reading) # type: ignore - - await waiter - return ssl_protocol._app_transport - - -class SocketStream(AsyncSocketStream): - def __init__( - self, stream_reader: asyncio.StreamReader, stream_writer: asyncio.StreamWriter - ): - self.stream_reader = stream_reader - self.stream_writer = stream_writer - self.read_lock = asyncio.Lock() - self.write_lock = asyncio.Lock() - - def get_http_version(self) -> str: - ssl_object = self.stream_writer.get_extra_info("ssl_object") - - if ssl_object is None: - return "HTTP/1.1" - - ident = ssl_object.selected_alpn_protocol() - return "HTTP/2" if ident == "h2" else "HTTP/1.1" - - async def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict - ) -> "SocketStream": - loop = asyncio.get_event_loop() - - stream_reader = asyncio.StreamReader() - protocol = asyncio.StreamReaderProtocol(stream_reader) - transport = self.stream_writer.transport - - loop_start_tls = getattr(loop, "start_tls", backport_start_tls) - - exc_map = {asyncio.TimeoutError: ConnectTimeout, OSError: ConnectError} - - with map_exceptions(exc_map): - transport = await asyncio.wait_for( - loop_start_tls( - transport, - protocol, - ssl_context, - server_hostname=hostname.decode("ascii"), - ), - timeout=timeout.get("connect"), - ) - - # Initialize the protocol, so it is made aware of being tied to - # a TLS connection. - # See: https://github.com/encode/httpx/issues/859 - protocol.connection_made(transport) - - stream_writer = asyncio.StreamWriter( - transport=transport, protocol=protocol, reader=stream_reader, loop=loop - ) - - ssl_stream = SocketStream(stream_reader, stream_writer) - # When we return a new SocketStream with new StreamReader/StreamWriter instances - # we need to keep references to the old StreamReader/StreamWriter so that they - # are not garbage collected and closed while we're still using them. - ssl_stream._inner = self # type: ignore - return ssl_stream - - async def read(self, n: int, timeout: TimeoutDict) -> bytes: - exc_map = {asyncio.TimeoutError: ReadTimeout, OSError: ReadError} - async with self.read_lock: - with map_exceptions(exc_map): - try: - return await asyncio.wait_for( - self.stream_reader.read(n), timeout.get("read") - ) - except AttributeError as exc: # pragma: nocover - if "resume_reading" in str(exc): - # Python's asyncio has a bug that can occur when a - # connection has been closed, while it is paused. - # See: https://github.com/encode/httpx/issues/1213 - # - # Returning an empty byte-string to indicate connection - # close will eventually raise an httpcore.RemoteProtocolError - # to the user when this goes through our HTTP parsing layer. - return b"" - raise - - async def write(self, data: bytes, timeout: TimeoutDict) -> None: - if not data: - return - - exc_map = {asyncio.TimeoutError: WriteTimeout, OSError: WriteError} - async with self.write_lock: - with map_exceptions(exc_map): - self.stream_writer.write(data) - return await asyncio.wait_for( - self.stream_writer.drain(), timeout.get("write") - ) - - async def aclose(self) -> None: - # SSL connections should issue the close and then abort, rather than - # waiting for the remote end of the connection to signal the EOF. - # - # See: - # - # * https://bugs.python.org/issue39758 - # * https://github.com/python-trio/trio/blob/ - # 31e2ae866ad549f1927d45ce073d4f0ea9f12419/trio/_ssl.py#L779-L829 - # - # And related issues caused if we simply omit the 'wait_closed' call, - # without first using `.abort()` - # - # * https://github.com/encode/httpx/issues/825 - # * https://github.com/encode/httpx/issues/914 - is_ssl = self.stream_writer.get_extra_info("ssl_object") is not None - - async with self.write_lock: - try: - self.stream_writer.close() - if is_ssl: - # Give the connection a chance to write any data in the buffer, - # and then forcibly tear down the SSL connection. - await asyncio.sleep(0) - self.stream_writer.transport.abort() # type: ignore - if hasattr(self.stream_writer, "wait_closed"): - # Python 3.7+ only. - await self.stream_writer.wait_closed() # type: ignore - except OSError: - pass - - def is_readable(self) -> bool: - transport = self.stream_reader._transport # type: ignore - sock: Optional[socket.socket] = transport.get_extra_info("socket") - return is_socket_readable(sock) - - -class Lock(AsyncLock): - def __init__(self) -> None: - self._lock = asyncio.Lock() - - async def release(self) -> None: - self._lock.release() - - async def acquire(self) -> None: - await self._lock.acquire() - - -class Semaphore(AsyncSemaphore): - def __init__(self, max_value: int, exc_class: type) -> None: - self.max_value = max_value - self.exc_class = exc_class - - @property - def semaphore(self) -> asyncio.BoundedSemaphore: - if not hasattr(self, "_semaphore"): - self._semaphore = asyncio.BoundedSemaphore(value=self.max_value) - return self._semaphore - - async def acquire(self, timeout: float = None) -> None: - try: - await asyncio.wait_for(self.semaphore.acquire(), timeout) - except asyncio.TimeoutError: - raise self.exc_class() - - async def release(self) -> None: - self.semaphore.release() - - -class AsyncioBackend(AsyncBackend): - def __init__(self) -> None: - global SSL_MONKEY_PATCH_APPLIED - - if not SSL_MONKEY_PATCH_APPLIED: - ssl_monkey_patch() - SSL_MONKEY_PATCH_APPLIED = True - - async def open_tcp_stream( - self, - hostname: bytes, - port: int, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - *, - local_address: Optional[str], - ) -> SocketStream: - host = hostname.decode("ascii") - connect_timeout = timeout.get("connect") - local_addr = None if local_address is None else (local_address, 0) - - exc_map = {asyncio.TimeoutError: ConnectTimeout, OSError: ConnectError} - with map_exceptions(exc_map): - stream_reader, stream_writer = await asyncio.wait_for( - asyncio.open_connection( - host, port, ssl=ssl_context, local_addr=local_addr - ), - connect_timeout, - ) - return SocketStream( - stream_reader=stream_reader, stream_writer=stream_writer - ) - - async def open_uds_stream( - self, - path: str, - hostname: bytes, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - ) -> AsyncSocketStream: - host = hostname.decode("ascii") - connect_timeout = timeout.get("connect") - kwargs: dict = {"server_hostname": host} if ssl_context is not None else {} - exc_map = {asyncio.TimeoutError: ConnectTimeout, OSError: ConnectError} - with map_exceptions(exc_map): - stream_reader, stream_writer = await asyncio.wait_for( - asyncio.open_unix_connection(path, ssl=ssl_context, **kwargs), - connect_timeout, - ) - return SocketStream( - stream_reader=stream_reader, stream_writer=stream_writer - ) - - def create_lock(self) -> AsyncLock: - return Lock() - - def create_semaphore(self, max_value: int, exc_class: type) -> AsyncSemaphore: - return Semaphore(max_value, exc_class=exc_class) - - async def time(self) -> float: - loop = asyncio.get_event_loop() - return loop.time() - - async def sleep(self, seconds: float) -> None: - await asyncio.sleep(seconds) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/auto.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/auto.py deleted file mode 100644 index 5579ab46..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/auto.py +++ /dev/null @@ -1,67 +0,0 @@ -from ssl import SSLContext -from typing import Optional - -import sniffio - -from .._types import TimeoutDict -from .base import AsyncBackend, AsyncLock, AsyncSemaphore, AsyncSocketStream - -# The following line is imported from the _sync modules -from .sync import SyncBackend, SyncLock, SyncSemaphore, SyncSocketStream # noqa - - -class AutoBackend(AsyncBackend): - @property - def backend(self) -> AsyncBackend: - if not hasattr(self, "_backend_implementation"): - backend = sniffio.current_async_library() - - if backend == "asyncio": - from .anyio import AnyIOBackend - - self._backend_implementation: AsyncBackend = AnyIOBackend() - elif backend == "trio": - from .trio import TrioBackend - - self._backend_implementation = TrioBackend() - elif backend == "curio": - from .curio import CurioBackend - - self._backend_implementation = CurioBackend() - else: # pragma: nocover - raise RuntimeError(f"Unsupported concurrency backend {backend!r}") - return self._backend_implementation - - async def open_tcp_stream( - self, - hostname: bytes, - port: int, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - *, - local_address: Optional[str], - ) -> AsyncSocketStream: - return await self.backend.open_tcp_stream( - hostname, port, ssl_context, timeout, local_address=local_address - ) - - async def open_uds_stream( - self, - path: str, - hostname: bytes, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - ) -> AsyncSocketStream: - return await self.backend.open_uds_stream(path, hostname, ssl_context, timeout) - - def create_lock(self) -> AsyncLock: - return self.backend.create_lock() - - def create_semaphore(self, max_value: int, exc_class: type) -> AsyncSemaphore: - return self.backend.create_semaphore(max_value, exc_class=exc_class) - - async def time(self) -> float: - return await self.backend.time() - - async def sleep(self, seconds: float) -> None: - await self.backend.sleep(seconds) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/base.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/base.py deleted file mode 100644 index 1ca6e31b..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/base.py +++ /dev/null @@ -1,137 +0,0 @@ -from ssl import SSLContext -from types import TracebackType -from typing import TYPE_CHECKING, Optional, Type - -from .._types import TimeoutDict - -if TYPE_CHECKING: # pragma: no cover - from .sync import SyncBackend - - -def lookup_async_backend(name: str) -> "AsyncBackend": - if name == "auto": - from .auto import AutoBackend - - return AutoBackend() - elif name == "asyncio": - from .asyncio import AsyncioBackend - - return AsyncioBackend() - elif name == "trio": - from .trio import TrioBackend - - return TrioBackend() - elif name == "curio": - from .curio import CurioBackend - - return CurioBackend() - elif name == "anyio": - from .anyio import AnyIOBackend - - return AnyIOBackend() - - raise ValueError("Invalid backend name {name!r}") - - -def lookup_sync_backend(name: str) -> "SyncBackend": - from .sync import SyncBackend - - return SyncBackend() - - -class AsyncSocketStream: - """ - A socket stream with read/write operations. Abstracts away any asyncio-specific - interfaces into a more generic base class, that we can use with alternate - backends, or for stand-alone test cases. - """ - - def get_http_version(self) -> str: - raise NotImplementedError() # pragma: no cover - - async def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict - ) -> "AsyncSocketStream": - raise NotImplementedError() # pragma: no cover - - async def read(self, n: int, timeout: TimeoutDict) -> bytes: - raise NotImplementedError() # pragma: no cover - - async def write(self, data: bytes, timeout: TimeoutDict) -> None: - raise NotImplementedError() # pragma: no cover - - async def aclose(self) -> None: - raise NotImplementedError() # pragma: no cover - - def is_readable(self) -> bool: - raise NotImplementedError() # pragma: no cover - - -class AsyncLock: - """ - An abstract interface for Lock classes. - """ - - async def __aenter__(self) -> None: - await self.acquire() - - async def __aexit__( - self, - exc_type: Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - await self.release() - - async def release(self) -> None: - raise NotImplementedError() # pragma: no cover - - async def acquire(self) -> None: - raise NotImplementedError() # pragma: no cover - - -class AsyncSemaphore: - """ - An abstract interface for Semaphore classes. - Abstracts away any asyncio-specific interfaces. - """ - - async def acquire(self, timeout: float = None) -> None: - raise NotImplementedError() # pragma: no cover - - async def release(self) -> None: - raise NotImplementedError() # pragma: no cover - - -class AsyncBackend: - async def open_tcp_stream( - self, - hostname: bytes, - port: int, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - *, - local_address: Optional[str], - ) -> AsyncSocketStream: - raise NotImplementedError() # pragma: no cover - - async def open_uds_stream( - self, - path: str, - hostname: bytes, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - ) -> AsyncSocketStream: - raise NotImplementedError() # pragma: no cover - - def create_lock(self) -> AsyncLock: - raise NotImplementedError() # pragma: no cover - - def create_semaphore(self, max_value: int, exc_class: type) -> AsyncSemaphore: - raise NotImplementedError() # pragma: no cover - - async def time(self) -> float: - raise NotImplementedError() # pragma: no cover - - async def sleep(self, seconds: float) -> None: - raise NotImplementedError() # pragma: no cover diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/curio.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/curio.py deleted file mode 100644 index 99a7b2cc..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/curio.py +++ /dev/null @@ -1,206 +0,0 @@ -from ssl import SSLContext, SSLSocket -from typing import Optional - -import curio -import curio.io - -from .._exceptions import ( - ConnectError, - ConnectTimeout, - ReadError, - ReadTimeout, - WriteError, - WriteTimeout, - map_exceptions, -) -from .._types import TimeoutDict -from .._utils import get_logger, is_socket_readable -from .base import AsyncBackend, AsyncLock, AsyncSemaphore, AsyncSocketStream - -logger = get_logger(__name__) - -ONE_DAY_IN_SECONDS = float(60 * 60 * 24) - - -def convert_timeout(value: Optional[float]) -> float: - return value if value is not None else ONE_DAY_IN_SECONDS - - -class Lock(AsyncLock): - def __init__(self) -> None: - self._lock = curio.Lock() - - async def acquire(self) -> None: - await self._lock.acquire() - - async def release(self) -> None: - await self._lock.release() - - -class Semaphore(AsyncSemaphore): - def __init__(self, max_value: int, exc_class: type) -> None: - self.max_value = max_value - self.exc_class = exc_class - - @property - def semaphore(self) -> curio.Semaphore: - if not hasattr(self, "_semaphore"): - self._semaphore = curio.Semaphore(value=self.max_value) - return self._semaphore - - async def acquire(self, timeout: float = None) -> None: - timeout = convert_timeout(timeout) - - try: - return await curio.timeout_after(timeout, self.semaphore.acquire()) - except curio.TaskTimeout: - raise self.exc_class() - - async def release(self) -> None: - await self.semaphore.release() - - -class SocketStream(AsyncSocketStream): - def __init__(self, socket: curio.io.Socket) -> None: - self.read_lock = curio.Lock() - self.write_lock = curio.Lock() - self.socket = socket - self.stream = socket.as_stream() - - def get_http_version(self) -> str: - if hasattr(self.socket, "_socket"): - raw_socket = self.socket._socket - - if isinstance(raw_socket, SSLSocket): - ident = raw_socket.selected_alpn_protocol() - return "HTTP/2" if ident == "h2" else "HTTP/1.1" - - return "HTTP/1.1" - - async def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict - ) -> "AsyncSocketStream": - connect_timeout = convert_timeout(timeout.get("connect")) - exc_map = { - curio.TaskTimeout: ConnectTimeout, - curio.CurioError: ConnectError, - OSError: ConnectError, - } - - with map_exceptions(exc_map): - wrapped_sock = curio.io.Socket( - ssl_context.wrap_socket( - self.socket._socket, - do_handshake_on_connect=False, - server_hostname=hostname.decode("ascii"), - ) - ) - - await curio.timeout_after( - connect_timeout, - wrapped_sock.do_handshake(), - ) - - return SocketStream(wrapped_sock) - - async def read(self, n: int, timeout: TimeoutDict) -> bytes: - read_timeout = convert_timeout(timeout.get("read")) - exc_map = { - curio.TaskTimeout: ReadTimeout, - curio.CurioError: ReadError, - OSError: ReadError, - } - - with map_exceptions(exc_map): - async with self.read_lock: - return await curio.timeout_after(read_timeout, self.stream.read(n)) - - async def write(self, data: bytes, timeout: TimeoutDict) -> None: - write_timeout = convert_timeout(timeout.get("write")) - exc_map = { - curio.TaskTimeout: WriteTimeout, - curio.CurioError: WriteError, - OSError: WriteError, - } - - with map_exceptions(exc_map): - async with self.write_lock: - await curio.timeout_after(write_timeout, self.stream.write(data)) - - async def aclose(self) -> None: - await self.stream.close() - await self.socket.close() - - def is_readable(self) -> bool: - return is_socket_readable(self.socket) - - -class CurioBackend(AsyncBackend): - async def open_tcp_stream( - self, - hostname: bytes, - port: int, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - *, - local_address: Optional[str], - ) -> AsyncSocketStream: - connect_timeout = convert_timeout(timeout.get("connect")) - exc_map = { - curio.TaskTimeout: ConnectTimeout, - curio.CurioError: ConnectError, - OSError: ConnectError, - } - host = hostname.decode("ascii") - - kwargs: dict = {} - if ssl_context is not None: - kwargs["ssl"] = ssl_context - kwargs["server_hostname"] = host - if local_address is not None: - kwargs["source_addr"] = (local_address, 0) - - with map_exceptions(exc_map): - sock: curio.io.Socket = await curio.timeout_after( - connect_timeout, - curio.open_connection(hostname, port, **kwargs), - ) - - return SocketStream(sock) - - async def open_uds_stream( - self, - path: str, - hostname: bytes, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - ) -> AsyncSocketStream: - connect_timeout = convert_timeout(timeout.get("connect")) - exc_map = { - curio.TaskTimeout: ConnectTimeout, - curio.CurioError: ConnectError, - OSError: ConnectError, - } - host = hostname.decode("ascii") - kwargs = ( - {} if ssl_context is None else {"ssl": ssl_context, "server_hostname": host} - ) - - with map_exceptions(exc_map): - sock: curio.io.Socket = await curio.timeout_after( - connect_timeout, curio.open_unix_connection(path, **kwargs) - ) - - return SocketStream(sock) - - def create_lock(self) -> AsyncLock: - return Lock() - - def create_semaphore(self, max_value: int, exc_class: type) -> AsyncSemaphore: - return Semaphore(max_value, exc_class) - - async def time(self) -> float: - return await curio.clock() - - async def sleep(self, seconds: float) -> None: - await curio.sleep(seconds) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/sync.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/sync.py deleted file mode 100644 index ee8f94b7..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/sync.py +++ /dev/null @@ -1,178 +0,0 @@ -import socket -import threading -import time -from ssl import SSLContext -from types import TracebackType -from typing import Optional, Type - -from .._exceptions import ( - ConnectError, - ConnectTimeout, - ReadError, - ReadTimeout, - WriteError, - WriteTimeout, - map_exceptions, -) -from .._types import TimeoutDict -from .._utils import is_socket_readable - - -class SyncSocketStream: - """ - A socket stream with read/write operations. Abstracts away any asyncio-specific - interfaces into a more generic base class, that we can use with alternate - backends, or for stand-alone test cases. - """ - - def __init__(self, sock: socket.socket) -> None: - self.sock = sock - self.read_lock = threading.Lock() - self.write_lock = threading.Lock() - - def get_http_version(self) -> str: - selected_alpn_protocol = getattr(self.sock, "selected_alpn_protocol", None) - if selected_alpn_protocol is not None: - ident = selected_alpn_protocol() - return "HTTP/2" if ident == "h2" else "HTTP/1.1" - return "HTTP/1.1" - - def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict - ) -> "SyncSocketStream": - connect_timeout = timeout.get("connect") - exc_map = {socket.timeout: ConnectTimeout, socket.error: ConnectError} - - with map_exceptions(exc_map): - self.sock.settimeout(connect_timeout) - wrapped = ssl_context.wrap_socket( - self.sock, server_hostname=hostname.decode("ascii") - ) - - return SyncSocketStream(wrapped) - - def read(self, n: int, timeout: TimeoutDict) -> bytes: - read_timeout = timeout.get("read") - exc_map = {socket.timeout: ReadTimeout, socket.error: ReadError} - - with self.read_lock: - with map_exceptions(exc_map): - self.sock.settimeout(read_timeout) - return self.sock.recv(n) - - def write(self, data: bytes, timeout: TimeoutDict) -> None: - write_timeout = timeout.get("write") - exc_map = {socket.timeout: WriteTimeout, socket.error: WriteError} - - with self.write_lock: - with map_exceptions(exc_map): - while data: - self.sock.settimeout(write_timeout) - n = self.sock.send(data) - data = data[n:] - - def close(self) -> None: - with self.write_lock: - try: - self.sock.close() - except socket.error: - pass - - def is_readable(self) -> bool: - return is_socket_readable(self.sock) - - -class SyncLock: - def __init__(self) -> None: - self._lock = threading.Lock() - - def __enter__(self) -> None: - self.acquire() - - def __exit__( - self, - exc_type: Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - self.release() - - def release(self) -> None: - self._lock.release() - - def acquire(self) -> None: - self._lock.acquire() - - -class SyncSemaphore: - def __init__(self, max_value: int, exc_class: type) -> None: - self.max_value = max_value - self.exc_class = exc_class - self._semaphore = threading.Semaphore(max_value) - - def acquire(self, timeout: float = None) -> None: - if not self._semaphore.acquire(timeout=timeout): # type: ignore - raise self.exc_class() - - def release(self) -> None: - self._semaphore.release() - - -class SyncBackend: - def open_tcp_stream( - self, - hostname: bytes, - port: int, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - *, - local_address: Optional[str], - ) -> SyncSocketStream: - address = (hostname.decode("ascii"), port) - connect_timeout = timeout.get("connect") - source_address = None if local_address is None else (local_address, 0) - exc_map = {socket.timeout: ConnectTimeout, socket.error: ConnectError} - - with map_exceptions(exc_map): - sock = socket.create_connection( - address, connect_timeout, source_address=source_address # type: ignore - ) - if ssl_context is not None: - sock = ssl_context.wrap_socket( - sock, server_hostname=hostname.decode("ascii") - ) - return SyncSocketStream(sock=sock) - - def open_uds_stream( - self, - path: str, - hostname: bytes, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - ) -> SyncSocketStream: - connect_timeout = timeout.get("connect") - exc_map = {socket.timeout: ConnectTimeout, socket.error: ConnectError} - - with map_exceptions(exc_map): - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.settimeout(connect_timeout) - sock.connect(path) - - if ssl_context is not None: - sock = ssl_context.wrap_socket( - sock, server_hostname=hostname.decode("ascii") - ) - - return SyncSocketStream(sock=sock) - - def create_lock(self) -> SyncLock: - return SyncLock() - - def create_semaphore(self, max_value: int, exc_class: type) -> SyncSemaphore: - return SyncSemaphore(max_value, exc_class=exc_class) - - def time(self) -> float: - return time.monotonic() - - def sleep(self, seconds: float) -> None: - time.sleep(seconds) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/trio.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/trio.py deleted file mode 100644 index d6e67c2e..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_backends/trio.py +++ /dev/null @@ -1,212 +0,0 @@ -from ssl import SSLContext -from typing import Optional - -import trio - -from .._exceptions import ( - ConnectError, - ConnectTimeout, - ReadError, - ReadTimeout, - WriteError, - WriteTimeout, - map_exceptions, -) -from .._types import TimeoutDict -from .base import AsyncBackend, AsyncLock, AsyncSemaphore, AsyncSocketStream - - -def none_as_inf(value: Optional[float]) -> float: - return value if value is not None else float("inf") - - -class SocketStream(AsyncSocketStream): - def __init__(self, stream: trio.abc.Stream) -> None: - self.stream = stream - self.read_lock = trio.Lock() - self.write_lock = trio.Lock() - - def get_http_version(self) -> str: - if not isinstance(self.stream, trio.SSLStream): - return "HTTP/1.1" - - ident = self.stream.selected_alpn_protocol() - return "HTTP/2" if ident == "h2" else "HTTP/1.1" - - async def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict - ) -> "SocketStream": - connect_timeout = none_as_inf(timeout.get("connect")) - exc_map = { - trio.TooSlowError: ConnectTimeout, - trio.BrokenResourceError: ConnectError, - } - ssl_stream = trio.SSLStream( - self.stream, - ssl_context=ssl_context, - server_hostname=hostname.decode("ascii"), - ) - - with map_exceptions(exc_map): - with trio.fail_after(connect_timeout): - await ssl_stream.do_handshake() - return SocketStream(ssl_stream) - - async def read(self, n: int, timeout: TimeoutDict) -> bytes: - read_timeout = none_as_inf(timeout.get("read")) - exc_map = {trio.TooSlowError: ReadTimeout, trio.BrokenResourceError: ReadError} - - async with self.read_lock: - with map_exceptions(exc_map): - try: - with trio.fail_after(read_timeout): - return await self.stream.receive_some(max_bytes=n) - except trio.TooSlowError as exc: - await self.stream.aclose() - raise exc - - async def write(self, data: bytes, timeout: TimeoutDict) -> None: - if not data: - return - - write_timeout = none_as_inf(timeout.get("write")) - exc_map = { - trio.TooSlowError: WriteTimeout, - trio.BrokenResourceError: WriteError, - } - - async with self.write_lock: - with map_exceptions(exc_map): - try: - with trio.fail_after(write_timeout): - return await self.stream.send_all(data) - except trio.TooSlowError as exc: - await self.stream.aclose() - raise exc - - async def aclose(self) -> None: - async with self.write_lock: - try: - await self.stream.aclose() - except trio.BrokenResourceError: - pass - - def is_readable(self) -> bool: - # Adapted from: https://github.com/encode/httpx/pull/143#issuecomment-515202982 - stream = self.stream - - # Peek through any SSLStream wrappers to get the underlying SocketStream. - while isinstance(stream, trio.SSLStream): - stream = stream.transport_stream - assert isinstance(stream, trio.SocketStream) - - return stream.socket.is_readable() - - -class Lock(AsyncLock): - def __init__(self) -> None: - self._lock = trio.Lock() - - async def release(self) -> None: - self._lock.release() - - async def acquire(self) -> None: - await self._lock.acquire() - - -class Semaphore(AsyncSemaphore): - def __init__(self, max_value: int, exc_class: type): - self.max_value = max_value - self.exc_class = exc_class - - @property - def semaphore(self) -> trio.Semaphore: - if not hasattr(self, "_semaphore"): - self._semaphore = trio.Semaphore(self.max_value, max_value=self.max_value) - return self._semaphore - - async def acquire(self, timeout: float = None) -> None: - timeout = none_as_inf(timeout) - - with trio.move_on_after(timeout): - await self.semaphore.acquire() - return - - raise self.exc_class() - - async def release(self) -> None: - self.semaphore.release() - - -class TrioBackend(AsyncBackend): - async def open_tcp_stream( - self, - hostname: bytes, - port: int, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - *, - local_address: Optional[str], - ) -> AsyncSocketStream: - connect_timeout = none_as_inf(timeout.get("connect")) - # Trio will support local_address from 0.16.1 onwards. - # We only include the keyword argument if a local_address - #  argument has been passed. - kwargs: dict = {} if local_address is None else {"local_address": local_address} - exc_map = { - OSError: ConnectError, - trio.TooSlowError: ConnectTimeout, - trio.BrokenResourceError: ConnectError, - } - - with map_exceptions(exc_map): - with trio.fail_after(connect_timeout): - stream: trio.abc.Stream = await trio.open_tcp_stream( - hostname, port, **kwargs - ) - - if ssl_context is not None: - stream = trio.SSLStream( - stream, ssl_context, server_hostname=hostname.decode("ascii") - ) - await stream.do_handshake() - - return SocketStream(stream=stream) - - async def open_uds_stream( - self, - path: str, - hostname: bytes, - ssl_context: Optional[SSLContext], - timeout: TimeoutDict, - ) -> AsyncSocketStream: - connect_timeout = none_as_inf(timeout.get("connect")) - exc_map = { - OSError: ConnectError, - trio.TooSlowError: ConnectTimeout, - trio.BrokenResourceError: ConnectError, - } - - with map_exceptions(exc_map): - with trio.fail_after(connect_timeout): - stream: trio.abc.Stream = await trio.open_unix_socket(path) - - if ssl_context is not None: - stream = trio.SSLStream( - stream, ssl_context, server_hostname=hostname.decode("ascii") - ) - await stream.do_handshake() - - return SocketStream(stream=stream) - - def create_lock(self) -> AsyncLock: - return Lock() - - def create_semaphore(self, max_value: int, exc_class: type) -> AsyncSemaphore: - return Semaphore(max_value, exc_class=exc_class) - - async def time(self) -> float: - return trio.current_time() - - async def sleep(self, seconds: float) -> None: - await trio.sleep(seconds) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_bytestreams.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_bytestreams.py deleted file mode 100644 index 317f4110..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_bytestreams.py +++ /dev/null @@ -1,96 +0,0 @@ -from typing import AsyncIterator, Callable, Iterator - -from ._async.base import AsyncByteStream -from ._sync.base import SyncByteStream - - -class ByteStream(AsyncByteStream, SyncByteStream): - """ - A concrete implementation for either sync or async byte streams. - - Example:: - - stream = httpcore.ByteStream(b"123") - - Parameters - ---------- - content: - A plain byte string used as the content of the stream. - """ - - def __init__(self, content: bytes) -> None: - self._content = content - - def __iter__(self) -> Iterator[bytes]: - yield self._content - - async def __aiter__(self) -> AsyncIterator[bytes]: - yield self._content - - -class IteratorByteStream(SyncByteStream): - """ - A concrete implementation for sync byte streams. - - Example:: - - def generate_content(): - yield b"Hello, world!" - ... - - stream = httpcore.IteratorByteStream(generate_content()) - - Parameters - ---------- - iterator: - A sync byte iterator, used as the content of the stream. - close_func: - An optional function called when closing the stream. - """ - - def __init__(self, iterator: Iterator[bytes], close_func: Callable = None) -> None: - self._iterator = iterator - self._close_func = close_func - - def __iter__(self) -> Iterator[bytes]: - for chunk in self._iterator: - yield chunk - - def close(self) -> None: - if self._close_func is not None: - self._close_func() - - -class AsyncIteratorByteStream(AsyncByteStream): - """ - A concrete implementation for async byte streams. - - Example:: - - async def generate_content(): - yield b"Hello, world!" - ... - - stream = httpcore.AsyncIteratorByteStream(generate_content()) - - Parameters - ---------- - aiterator: - An async byte iterator, used as the content of the stream. - aclose_func: - An optional async function called when closing the stream. - """ - - def __init__( - self, aiterator: AsyncIterator[bytes], aclose_func: Callable = None - ) -> None: - self._aiterator = aiterator - self._aclose_func = aclose_func - - async def __aiter__(self) -> AsyncIterator[bytes]: - async for chunk in self._aiterator: - yield chunk - - async def aclose(self) -> None: - if self._aclose_func is not None: - await self._aclose_func() diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_exceptions.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_exceptions.py deleted file mode 100644 index ba568299..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_exceptions.py +++ /dev/null @@ -1,79 +0,0 @@ -import contextlib -from typing import Dict, Iterator, Type - - -@contextlib.contextmanager -def map_exceptions(map: Dict[Type[Exception], Type[Exception]]) -> Iterator[None]: - try: - yield - except Exception as exc: # noqa: PIE786 - for from_exc, to_exc in map.items(): - if isinstance(exc, from_exc): - raise to_exc(exc) from None - raise - - -class UnsupportedProtocol(Exception): - pass - - -class ProtocolError(Exception): - pass - - -class RemoteProtocolError(ProtocolError): - pass - - -class LocalProtocolError(ProtocolError): - pass - - -class ProxyError(Exception): - pass - - -# Timeout errors - - -class TimeoutException(Exception): - pass - - -class PoolTimeout(TimeoutException): - pass - - -class ConnectTimeout(TimeoutException): - pass - - -class ReadTimeout(TimeoutException): - pass - - -class WriteTimeout(TimeoutException): - pass - - -# Network errors - - -class NetworkError(Exception): - pass - - -class ConnectError(NetworkError): - pass - - -class ReadError(NetworkError): - pass - - -class WriteError(NetworkError): - pass - - -class CloseError(NetworkError): - pass diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 4fbf7f3baeadefb4df9c092975932ac4569ed86d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmYe~<>g`kf`|Vc6G8N25P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_`i&acOWkyMU zUQAJ9UP^v$OmK2Wetu4jr?;zPd~tG7VnJ$Aj9yu4URjJ!W>QRXW=X1UL1J=tVtQ(E vOh!pbL2`aks(yTNWnQv=e0*kJW=VX!UP0w84x8Nkl+v73JCKE+ftUdRggq~N diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/base.cpython-39.pyc deleted file mode 100644 index 6614e7d266b6b7488a1a8a5ed19be42c848e9273..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4315 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/connection_pool.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/connection_pool.cpython-39.pyc deleted file mode 100644 index bd797799ec35c57f2f242d6c10d11289f74db036..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10644 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 NC4P;(Ia8WB@xNV`b$b8+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http.cpython-39.pyc deleted file mode 100644 index c93b93d5179cf622ace7ac5c528f76f53f0e4c18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1928 zcmb7E&5qkP5T1p)%?#fLh_0!2~eXM-l_!U$^jA{bC;adss{5*?D- z)_ZLBG4cX=CEbdg_7!qSIwLu*5v&0(1r9jkaQJ;QoDqXTkKy?D<0J9GW$ZmE+XMfx zhd9j%3dy9CvD^tAhsl;~XRW*)w(GTExS74`BgUHeBV3y{fN_&#V_S$Lej>+!X zZ1!TNMPZgo+nAhg4-b`xI8A~ASm;O=wxBJYw+=zSazht7wdTqWYTjD&q>q}v)(|pk z!CLFd1Jt_m2zqb;eHh5WTUQR{;Z-Lb%07}iuI>@E$HD-?LwW_oHdO@@@if>{7cp`8 zJZMex2~Ib`4}_@0cFqkq^_8pXV=D ziB-iM!y#2ZpT>z&+5GwMPaj1l)?x{IKE8nBVt$$~<|ei9<5I-0#5tIGV(l_k8XiOj zkv|}Hyj)doTAZma!J^zS=kmLoiH*r_FHR0}YF&msz8-(n;ovW4x`dZJJ>xb39&aMX zQ^V7O3vR5i!2e1>15YhCi7GS67igO)19H4^IMEbA-6uhTX~ZF}s(y1Ss*jLC!^*w< zeg~^<`&+O(*?`%DU0iC7SHm5y!B!TofGJ&ACd8bFSfa3C8Y~n?CXr z7b4Bb-~BC$yWZHg{bb};L86Q;L=M$~FPAb( zyvtoV-56tU8y!|b6cO7fs(MkBD_Lf=?nlwtk&(8Fi~RrlEEl z4xfclAq@Ri-@&i_AB1?* AyZ`_I diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http11.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http11.cpython-39.pyc deleted file mode 100644 index 4bd2e49cf909e054bc8f78abd95658b1ba3cd7e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8579 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 M_MK6vW^?*q0My1X{r~^~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http2.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/__pycache__/http2.cpython-39.pyc deleted file mode 100644 index 626c5503885757f8bfd7863c9d51dbc95cb14ce5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14059 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 Iterator[bytes]: - """ - Yield bytes representing the request or response body. - """ - yield b"" # pragma: nocover - - def close(self) -> None: - """ - Must be called by the client to indicate that the stream has been closed. - """ - pass # pragma: nocover - - def read(self) -> bytes: - try: - return b"".join([part for part in self]) - finally: - self.close() - - -class SyncHTTPTransport: - """ - The base interface for sending HTTP requests. - - Concrete implementations should subclass this class, and implement - the :meth:`handle_request` method, and optionally the :meth:`close` method. - """ - - def handle_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - """ - The interface for sending a single HTTP request, and returning a response. - - Parameters - ---------- - method: - The HTTP method, such as ``b'GET'``. - url: - The URL as a 4-tuple of (scheme, host, port, path). - headers: - Any HTTP headers to send with the request. - stream: - The body of the HTTP request. - extensions: - A dictionary of optional extensions. - - Returns - ------- - status_code: - The HTTP status code, such as ``200``. - headers: - Any HTTP headers included on the response. - stream: - The body of the HTTP response. - extensions: - A dictionary of optional extensions. - """ - raise NotImplementedError() # pragma: nocover - - def close(self) -> None: - """ - Close the implementation, which should close any outstanding response streams, - and any keep alive connections. - """ - - def __enter__(self: T) -> T: - return self - - def __exit__( - self, - exc_type: Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - self.close() diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/connection.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/connection.py deleted file mode 100644 index 382a4f9f..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/connection.py +++ /dev/null @@ -1,220 +0,0 @@ -from ssl import SSLContext -from typing import List, Optional, Tuple, cast - -from .._backends.sync import SyncBackend, SyncLock, SyncSocketStream, SyncBackend -from .._exceptions import ConnectError, ConnectTimeout -from .._types import URL, Headers, Origin, TimeoutDict -from .._utils import exponential_backoff, get_logger, url_to_origin -from .base import SyncByteStream, SyncHTTPTransport, NewConnectionRequired -from .http import SyncBaseHTTPConnection -from .http11 import SyncHTTP11Connection - -logger = get_logger(__name__) - -RETRIES_BACKOFF_FACTOR = 0.5 # 0s, 0.5s, 1s, 2s, 4s, etc. - - -class SyncHTTPConnection(SyncHTTPTransport): - def __init__( - self, - origin: Origin, - http1: bool = True, - http2: bool = False, - keepalive_expiry: float = None, - uds: str = None, - ssl_context: SSLContext = None, - socket: SyncSocketStream = None, - local_address: str = None, - retries: int = 0, - backend: SyncBackend = None, - ): - self.origin = origin - self._http1_enabled = http1 - self._http2_enabled = http2 - self._keepalive_expiry = keepalive_expiry - self._uds = uds - self._ssl_context = SSLContext() if ssl_context is None else ssl_context - self.socket = socket - self._local_address = local_address - self._retries = retries - - alpn_protocols: List[str] = [] - if http1: - alpn_protocols.append("http/1.1") - if http2: - alpn_protocols.append("h2") - - self._ssl_context.set_alpn_protocols(alpn_protocols) - - self.connection: Optional[SyncBaseHTTPConnection] = None - self._is_http11 = False - self._is_http2 = False - self._connect_failed = False - self._expires_at: Optional[float] = None - self._backend = SyncBackend() if backend is None else backend - - def __repr__(self) -> str: - return f"" - - def info(self) -> str: - if self.connection is None: - return "Connection failed" if self._connect_failed else "Connecting" - return self.connection.info() - - def should_close(self) -> bool: - """ - Return `True` if the connection is in a state where it should be closed. - This occurs when any of the following occur: - - * There are no active requests on an HTTP/1.1 connection, and the underlying - socket is readable. The only valid state the socket can be readable in - if this occurs is when the b"" EOF marker is about to be returned, - indicating a server disconnect. - * There are no active requests being made and the keepalive timeout has passed. - """ - if self.connection is None: - return False - return self.connection.should_close() - - def is_idle(self) -> bool: - """ - Return `True` if the connection is currently idle. - """ - if self.connection is None: - return False - return self.connection.is_idle() - - def is_closed(self) -> bool: - if self.connection is None: - return self._connect_failed - return self.connection.is_closed() - - def is_available(self) -> bool: - """ - Return `True` if the connection is currently able to accept an outgoing request. - This occurs when any of the following occur: - - * The connection has not yet been opened, and HTTP/2 support is enabled. - We don't *know* at this point if we'll end up on an HTTP/2 connection or - not, but we *might* do, so we indicate availability. - * The connection has been opened, and is currently idle. - * The connection is open, and is an HTTP/2 connection. The connection must - also not currently be exceeding the maximum number of allowable concurrent - streams and must not have exhausted the maximum total number of stream IDs. - """ - if self.connection is None: - return self._http2_enabled and not self.is_closed - return self.connection.is_available() - - @property - def request_lock(self) -> SyncLock: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_request_lock"): - self._request_lock = self._backend.create_lock() - return self._request_lock - - def handle_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - assert url_to_origin(url) == self.origin - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - with self.request_lock: - if self.connection is None: - if self._connect_failed: - raise NewConnectionRequired() - if not self.socket: - logger.trace( - "open_socket origin=%r timeout=%r", self.origin, timeout - ) - self.socket = self._open_socket(timeout) - self._create_connection(self.socket) - elif not self.connection.is_available(): - raise NewConnectionRequired() - - assert self.connection is not None - logger.trace( - "connection.handle_request method=%r url=%r headers=%r", - method, - url, - headers, - ) - return self.connection.handle_request( - method, url, headers, stream, extensions - ) - - def _open_socket(self, timeout: TimeoutDict = None) -> SyncSocketStream: - scheme, hostname, port = self.origin - timeout = {} if timeout is None else timeout - ssl_context = self._ssl_context if scheme == b"https" else None - - retries_left = self._retries - delays = exponential_backoff(factor=RETRIES_BACKOFF_FACTOR) - - while True: - try: - if self._uds is None: - return self._backend.open_tcp_stream( - hostname, - port, - ssl_context, - timeout, - local_address=self._local_address, - ) - else: - return self._backend.open_uds_stream( - self._uds, hostname, ssl_context, timeout - ) - except (ConnectError, ConnectTimeout): - if retries_left <= 0: - self._connect_failed = True - raise - retries_left -= 1 - delay = next(delays) - self._backend.sleep(delay) - except Exception: # noqa: PIE786 - self._connect_failed = True - raise - - def _create_connection(self, socket: SyncSocketStream) -> None: - http_version = socket.get_http_version() - logger.trace( - "create_connection socket=%r http_version=%r", socket, http_version - ) - if http_version == "HTTP/2" or ( - self._http2_enabled and not self._http1_enabled - ): - from .http2 import SyncHTTP2Connection - - self._is_http2 = True - self.connection = SyncHTTP2Connection( - socket=socket, - keepalive_expiry=self._keepalive_expiry, - backend=self._backend, - ) - else: - self._is_http11 = True - self.connection = SyncHTTP11Connection( - socket=socket, keepalive_expiry=self._keepalive_expiry - ) - - def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict = None - ) -> None: - if self.connection is not None: - logger.trace("start_tls hostname=%r timeout=%r", hostname, timeout) - self.socket = self.connection.start_tls( - hostname, ssl_context, timeout - ) - logger.trace("start_tls complete hostname=%r timeout=%r", hostname, timeout) - - def close(self) -> None: - with self.request_lock: - if self.connection is not None: - self.connection.close() diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/connection_pool.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/connection_pool.py deleted file mode 100644 index 0bd759db..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/connection_pool.py +++ /dev/null @@ -1,362 +0,0 @@ -import warnings -from ssl import SSLContext -from typing import ( - Iterator, - Callable, - Dict, - List, - Optional, - Set, - Tuple, - Union, - cast, -) - -from .._backends.sync import SyncBackend, SyncLock, SyncSemaphore -from .._backends.base import lookup_sync_backend -from .._exceptions import LocalProtocolError, PoolTimeout, UnsupportedProtocol -from .._threadlock import ThreadLock -from .._types import URL, Headers, Origin, TimeoutDict -from .._utils import get_logger, origin_to_url_string, url_to_origin -from .base import SyncByteStream, SyncHTTPTransport, NewConnectionRequired -from .connection import SyncHTTPConnection - -logger = get_logger(__name__) - - -class NullSemaphore(SyncSemaphore): - def __init__(self) -> None: - pass - - def acquire(self, timeout: float = None) -> None: - return - - def release(self) -> None: - return - - -class ResponseByteStream(SyncByteStream): - def __init__( - self, - stream: SyncByteStream, - connection: SyncHTTPConnection, - callback: Callable, - ) -> None: - """ - A wrapper around the response stream that we return from - `.handle_request()`. - - Ensures that when `stream.close()` is called, the connection pool - is notified via a callback. - """ - self.stream = stream - self.connection = connection - self.callback = callback - - def __iter__(self) -> Iterator[bytes]: - for chunk in self.stream: - yield chunk - - def close(self) -> None: - try: - # Call the underlying stream close callback. - # This will be a call to `SyncHTTP11Connection._response_closed()` - # or `SyncHTTP2Stream._response_closed()`. - self.stream.close() - finally: - # Call the connection pool close callback. - # This will be a call to `SyncConnectionPool._response_closed()`. - self.callback(self.connection) - - -class SyncConnectionPool(SyncHTTPTransport): - """ - A connection pool for making HTTP requests. - - Parameters - ---------- - ssl_context: - An SSL context to use for verifying connections. - max_connections: - The maximum number of concurrent connections to allow. - max_keepalive_connections: - The maximum number of connections to allow before closing keep-alive - connections. - keepalive_expiry: - The maximum time to allow before closing a keep-alive connection. - http1: - Enable/Disable HTTP/1.1 support. Defaults to True. - http2: - Enable/Disable HTTP/2 support. Defaults to False. - uds: - Path to a Unix Domain Socket to use instead of TCP sockets. - local_address: - Local address to connect from. Can also be used to connect using a particular - address family. Using ``local_address="0.0.0.0"`` will connect using an - ``AF_INET`` address (IPv4), while using ``local_address="::"`` will connect - using an ``AF_INET6`` address (IPv6). - retries: - The maximum number of retries when trying to establish a connection. - backend: - A name indicating which concurrency backend to use. - """ - - def __init__( - self, - ssl_context: SSLContext = None, - max_connections: int = None, - max_keepalive_connections: int = None, - keepalive_expiry: float = None, - http1: bool = True, - http2: bool = False, - uds: str = None, - local_address: str = None, - retries: int = 0, - max_keepalive: int = None, - backend: Union[SyncBackend, str] = "sync", - ): - if max_keepalive is not None: - warnings.warn( - "'max_keepalive' is deprecated. Use 'max_keepalive_connections'.", - DeprecationWarning, - ) - max_keepalive_connections = max_keepalive - - if isinstance(backend, str): - backend = lookup_sync_backend(backend) - - self._ssl_context = SSLContext() if ssl_context is None else ssl_context - self._max_connections = max_connections - self._max_keepalive_connections = max_keepalive_connections - self._keepalive_expiry = keepalive_expiry - self._http1 = http1 - self._http2 = http2 - self._uds = uds - self._local_address = local_address - self._retries = retries - self._connections: Dict[Origin, Set[SyncHTTPConnection]] = {} - self._thread_lock = ThreadLock() - self._backend = backend - self._next_keepalive_check = 0.0 - - if not (http1 or http2): - raise ValueError("Either http1 or http2 must be True.") - - if http2: - try: - import h2 # noqa: F401 - except ImportError: - raise ImportError( - "Attempted to use http2=True, but the 'h2' " - "package is not installed. Use 'pip install httpcore[http2]'." - ) - - @property - def _connection_semaphore(self) -> SyncSemaphore: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_internal_semaphore"): - if self._max_connections is not None: - self._internal_semaphore = self._backend.create_semaphore( - self._max_connections, exc_class=PoolTimeout - ) - else: - self._internal_semaphore = NullSemaphore() - - return self._internal_semaphore - - @property - def _connection_acquiry_lock(self) -> SyncLock: - if not hasattr(self, "_internal_connection_acquiry_lock"): - self._internal_connection_acquiry_lock = self._backend.create_lock() - return self._internal_connection_acquiry_lock - - def _create_connection( - self, - origin: Tuple[bytes, bytes, int], - ) -> SyncHTTPConnection: - return SyncHTTPConnection( - origin=origin, - http1=self._http1, - http2=self._http2, - keepalive_expiry=self._keepalive_expiry, - uds=self._uds, - ssl_context=self._ssl_context, - local_address=self._local_address, - retries=self._retries, - backend=self._backend, - ) - - def handle_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - if not url[0]: - raise UnsupportedProtocol( - "Request URL missing either an 'http://' or 'https://' protocol." - ) - - if url[0] not in (b"http", b"https"): - protocol = url[0].decode("ascii") - raise UnsupportedProtocol( - f"Request URL has an unsupported protocol '{protocol}://'." - ) - - if not url[1]: - raise LocalProtocolError("Missing hostname in URL.") - - origin = url_to_origin(url) - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - self._keepalive_sweep() - - connection: Optional[SyncHTTPConnection] = None - while connection is None: - with self._connection_acquiry_lock: - # We get-or-create a connection as an atomic operation, to ensure - # that HTTP/2 requests issued in close concurrency will end up - # on the same connection. - logger.trace("get_connection_from_pool=%r", origin) - connection = self._get_connection_from_pool(origin) - - if connection is None: - connection = self._create_connection(origin=origin) - logger.trace("created connection=%r", connection) - self._add_to_pool(connection, timeout=timeout) - else: - logger.trace("reuse connection=%r", connection) - - try: - response = connection.handle_request( - method, url, headers=headers, stream=stream, extensions=extensions - ) - except NewConnectionRequired: - connection = None - except BaseException: # noqa: PIE786 - # See https://github.com/encode/httpcore/pull/305 for motivation - # behind catching 'BaseException' rather than 'Exception' here. - logger.trace("remove from pool connection=%r", connection) - self._remove_from_pool(connection) - raise - - status_code, headers, stream, extensions = response - wrapped_stream = ResponseByteStream( - stream, connection=connection, callback=self._response_closed - ) - return status_code, headers, wrapped_stream, extensions - - def _get_connection_from_pool( - self, origin: Origin - ) -> Optional[SyncHTTPConnection]: - # Determine expired keep alive connections on this origin. - reuse_connection = None - connections_to_close = set() - - for connection in self._connections_for_origin(origin): - if connection.should_close(): - connections_to_close.add(connection) - self._remove_from_pool(connection) - elif connection.is_available(): - reuse_connection = connection - - # Close any dropped connections. - for connection in connections_to_close: - connection.close() - - return reuse_connection - - def _response_closed(self, connection: SyncHTTPConnection) -> None: - remove_from_pool = False - close_connection = False - - if connection.is_closed(): - remove_from_pool = True - elif connection.is_idle(): - num_connections = len(self._get_all_connections()) - if ( - self._max_keepalive_connections is not None - and num_connections > self._max_keepalive_connections - ): - remove_from_pool = True - close_connection = True - - if remove_from_pool: - self._remove_from_pool(connection) - - if close_connection: - connection.close() - - def _keepalive_sweep(self) -> None: - """ - Remove any IDLE connections that have expired past their keep-alive time. - """ - if self._keepalive_expiry is None: - return - - now = self._backend.time() - if now < self._next_keepalive_check: - return - - self._next_keepalive_check = now + min(1.0, self._keepalive_expiry) - connections_to_close = set() - - for connection in self._get_all_connections(): - if connection.should_close(): - connections_to_close.add(connection) - self._remove_from_pool(connection) - - for connection in connections_to_close: - connection.close() - - def _add_to_pool( - self, connection: SyncHTTPConnection, timeout: TimeoutDict - ) -> None: - logger.trace("adding connection to pool=%r", connection) - self._connection_semaphore.acquire(timeout=timeout.get("pool", None)) - with self._thread_lock: - self._connections.setdefault(connection.origin, set()) - self._connections[connection.origin].add(connection) - - def _remove_from_pool(self, connection: SyncHTTPConnection) -> None: - logger.trace("removing connection from pool=%r", connection) - with self._thread_lock: - if connection in self._connections.get(connection.origin, set()): - self._connection_semaphore.release() - self._connections[connection.origin].remove(connection) - if not self._connections[connection.origin]: - del self._connections[connection.origin] - - def _connections_for_origin(self, origin: Origin) -> Set[SyncHTTPConnection]: - return set(self._connections.get(origin, set())) - - def _get_all_connections(self) -> Set[SyncHTTPConnection]: - connections: Set[SyncHTTPConnection] = set() - for connection_set in self._connections.values(): - connections |= connection_set - return connections - - def close(self) -> None: - connections = self._get_all_connections() - for connection in connections: - self._remove_from_pool(connection) - - # Close all connections - for connection in connections: - connection.close() - - def get_connection_info(self) -> Dict[str, List[str]]: - """ - Returns a dict of origin URLs to a list of summary strings for each connection. - """ - self._keepalive_sweep() - - stats = {} - for origin, connections in self._connections.items(): - stats[origin_to_url_string(origin)] = sorted( - [connection.info() for connection in connections] - ) - return stats diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http.py deleted file mode 100644 index c128a96b..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http.py +++ /dev/null @@ -1,42 +0,0 @@ -from ssl import SSLContext - -from .._backends.sync import SyncSocketStream -from .._types import TimeoutDict -from .base import SyncHTTPTransport - - -class SyncBaseHTTPConnection(SyncHTTPTransport): - def info(self) -> str: - raise NotImplementedError() # pragma: nocover - - def should_close(self) -> bool: - """ - Return `True` if the connection is in a state where it should be closed. - """ - raise NotImplementedError() # pragma: nocover - - def is_idle(self) -> bool: - """ - Return `True` if the connection is currently idle. - """ - raise NotImplementedError() # pragma: nocover - - def is_closed(self) -> bool: - """ - Return `True` if the connection has been closed. - """ - raise NotImplementedError() # pragma: nocover - - def is_available(self) -> bool: - """ - Return `True` if the connection is currently able to accept an outgoing request. - """ - raise NotImplementedError() # pragma: nocover - - def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict = None - ) -> SyncSocketStream: - """ - Upgrade the underlying socket to TLS. - """ - raise NotImplementedError() # pragma: nocover diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http11.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http11.py deleted file mode 100644 index 5dbb42e0..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http11.py +++ /dev/null @@ -1,269 +0,0 @@ -import enum -import time -from ssl import SSLContext -from typing import Iterator, List, Optional, Tuple, Union, cast - -import h11 - -from .._backends.sync import SyncSocketStream -from .._bytestreams import IteratorByteStream -from .._exceptions import LocalProtocolError, RemoteProtocolError, map_exceptions -from .._types import URL, Headers, TimeoutDict -from .._utils import get_logger -from .base import SyncByteStream, NewConnectionRequired -from .http import SyncBaseHTTPConnection - -H11Event = Union[ - h11.Request, - h11.Response, - h11.InformationalResponse, - h11.Data, - h11.EndOfMessage, - h11.ConnectionClosed, -] - - -class ConnectionState(enum.IntEnum): - NEW = 0 - ACTIVE = 1 - IDLE = 2 - CLOSED = 3 - - -logger = get_logger(__name__) - - -class SyncHTTP11Connection(SyncBaseHTTPConnection): - READ_NUM_BYTES = 64 * 1024 - - def __init__(self, socket: SyncSocketStream, keepalive_expiry: float = None): - self.socket = socket - - self._keepalive_expiry: Optional[float] = keepalive_expiry - self._should_expire_at: Optional[float] = None - self._h11_state = h11.Connection(our_role=h11.CLIENT) - self._state = ConnectionState.NEW - - def __repr__(self) -> str: - return f"" - - def _now(self) -> float: - return time.monotonic() - - def _server_disconnected(self) -> bool: - """ - Return True if the connection is idle, and the underlying socket is readable. - The only valid state the socket can be readable here is when the b"" - EOF marker is about to be returned, indicating a server disconnect. - """ - return self._state == ConnectionState.IDLE and self.socket.is_readable() - - def _keepalive_expired(self) -> bool: - """ - Return True if the connection is idle, and has passed it's keepalive - expiry time. - """ - return ( - self._state == ConnectionState.IDLE - and self._should_expire_at is not None - and self._now() >= self._should_expire_at - ) - - def info(self) -> str: - return f"HTTP/1.1, {self._state.name}" - - def should_close(self) -> bool: - """ - Return `True` if the connection is in a state where it should be closed. - """ - return self._server_disconnected() or self._keepalive_expired() - - def is_idle(self) -> bool: - """ - Return `True` if the connection is currently idle. - """ - return self._state == ConnectionState.IDLE - - def is_closed(self) -> bool: - """ - Return `True` if the connection has been closed. - """ - return self._state == ConnectionState.CLOSED - - def is_available(self) -> bool: - """ - Return `True` if the connection is currently able to accept an outgoing request. - """ - return self._state == ConnectionState.IDLE - - def handle_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - """ - Send a single HTTP/1.1 request. - - Note that there is no kind of task/thread locking at this layer of interface. - Dealing with locking for concurrency is handled by the `SyncHTTPConnection`. - """ - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - if self._state in (ConnectionState.NEW, ConnectionState.IDLE): - self._state = ConnectionState.ACTIVE - self._should_expire_at = None - else: - raise NewConnectionRequired() - - self._send_request(method, url, headers, timeout) - self._send_request_body(stream, timeout) - ( - http_version, - status_code, - reason_phrase, - headers, - ) = self._receive_response(timeout) - response_stream = IteratorByteStream( - iterator=self._receive_response_data(timeout), - close_func=self._response_closed, - ) - extensions = { - "http_version": http_version, - "reason_phrase": reason_phrase, - } - return (status_code, headers, response_stream, extensions) - - def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict = None - ) -> SyncSocketStream: - timeout = {} if timeout is None else timeout - self.socket = self.socket.start_tls(hostname, ssl_context, timeout) - return self.socket - - def _send_request( - self, method: bytes, url: URL, headers: Headers, timeout: TimeoutDict - ) -> None: - """ - Send the request line and headers. - """ - logger.trace("send_request method=%r url=%r headers=%s", method, url, headers) - _scheme, _host, _port, target = url - with map_exceptions({h11.LocalProtocolError: LocalProtocolError}): - event = h11.Request(method=method, target=target, headers=headers) - self._send_event(event, timeout) - - def _send_request_body( - self, stream: SyncByteStream, timeout: TimeoutDict - ) -> None: - """ - Send the request body. - """ - # Send the request body. - for chunk in stream: - logger.trace("send_data=Data(<%d bytes>)", len(chunk)) - event = h11.Data(data=chunk) - self._send_event(event, timeout) - - # Finalize sending the request. - event = h11.EndOfMessage() - self._send_event(event, timeout) - - def _send_event(self, event: H11Event, timeout: TimeoutDict) -> None: - """ - Send a single `h11` event to the network, waiting for the data to - drain before returning. - """ - bytes_to_send = self._h11_state.send(event) - self.socket.write(bytes_to_send, timeout) - - def _receive_response( - self, timeout: TimeoutDict - ) -> Tuple[bytes, int, bytes, List[Tuple[bytes, bytes]]]: - """ - Read the response status and headers from the network. - """ - while True: - event = self._receive_event(timeout) - if isinstance(event, h11.Response): - break - - http_version = b"HTTP/" + event.http_version - - # h11 version 0.11+ supports a `raw_items` interface to get the - # raw header casing, rather than the enforced lowercase headers. - headers = event.headers.raw_items() - - return http_version, event.status_code, event.reason, headers - - def _receive_response_data( - self, timeout: TimeoutDict - ) -> Iterator[bytes]: - """ - Read the response data from the network. - """ - while True: - event = self._receive_event(timeout) - if isinstance(event, h11.Data): - logger.trace("receive_event=Data(<%d bytes>)", len(event.data)) - yield bytes(event.data) - elif isinstance(event, (h11.EndOfMessage, h11.PAUSED)): - logger.trace("receive_event=%r", event) - break - - def _receive_event(self, timeout: TimeoutDict) -> H11Event: - """ - Read a single `h11` event, reading more data from the network if needed. - """ - while True: - with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}): - event = self._h11_state.next_event() - - if event is h11.NEED_DATA: - data = self.socket.read(self.READ_NUM_BYTES, timeout) - - # If we feed this case through h11 we'll raise an exception like: - # - # httpcore.RemoteProtocolError: can't handle event type - # ConnectionClosed when role=SERVER and state=SEND_RESPONSE - # - # Which is accurate, but not very informative from an end-user - # perspective. Instead we handle messaging for this case distinctly. - if data == b"" and self._h11_state.their_state == h11.SEND_RESPONSE: - msg = "Server disconnected without sending a response." - raise RemoteProtocolError(msg) - - self._h11_state.receive_data(data) - else: - assert event is not h11.NEED_DATA - break - return event - - def _response_closed(self) -> None: - logger.trace( - "response_closed our_state=%r their_state=%r", - self._h11_state.our_state, - self._h11_state.their_state, - ) - if ( - self._h11_state.our_state is h11.DONE - and self._h11_state.their_state is h11.DONE - ): - self._h11_state.start_next_cycle() - self._state = ConnectionState.IDLE - if self._keepalive_expiry is not None: - self._should_expire_at = self._now() + self._keepalive_expiry - else: - self.close() - - def close(self) -> None: - if self._state != ConnectionState.CLOSED: - self._state = ConnectionState.CLOSED - - if self._h11_state.our_state is h11.MUST_CLOSE: - event = h11.ConnectionClosed() - self._h11_state.send(event) - - self.socket.close() diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http2.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http2.py deleted file mode 100644 index 90caf5fa..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http2.py +++ /dev/null @@ -1,446 +0,0 @@ -import enum -import time -from ssl import SSLContext -from typing import Iterator, Dict, List, Optional, Tuple, cast - -import h2.connection -import h2.events -from h2.config import H2Configuration -from h2.exceptions import NoAvailableStreamIDError -from h2.settings import SettingCodes, Settings - -from .._backends.sync import SyncBackend, SyncLock, SyncSemaphore, SyncSocketStream -from .._bytestreams import IteratorByteStream -from .._exceptions import LocalProtocolError, PoolTimeout, RemoteProtocolError -from .._types import URL, Headers, TimeoutDict -from .._utils import get_logger -from .base import SyncByteStream, NewConnectionRequired -from .http import SyncBaseHTTPConnection - -logger = get_logger(__name__) - - -class ConnectionState(enum.IntEnum): - IDLE = 0 - ACTIVE = 1 - CLOSED = 2 - - -class SyncHTTP2Connection(SyncBaseHTTPConnection): - READ_NUM_BYTES = 64 * 1024 - CONFIG = H2Configuration(validate_inbound_headers=False) - - def __init__( - self, - socket: SyncSocketStream, - backend: SyncBackend, - keepalive_expiry: float = None, - ): - self.socket = socket - - self._backend = backend - self._h2_state = h2.connection.H2Connection(config=self.CONFIG) - - self._sent_connection_init = False - self._streams: Dict[int, SyncHTTP2Stream] = {} - self._events: Dict[int, List[h2.events.Event]] = {} - - self._keepalive_expiry: Optional[float] = keepalive_expiry - self._should_expire_at: Optional[float] = None - self._state = ConnectionState.ACTIVE - self._exhausted_available_stream_ids = False - - def __repr__(self) -> str: - return f"" - - def info(self) -> str: - return f"HTTP/2, {self._state.name}, {len(self._streams)} streams" - - def _now(self) -> float: - return time.monotonic() - - def should_close(self) -> bool: - """ - Return `True` if the connection is currently idle, and the keepalive - timeout has passed. - """ - return ( - self._state == ConnectionState.IDLE - and self._should_expire_at is not None - and self._now() >= self._should_expire_at - ) - - def is_idle(self) -> bool: - """ - Return `True` if the connection is currently idle. - """ - return self._state == ConnectionState.IDLE - - def is_closed(self) -> bool: - """ - Return `True` if the connection has been closed. - """ - return self._state == ConnectionState.CLOSED - - def is_available(self) -> bool: - """ - Return `True` if the connection is currently able to accept an outgoing request. - This occurs when any of the following occur: - - * The connection has not yet been opened, and HTTP/2 support is enabled. - We don't *know* at this point if we'll end up on an HTTP/2 connection or - not, but we *might* do, so we indicate availability. - * The connection has been opened, and is currently idle. - * The connection is open, and is an HTTP/2 connection. The connection must - also not have exhausted the maximum total number of stream IDs. - """ - return ( - self._state != ConnectionState.CLOSED - and not self._exhausted_available_stream_ids - ) - - @property - def init_lock(self) -> SyncLock: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_initialization_lock"): - self._initialization_lock = self._backend.create_lock() - return self._initialization_lock - - @property - def read_lock(self) -> SyncLock: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_read_lock"): - self._read_lock = self._backend.create_lock() - return self._read_lock - - @property - def max_streams_semaphore(self) -> SyncSemaphore: - # We do this lazily, to make sure backend autodetection always - # runs within an async context. - if not hasattr(self, "_max_streams_semaphore"): - max_streams = self._h2_state.local_settings.max_concurrent_streams - self._max_streams_semaphore = self._backend.create_semaphore( - max_streams, exc_class=PoolTimeout - ) - return self._max_streams_semaphore - - def start_tls( - self, hostname: bytes, ssl_context: SSLContext, timeout: TimeoutDict = None - ) -> SyncSocketStream: - raise NotImplementedError("TLS upgrade not supported on HTTP/2 connections.") - - def handle_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - with self.init_lock: - if not self._sent_connection_init: - # The very first stream is responsible for initiating the connection. - self._state = ConnectionState.ACTIVE - self.send_connection_init(timeout) - self._sent_connection_init = True - - self.max_streams_semaphore.acquire() - try: - try: - stream_id = self._h2_state.get_next_available_stream_id() - except NoAvailableStreamIDError: - self._exhausted_available_stream_ids = True - raise NewConnectionRequired() - else: - self._state = ConnectionState.ACTIVE - self._should_expire_at = None - - h2_stream = SyncHTTP2Stream(stream_id=stream_id, connection=self) - self._streams[stream_id] = h2_stream - self._events[stream_id] = [] - return h2_stream.handle_request( - method, url, headers, stream, extensions - ) - except Exception: # noqa: PIE786 - self.max_streams_semaphore.release() - raise - - def send_connection_init(self, timeout: TimeoutDict) -> None: - """ - The HTTP/2 connection requires some initial setup before we can start - using individual request/response streams on it. - """ - # Need to set these manually here instead of manipulating via - # __setitem__() otherwise the H2Connection will emit SettingsUpdate - # frames in addition to sending the undesired defaults. - self._h2_state.local_settings = Settings( - client=True, - initial_values={ - # Disable PUSH_PROMISE frames from the server since we don't do anything - # with them for now. Maybe when we support caching? - SettingCodes.ENABLE_PUSH: 0, - # These two are taken from h2 for safe defaults - SettingCodes.MAX_CONCURRENT_STREAMS: 100, - SettingCodes.MAX_HEADER_LIST_SIZE: 65536, - }, - ) - - # Some websites (*cough* Yahoo *cough*) balk at this setting being - # present in the initial handshake since it's not defined in the original - # RFC despite the RFC mandating ignoring settings you don't know about. - del self._h2_state.local_settings[ - h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL - ] - - logger.trace("initiate_connection=%r", self) - self._h2_state.initiate_connection() - self._h2_state.increment_flow_control_window(2 ** 24) - data_to_send = self._h2_state.data_to_send() - self.socket.write(data_to_send, timeout) - - def is_socket_readable(self) -> bool: - return self.socket.is_readable() - - def close(self) -> None: - logger.trace("close_connection=%r", self) - if self._state != ConnectionState.CLOSED: - self._state = ConnectionState.CLOSED - - self.socket.close() - - def wait_for_outgoing_flow(self, stream_id: int, timeout: TimeoutDict) -> int: - """ - Returns the maximum allowable outgoing flow for a given stream. - If the allowable flow is zero, then waits on the network until - WindowUpdated frames have increased the flow rate. - https://tools.ietf.org/html/rfc7540#section-6.9 - """ - local_flow = self._h2_state.local_flow_control_window(stream_id) - connection_flow = self._h2_state.max_outbound_frame_size - flow = min(local_flow, connection_flow) - while flow == 0: - self.receive_events(timeout) - local_flow = self._h2_state.local_flow_control_window(stream_id) - connection_flow = self._h2_state.max_outbound_frame_size - flow = min(local_flow, connection_flow) - return flow - - def wait_for_event( - self, stream_id: int, timeout: TimeoutDict - ) -> h2.events.Event: - """ - Returns the next event for a given stream. - If no events are available yet, then waits on the network until - an event is available. - """ - with self.read_lock: - while not self._events[stream_id]: - self.receive_events(timeout) - return self._events[stream_id].pop(0) - - def receive_events(self, timeout: TimeoutDict) -> None: - """ - Read some data from the network, and update the H2 state. - """ - data = self.socket.read(self.READ_NUM_BYTES, timeout) - if data == b"": - raise RemoteProtocolError("Server disconnected") - - events = self._h2_state.receive_data(data) - for event in events: - event_stream_id = getattr(event, "stream_id", 0) - logger.trace("receive_event stream_id=%r event=%s", event_stream_id, event) - - if hasattr(event, "error_code"): - raise RemoteProtocolError(event) - - if event_stream_id in self._events: - self._events[event_stream_id].append(event) - - data_to_send = self._h2_state.data_to_send() - self.socket.write(data_to_send, timeout) - - def send_headers( - self, stream_id: int, headers: Headers, end_stream: bool, timeout: TimeoutDict - ) -> None: - logger.trace("send_headers stream_id=%r headers=%r", stream_id, headers) - self._h2_state.send_headers(stream_id, headers, end_stream=end_stream) - self._h2_state.increment_flow_control_window(2 ** 24, stream_id=stream_id) - data_to_send = self._h2_state.data_to_send() - self.socket.write(data_to_send, timeout) - - def send_data( - self, stream_id: int, chunk: bytes, timeout: TimeoutDict - ) -> None: - logger.trace("send_data stream_id=%r chunk=%r", stream_id, chunk) - self._h2_state.send_data(stream_id, chunk) - data_to_send = self._h2_state.data_to_send() - self.socket.write(data_to_send, timeout) - - def end_stream(self, stream_id: int, timeout: TimeoutDict) -> None: - logger.trace("end_stream stream_id=%r", stream_id) - self._h2_state.end_stream(stream_id) - data_to_send = self._h2_state.data_to_send() - self.socket.write(data_to_send, timeout) - - def acknowledge_received_data( - self, stream_id: int, amount: int, timeout: TimeoutDict - ) -> None: - self._h2_state.acknowledge_received_data(amount, stream_id) - data_to_send = self._h2_state.data_to_send() - self.socket.write(data_to_send, timeout) - - def close_stream(self, stream_id: int) -> None: - try: - logger.trace("close_stream stream_id=%r", stream_id) - del self._streams[stream_id] - del self._events[stream_id] - - if not self._streams: - if self._state == ConnectionState.ACTIVE: - if self._exhausted_available_stream_ids: - self.close() - else: - self._state = ConnectionState.IDLE - if self._keepalive_expiry is not None: - self._should_expire_at = ( - self._now() + self._keepalive_expiry - ) - finally: - self.max_streams_semaphore.release() - - -class SyncHTTP2Stream: - def __init__(self, stream_id: int, connection: SyncHTTP2Connection) -> None: - self.stream_id = stream_id - self.connection = connection - - def handle_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - headers = [(k.lower(), v) for (k, v) in headers] - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - - # Send the request. - seen_headers = set(key for key, value in headers) - has_body = ( - b"content-length" in seen_headers or b"transfer-encoding" in seen_headers - ) - - self.send_headers(method, url, headers, has_body, timeout) - if has_body: - self.send_body(stream, timeout) - - # Receive the response. - status_code, headers = self.receive_response(timeout) - response_stream = IteratorByteStream( - iterator=self.body_iter(timeout), close_func=self._response_closed - ) - - extensions = { - "http_version": b"HTTP/2", - } - return (status_code, headers, response_stream, extensions) - - def send_headers( - self, - method: bytes, - url: URL, - headers: Headers, - has_body: bool, - timeout: TimeoutDict, - ) -> None: - scheme, hostname, port, path = url - - # In HTTP/2 the ':authority' pseudo-header is used instead of 'Host'. - # In order to gracefully handle HTTP/1.1 and HTTP/2 we always require - # HTTP/1.1 style headers, and map them appropriately if we end up on - # an HTTP/2 connection. - authority = None - - for k, v in headers: - if k == b"host": - authority = v - break - - if authority is None: - # Mirror the same error we'd see with `h11`, so that the behaviour - # is consistent. Although we're dealing with an `:authority` - # pseudo-header by this point, from an end-user perspective the issue - # is that the outgoing request needed to include a `host` header. - raise LocalProtocolError("Missing mandatory Host: header") - - headers = [ - (b":method", method), - (b":authority", authority), - (b":scheme", scheme), - (b":path", path), - ] + [ - (k, v) - for k, v in headers - if k - not in ( - b"host", - b"transfer-encoding", - ) - ] - end_stream = not has_body - - self.connection.send_headers(self.stream_id, headers, end_stream, timeout) - - def send_body(self, stream: SyncByteStream, timeout: TimeoutDict) -> None: - for data in stream: - while data: - max_flow = self.connection.wait_for_outgoing_flow( - self.stream_id, timeout - ) - chunk_size = min(len(data), max_flow) - chunk, data = data[:chunk_size], data[chunk_size:] - self.connection.send_data(self.stream_id, chunk, timeout) - - self.connection.end_stream(self.stream_id, timeout) - - def receive_response( - self, timeout: TimeoutDict - ) -> Tuple[int, List[Tuple[bytes, bytes]]]: - """ - Read the response status and headers from the network. - """ - while True: - event = self.connection.wait_for_event(self.stream_id, timeout) - if isinstance(event, h2.events.ResponseReceived): - break - - status_code = 200 - headers = [] - for k, v in event.headers: - if k == b":status": - status_code = int(v.decode("ascii", errors="ignore")) - elif not k.startswith(b":"): - headers.append((k, v)) - - return (status_code, headers) - - def body_iter(self, timeout: TimeoutDict) -> Iterator[bytes]: - while True: - event = self.connection.wait_for_event(self.stream_id, timeout) - if isinstance(event, h2.events.DataReceived): - amount = event.flow_controlled_length - self.connection.acknowledge_received_data( - self.stream_id, amount, timeout - ) - yield event.data - elif isinstance(event, (h2.events.StreamEnded, h2.events.StreamReset)): - break - - def _response_closed(self) -> None: - self.connection.close_stream(self.stream_id) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http_proxy.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http_proxy.py deleted file mode 100644 index 78c02e29..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_sync/http_proxy.py +++ /dev/null @@ -1,290 +0,0 @@ -from http import HTTPStatus -from ssl import SSLContext -from typing import Tuple, cast - -from .._bytestreams import ByteStream -from .._exceptions import ProxyError -from .._types import URL, Headers, TimeoutDict -from .._utils import get_logger, url_to_origin -from .base import SyncByteStream -from .connection import SyncHTTPConnection -from .connection_pool import SyncConnectionPool, ResponseByteStream - -logger = get_logger(__name__) - - -def get_reason_phrase(status_code: int) -> str: - try: - return HTTPStatus(status_code).phrase - except ValueError: - return "" - - -def merge_headers( - default_headers: Headers = None, override_headers: Headers = None -) -> Headers: - """ - Append default_headers and override_headers, de-duplicating if a key existing in - both cases. - """ - default_headers = [] if default_headers is None else default_headers - override_headers = [] if override_headers is None else override_headers - has_override = set([key.lower() for key, value in override_headers]) - default_headers = [ - (key, value) - for key, value in default_headers - if key.lower() not in has_override - ] - return default_headers + override_headers - - -class SyncHTTPProxy(SyncConnectionPool): - """ - A connection pool for making HTTP requests via an HTTP proxy. - - Parameters - ---------- - proxy_url: - The URL of the proxy service as a 4-tuple of (scheme, host, port, path). - proxy_headers: - A list of proxy headers to include. - proxy_mode: - A proxy mode to operate in. May be "DEFAULT", "FORWARD_ONLY", or "TUNNEL_ONLY". - ssl_context: - An SSL context to use for verifying connections. - max_connections: - The maximum number of concurrent connections to allow. - max_keepalive_connections: - The maximum number of connections to allow before closing keep-alive - connections. - http2: - Enable HTTP/2 support. - """ - - def __init__( - self, - proxy_url: URL, - proxy_headers: Headers = None, - proxy_mode: str = "DEFAULT", - ssl_context: SSLContext = None, - max_connections: int = None, - max_keepalive_connections: int = None, - keepalive_expiry: float = None, - http2: bool = False, - backend: str = "sync", - # Deprecated argument style: - max_keepalive: int = None, - ): - assert proxy_mode in ("DEFAULT", "FORWARD_ONLY", "TUNNEL_ONLY") - - self.proxy_origin = url_to_origin(proxy_url) - self.proxy_headers = [] if proxy_headers is None else proxy_headers - self.proxy_mode = proxy_mode - super().__init__( - ssl_context=ssl_context, - max_connections=max_connections, - max_keepalive_connections=max_keepalive_connections, - keepalive_expiry=keepalive_expiry, - http2=http2, - backend=backend, - max_keepalive=max_keepalive, - ) - - def handle_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - if self._keepalive_expiry is not None: - self._keepalive_sweep() - - if ( - self.proxy_mode == "DEFAULT" and url[0] == b"http" - ) or self.proxy_mode == "FORWARD_ONLY": - # By default HTTP requests should be forwarded. - logger.trace( - "forward_request proxy_origin=%r proxy_headers=%r method=%r url=%r", - self.proxy_origin, - self.proxy_headers, - method, - url, - ) - return self._forward_request( - method, url, headers=headers, stream=stream, extensions=extensions - ) - else: - # By default HTTPS should be tunnelled. - logger.trace( - "tunnel_request proxy_origin=%r proxy_headers=%r method=%r url=%r", - self.proxy_origin, - self.proxy_headers, - method, - url, - ) - return self._tunnel_request( - method, url, headers=headers, stream=stream, extensions=extensions - ) - - def _forward_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - """ - Forwarded proxy requests include the entire URL as the HTTP target, - rather than just the path. - """ - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - origin = self.proxy_origin - connection = self._get_connection_from_pool(origin) - - if connection is None: - connection = SyncHTTPConnection( - origin=origin, - http2=self._http2, - keepalive_expiry=self._keepalive_expiry, - ssl_context=self._ssl_context, - ) - self._add_to_pool(connection, timeout) - - # Issue a forwarded proxy request... - - # GET https://www.example.org/path HTTP/1.1 - # [proxy headers] - # [headers] - scheme, host, port, path = url - if port is None: - target = b"%b://%b%b" % (scheme, host, path) - else: - target = b"%b://%b:%d%b" % (scheme, host, port, path) - - url = self.proxy_origin + (target,) - headers = merge_headers(self.proxy_headers, headers) - - ( - status_code, - headers, - stream, - extensions, - ) = connection.handle_request( - method, url, headers=headers, stream=stream, extensions=extensions - ) - - wrapped_stream = ResponseByteStream( - stream, connection=connection, callback=self._response_closed - ) - - return status_code, headers, wrapped_stream, extensions - - def _tunnel_request( - self, - method: bytes, - url: URL, - headers: Headers, - stream: SyncByteStream, - extensions: dict, - ) -> Tuple[int, Headers, SyncByteStream, dict]: - """ - Tunnelled proxy requests require an initial CONNECT request to - establish the connection, and then send regular requests. - """ - timeout = cast(TimeoutDict, extensions.get("timeout", {})) - origin = url_to_origin(url) - connection = self._get_connection_from_pool(origin) - - if connection is None: - scheme, host, port = origin - - # First, create a connection to the proxy server - proxy_connection = SyncHTTPConnection( - origin=self.proxy_origin, - http2=self._http2, - keepalive_expiry=self._keepalive_expiry, - ssl_context=self._ssl_context, - ) - - # Issue a CONNECT request... - - # CONNECT www.example.org:80 HTTP/1.1 - # [proxy-headers] - target = b"%b:%d" % (host, port) - connect_url = self.proxy_origin + (target,) - connect_headers = [(b"Host", target), (b"Accept", b"*/*")] - connect_headers = merge_headers(connect_headers, self.proxy_headers) - - try: - ( - proxy_status_code, - _, - proxy_stream, - _, - ) = proxy_connection.handle_request( - b"CONNECT", - connect_url, - headers=connect_headers, - stream=ByteStream(b""), - extensions=extensions, - ) - - proxy_reason = get_reason_phrase(proxy_status_code) - logger.trace( - "tunnel_response proxy_status_code=%r proxy_reason=%r ", - proxy_status_code, - proxy_reason, - ) - # Read the response data without closing the socket - for _ in proxy_stream: - pass - - # See if the tunnel was successfully established. - if proxy_status_code < 200 or proxy_status_code > 299: - msg = "%d %s" % (proxy_status_code, proxy_reason) - raise ProxyError(msg) - - # Upgrade to TLS if required - # We assume the target speaks TLS on the specified port - if scheme == b"https": - proxy_connection.start_tls(host, self._ssl_context, timeout) - except Exception as exc: - proxy_connection.close() - raise ProxyError(exc) - - # The CONNECT request is successful, so we have now SWITCHED PROTOCOLS. - # This means the proxy connection is now unusable, and we must create - # a new one for regular requests, making sure to use the same socket to - # retain the tunnel. - connection = SyncHTTPConnection( - origin=origin, - http2=self._http2, - keepalive_expiry=self._keepalive_expiry, - ssl_context=self._ssl_context, - socket=proxy_connection.socket, - ) - self._add_to_pool(connection, timeout) - - # Once the connection has been established we can send requests on - # it as normal. - ( - status_code, - headers, - stream, - extensions, - ) = connection.handle_request( - method, - url, - headers=headers, - stream=stream, - extensions=extensions, - ) - - wrapped_stream = ResponseByteStream( - stream, connection=connection, callback=self._response_closed - ) - - return status_code, headers, wrapped_stream, extensions diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_threadlock.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_threadlock.py deleted file mode 100644 index 2ff2bc37..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_threadlock.py +++ /dev/null @@ -1,35 +0,0 @@ -import threading -from types import TracebackType -from typing import Type - - -class ThreadLock: - """ - Provides thread safety when used as a sync context manager, or a - no-op when used as an async context manager. - """ - - def __init__(self) -> None: - self.lock = threading.Lock() - - def __enter__(self) -> None: - self.lock.acquire() - - def __exit__( - self, - exc_type: Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - self.lock.release() - - async def __aenter__(self) -> None: - pass - - async def __aexit__( - self, - exc_type: Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - pass diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_types.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_types.py deleted file mode 100644 index 2f9eeba7..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_types.py +++ /dev/null @@ -1,12 +0,0 @@ -""" -Type definitions for type checking purposes. -""" - -from typing import List, Mapping, Optional, Tuple, TypeVar, Union - -T = TypeVar("T") -StrOrBytes = Union[str, bytes] -Origin = Tuple[bytes, bytes, int] -URL = Tuple[bytes, bytes, Optional[int], bytes] -Headers = List[Tuple[bytes, bytes]] -TimeoutDict = Mapping[str, Optional[float]] diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_utils.py b/IKEA_scraper/.venv/Lib/site-packages/httpcore/_utils.py deleted file mode 100644 index 978b87a2..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpcore/_utils.py +++ /dev/null @@ -1,105 +0,0 @@ -import itertools -import logging -import os -import select -import socket -import sys -import typing - -from ._types import URL, Origin - -_LOGGER_INITIALIZED = False -TRACE_LOG_LEVEL = 5 -DEFAULT_PORTS = {b"http": 80, b"https": 443} - - -class Logger(logging.Logger): - # Stub for type checkers. - def trace(self, message: str, *args: typing.Any, **kwargs: typing.Any) -> None: - ... # pragma: nocover - - -def get_logger(name: str) -> Logger: - """ - Get a `logging.Logger` instance, and optionally - set up debug logging based on the HTTPCORE_LOG_LEVEL or HTTPX_LOG_LEVEL - environment variables. - """ - global _LOGGER_INITIALIZED - if not _LOGGER_INITIALIZED: - _LOGGER_INITIALIZED = True - logging.addLevelName(TRACE_LOG_LEVEL, "TRACE") - - log_level = os.environ.get( - "HTTPCORE_LOG_LEVEL", os.environ.get("HTTPX_LOG_LEVEL", "") - ).upper() - if log_level in ("DEBUG", "TRACE"): - logger = logging.getLogger("httpcore") - logger.setLevel(logging.DEBUG if log_level == "DEBUG" else TRACE_LOG_LEVEL) - handler = logging.StreamHandler(sys.stderr) - handler.setFormatter( - logging.Formatter( - fmt="%(levelname)s [%(asctime)s] %(name)s - %(message)s", - datefmt="%Y-%m-%d %H:%M:%S", - ) - ) - logger.addHandler(handler) - - logger = logging.getLogger(name) - - def trace(message: str, *args: typing.Any, **kwargs: typing.Any) -> None: - logger.log(TRACE_LOG_LEVEL, message, *args, **kwargs) - - logger.trace = trace # type: ignore - - return typing.cast(Logger, logger) - - -def url_to_origin(url: URL) -> Origin: - scheme, host, explicit_port = url[:3] - default_port = DEFAULT_PORTS[scheme] - port = default_port if explicit_port is None else explicit_port - return scheme, host, port - - -def origin_to_url_string(origin: Origin) -> str: - scheme, host, explicit_port = origin - port = f":{explicit_port}" if explicit_port != DEFAULT_PORTS[scheme] else "" - return f"{scheme.decode('ascii')}://{host.decode('ascii')}{port}" - - -def exponential_backoff(factor: float) -> typing.Iterator[float]: - yield 0 - for n in itertools.count(2): - yield factor * (2 ** (n - 2)) - - -def is_socket_readable(sock: typing.Optional[socket.socket]) -> bool: - """ - Return whether a socket, as identifed by its file descriptor, is readable. - - "A socket is readable" means that the read buffer isn't empty, i.e. that calling - .recv() on it would immediately return some data. - """ - # NOTE: we want check for readability without actually attempting to read, because - # we don't want to block forever if it's not readable. - - # In the case that the socket no longer exists, or cannot return a file - # descriptor, we treat it as being readable, as if it the next read operation - # on it is ready to return the terminating `b""`. - sock_fd = None if sock is None else sock.fileno() - if sock_fd is None or sock_fd < 0: - return True - - # The implementation below was stolen from: - # https://github.com/python-trio/trio/blob/20ee2b1b7376db637435d80e266212a35837ddcc/trio/_socket.py#L471-L478 - # See also: https://github.com/encode/httpcore/pull/193#issuecomment-703129316 - - # Use select.select on Windows, and when poll is unavailable and select.poll - # everywhere else. (E.g. When eventlet is in use. See #327) - if sys.platform == "win32" or getattr(select, "poll", None) is None: - rready, _, _ = select.select([sock_fd], [], [], 0) - return bool(rready) - p = select.poll() - p.register(sock_fd, select.POLLIN) - return bool(p.poll(0)) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpcore/py.typed b/IKEA_scraper/.venv/Lib/site-packages/httpcore/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/INSTALLER b/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/LICENSE.md b/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/LICENSE.md deleted file mode 100644 index ab79d16a..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright © 2019, [Encode OSS Ltd](https://www.encode.io/). -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its contributors may 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 HOLDER 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/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/METADATA b/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/METADATA deleted file mode 100644 index 8a07aad3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/METADATA +++ /dev/null @@ -1,990 +0,0 @@ -Metadata-Version: 2.1 -Name: httpx -Version: 0.19.0 -Summary: The next generation HTTP client. -Home-page: https://github.com/encode/httpx -Author: Tom Christie -Author-email: tom@tomchristie.com -License: BSD -Project-URL: Changelog, https://github.com/encode/httpx/blob/master/CHANGELOG.md -Project-URL: Documentation, https://www.python-httpx.org -Project-URL: Source, https://github.com/encode/httpx -Platform: UNKNOWN -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: Topic :: Internet :: WWW/HTTP -Classifier: Framework :: AsyncIO -Classifier: Framework :: Trio -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3 :: Only -Requires-Python: >=3.6 -Description-Content-Type: text/markdown -Requires-Dist: certifi -Requires-Dist: charset-normalizer -Requires-Dist: sniffio -Requires-Dist: rfc3986[idna2008] (<2,>=1.3) -Requires-Dist: httpcore (<0.14.0,>=0.13.3) -Requires-Dist: async-generator ; python_version < "3.7" -Provides-Extra: brotli -Requires-Dist: brotlicffi ; (platform_python_implementation != "CPython") and extra == 'brotli' -Requires-Dist: brotli ; (platform_python_implementation == "CPython") and extra == 'brotli' -Provides-Extra: http2 -Requires-Dist: h2 (<5,>=3) ; extra == 'http2' - -

- HTTPX -

- -

HTTPX - A next-generation HTTP client for Python.

- -

- - Test Suite - - - Package version - -

- -HTTPX is a fully featured HTTP client for Python 3, which provides sync and async APIs, and support for both HTTP/1.1 and HTTP/2. - -**Note**: _HTTPX should be considered in beta. We believe we've got the public API to -a stable point now, but would strongly recommend pinning your dependencies to the `0.19.*` -release, so that you're able to properly review [API changes between package updates](https://github.com/encode/httpx/blob/master/CHANGELOG.md). A 1.0 release is expected to be issued sometime in 2021._ - ---- - -Let's get started... - -```pycon ->>> import httpx ->>> r = httpx.get('https://www.example.org/') ->>> r - ->>> r.status_code -200 ->>> r.headers['content-type'] -'text/html; charset=UTF-8' ->>> r.text -'\n\n\nExample Domain...' -``` - -Or, using the async API... - -_Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.8+ with `python -m asyncio` to try this code interactively._ - -```pycon ->>> import httpx ->>> async with httpx.AsyncClient() as client: -... r = await client.get('https://www.example.org/') -... ->>> r - -``` - -## Features - -HTTPX builds on the well-established usability of `requests`, and gives you: - -* A broadly [requests-compatible API](https://www.python-httpx.org/compatibility/). -* Standard synchronous interface, but with [async support if you need it](https://www.python-httpx.org/async/). -* HTTP/1.1 [and HTTP/2 support](https://www.python-httpx.org/http2/). -* Ability to make requests directly to [WSGI applications](https://www.python-httpx.org/advanced/#calling-into-python-web-apps) or [ASGI applications](https://www.python-httpx.org/async/#calling-into-python-web-apps). -* Strict timeouts everywhere. -* Fully type annotated. -* 100% test coverage. - -Plus all the standard features of `requests`... - -* International Domains and URLs -* Keep-Alive & Connection Pooling -* Sessions with Cookie Persistence -* Browser-style SSL Verification -* Basic/Digest Authentication -* Elegant Key/Value Cookies -* Automatic Decompression -* Automatic Content Decoding -* Unicode Response Bodies -* Multipart File Uploads -* HTTP(S) Proxy Support -* Connection Timeouts -* Streaming Downloads -* .netrc Support -* Chunked Requests - -## Installation - -Install with pip: - -```shell -$ pip install httpx -``` - -Or, to include the optional HTTP/2 support, use: - -```shell -$ pip install httpx[http2] -``` - -HTTPX requires Python 3.6+. - -## Documentation - -Project documentation is available at [https://www.python-httpx.org/](https://www.python-httpx.org/). - -For a run-through of all the basics, head over to the [QuickStart](https://www.python-httpx.org/quickstart/). - -For more advanced topics, see the [Advanced Usage](https://www.python-httpx.org/advanced/) section, the [async support](https://www.python-httpx.org/async/) section, or the [HTTP/2](https://www.python-httpx.org/http2/) section. - -The [Developer Interface](https://www.python-httpx.org/api/) provides a comprehensive API reference. - -To find out about tools that integrate with HTTPX, see [Third Party Packages](https://www.python-httpx.org/third_party_packages/). - -## Contribute - -If you want to contribute with HTTPX check out the [Contributing Guide](https://www.python-httpx.org/contributing/) to learn how to start. - -## Dependencies - -The HTTPX project relies on these excellent libraries: - -* `httpcore` - The underlying transport implementation for `httpx`. - * `h11` - HTTP/1.1 support. - * `h2` - HTTP/2 support. *(Optional)* -* `certifi` - SSL certificates. -* `charset_normalizer` - Charset auto-detection. -* `rfc3986` - URL parsing & normalization. - * `idna` - Internationalized domain name support. -* `sniffio` - Async library autodetection. -* `async_generator` - Backport support for `contextlib.asynccontextmanager`. *(Only required for Python 3.6)* -* `brotli` or `brotlicffi` - Decoding for "brotli" compressed responses. *(Optional)* - -A huge amount of credit is due to `requests` for the API layout that -much of this work follows, as well as to `urllib3` for plenty of design -inspiration around the lower-level networking details. - -

— ⭐️ —

-

HTTPX is BSD licensed code. Designed & built in Brighton, England.

- - -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -## 0.19.0 (19th June, 2021) - -### Added - -* Add support for `Client(allow_redirects=)`. (Pull #1790) -* Add automatic character set detection, when no `charset` is included in the response `Content-Type` header. (Pull #1791) - -### Changed - -* Event hooks are now also called for any additional redirect or auth requests/responses. (Pull #1806) -* Strictly enforce that upload files must be opened in binary mode. (Pull #1736) -* Strictly enforce that client instances can only be opened and closed once, and cannot be re-opened. (Pull #1800) -* Drop `mode` argument from `httpx.Proxy(..., mode=...)`. (Pull #1795) - -## 0.18.2 (17th June, 2021) - -### Added - -* Support for Python 3.10. (Pull #1687) -* Expose `httpx.USE_CLIENT_DEFAULT`, used as the default to `auth` and `timeout` parameters in request methods. (Pull #1634) -* Support [HTTP/2 "prior knowledge"](https://python-hyper.org/projects/hyper-h2/en/v2.3.1/negotiating-http2.html#prior-knowledge), using `httpx.Client(http1=False, http2=True)`. (Pull #1624) - -### Fixed - -* Clean up some cases where warnings were being issued. (Pull #1687) -* Prefer Content-Length over Transfer-Encoding: chunked for content= cases. (Pull #1619) - -## 0.18.1 (29th April, 2021) - -### Changed - -* Update brotli support to use the `brotlicffi` package (Pull #1605) -* Ensure that `Request(..., stream=...)` does not auto-generate any headers on the request instance. (Pull #1607) - -### Fixed - -* Pass through `timeout=...` in top-level httpx.stream() function. (Pull #1613) -* Map httpcore transport close exceptions to httpx exceptions. (Pull #1606) - -## 0.18.0 (27th April, 2021) - -The 0.18.x release series formalises our low-level Transport API, introducing the base classes `httpx.BaseTransport` and `httpx.AsyncBaseTransport`. - -See the "[Writing custom transports](https://www.python-httpx.org/advanced/#writing-custom-transports)" documentation and the [`httpx.BaseTransport.handle_request()`](https://github.com/encode/httpx/blob/397aad98fdc8b7580a5fc3e88f1578b4302c6382/httpx/_transports/base.py#L77-L147) docstring for more complete details on implementing custom transports. - -Pull request #1522 includes a checklist of differences from the previous `httpcore` transport API, for developers implementing custom transports. - -The following API changes have been issuing deprecation warnings since 0.17.0 onwards, and are now fully deprecated... - -* You should now use httpx.codes consistently instead of httpx.StatusCodes. -* Use limits=... instead of pool_limits=.... -* Use proxies={"http://": ...} instead of proxies={"http": ...} for scheme-specific mounting. - -### Changed - -* Transport instances now inherit from `httpx.BaseTransport` or `httpx.AsyncBaseTransport`, - and should implement either the `handle_request` method or `handle_async_request` method. (Pull #1522, #1550) -* The `response.ext` property and `Response(ext=...)` argument are now named `extensions`. (Pull #1522) -* The recommendation to not use `data=` in favour of `content=` has now been escalated to a deprecation warning. (Pull #1573) -* Drop `Response(on_close=...)` from API, since it was a bit of leaking implementation detail. (Pull #1572) -* When using a client instance, cookies should always be set on the client, rather than on a per-request basis. We prefer enforcing a stricter API here because it provides clearer expectations around cookie persistence, particularly when redirects occur. (Pull #1574) -* The runtime exception `httpx.ResponseClosed` is now named `httpx.StreamClosed`. (#1584) -* The `httpx.QueryParams` model now presents an immutable interface. There is a discussion on [the design and motivation here](https://github.com/encode/httpx/discussions/1599). Use `client.params = client.params.merge(...)` instead of `client.params.update(...)`. The basic query manipulation methods are `query.set(...)`, `query.add(...)`, and `query.remove()`. (#1600) - -### Added - -* The `Request` and `Response` classes can now be serialized using pickle. (#1579) -* Handle `data={"key": [None|int|float|bool]}` cases. (Pull #1539) -* Support `httpx.URL(**kwargs)`, for example `httpx.URL(scheme="https", host="www.example.com", path="/')`, or `httpx.URL("https://www.example.com/", username="tom@gmail.com", password="123 456")`. (Pull #1601) -* Support `url.copy_with(params=...)`. (Pull #1601) -* Add `url.params` parameter, returning an immutable `QueryParams` instance. (Pull #1601) -* Support query manipulation methods on the URL class. These are `url.copy_set_param()`, `url.copy_add_param()`, `url.copy_remove_param()`, `url.copy_merge_params()`. (Pull #1601) -* The `httpx.URL` class now performs port normalization, so `:80` ports are stripped from `http` URLs and `:443` ports are stripped from `https` URLs. (Pull #1603) -* The `URL.host` property returns unicode strings for internationalized domain names. The `URL.raw_host` property returns byte strings with IDNA escaping applied. (Pull #1590) - -### Fixed - -* Fix Content-Length for cases of `files=...` where unicode string is used as the file content. (Pull #1537) -* Fix some cases of merging relative URLs against `Client(base_url=...)`. (Pull #1532) -* The `request.content` attribute is now always available except for streaming content, which requires an explicit `.read()`. (Pull #1583) - -## 0.17.1 (March 15th, 2021) - -### Fixed - -* Type annotation on `CertTypes` allows `keyfile` and `password` to be optional. (Pull #1503) -* Fix httpcore pinned version. (Pull #1495) - -## 0.17.0 (February 28th, 2021) - -### Added - -* Add `httpx.MockTransport()`, allowing to mock out a transport using pre-determined responses. (Pull #1401, Pull #1449) -* Add `httpx.HTTPTransport()` and `httpx.AsyncHTTPTransport()` default transports. (Pull #1399) -* Add mount API support, using `httpx.Client(mounts=...)`. (Pull #1362) -* Add `chunk_size` parameter to `iter_raw()`, `iter_bytes()`, `iter_text()`. (Pull #1277) -* Add `keepalive_expiry` parameter to `httpx.Limits()` configuration. (Pull #1398) -* Add repr to `httpx.Cookies` to display available cookies. (Pull #1411) -* Add support for `params=` (previously only `params=` was supported). (Pull #1426) - -### Fixed - -* Add missing `raw_path` to ASGI scope. (Pull #1357) -* Tweak `create_ssl_context` defaults to use `trust_env=True`. (Pull #1447) -* Properly URL-escape WSGI `PATH_INFO`. (Pull #1391) -* Properly set default ports in WSGI transport. (Pull #1469) -* Properly encode slashes when using `base_url`. (Pull #1407) -* Properly map exceptions in `request.aclose()`. (Pull #1465) - -## 0.16.1 (October 8th, 2020) - -### Fixed - -* Support literal IPv6 addresses in URLs. (Pull #1349) -* Force lowercase headers in ASGI scope dictionaries. (Pull #1351) - -## 0.16.0 (October 6th, 2020) - -### Changed - -* Preserve HTTP header casing. (Pull #1338, encode/httpcore#216, python-hyper/h11#104) -* Drop `response.next()` and `response.anext()` methods in favour of `response.next_request` attribute. (Pull #1339) -* Closed clients now raise a runtime error if attempting to send a request. (Pull #1346) - -### Added - -* Add Python 3.9 to officially supported versions. -* Type annotate `__enter__`/`__exit__`/`__aenter__`/`__aexit__` in a way that supports subclasses of `Client` and `AsyncClient`. (Pull #1336) - -## 0.15.5 (October 1st, 2020) - -### Added - -* Add `response.next_request` (Pull #1334) - -## 0.15.4 (September 25th, 2020) - -### Added - -* Support direct comparisons between `Headers` and dicts or lists of two-tuples. Eg. `assert response.headers == {"Content-Length": 24}` (Pull #1326) - -### Fixed - -* Fix automatic `.read()` when `Response` instances are created with `content=` (Pull #1324) - -## 0.15.3 (September 24th, 2020) - -### Fixed - -* Fixed connection leak in async client due to improper closing of response streams. (Pull #1316) - -## 0.15.2 (September 23nd, 2020) - -### Fixed - -* Fixed `response.elapsed` property. (Pull #1313) -* Fixed client authentication interaction with `.stream()`. (Pull #1312) - -## 0.15.1 (September 23nd, 2020) - -### Fixed - -* ASGITransport now properly applies URL decoding to the `path` component, as-per the ASGI spec. (Pull #1307) - -## 0.15.0 (September 22nd, 2020) - -### Added - -* Added support for curio. (Pull https://github.com/encode/httpcore/pull/168) -* Added support for event hooks. (Pull #1246) -* Added support for authentication flows which require either sync or async I/O. (Pull #1217) -* Added support for monitoring download progress with `response.num_bytes_downloaded`. (Pull #1268) -* Added `Request(content=...)` for byte content, instead of overloading `Request(data=...)` (Pull #1266) -* Added support for all URL components as parameter names when using `url.copy_with(...)`. (Pull #1285) -* Neater split between automatically populated headers on `Request` instances, vs default `client.headers`. (Pull #1248) -* Unclosed `AsyncClient` instances will now raise warnings if garbage collected. (Pull #1197) -* Support `Response(content=..., text=..., html=..., json=...)` for creating usable response instances in code. (Pull #1265, #1297) -* Support instantiating requests from the low-level transport API. (Pull #1293) -* Raise errors on invalid URL types. (Pull #1259) - -### Changed - -* Cleaned up expected behaviour for URL escaping. `url.path` is now URL escaped. (Pull #1285) -* Cleaned up expected behaviour for bytes vs str in URL components. `url.userinfo` and `url.query` are not URL escaped, and so return bytes. (Pull #1285) -* Drop `url.authority` property in favour of `url.netloc`, since "authority" was semantically incorrect. (Pull #1285) -* Drop `url.full_path` property in favour of `url.raw_path`, for better consistency with other parts of the API. (Pull #1285) -* No longer use the `chardet` library for auto-detecting charsets, instead defaulting to a simpler approach when no charset is specified. (#1269) - -### Fixed - -* Swapped ordering of redirects and authentication flow. (Pull #1267) -* `.netrc` lookups should use host, not host+port. (Pull #1298) - -### Removed - -* The `URLLib3Transport` class no longer exists. We've published it instead as an example of [a custom transport class](https://gist.github.com/florimondmanca/d56764d78d748eb9f73165da388e546e). (Pull #1182) -* Drop `request.timer` attribute, which was being used internally to set `response.elapsed`. (Pull #1249) -* Drop `response.decoder` attribute, which was being used internally. (Pull #1276) -* `Request.prepare()` is now a private method. (Pull #1284) -* The `Headers.getlist()` method had previously been deprecated in favour of `Headers.get_list()`. It is now fully removed. -* The `QueryParams.getlist()` method had previously been deprecated in favour of `QueryParams.get_list()`. It is now fully removed. -* The `URL.is_ssl` property had previously been deprecated in favour of `URL.scheme == "https"`. It is now fully removed. -* The `httpx.PoolLimits` class had previously been deprecated in favour of `httpx.Limits`. It is now fully removed. -* The `max_keepalive` setting had previously been deprecated in favour of the more explicit `max_keepalive_connections`. It is now fully removed. -* The verbose `httpx.Timeout(5.0, connect_timeout=60.0)` style had previously been deprecated in favour of `httpx.Timeout(5.0, connect=60.0)`. It is now fully removed. -* Support for instantiating a timeout config missing some defaults, such as `httpx.Timeout(connect=60.0)`, had previously been deprecated in favour of enforcing a more explicit style, such as `httpx.Timeout(5.0, connect=60.0)`. This is now strictly enforced. - -## 0.14.3 (September 2nd, 2020) - -### Added - -* `http.Response()` may now be instantiated without a `request=...` parameter. Useful for some unit testing cases. (Pull #1238) -* Add `103 Early Hints` and `425 Too Early` status codes. (Pull #1244) - -### Fixed - -* `DigestAuth` now handles responses that include multiple 'WWW-Authenticate' headers. (Pull #1240) -* Call into transport `__enter__`/`__exit__` or `__aenter__`/`__aexit__` when client is used in a context manager style. (Pull #1218) - -## 0.14.2 (August 24th, 2020) - -### Added - -* Support `client.get(..., auth=None)` to bypass the default authentication on a clients. (Pull #1115) -* Support `client.auth = ...` property setter. (Pull #1185) -* Support `httpx.get(..., proxies=...)` on top-level request functions. (Pull #1198) -* Display instances with nicer import styles. (Eg. ) (Pull #1155) -* Support `cookies=[(key, value)]` list-of-two-tuples style usage. (Pull #1211) - -### Fixed - -* Ensure that automatically included headers on a request may be modified. (Pull #1205) -* Allow explicit `Content-Length` header on streaming requests. (Pull #1170) -* Handle URL quoted usernames and passwords properly. (Pull #1159) -* Use more consistent default for `HEAD` requests, setting `allow_redirects=True`. (Pull #1183) -* If a transport error occurs while streaming the response, raise an `httpx` exception, not the underlying `httpcore` exception. (Pull #1190) -* Include the underlying `httpcore` traceback, when transport exceptions occur. (Pull #1199) - -## 0.14.1 (August 11th, 2020) - -### Added - -* The `httpx.URL(...)` class now raises `httpx.InvalidURL` on invalid URLs, rather than exposing the underlying `rfc3986` exception. If a redirect response includes an invalid 'Location' header, then a `RemoteProtocolError` exception is raised, which will be associated with the request that caused it. (Pull #1163) - -### Fixed - -* Handling multiple `Set-Cookie` headers became broken in the 0.14.0 release, and is now resolved. (Pull #1156) - -## 0.14.0 (August 7th, 2020) - -The 0.14 release includes a range of improvements to the public API, intended on preparing for our upcoming 1.0 release. - -* Our HTTP/2 support is now fully optional. **You now need to use `pip install httpx[http2]` if you want to include the HTTP/2 dependancies.** -* Our HSTS support has now been removed. Rewriting URLs from `http` to `https` if the host is on the HSTS list can be beneficial in avoiding roundtrips to incorrectly formed URLs, but on balance we've decided to remove this feature, on the principle of least surprise. Most programmatic clients do not include HSTS support, and for now we're opting to remove our support for it. -* Our exception hierarchy has been overhauled. Most users will want to stick with their existing `httpx.HTTPError` usage, but we've got a clearer overall structure now. See https://www.python-httpx.org/exceptions/ for more details. - -When upgrading you should be aware of the following public API changes. Note that deprecated usages will currently continue to function, but will issue warnings. - -* You should now use `httpx.codes` consistently instead of `httpx.StatusCodes`. -* Usage of `httpx.Timeout()` should now always include an explicit default. Eg. `httpx.Timeout(None, pool=5.0)`. -* When using `httpx.Timeout()`, we now have more concisely named keyword arguments. Eg. `read=5.0`, instead of `read_timeout=5.0`. -* Use `httpx.Limits()` instead of `httpx.PoolLimits()`, and `limits=...` instead of `pool_limits=...`. -* The `httpx.Limits(max_keepalive=...)` argument is now deprecated in favour of a more explicit `httpx.Limits(max_keepalive_connections=...)`. -* Keys used with `Client(proxies={...})` should now be in the style of `{"http://": ...}`, rather than `{"http": ...}`. -* The multidict methods `Headers.getlist()` and `QueryParams.getlist()` are deprecated in favour of more consistent `.get_list()` variants. -* The `URL.is_ssl` property is deprecated in favour of `URL.scheme == "https"`. -* The `URL.join(relative_url=...)` method is now `URL.join(url=...)`. This change does not support warnings for the deprecated usage style. - -One notable aspect of the 0.14.0 release is that it tightens up the public API for `httpx`, by ensuring that several internal attributes and methods have now become strictly private. - -The following previously had nominally public names on the client, but were all undocumented and intended solely for internal usage. They are all now replaced with underscored names, and should not be relied on or accessed. - -These changes should not affect users who have been working from the `httpx` documentation. - -* `.merge_url()`, `.merge_headers()`, `.merge_cookies()`, `.merge_queryparams()` -* `.build_auth()`, `.build_redirect_request()` -* `.redirect_method()`, `.redirect_url()`, `.redirect_headers()`, `.redirect_stream()` -* `.send_handling_redirects()`, `.send_handling_auth()`, `.send_single_request()` -* `.init_transport()`, `.init_proxy_transport()` -* `.proxies`, `.transport`, `.netrc`, `.get_proxy_map()` - -See pull requests #997, #1065, #1071. - -Some areas of API which were already on the deprecation path, and were raising warnings or errors in 0.13.x have now been escalated to being fully removed. - -* Drop `ASGIDispatch`, `WSGIDispatch`, which have been replaced by `ASGITransport`, `WSGITransport`. -* Drop `dispatch=...`` on client, which has been replaced by `transport=...`` -* Drop `soft_limit`, `hard_limit`, which have been replaced by `max_keepalive` and `max_connections`. -* Drop `Response.stream` and` `Response.raw`, which have been replaced by ``.aiter_bytes` and `.aiter_raw`. -* Drop `proxies=` in favor of `proxies=httpx.Proxy(...)`. - -See pull requests #1057, #1058. - -### Added - -* Added dedicated exception class `httpx.HTTPStatusError` for `.raise_for_status()` exceptions. (Pull #1072) -* Added `httpx.create_ssl_context()` helper function. (Pull #996) -* Support for proxy exlcusions like `proxies={"https://www.example.com": None}`. (Pull #1099) -* Support `QueryParams(None)` and `client.params = None`. (Pull #1060) - -### Changed - -* Use `httpx.codes` consistently in favour of `httpx.StatusCodes` which is placed into deprecation. (Pull #1088) -* Usage of `httpx.Timeout()` should now always include an explicit default. Eg. `httpx.Timeout(None, pool=5.0)`. (Pull #1085) -* Switch to more concise `httpx.Timeout()` keyword arguments. Eg. `read=5.0`, instead of `read_timeout=5.0`. (Pull #1111) -* Use `httpx.Limits()` instead of `httpx.PoolLimits()`, and `limits=...` instead of `pool_limits=...`. (Pull #1113) -* Keys used with `Client(proxies={...})` should now be in the style of `{"http://": ...}`, rather than `{"http": ...}`. (Pull #1127) -* The multidict methods `Headers.getlist` and `QueryParams.getlist` are deprecated in favour of more consistent `.get_list()` variants. (Pull #1089) -* `URL.port` becomes `Optional[int]`. Now only returns a port if one is explicitly included in the URL string. (Pull #1080) -* The `URL(..., allow_relative=[bool])` parameter no longer exists. All URL instances may be relative. (Pull #1073) -* Drop unnecessary `url.full_path = ...` property setter. (Pull #1069) -* The `URL.join(relative_url=...)` method is now `URL.join(url=...)`. (Pull #1129) -* The `URL.is_ssl` property is deprecated in favour of `URL.scheme == "https"`. (Pull #1128) - -### Fixed - -* Add missing `Response.next()` method. (Pull #1055) -* Ensure all exception classes are exposed as public API. (Pull #1045) -* Support multiple items with an identical field name in multipart encodings. (Pull #777) -* Skip HSTS preloading on single-label domains. (Pull #1074) -* Fixes for `Response.iter_lines()`. (Pull #1033, #1075) -* Ignore permission errors when accessing `.netrc` files. (Pull #1104) -* Allow bare hostnames in `HTTP_PROXY` etc... environment variables. (Pull #1120) -* Settings `app=...` or `transport=...` bypasses any environment based proxy defaults. (Pull #1122) -* Fix handling of `.base_url` when a path component is included in the base URL. (Pull #1130) - ---- - -## 0.13.3 (May 29th, 2020) - -### Fixed - -* Include missing keepalive expiry configuration. (Pull #1005) -* Improved error message when URL redirect has a custom scheme. (Pull #1002) - -## 0.13.2 (May 27th, 2020) - -### Fixed - -* Include explicit "Content-Length: 0" on POST, PUT, PATCH if no request body is used. (Pull #995) -* Add `http2` option to `httpx.Client`. (Pull #982) -* Tighten up API typing in places. (Pull #992, #999) - -## 0.13.1 (May 22nd, 2020) - -### Fixed - -* Fix pool options deprecation warning. (Pull #980) -* Include `httpx.URLLib3ProxyTransport` in top-level API. (Pull #979) - -## 0.13.0 (May 22nd, 2020) - -This release switches to `httpcore` for all the internal networking, which means: - -* We're using the same codebase for both our sync and async clients. -* HTTP/2 support is now available with the sync client. -* We no longer have a `urllib3` dependency for our sync client, although there is still an *optional* `URLLib3Transport` class. - -It also means we've had to remove our UDS support, since maintaining that would have meant having to push back our work towards a 1.0 release, which isn't a trade-off we wanted to make. - -We also now have [a public "Transport API"](https://www.python-httpx.org/advanced/#custom-transports), which you can use to implement custom transport implementations against. This formalises and replaces our previously private "Dispatch API". - -### Changed - -* Use `httpcore` for underlying HTTP transport. Drop `urllib3` requirement. (Pull #804, #967) -* Rename pool limit options from `soft_limit`/`hard_limit` to `max_keepalive`/`max_connections`. (Pull #968) -* The previous private "Dispatch API" has now been promoted to a public "Transport API". When customizing the transport use `transport=...`. The `ASGIDispatch` and `WSGIDispatch` class naming is deprecated in favour of `ASGITransport` and `WSGITransport`. (Pull #963) - -### Added - -* Added `URLLib3Transport` class for optional `urllib3` transport support. (Pull #804, #963) -* Streaming multipart uploads. (Pull #857) -* Logging via HTTPCORE_LOG_LEVEL and HTTPX_LOG_LEVEL environment variables -and TRACE level logging. (Pull encode/httpcore#79) - -### Fixed - -* Performance improvement in brotli decoder. (Pull #906) -* Proper warning level of deprecation notice in `Response.stream` and `Response.raw`. (Pull #908) -* Fix support for generator based WSGI apps. (Pull #887) -* Reuse of connections on HTTP/2 in close concurrency situations. (Pull encode/httpcore#81) -* Honor HTTP/2 max concurrent streams settings (Pull encode/httpcore#89, encode/httpcore#90) -* Fix bytes support in multipart uploads. (Pull #974) -* Improve typing support for `files=...`. (Pull #976) - -### Removed - -* Dropped support for `Client(uds=...)` (Pull #804) - -## 0.13.0.dev2 (May 12th, 2020) - -The 0.13.0.dev2 is a *pre-release* version. To install it, use `pip install httpx --pre`. - -### Added - -* Logging via HTTPCORE_LOG_LEVEL and HTTPX_LOG_LEVEL environment variables -and TRACE level logging. (HTTPCore Pull #79) - -### Fixed - -* Reuse of connections on HTTP/2 in close concurrency situations. (HTTPCore Pull #81) -* When using an `app=` observe neater disconnect behaviour instead of sending empty body messages. (Pull #919) - -## 0.13.0.dev1 (May 6th, 2020) - -The 0.13.0.dev1 is a *pre-release* version. To install it, use `pip install httpx --pre`. - -### Fixed - -* Passing `http2` flag to proxy dispatchers. (Pull #934) -* Use [`httpcore` v0.8.3](https://github.com/encode/httpcore/releases/tag/0.8.3) -which addresses problems in handling of headers when using proxies. - -## 0.13.0.dev0 (April 30th, 2020) - -The 0.13.0.dev0 is a *pre-release* version. To install it, use `pip install httpx --pre`. - -This release switches to `httpcore` for all the internal networking, which means: - -* We're using the same codebase for both our sync and async clients. -* HTTP/2 support is now available with the sync client. -* We no longer have a `urllib3` dependency for our sync client, although there is still an *optional* `URLLib3Dispatcher` class. - -It also means we've had to remove our UDS support, since maintaining that would have meant having to push back our work towards a 1.0 release, which isn't a trade-off we wanted to make. - -### Changed - -* Use `httpcore` for underlying HTTP transport. Drop `urllib3` requirement. (Pull #804) - -### Added - -* Added `URLLib3Dispatcher` class for optional `urllib3` transport support. (Pull #804) -* Streaming multipart uploads. (Pull #857) - -### Fixed - -* Performance improvement in brotli decoder. (Pull #906) -* Proper warning level of deprecation notice in `Response.stream` and `Response.raw`. (Pull #908) -* Fix support for generator based WSGI apps. (Pull #887) - -### Removed - -* Dropped support for `Client(uds=...)` (Pull #804) - ---- - -## 0.12.1 (March 19th, 2020) - -### Fixed - -* Resolved packaging issue, where additional files were being included. - -## 0.12.0 (March 9th, 2020) - -The 0.12 release tightens up the API expectations for `httpx` by switching to private module names to enforce better clarity around public API. - -All imports of `httpx` should import from the top-level package only, such as `from httpx import Request`, rather than importing from privately namespaced modules such as `from httpx._models import Request`. - -### Added - -* Support making response body available to auth classes with `.requires_response_body`. (Pull #803) -* Export `NetworkError` exception. (Pull #814) -* Add support for `NO_PROXY` environment variable. (Pull #835) - -### Changed - -* Switched to private module names. (Pull #785) -* Drop redirect looping detection and the `RedirectLoop` exception, instead using `TooManyRedirects`. (Pull #819) -* Drop `backend=...` parameter on `AsyncClient`, in favour of always autodetecting `trio`/`asyncio`. (Pull #791) - -### Fixed - -* Support basic auth credentials in proxy URLs. (Pull #780) -* Fix `httpx.Proxy(url, mode="FORWARD_ONLY")` configuration. (Pull #788) -* Fallback to setting headers as UTF-8 if no encoding is specified. (Pull #820) -* Close proxy dispatches classes on client close. (Pull #826) -* Support custom `cert` parameters even if `verify=False`. (Pull #796) -* Don't support invalid dict-of-dicts form data in `data=...`. (Pull #811) - ---- - -## 0.11.1 (January 17th, 2020) - -### Fixed - -* Fixed usage of `proxies=...` on `Client()`. (Pull #763) -* Support both `zlib` and `deflate` style encodings on `Content-Encoding: deflate`. (Pull #758) -* Fix for streaming a redirect response body with `allow_redirects=False`. (Pull #766) -* Handle redirect with malformed Location headers missing host. (Pull #774) - -## 0.11.0 (January 9th, 2020) - -The 0.11 release reintroduces our sync support, so that `httpx` now supports both a standard thread-concurrency API, and an async API. - -Existing async `httpx` users that are upgrading to 0.11 should ensure that: - -* Async codebases should always use a client instance to make requests, instead of the top-level API. -* The async client is named as `httpx.AsyncClient()`, instead of `httpx.Client()`. -* When instantiating proxy configurations use the `httpx.Proxy()` class, instead of the previous `httpx.HTTPProxy()`. This new configuration class works for configuring both sync and async clients. - -We believe the API is now pretty much stable, and are aiming for a 1.0 release sometime on or before April 2020. - -### Changed - -- Top level API such as `httpx.get(url, ...)`, `httpx.post(url, ...)`, `httpx.request(method, url, ...)` becomes synchronous. -- Added `httpx.Client()` for synchronous clients, with `httpx.AsyncClient` being used for async clients. -- Switched to `proxies=httpx.Proxy(...)` for proxy configuration. -- Network connection errors are wrapped in `httpx.NetworkError`, rather than exposing lower-level exception types directly. - -### Removed - -- The `request.url.origin` property and `httpx.Origin` class are no longer available. -- The per-request `cert`, `verify`, and `trust_env` arguments are escalated from raising errors if used, to no longer being available. These arguments should be used on a per-client instance instead, or in the top-level API. -- The `stream` argument has escalated from raising an error when used, to no longer being available. Use the `client.stream(...)` or `httpx.stream()` streaming API instead. - -### Fixed - -- Redirect loop detection matches against `(method, url)` rather than `url`. (Pull #734) - ---- - -## 0.10.1 (December 31st, 2019) - -### Fixed - -- Fix issue with concurrent connection acquiry. (Pull #700) -- Fix write error on closing HTTP/2 connections. (Pull #699) - -## 0.10.0 (December 29th, 2019) - -The 0.10.0 release makes some changes that will allow us to support both sync and async interfaces. - -In particular with streaming responses the `response.read()` method becomes `response.aread()`, and the `response.close()` method becomes `response.aclose()`. - -If following redirects explicitly the `response.next()` method becomes `response.anext()`. - -### Fixed - -- End HTTP/2 streams immediately on no-body requests, rather than sending an empty body message. (Pull #682) -- Improve typing for `Response.request`: switch from `Optional[Request]` to `Request`. (Pull #666) -- `Response.elapsed` now reflects the entire download time. (Pull #687, #692) - -### Changed - -- Added `AsyncClient` as a synonym for `Client`. (Pull #680) -- Switch to `response.aread()` for conditionally reading streaming responses. (Pull #674) -- Switch to `response.aclose()` and `client.aclose()` for explicit closing. (Pull #674, #675) -- Switch to `response.anext()` for resolving the next redirect response. (Pull #676) - -### Removed - -- When using a client instance, the per-request usage of `verify`, `cert`, and `trust_env` have now escalated from raising a warning to raising an error. You should set these arguments on the client instead. (Pull #617) -- Removed the undocumented `request.read()`, since end users should not require it. - ---- - -## 0.9.5 (December 20th, 2019) - -### Fixed - -- Fix Host header and HSTS rewrites when an explicit `:80` port is included in URL. (Pull #649) -- Query Params on the URL string are merged with any `params=...` argument. (Pull #653) -- More robust behavior when closing connections. (Pull #640) -- More robust behavior when handling HTTP/2 headers with trailing whitespace. (Pull #637) -- Allow any explicit `Content-Type` header to take precedence over the encoding default. (Pull #633) - -## 0.9.4 (December 12th, 2019) - -### Fixed - -- Added expiry to Keep-Alive connections, resolving issues with acquiring connections. (Pull #627) -- Increased flow control windows on HTTP/2, resolving download speed issues. (Pull #629) - -## 0.9.3 (December 7th, 2019) - -### Fixed - -- Fixed HTTP/2 with autodetection backend. (Pull #614) - -## 0.9.2 (December 7th, 2019) - -* Released due to packaging build artifact. - -## 0.9.1 (December 6th, 2019) - -* Released due to packaging build artifact. - -## 0.9.0 (December 6th, 2019) - -The 0.9 releases brings some major new features, including: - -* A new streaming API. -* Autodetection of either asyncio or trio. -* Nicer timeout configuration. -* HTTP/2 support off by default, but can be enabled. - -We've also removed all private types from the top-level package export. - -In order to ensure you are only ever working with public API you should make -sure to only import the top-level package eg. `import httpx`, rather than -importing modules within the package. - -### Added - -- Added concurrency backend autodetection. (Pull #585) -- Added `Client(backend='trio')` and `Client(backend='asyncio')` API. (Pull #585) -- Added `response.stream_lines()` API. (Pull #575) -- Added `response.is_error` API. (Pull #574) -- Added support for `timeout=Timeout(5.0, connect_timeout=60.0)` styles. (Pull #593) - -### Fixed - -- Requests or Clients with `timeout=None` now correctly always disable timeouts. (Pull #592) -- Request 'Authorization' headers now have priority over `.netrc` authentication info. (Commit 095b691) -- Files without a filename no longer set a Content-Type in multipart data. (Commit ed94950) - -### Changed - -- Added `httpx.stream()` API. Using `stream=True` now results in a warning. (Pull #600, #610) -- HTTP/2 support is switched to "off by default", but can be enabled explicitly. (Pull #584) -- Switched to `Client(http2=True)` API from `Client(http_versions=["HTTP/1.1", "HTTP/2"])`. (Pull #586) -- Removed all private types from the top-level package export. (Pull #608) -- The SSL configuration settings of `verify`, `cert`, and `trust_env` now raise warnings if used per-request when using a Client instance. They should always be set on the Client instance itself. (Pull #597) -- Use plain strings "TUNNEL_ONLY" or "FORWARD_ONLY" on the HTTPProxy `proxy_mode` argument. The `HTTPProxyMode` enum still exists, but its usage will raise warnings. (#610) -- Pool timeouts are now on the timeout configuration, not the pool limits configuration. (Pull #563) -- The timeout configuration is now named `httpx.Timeout(...)`, not `httpx.TimeoutConfig(...)`. The old version currently remains as a synonym for backwards compatability. (Pull #591) - ---- - -## 0.8.0 (November 27, 2019) - -### Removed - -- The synchronous API has been removed, in order to allow us to fundamentally change how we approach supporting both sync and async variants. (See #588 for more details.) - ---- - -## 0.7.8 (November 17, 2019) - -### Added - -- Add support for proxy tunnels for Python 3.6 + asyncio. (Pull #521) - -## 0.7.7 (November 15, 2019) - -### Fixed - -- Resolve an issue with cookies behavior on redirect requests. (Pull #529) - -### Added - -- Add request/response DEBUG logs. (Pull #502) -- Use TRACE log level for low level info. (Pull #500) - -## 0.7.6 (November 2, 2019) - -### Removed - -- Drop `proxies` parameter from the high-level API. (Pull #485) - -### Fixed - -- Tweak multipart files: omit null filenames, add support for `str` file contents. (Pull #482) -- Cache NETRC authentication per-client. (Pull #400) -- Rely on `getproxies` for all proxy environment variables. (Pull #470) -- Wait for the `asyncio` stream to close when closing a connection. (Pull #494) - -## 0.7.5 (October 10, 2019) - -### Added - -- Allow lists of values to be passed to `params`. (Pull #386) -- `ASGIDispatch`, `WSGIDispatch` are now available in the `httpx.dispatch` namespace. (Pull #407) -- `HTTPError` is now available in the `httpx` namespace. (Pull #421) -- Add support for `start_tls()` to the Trio concurrency backend. (Pull #467) - -### Fixed - -- Username and password are no longer included in the `Host` header when basic authentication - credentials are supplied via the URL. (Pull #417) - -### Removed - -- The `.delete()` function no longer has `json`, `data`, or `files` parameters - to match the expected semantics of the `DELETE` method. (Pull #408) -- Removed the `trio` extra. Trio support is detected automatically. (Pull #390) - -## 0.7.4 (September 25, 2019) - -### Added - -- Add Trio concurrency backend. (Pull #276) -- Add `params` parameter to `Client` for setting default query parameters. (Pull #372) -- Add support for `SSL_CERT_FILE` and `SSL_CERT_DIR` environment variables. (Pull #307) -- Add debug logging to calls into ASGI apps. (Pull #371) -- Add debug logging to SSL configuration. (Pull #378) - -### Fixed - -- Fix a bug when using `Client` without timeouts in Python 3.6. (Pull #383) -- Propagate `Client` configuration to HTTP proxies. (Pull #377) - -## 0.7.3 (September 20, 2019) - -### Added - -- HTTP Proxy support. (Pulls #259, #353) -- Add Digest authentication. (Pull #332) -- Add `.build_request()` method to `Client` and `AsyncClient`. (Pull #319) -- Add `.elapsed` property on responses. (Pull #351) -- Add support for `SSLKEYLOGFILE` in Python 3.8b4+. (Pull #301) - -### Removed - -- Drop NPN support for HTTP version negotiation. (Pull #314) - -### Fixed - -- Fix distribution of type annotations for mypy (Pull #361). -- Set `Host` header when redirecting cross-origin. (Pull #321) -- Drop `Content-Length` headers on `GET` redirects. (Pull #310) -- Raise `KeyError` if header isn't found in `Headers`. (Pull #324) -- Raise `NotRedirectResponse` in `response.next()` if there is no redirection to perform. (Pull #297) -- Fix bug in calculating the HTTP/2 maximum frame size. (Pull #153) - -## 0.7.2 (August 28, 2019) - -- Enforce using `httpx.AsyncioBackend` for the synchronous client. (Pull #232) -- `httpx.ConnectionPool` will properly release a dropped connection. (Pull #230) -- Remove the `raise_app_exceptions` argument from `Client`. (Pull #238) -- `DecodeError` will no longer be raised for an empty body encoded with Brotli. (Pull #237) -- Added `http_versions` parameter to `Client`. (Pull #250) -- Only use HTTP/1.1 on short-lived connections like `httpx.get()`. (Pull #284) -- Convert `Client.cookies` and `Client.headers` when set as a property. (Pull #274) -- Setting `HTTPX_DEBUG=1` enables debug logging on all requests. (Pull #277) - -## 0.7.1 (August 18, 2019) - -- Include files with source distribution to be installable. (Pull #233) - -## 0.7.0 (August 17, 2019) - -- Add the `trust_env` property to `BaseClient`. (Pull #187) -- Add the `links` property to `BaseResponse`. (Pull #211) -- Accept `ssl.SSLContext` instances into `SSLConfig(verify=...)`. (Pull #215) -- Add `Response.stream_text()` with incremental encoding detection. (Pull #183) -- Properly updated the `Host` header when a redirect changes the origin. (Pull #199) -- Ignore invalid `Content-Encoding` headers. (Pull #196) -- Use `~/.netrc` and `~/_netrc` files by default when `trust_env=True`. (Pull #189) -- Create exception base class `HTTPError` with `request` and `response` properties. (Pull #162) -- Add HSTS preload list checking within `BaseClient` to upgrade HTTP URLs to HTTPS. (Pull #184) -- Switch IDNA encoding from IDNA 2003 to IDNA 2008. (Pull #161) -- Expose base classes for alternate concurrency backends. (Pull #178) -- Improve Multipart parameter encoding. (Pull #167) -- Add the `headers` proeprty to `BaseClient`. (Pull #159) -- Add support for Google's `brotli` library. (Pull #156) -- Remove deprecated TLS versions (TLSv1 and TLSv1.1) from default `SSLConfig`. (Pull #155) -- Fix `URL.join(...)` to work similarly to RFC 3986 URL joining. (Pull #144) - ---- - -## 0.6.8 (July 25, 2019) - -- Check for disconnections when searching for an available - connection in `ConnectionPool.keepalive_connections` (Pull #145) -- Allow string comparison for `URL` objects (Pull #139) -- Add HTTP status codes 418 and 451 (Pull #135) -- Add support for client certificate passwords (Pull #118) -- Enable post-handshake client cert authentication for TLSv1.3 (Pull #118) -- Disable using `commonName` for hostname checking for OpenSSL 1.1.0+ (Pull #118) -- Detect encoding for `Response.json()` (Pull #116) - -## 0.6.7 (July 8, 2019) - -- Check for connection aliveness on re-acquiry (Pull #111) - -## 0.6.6 (July 3, 2019) - -- Improve `USER_AGENT` (Pull #110) -- Add `Connection: keep-alive` by default to HTTP/1.1 connections. (Pull #110) - -## 0.6.5 (June 27, 2019) - -- Include `Host` header by default. (Pull #109) -- Improve HTTP protocol detection. (Pull #107) - -## 0.6.4 (June 25, 2019) - -- Implement read and write timeouts (Pull #104) - -## 0.6.3 (June 24, 2019) - -- Handle early connection closes (Pull #103) - -## 0.6.2 (June 23, 2019) - -- Use urllib3's `DEFAULT_CIPHERS` for the `SSLConfig` object. (Pull #100) - -## 0.6.1 (June 21, 2019) - -- Add support for setting a `base_url` on the `Client`. - -## 0.6.0 (June 21, 2019) - -- Honor `local_flow_control_window` for HTTP/2 connections (Pull #98) - - diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/RECORD deleted file mode 100644 index e9acb0d1..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/RECORD +++ /dev/null @@ -1,50 +0,0 @@ -httpx-0.19.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -httpx-0.19.0.dist-info/LICENSE.md,sha256=TsWdVE8StfU5o6cW_TIaxYzNgDC0ZSIfLIgCAM3yjY0,1508 -httpx-0.19.0.dist-info/METADATA,sha256=a7mq7nlrwLwsYYiQBI5oLUrVdnjFRVtXZz3ZT0Mpra0,45612 -httpx-0.19.0.dist-info/RECORD,, -httpx-0.19.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -httpx-0.19.0.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 -httpx-0.19.0.dist-info/top_level.txt,sha256=8QYqFolXm27kV0x-8K8V5t-uZskSHKtq8jZVxGwtIq4,24 -httpx/__init__.py,sha256=UaP-xFey6dHDXR9KS5XZF9otl_3WNdk_2xGc1pB_7CE,2761 -httpx/__pycache__/__init__.cpython-39.pyc,, -httpx/__pycache__/__version__.cpython-39.pyc,, -httpx/__pycache__/_api.cpython-39.pyc,, -httpx/__pycache__/_auth.cpython-39.pyc,, -httpx/__pycache__/_client.cpython-39.pyc,, -httpx/__pycache__/_compat.cpython-39.pyc,, -httpx/__pycache__/_config.cpython-39.pyc,, -httpx/__pycache__/_content.cpython-39.pyc,, -httpx/__pycache__/_decoders.cpython-39.pyc,, -httpx/__pycache__/_exceptions.cpython-39.pyc,, -httpx/__pycache__/_models.cpython-39.pyc,, -httpx/__pycache__/_multipart.cpython-39.pyc,, -httpx/__pycache__/_status_codes.cpython-39.pyc,, -httpx/__pycache__/_types.cpython-39.pyc,, -httpx/__pycache__/_utils.cpython-39.pyc,, -httpx/__version__.py,sha256=XzEsmr71JIVGLXSchoYB6jqHfy9bLrz53XF5iCCle2k,108 -httpx/_api.py,sha256=HQxn11Qq20DXoSLNDTADpHsNaZZc1LbeQ6UT7dNkkCw,11676 -httpx/_auth.py,sha256=_oB2rvFKngdFpBvFSZKM1k7U1Q4rqRfimCmb7DmtVB0,10242 -httpx/_client.py,sha256=vYrgA06-EFHGIvICPlHRjdzi794UYmF0Kash3TwD9K0,65056 -httpx/_compat.py,sha256=sn1fBUUq7iIxOREBEa9VuDxAKP8kiHORSLI_h3fSi4k,1856 -httpx/_config.py,sha256=eAaNjV4RpAtvk-WzL_mgDx_-Y4gmsaMZMnuuY1vxA-0,11842 -httpx/_content.py,sha256=Z48LbGjD2tLH_oPB1dISGi4tpGWg-ncOngclWJblBGQ,6916 -httpx/_decoders.py,sha256=dz5F-Sud-HFLkdR715RDoqSiSmwi4E2hqmviNpgxNxc,10155 -httpx/_exceptions.py,sha256=MOrPYbCWreCtlgwn1msgaaTrvFBAM6t5GXe4X8ud9aM,7797 -httpx/_models.py,sha256=iU-BJ7eXQ8dmuDClF1ESq38xI6xzeUqs204CAYZoClk,66272 -httpx/_multipart.py,sha256=EB0v22oqGZUc-tZ2_Op72mdIWw7t5gNSS0hwU2VUOfw,6807 -httpx/_status_codes.py,sha256=b4bJYEAu6SsNKx1VhYAaM1UA20h7TyokwU57k3UuCqE,5313 -httpx/_transports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -httpx/_transports/__pycache__/__init__.cpython-39.pyc,, -httpx/_transports/__pycache__/asgi.cpython-39.pyc,, -httpx/_transports/__pycache__/base.cpython-39.pyc,, -httpx/_transports/__pycache__/default.cpython-39.pyc,, -httpx/_transports/__pycache__/mock.cpython-39.pyc,, -httpx/_transports/__pycache__/wsgi.cpython-39.pyc,, -httpx/_transports/asgi.py,sha256=yGmxK-GImAyCRzDUwlX7rFNLeRiohorlJEt2t04_tp0,5189 -httpx/_transports/base.py,sha256=vsxknZSyqLrd0bUTG7xqEjIJUEYyyEJd1QpWGLBd0Hk,6723 -httpx/_transports/default.py,sha256=aE6HQaXJSGL3uASapD3zrEKQDlFG8TF587hdksgR2G0,9461 -httpx/_transports/mock.py,sha256=ITDBS0y8Jg_yTNKXz3SSEnlNRD-c9Yws_I1Xh3JB_Vo,2063 -httpx/_transports/wsgi.py,sha256=954IFakUZse4SH_InSEDgKv2_c37RUUFkiqdMtRC6KI,4481 -httpx/_types.py,sha256=sM2JdaXu7Q3t74SryvYu6sTb1LULi6DdI_SCVJQ1yz4,2202 -httpx/_utils.py,sha256=yen2GFqPpU8VUQ0vuPOwu31XFE4ocsa9FheV6aq4qGs,16568 -httpx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/REQUESTED b/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/REQUESTED deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/WHEEL b/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/WHEEL deleted file mode 100644 index 5bad85fd..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.0) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/top_level.txt b/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/top_level.txt deleted file mode 100644 index c180eb2f..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx-0.19.0.dist-info/top_level.txt +++ /dev/null @@ -1,2 +0,0 @@ -httpx -httpx/_transports diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/__init__.py deleted file mode 100644 index 4af3904f..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/__init__.py +++ /dev/null @@ -1,124 +0,0 @@ -from .__version__ import __description__, __title__, __version__ -from ._api import delete, get, head, options, patch, post, put, request, stream -from ._auth import Auth, BasicAuth, DigestAuth -from ._client import USE_CLIENT_DEFAULT, AsyncClient, Client -from ._config import Limits, Proxy, Timeout, create_ssl_context -from ._content import ByteStream -from ._exceptions import ( - CloseError, - ConnectError, - ConnectTimeout, - CookieConflict, - DecodingError, - HTTPError, - HTTPStatusError, - InvalidURL, - LocalProtocolError, - NetworkError, - PoolTimeout, - ProtocolError, - ProxyError, - ReadError, - ReadTimeout, - RemoteProtocolError, - RequestError, - RequestNotRead, - ResponseNotRead, - StreamClosed, - StreamConsumed, - StreamError, - TimeoutException, - TooManyRedirects, - TransportError, - UnsupportedProtocol, - WriteError, - WriteTimeout, -) -from ._models import URL, Cookies, Headers, QueryParams, Request, Response -from ._status_codes import codes -from ._transports.asgi import ASGITransport -from ._transports.base import ( - AsyncBaseTransport, - AsyncByteStream, - BaseTransport, - SyncByteStream, -) -from ._transports.default import AsyncHTTPTransport, HTTPTransport -from ._transports.mock import MockTransport -from ._transports.wsgi import WSGITransport - -__all__ = [ - "__description__", - "__title__", - "__version__", - "ASGITransport", - "AsyncBaseTransport", - "AsyncByteStream", - "AsyncClient", - "AsyncHTTPTransport", - "Auth", - "BaseTransport", - "BasicAuth", - "ByteStream", - "Client", - "CloseError", - "codes", - "ConnectError", - "ConnectTimeout", - "CookieConflict", - "Cookies", - "create_ssl_context", - "DecodingError", - "delete", - "DigestAuth", - "get", - "head", - "Headers", - "HTTPError", - "HTTPStatusError", - "HTTPTransport", - "InvalidURL", - "Limits", - "LocalProtocolError", - "MockTransport", - "NetworkError", - "options", - "patch", - "PoolTimeout", - "post", - "ProtocolError", - "Proxy", - "ProxyError", - "put", - "QueryParams", - "ReadError", - "ReadTimeout", - "RemoteProtocolError", - "request", - "Request", - "RequestError", - "RequestNotRead", - "Response", - "ResponseNotRead", - "stream", - "StreamClosed", - "StreamConsumed", - "StreamError", - "SyncByteStream", - "Timeout", - "TimeoutException", - "TooManyRedirects", - "TransportError", - "UnsupportedProtocol", - "URL", - "USE_CLIENT_DEFAULT", - "WriteError", - "WriteTimeout", - "WSGITransport", -] - - -__locals = locals() -for __name in __all__: - if not __name.startswith("__"): - setattr(__locals[__name], "__module__", "httpx") # noqa diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 01b0d7e06de9ca69f3f9efa2a2ea854ac383be83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2452 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 V!PKFdD}SR{l}{_R%2^6S{vUo)-`fBH diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_content.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_content.cpython-39.pyc deleted file mode 100644 index 429fa64e4477a433ec80eeef010f8f955860d57b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6764 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_exceptions.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_exceptions.cpython-39.pyc deleted file mode 100644 index 8bd0c058847e9cb8a2f058e13bdface44dec7664..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10584 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%0Aly4wirk!VTkF(kBXAw&vgJ_q0 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 M_+1=qd1>bV3xzG6H2?qr diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_multipart.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_multipart.cpython-39.pyc deleted file mode 100644 index 937b9945f14434906946d12ee930d4a53a6527e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6496 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_status_codes.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_status_codes.cpython-39.pyc deleted file mode 100644 index 749673ca1fe56a26bd488ca65c96a1d283435b63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5612 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_types.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/__pycache__/_types.cpython-39.pyc deleted file mode 100644 index bf3bf66f35361824231596d814872c7bbdca6303..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1709 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/__version__.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/__version__.py deleted file mode 100644 index bab8a1c0..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/__version__.py +++ /dev/null @@ -1,3 +0,0 @@ -__title__ = "httpx" -__description__ = "A next generation HTTP client, for Python 3." -__version__ = "0.19.0" diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_api.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_api.py deleted file mode 100644 index da818538..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_api.py +++ /dev/null @@ -1,445 +0,0 @@ -import typing -from contextlib import contextmanager - -from ._client import Client -from ._config import DEFAULT_TIMEOUT_CONFIG -from ._models import Response -from ._types import ( - AuthTypes, - CertTypes, - CookieTypes, - HeaderTypes, - ProxiesTypes, - QueryParamTypes, - RequestContent, - RequestData, - RequestFiles, - TimeoutTypes, - URLTypes, - VerifyTypes, -) - - -def request( - method: str, - url: URLTypes, - *, - params: QueryParamTypes = None, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - allow_redirects: bool = True, - verify: VerifyTypes = True, - cert: CertTypes = None, - trust_env: bool = True, -) -> Response: - """ - Sends an HTTP request. - - **Parameters:** - - * **method** - HTTP method for the new `Request` object: `GET`, `OPTIONS`, - `HEAD`, `POST`, `PUT`, `PATCH`, or `DELETE`. - * **url** - URL for the new `Request` object. - * **params** - *(optional)* Query parameters to include in the URL, as a - string, dictionary, or sequence of two-tuples. - * **content** - *(optional)* Binary content to include in the body of the - request, as bytes or a byte iterator. - * **data** - *(optional)* Form data to include in the body of the request, - as a dictionary. - * **files** - *(optional)* A dictionary of upload files to include in the - body of the request. - * **json** - *(optional)* A JSON serializable object to include in the body - of the request. - * **headers** - *(optional)* Dictionary of HTTP headers to include in the - request. - * **cookies** - *(optional)* Dictionary of Cookie items to include in the - request. - * **auth** - *(optional)* An authentication class to use when sending the - request. - * **proxies** - *(optional)* A dictionary mapping proxy keys to proxy URLs. - * **timeout** - *(optional)* The timeout configuration to use when sending - the request. - * **allow_redirects** - *(optional)* Enables or disables HTTP redirects. - * **verify** - *(optional)* SSL certificates (a.k.a CA bundle) used to - verify the identity of requested hosts. Either `True` (default CA bundle), - a path to an SSL certificate file, an `ssl.SSLContext`, or `False` - (which will disable verification). - * **cert** - *(optional)* An SSL certificate used by the requested host - to authenticate the client. Either a path to an SSL certificate file, or - two-tuple of (certificate file, key file), or a three-tuple of (certificate - file, key file, password). - * **trust_env** - *(optional)* Enables or disables usage of environment - variables for configuration. - - **Returns:** `Response` - - Usage: - - ``` - >>> import httpx - >>> response = httpx.request('GET', 'https://httpbin.org/get') - >>> response - - ``` - """ - with Client( - cookies=cookies, - proxies=proxies, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) as client: - return client.request( - method=method, - url=url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - auth=auth, - allow_redirects=allow_redirects, - ) - - -@contextmanager -def stream( - method: str, - url: URLTypes, - *, - params: QueryParamTypes = None, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - allow_redirects: bool = True, - verify: VerifyTypes = True, - cert: CertTypes = None, - trust_env: bool = True, -) -> typing.Iterator[Response]: - """ - Alternative to `httpx.request()` that streams the response body - instead of loading it into memory at once. - - **Parameters**: See `httpx.request`. - - See also: [Streaming Responses][0] - - [0]: /quickstart#streaming-responses - """ - with Client( - cookies=cookies, - proxies=proxies, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) as client: - with client.stream( - method=method, - url=url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - auth=auth, - allow_redirects=allow_redirects, - ) as response: - yield response - - -def get( - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - allow_redirects: bool = True, - cert: CertTypes = None, - verify: VerifyTypes = True, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - trust_env: bool = True, -) -> Response: - """ - Sends a `GET` request. - - **Parameters**: See `httpx.request`. - - Note that the `data`, `files`, and `json` parameters are not available on - this function, as `GET` requests should not include a request body. - """ - return request( - "GET", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - proxies=proxies, - allow_redirects=allow_redirects, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) - - -def options( - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - allow_redirects: bool = True, - cert: CertTypes = None, - verify: VerifyTypes = True, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - trust_env: bool = True, -) -> Response: - """ - Sends an `OPTIONS` request. - - **Parameters**: See `httpx.request`. - - Note that the `data`, `files`, and `json` parameters are not available on - this function, as `OPTIONS` requests should not include a request body. - """ - return request( - "OPTIONS", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - proxies=proxies, - allow_redirects=allow_redirects, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) - - -def head( - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - allow_redirects: bool = True, - cert: CertTypes = None, - verify: VerifyTypes = True, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - trust_env: bool = True, -) -> Response: - """ - Sends a `HEAD` request. - - **Parameters**: See `httpx.request`. - - Note that the `data`, `files`, and `json` parameters are not available on - this function, as `HEAD` requests should not include a request body. - """ - return request( - "HEAD", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - proxies=proxies, - allow_redirects=allow_redirects, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) - - -def post( - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - allow_redirects: bool = True, - cert: CertTypes = None, - verify: VerifyTypes = True, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - trust_env: bool = True, -) -> Response: - """ - Sends a `POST` request. - - **Parameters**: See `httpx.request`. - """ - return request( - "POST", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - proxies=proxies, - allow_redirects=allow_redirects, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) - - -def put( - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - allow_redirects: bool = True, - cert: CertTypes = None, - verify: VerifyTypes = True, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - trust_env: bool = True, -) -> Response: - """ - Sends a `PUT` request. - - **Parameters**: See `httpx.request`. - """ - return request( - "PUT", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - proxies=proxies, - allow_redirects=allow_redirects, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) - - -def patch( - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - allow_redirects: bool = True, - cert: CertTypes = None, - verify: VerifyTypes = True, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - trust_env: bool = True, -) -> Response: - """ - Sends a `PATCH` request. - - **Parameters**: See `httpx.request`. - """ - return request( - "PATCH", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - proxies=proxies, - allow_redirects=allow_redirects, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) - - -def delete( - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: AuthTypes = None, - proxies: ProxiesTypes = None, - allow_redirects: bool = True, - cert: CertTypes = None, - verify: VerifyTypes = True, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - trust_env: bool = True, -) -> Response: - """ - Sends a `DELETE` request. - - **Parameters**: See `httpx.request`. - - Note that the `data`, `files`, and `json` parameters are not available on - this function, as `DELETE` requests should not include a request body. - """ - return request( - "DELETE", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - proxies=proxies, - allow_redirects=allow_redirects, - cert=cert, - verify=verify, - timeout=timeout, - trust_env=trust_env, - ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_auth.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_auth.py deleted file mode 100644 index 343f9cdd..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_auth.py +++ /dev/null @@ -1,304 +0,0 @@ -import hashlib -import os -import re -import time -import typing -from base64 import b64encode -from urllib.request import parse_http_list - -from ._exceptions import ProtocolError -from ._models import Request, Response -from ._utils import to_bytes, to_str, unquote - - -class Auth: - """ - Base class for all authentication schemes. - - To implement a custom authentication scheme, subclass `Auth` and override - the `.auth_flow()` method. - - If the authentication scheme does I/O such as disk access or network calls, or uses - synchronization primitives such as locks, you should override `.sync_auth_flow()` - and/or `.async_auth_flow()` instead of `.auth_flow()` to provide specialized - implementations that will be used by `Client` and `AsyncClient` respectively. - """ - - requires_request_body = False - requires_response_body = False - - def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: - """ - Execute the authentication flow. - - To dispatch a request, `yield` it: - - ``` - yield request - ``` - - The client will `.send()` the response back into the flow generator. You can - access it like so: - - ``` - response = yield request - ``` - - A `return` (or reaching the end of the generator) will result in the - client returning the last response obtained from the server. - - You can dispatch as many requests as is necessary. - """ - yield request - - def sync_auth_flow( - self, request: Request - ) -> typing.Generator[Request, Response, None]: - """ - Execute the authentication flow synchronously. - - By default, this defers to `.auth_flow()`. You should override this method - when the authentication scheme does I/O and/or uses concurrency primitives. - """ - if self.requires_request_body: - request.read() - - flow = self.auth_flow(request) - request = next(flow) - - while True: - response = yield request - if self.requires_response_body: - response.read() - - try: - request = flow.send(response) - except StopIteration: - break - - async def async_auth_flow( - self, request: Request - ) -> typing.AsyncGenerator[Request, Response]: - """ - Execute the authentication flow asynchronously. - - By default, this defers to `.auth_flow()`. You should override this method - when the authentication scheme does I/O and/or uses concurrency primitives. - """ - if self.requires_request_body: - await request.aread() - - flow = self.auth_flow(request) - request = next(flow) - - while True: - response = yield request - if self.requires_response_body: - await response.aread() - - try: - request = flow.send(response) - except StopIteration: - break - - -class FunctionAuth(Auth): - """ - Allows the 'auth' argument to be passed as a simple callable function, - that takes the request, and returns a new, modified request. - """ - - def __init__(self, func: typing.Callable[[Request], Request]) -> None: - self._func = func - - def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: - yield self._func(request) - - -class BasicAuth(Auth): - """ - Allows the 'auth' argument to be passed as a (username, password) pair, - and uses HTTP Basic authentication. - """ - - def __init__( - self, username: typing.Union[str, bytes], password: typing.Union[str, bytes] - ): - self._auth_header = self._build_auth_header(username, password) - - def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: - request.headers["Authorization"] = self._auth_header - yield request - - def _build_auth_header( - self, username: typing.Union[str, bytes], password: typing.Union[str, bytes] - ) -> str: - userpass = b":".join((to_bytes(username), to_bytes(password))) - token = b64encode(userpass).decode() - return f"Basic {token}" - - -class DigestAuth(Auth): - _ALGORITHM_TO_HASH_FUNCTION: typing.Dict[str, typing.Callable] = { - "MD5": hashlib.md5, - "MD5-SESS": hashlib.md5, - "SHA": hashlib.sha1, - "SHA-SESS": hashlib.sha1, - "SHA-256": hashlib.sha256, - "SHA-256-SESS": hashlib.sha256, - "SHA-512": hashlib.sha512, - "SHA-512-SESS": hashlib.sha512, - } - - def __init__( - self, username: typing.Union[str, bytes], password: typing.Union[str, bytes] - ) -> None: - self._username = to_bytes(username) - self._password = to_bytes(password) - - def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: - response = yield request - - if response.status_code != 401 or "www-authenticate" not in response.headers: - # If the response is not a 401 then we don't - # need to build an authenticated request. - return - - for auth_header in response.headers.get_list("www-authenticate"): - if auth_header.lower().startswith("digest "): - break - else: - # If the response does not include a 'WWW-Authenticate: Digest ...' - # header, then we don't need to build an authenticated request. - return - - challenge = self._parse_challenge(request, response, auth_header) - request.headers["Authorization"] = self._build_auth_header(request, challenge) - yield request - - def _parse_challenge( - self, request: Request, response: Response, auth_header: str - ) -> "_DigestAuthChallenge": - """ - Returns a challenge from a Digest WWW-Authenticate header. - These take the form of: - `Digest realm="realm@host.com",qop="auth,auth-int",nonce="abc",opaque="xyz"` - """ - scheme, _, fields = auth_header.partition(" ") - - # This method should only ever have been called with a Digest auth header. - assert scheme.lower() == "digest" - - header_dict: typing.Dict[str, str] = {} - for field in parse_http_list(fields): - key, value = field.strip().split("=", 1) - header_dict[key] = unquote(value) - - try: - realm = header_dict["realm"].encode() - nonce = header_dict["nonce"].encode() - algorithm = header_dict.get("algorithm", "MD5") - opaque = header_dict["opaque"].encode() if "opaque" in header_dict else None - qop = header_dict["qop"].encode() if "qop" in header_dict else None - return _DigestAuthChallenge( - realm=realm, nonce=nonce, algorithm=algorithm, opaque=opaque, qop=qop - ) - except KeyError as exc: - message = "Malformed Digest WWW-Authenticate header" - raise ProtocolError(message, request=request) from exc - - def _build_auth_header( - self, request: Request, challenge: "_DigestAuthChallenge" - ) -> str: - hash_func = self._ALGORITHM_TO_HASH_FUNCTION[challenge.algorithm] - - def digest(data: bytes) -> bytes: - return hash_func(data).hexdigest().encode() - - A1 = b":".join((self._username, challenge.realm, self._password)) - - path = request.url.raw_path - A2 = b":".join((request.method.encode(), path)) - # TODO: implement auth-int - HA2 = digest(A2) - - nonce_count = 1 # TODO: implement nonce counting - nc_value = b"%08x" % nonce_count - cnonce = self._get_client_nonce(nonce_count, challenge.nonce) - - HA1 = digest(A1) - if challenge.algorithm.lower().endswith("-sess"): - HA1 = digest(b":".join((HA1, challenge.nonce, cnonce))) - - qop = self._resolve_qop(challenge.qop, request=request) - if qop is None: - digest_data = [HA1, challenge.nonce, HA2] - else: - digest_data = [challenge.nonce, nc_value, cnonce, qop, HA2] - key_digest = b":".join(digest_data) - - format_args = { - "username": self._username, - "realm": challenge.realm, - "nonce": challenge.nonce, - "uri": path, - "response": digest(b":".join((HA1, key_digest))), - "algorithm": challenge.algorithm.encode(), - } - if challenge.opaque: - format_args["opaque"] = challenge.opaque - if qop: - format_args["qop"] = b"auth" - format_args["nc"] = nc_value - format_args["cnonce"] = cnonce - - return "Digest " + self._get_header_value(format_args) - - def _get_client_nonce(self, nonce_count: int, nonce: bytes) -> bytes: - s = str(nonce_count).encode() - s += nonce - s += time.ctime().encode() - s += os.urandom(8) - - return hashlib.sha1(s).hexdigest()[:16].encode() - - def _get_header_value(self, header_fields: typing.Dict[str, bytes]) -> str: - NON_QUOTED_FIELDS = ("algorithm", "qop", "nc") - QUOTED_TEMPLATE = '{}="{}"' - NON_QUOTED_TEMPLATE = "{}={}" - - header_value = "" - for i, (field, value) in enumerate(header_fields.items()): - if i > 0: - header_value += ", " - template = ( - QUOTED_TEMPLATE - if field not in NON_QUOTED_FIELDS - else NON_QUOTED_TEMPLATE - ) - header_value += template.format(field, to_str(value)) - - return header_value - - def _resolve_qop( - self, qop: typing.Optional[bytes], request: Request - ) -> typing.Optional[bytes]: - if qop is None: - return None - qops = re.split(b", ?", qop) - if b"auth" in qops: - return b"auth" - - if qops == [b"auth-int"]: - raise NotImplementedError("Digest auth-int support is not yet implemented") - - message = f'Unexpected qop value "{qop!r}" in digest auth' - raise ProtocolError(message, request=request) - - -class _DigestAuthChallenge(typing.NamedTuple): - realm: bytes - nonce: bytes - algorithm: str - opaque: typing.Optional[bytes] - qop: typing.Optional[bytes] diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_client.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_client.py deleted file mode 100644 index 9afe8132..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_client.py +++ /dev/null @@ -1,2007 +0,0 @@ -import datetime -import enum -import typing -import warnings -from contextlib import contextmanager -from types import TracebackType - -from .__version__ import __version__ -from ._auth import Auth, BasicAuth, FunctionAuth -from ._compat import asynccontextmanager -from ._config import ( - DEFAULT_LIMITS, - DEFAULT_MAX_REDIRECTS, - DEFAULT_TIMEOUT_CONFIG, - Limits, - Proxy, - Timeout, -) -from ._decoders import SUPPORTED_DECODERS -from ._exceptions import ( - InvalidURL, - RemoteProtocolError, - TooManyRedirects, - request_context, -) -from ._models import URL, Cookies, Headers, QueryParams, Request, Response -from ._status_codes import codes -from ._transports.asgi import ASGITransport -from ._transports.base import ( - AsyncBaseTransport, - AsyncByteStream, - BaseTransport, - SyncByteStream, -) -from ._transports.default import AsyncHTTPTransport, HTTPTransport -from ._transports.wsgi import WSGITransport -from ._types import ( - AuthTypes, - CertTypes, - CookieTypes, - HeaderTypes, - ProxiesTypes, - QueryParamTypes, - RequestContent, - RequestData, - RequestFiles, - TimeoutTypes, - URLTypes, - VerifyTypes, -) -from ._utils import ( - NetRCInfo, - Timer, - URLPattern, - get_environment_proxies, - get_logger, - same_origin, -) - -# The type annotation for @classmethod and context managers here follows PEP 484 -# https://www.python.org/dev/peps/pep-0484/#annotating-instance-and-class-methods -T = typing.TypeVar("T", bound="Client") -U = typing.TypeVar("U", bound="AsyncClient") - - -class UseClientDefault: - """ - For some parameters such as `auth=...` and `timeout=...` we need to be able - to indicate the default "unset" state, in a way that is distinctly different - to using `None`. - - The default "unset" state indicates that whatever default is set on the - client should be used. This is different to setting `None`, which - explicitly disables the parameter, possibly overriding a client default. - - For example we use `timeout=USE_CLIENT_DEFAULT` in the `request()` signature. - Omitting the `timeout` parameter will send a request using whatever default - timeout has been configured on the client. Including `timeout=None` will - ensure no timeout is used. - - Note that user code shouldn't need to use the `USE_CLIENT_DEFAULT` constant, - but it is used internally when a parameter is not included. - """ - - pass # pragma: nocover - - -USE_CLIENT_DEFAULT = UseClientDefault() - - -logger = get_logger(__name__) - -USER_AGENT = f"python-httpx/{__version__}" -ACCEPT_ENCODING = ", ".join( - [key for key in SUPPORTED_DECODERS.keys() if key != "identity"] -) - - -class ClientState(enum.Enum): - # UNOPENED: - # The client has been instantiated, but has not been used to send a request, - # or been opened by entering the context of a `with` block. - UNOPENED = 1 - # OPENED: - # The client has either sent a request, or is within a `with` block. - OPENED = 2 - # CLOSED: - # The client has either exited the `with` block, or `close()` has - # been called explicitly. - CLOSED = 3 - - -class BoundSyncStream(SyncByteStream): - """ - A byte stream that is bound to a given response instance, and that - ensures the `response.elapsed` is set once the response is closed. - """ - - def __init__( - self, stream: SyncByteStream, response: Response, timer: Timer - ) -> None: - self._stream = stream - self._response = response - self._timer = timer - - def __iter__(self) -> typing.Iterator[bytes]: - for chunk in self._stream: - yield chunk - - def close(self) -> None: - seconds = self._timer.sync_elapsed() - self._response.elapsed = datetime.timedelta(seconds=seconds) - self._stream.close() - - -class BoundAsyncStream(AsyncByteStream): - """ - An async byte stream that is bound to a given response instance, and that - ensures the `response.elapsed` is set once the response is closed. - """ - - def __init__( - self, stream: AsyncByteStream, response: Response, timer: Timer - ) -> None: - self._stream = stream - self._response = response - self._timer = timer - - async def __aiter__(self) -> typing.AsyncIterator[bytes]: - async for chunk in self._stream: - yield chunk - - async def aclose(self) -> None: - seconds = await self._timer.async_elapsed() - self._response.elapsed = datetime.timedelta(seconds=seconds) - await self._stream.aclose() - - -class BaseClient: - def __init__( - self, - *, - auth: AuthTypes = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - allow_redirects: bool = True, - max_redirects: int = DEFAULT_MAX_REDIRECTS, - event_hooks: typing.Mapping[str, typing.List[typing.Callable]] = None, - base_url: URLTypes = "", - trust_env: bool = True, - ): - event_hooks = {} if event_hooks is None else event_hooks - - self._base_url = self._enforce_trailing_slash(URL(base_url)) - - self._auth = self._build_auth(auth) - self._params = QueryParams(params) - self.headers = Headers(headers) - self._cookies = Cookies(cookies) - self._timeout = Timeout(timeout) - self.allow_redirects = allow_redirects - self.max_redirects = max_redirects - self._event_hooks = { - "request": list(event_hooks.get("request", [])), - "response": list(event_hooks.get("response", [])), - } - self._trust_env = trust_env - self._netrc = NetRCInfo() - self._state = ClientState.UNOPENED - - @property - def is_closed(self) -> bool: - """ - Check if the client being closed - """ - return self._state == ClientState.CLOSED - - @property - def trust_env(self) -> bool: - return self._trust_env - - def _enforce_trailing_slash(self, url: URL) -> URL: - if url.raw_path.endswith(b"/"): - return url - return url.copy_with(raw_path=url.raw_path + b"/") - - def _get_proxy_map( - self, proxies: typing.Optional[ProxiesTypes], allow_env_proxies: bool - ) -> typing.Dict[str, typing.Optional[Proxy]]: - if proxies is None: - if allow_env_proxies: - return { - key: None if url is None else Proxy(url=url) - for key, url in get_environment_proxies().items() - } - return {} - if isinstance(proxies, dict): - new_proxies = {} - for key, value in proxies.items(): - proxy = Proxy(url=value) if isinstance(value, (str, URL)) else value - new_proxies[str(key)] = proxy - return new_proxies - else: - proxy = Proxy(url=proxies) if isinstance(proxies, (str, URL)) else proxies - return {"all://": proxy} - - @property - def timeout(self) -> Timeout: - return self._timeout - - @timeout.setter - def timeout(self, timeout: TimeoutTypes) -> None: - self._timeout = Timeout(timeout) - - @property - def event_hooks(self) -> typing.Dict[str, typing.List[typing.Callable]]: - return self._event_hooks - - @event_hooks.setter - def event_hooks( - self, event_hooks: typing.Dict[str, typing.List[typing.Callable]] - ) -> None: - self._event_hooks = { - "request": list(event_hooks.get("request", [])), - "response": list(event_hooks.get("response", [])), - } - - @property - def auth(self) -> typing.Optional[Auth]: - """ - Authentication class used when none is passed at the request-level. - - See also [Authentication][0]. - - [0]: /quickstart/#authentication - """ - return self._auth - - @auth.setter - def auth(self, auth: AuthTypes) -> None: - self._auth = self._build_auth(auth) - - @property - def base_url(self) -> URL: - """ - Base URL to use when sending requests with relative URLs. - """ - return self._base_url - - @base_url.setter - def base_url(self, url: URLTypes) -> None: - self._base_url = self._enforce_trailing_slash(URL(url)) - - @property - def headers(self) -> Headers: - """ - HTTP headers to include when sending requests. - """ - return self._headers - - @headers.setter - def headers(self, headers: HeaderTypes) -> None: - client_headers = Headers( - { - b"Accept": b"*/*", - b"Accept-Encoding": ACCEPT_ENCODING.encode("ascii"), - b"Connection": b"keep-alive", - b"User-Agent": USER_AGENT.encode("ascii"), - } - ) - client_headers.update(headers) - self._headers = client_headers - - @property - def cookies(self) -> Cookies: - """ - Cookie values to include when sending requests. - """ - return self._cookies - - @cookies.setter - def cookies(self, cookies: CookieTypes) -> None: - self._cookies = Cookies(cookies) - - @property - def params(self) -> QueryParams: - """ - Query parameters to include in the URL when sending requests. - """ - return self._params - - @params.setter - def params(self, params: QueryParamTypes) -> None: - self._params = QueryParams(params) - - def build_request( - self, - method: str, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - ) -> Request: - """ - Build and return a request instance. - - * The `params`, `headers` and `cookies` arguments - are merged with any values set on the client. - * The `url` argument is merged with any `base_url` set on the client. - - See also: [Request instances][0] - - [0]: /advanced/#request-instances - """ - url = self._merge_url(url) - headers = self._merge_headers(headers) - cookies = self._merge_cookies(cookies) - params = self._merge_queryparams(params) - return Request( - method, - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - ) - - def _merge_url(self, url: URLTypes) -> URL: - """ - Merge a URL argument together with any 'base_url' on the client, - to create the URL used for the outgoing request. - """ - merge_url = URL(url) - if merge_url.is_relative_url: - # To merge URLs we always append to the base URL. To get this - # behaviour correct we always ensure the base URL ends in a '/' - # seperator, and strip any leading '/' from the merge URL. - # - # So, eg... - # - # >>> client = Client(base_url="https://www.example.com/subpath") - # >>> client.base_url - # URL('https://www.example.com/subpath/') - # >>> client.build_request("GET", "/path").url - # URL('https://www.example.com/subpath/path') - merge_raw_path = self.base_url.raw_path + merge_url.raw_path.lstrip(b"/") - return self.base_url.copy_with(raw_path=merge_raw_path) - return merge_url - - def _merge_cookies( - self, cookies: CookieTypes = None - ) -> typing.Optional[CookieTypes]: - """ - Merge a cookies argument together with any cookies on the client, - to create the cookies used for the outgoing request. - """ - if cookies or self.cookies: - merged_cookies = Cookies(self.cookies) - merged_cookies.update(cookies) - return merged_cookies - return cookies - - def _merge_headers( - self, headers: HeaderTypes = None - ) -> typing.Optional[HeaderTypes]: - """ - Merge a headers argument together with any headers on the client, - to create the headers used for the outgoing request. - """ - merged_headers = Headers(self.headers) - merged_headers.update(headers) - return merged_headers - - def _merge_queryparams( - self, params: QueryParamTypes = None - ) -> typing.Optional[QueryParamTypes]: - """ - Merge a queryparams argument together with any queryparams on the client, - to create the queryparams used for the outgoing request. - """ - if params or self.params: - merged_queryparams = QueryParams(self.params) - merged_queryparams = merged_queryparams.merge(params) - return merged_queryparams - return params - - def _build_auth(self, auth: AuthTypes) -> typing.Optional[Auth]: - if auth is None: - return None - elif isinstance(auth, tuple): - return BasicAuth(username=auth[0], password=auth[1]) - elif isinstance(auth, Auth): - return auth - elif callable(auth): - return FunctionAuth(func=auth) - else: - raise TypeError(f'Invalid "auth" argument: {auth!r}') - - def _build_request_auth( - self, - request: Request, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Auth: - auth = ( - self._auth if isinstance(auth, UseClientDefault) else self._build_auth(auth) - ) - - if auth is not None: - return auth - - username, password = request.url.username, request.url.password - if username or password: - return BasicAuth(username=username, password=password) - - if self.trust_env and "Authorization" not in request.headers: - credentials = self._netrc.get_credentials(request.url.host) - if credentials is not None: - return BasicAuth(username=credentials[0], password=credentials[1]) - - return Auth() - - def _build_redirect_request(self, request: Request, response: Response) -> Request: - """ - Given a request and a redirect response, return a new request that - should be used to effect the redirect. - """ - method = self._redirect_method(request, response) - url = self._redirect_url(request, response) - headers = self._redirect_headers(request, url, method) - stream = self._redirect_stream(request, method) - cookies = Cookies(self.cookies) - return Request( - method=method, url=url, headers=headers, cookies=cookies, stream=stream - ) - - def _redirect_method(self, request: Request, response: Response) -> str: - """ - When being redirected we may want to change the method of the request - based on certain specs or browser behavior. - """ - method = request.method - - # https://tools.ietf.org/html/rfc7231#section-6.4.4 - if response.status_code == codes.SEE_OTHER and method != "HEAD": - method = "GET" - - # Do what the browsers do, despite standards... - # Turn 302s into GETs. - if response.status_code == codes.FOUND and method != "HEAD": - method = "GET" - - # If a POST is responded to with a 301, turn it into a GET. - # This bizarre behaviour is explained in 'requests' issue 1704. - if response.status_code == codes.MOVED_PERMANENTLY and method == "POST": - method = "GET" - - return method - - def _redirect_url(self, request: Request, response: Response) -> URL: - """ - Return the URL for the redirect to follow. - """ - location = response.headers["Location"] - - try: - url = URL(location) - except InvalidURL as exc: - raise RemoteProtocolError( - f"Invalid URL in location header: {exc}.", request=request - ) from None - - # Handle malformed 'Location' headers that are "absolute" form, have no host. - # See: https://github.com/encode/httpx/issues/771 - if url.scheme and not url.host: - url = url.copy_with(host=request.url.host) - - # Facilitate relative 'Location' headers, as allowed by RFC 7231. - # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') - if url.is_relative_url: - url = request.url.join(url) - - # Attach previous fragment if needed (RFC 7231 7.1.2) - if request.url.fragment and not url.fragment: - url = url.copy_with(fragment=request.url.fragment) - - return url - - def _redirect_headers(self, request: Request, url: URL, method: str) -> Headers: - """ - Return the headers that should be used for the redirect request. - """ - headers = Headers(request.headers) - - if not same_origin(url, request.url): - # Strip Authorization headers when responses are redirected away from - # the origin. - headers.pop("Authorization", None) - - # Update the Host header. - headers["Host"] = url.netloc.decode("ascii") - - if method != request.method and method == "GET": - # If we've switch to a 'GET' request, then strip any headers which - # are only relevant to the request body. - headers.pop("Content-Length", None) - headers.pop("Transfer-Encoding", None) - - # We should use the client cookie store to determine any cookie header, - # rather than whatever was on the original outgoing request. - headers.pop("Cookie", None) - - return headers - - def _redirect_stream( - self, request: Request, method: str - ) -> typing.Optional[typing.Union[SyncByteStream, AsyncByteStream]]: - """ - Return the body that should be used for the redirect request. - """ - if method != request.method and method == "GET": - return None - - return request.stream - - -class Client(BaseClient): - """ - An HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc. - - Usage: - - ```python - >>> client = httpx.Client() - >>> response = client.get('https://example.org') - ``` - - **Parameters:** - - * **auth** - *(optional)* An authentication class to use when sending - requests. - * **params** - *(optional)* Query parameters to include in request URLs, as - a string, dictionary, or sequence of two-tuples. - * **headers** - *(optional)* Dictionary of HTTP headers to include when - sending requests. - * **cookies** - *(optional)* Dictionary of Cookie items to include when - sending requests. - * **verify** - *(optional)* SSL certificates (a.k.a CA bundle) used to - verify the identity of requested hosts. Either `True` (default CA bundle), - a path to an SSL certificate file, an `ssl.SSLContext`, or `False` - (which will disable verification). - * **cert** - *(optional)* An SSL certificate used by the requested host - to authenticate the client. Either a path to an SSL certificate file, or - two-tuple of (certificate file, key file), or a three-tuple of (certificate - file, key file, password). - * **proxies** - *(optional)* A dictionary mapping proxy keys to proxy - URLs. - * **timeout** - *(optional)* The timeout configuration to use when sending - requests. - * **limits** - *(optional)* The limits configuration to use. - * **max_redirects** - *(optional)* The maximum number of redirect responses - that should be followed. - * **base_url** - *(optional)* A URL to use as the base when building - request URLs. - * **transport** - *(optional)* A transport class to use for sending requests - over the network. - * **app** - *(optional)* An WSGI application to send requests to, - rather than sending actual network requests. - * **trust_env** - *(optional)* Enables or disables usage of environment - variables for configuration. - """ - - def __init__( - self, - *, - auth: AuthTypes = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - verify: VerifyTypes = True, - cert: CertTypes = None, - http1: bool = True, - http2: bool = False, - proxies: ProxiesTypes = None, - mounts: typing.Mapping[str, BaseTransport] = None, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - limits: Limits = DEFAULT_LIMITS, - max_redirects: int = DEFAULT_MAX_REDIRECTS, - event_hooks: typing.Mapping[str, typing.List[typing.Callable]] = None, - base_url: URLTypes = "", - transport: BaseTransport = None, - app: typing.Callable = None, - trust_env: bool = True, - ): - super().__init__( - auth=auth, - params=params, - headers=headers, - cookies=cookies, - timeout=timeout, - max_redirects=max_redirects, - event_hooks=event_hooks, - base_url=base_url, - trust_env=trust_env, - ) - - if http2: - try: - import h2 # noqa - except ImportError: # pragma: nocover - raise ImportError( - "Using http2=True, but the 'h2' package is not installed. " - "Make sure to install httpx using `pip install httpx[http2]`." - ) from None - - allow_env_proxies = trust_env and app is None and transport is None - proxy_map = self._get_proxy_map(proxies, allow_env_proxies) - - self._transport = self._init_transport( - verify=verify, - cert=cert, - http1=http1, - http2=http2, - limits=limits, - transport=transport, - app=app, - trust_env=trust_env, - ) - self._mounts: typing.Dict[URLPattern, typing.Optional[BaseTransport]] = { - URLPattern(key): None - if proxy is None - else self._init_proxy_transport( - proxy, - verify=verify, - cert=cert, - http1=http1, - http2=http2, - limits=limits, - trust_env=trust_env, - ) - for key, proxy in proxy_map.items() - } - if mounts is not None: - self._mounts.update( - {URLPattern(key): transport for key, transport in mounts.items()} - ) - - self._mounts = dict(sorted(self._mounts.items())) - - def _init_transport( - self, - verify: VerifyTypes = True, - cert: CertTypes = None, - http1: bool = True, - http2: bool = False, - limits: Limits = DEFAULT_LIMITS, - transport: BaseTransport = None, - app: typing.Callable = None, - trust_env: bool = True, - ) -> BaseTransport: - if transport is not None: - return transport - - if app is not None: - return WSGITransport(app=app) - - return HTTPTransport( - verify=verify, - cert=cert, - http1=http1, - http2=http2, - limits=limits, - trust_env=trust_env, - ) - - def _init_proxy_transport( - self, - proxy: Proxy, - verify: VerifyTypes = True, - cert: CertTypes = None, - http1: bool = True, - http2: bool = False, - limits: Limits = DEFAULT_LIMITS, - trust_env: bool = True, - ) -> BaseTransport: - return HTTPTransport( - verify=verify, - cert=cert, - http1=http1, - http2=http2, - limits=limits, - trust_env=trust_env, - proxy=proxy, - ) - - def _transport_for_url(self, url: URL) -> BaseTransport: - """ - Returns the transport instance that should be used for a given URL. - This will either be the standard connection pool, or a proxy. - """ - for pattern, transport in self._mounts.items(): - if pattern.matches(url): - return self._transport if transport is None else transport - - return self._transport - - def request( - self, - method: str, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Build and send a request. - - Equivalent to: - - ```python - request = client.build_request(...) - response = client.send(request, ...) - ``` - - See `Client.build_request()`, `Client.send()` and - [Merging of configuration][0] for how the various parameters - are merged with client-level configuration. - - [0]: /advanced/#merging-of-configuration - """ - if cookies is not None: - message = ( - "Setting per-request cookies=<...> is being deprecated, because " - "the expected behaviour on cookie persistence is ambiguous. Set " - "cookies directly on the client instance instead." - ) - warnings.warn(message, DeprecationWarning) - - request = self.build_request( - method=method, - url=url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - ) - return self.send( - request, auth=auth, allow_redirects=allow_redirects, timeout=timeout - ) - - @contextmanager - def stream( - self, - method: str, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> typing.Iterator[Response]: - """ - Alternative to `httpx.request()` that streams the response body - instead of loading it into memory at once. - - **Parameters**: See `httpx.request`. - - See also: [Streaming Responses][0] - - [0]: /quickstart#streaming-responses - """ - request = self.build_request( - method=method, - url=url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - ) - response = self.send( - request=request, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - stream=True, - ) - try: - yield response - finally: - response.close() - - def send( - self, - request: Request, - *, - stream: bool = False, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a request. - - The request is sent as-is, unmodified. - - Typically you'll want to build one with `Client.build_request()` - so that any client-level configuration is merged into the request, - but passing an explicit `httpx.Request()` is supported as well. - - See also: [Request instances][0] - - [0]: /advanced/#request-instances - """ - if self._state == ClientState.CLOSED: - raise RuntimeError("Cannot send a request, as the client has been closed.") - - self._state = ClientState.OPENED - timeout = ( - self.timeout if isinstance(timeout, UseClientDefault) else Timeout(timeout) - ) - allow_redirects = ( - self.allow_redirects - if isinstance(allow_redirects, UseClientDefault) - else allow_redirects - ) - - auth = self._build_request_auth(request, auth) - - response = self._send_handling_auth( - request, - auth=auth, - timeout=timeout, - allow_redirects=allow_redirects, - history=[], - ) - try: - if not stream: - response.read() - - return response - - except Exception as exc: - response.close() - raise exc - - def _send_handling_auth( - self, - request: Request, - auth: Auth, - timeout: Timeout, - allow_redirects: bool, - history: typing.List[Response], - ) -> Response: - auth_flow = auth.sync_auth_flow(request) - try: - request = next(auth_flow) - - while True: - response = self._send_handling_redirects( - request, - timeout=timeout, - allow_redirects=allow_redirects, - history=history, - ) - try: - try: - next_request = auth_flow.send(response) - except StopIteration: - return response - - response.history = list(history) - response.read() - request = next_request - history.append(response) - - except Exception as exc: - response.close() - raise exc - finally: - auth_flow.close() - - def _send_handling_redirects( - self, - request: Request, - timeout: Timeout, - allow_redirects: bool, - history: typing.List[Response], - ) -> Response: - while True: - if len(history) > self.max_redirects: - raise TooManyRedirects( - "Exceeded maximum allowed redirects.", request=request - ) - - for hook in self._event_hooks["request"]: - hook(request) - - response = self._send_single_request(request, timeout) - try: - for hook in self._event_hooks["response"]: - hook(response) - response.history = list(history) - - if not response.is_redirect: - return response - - request = self._build_redirect_request(request, response) - history = history + [response] - - if allow_redirects: - response.read() - else: - response.next_request = request - return response - - except Exception as exc: - response.close() - raise exc - - def _send_single_request(self, request: Request, timeout: Timeout) -> Response: - """ - Sends a single request, without handling any redirections. - """ - transport = self._transport_for_url(request.url) - timer = Timer() - timer.sync_start() - - if not isinstance(request.stream, SyncByteStream): - raise RuntimeError( - "Attempted to send an async request with a sync Client instance." - ) - - with request_context(request=request): - (status_code, headers, stream, extensions) = transport.handle_request( - request.method.encode(), - request.url.raw, - headers=request.headers.raw, - stream=request.stream, - extensions={"timeout": timeout.as_dict()}, - ) - - response = Response( - status_code, - headers=headers, - stream=stream, - extensions=extensions, - request=request, - ) - - response.stream = BoundSyncStream(stream, response=response, timer=timer) - self.cookies.extract_cookies(response) - - status = f"{response.status_code} {response.reason_phrase}" - response_line = f"{response.http_version} {status}" - logger.debug(f'HTTP Request: {request.method} {request.url} "{response_line}"') - - return response - - def get( - self, - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `GET` request. - - **Parameters**: See `httpx.request`. - """ - return self.request( - "GET", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - def options( - self, - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send an `OPTIONS` request. - - **Parameters**: See `httpx.request`. - """ - return self.request( - "OPTIONS", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - def head( - self, - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `HEAD` request. - - **Parameters**: See `httpx.request`. - """ - return self.request( - "HEAD", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - def post( - self, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `POST` request. - - **Parameters**: See `httpx.request`. - """ - return self.request( - "POST", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - def put( - self, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `PUT` request. - - **Parameters**: See `httpx.request`. - """ - return self.request( - "PUT", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - def patch( - self, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `PATCH` request. - - **Parameters**: See `httpx.request`. - """ - return self.request( - "PATCH", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - def delete( - self, - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `DELETE` request. - - **Parameters**: See `httpx.request`. - """ - return self.request( - "DELETE", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - def close(self) -> None: - """ - Close transport and proxies. - """ - if self._state != ClientState.CLOSED: - self._state = ClientState.CLOSED - - self._transport.close() - for transport in self._mounts.values(): - if transport is not None: - transport.close() - - def __enter__(self: T) -> T: - if self._state != ClientState.UNOPENED: - msg = { - ClientState.OPENED: "Cannot open a client instance more than once.", - ClientState.CLOSED: "Cannot reopen a client instance, once it has been closed.", - }[self._state] - raise RuntimeError(msg) - - self._state = ClientState.OPENED - - self._transport.__enter__() - for transport in self._mounts.values(): - if transport is not None: - transport.__enter__() - return self - - def __exit__( - self, - exc_type: typing.Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - self._state = ClientState.CLOSED - - self._transport.__exit__(exc_type, exc_value, traceback) - for transport in self._mounts.values(): - if transport is not None: - transport.__exit__(exc_type, exc_value, traceback) - - def __del__(self) -> None: - # We use 'getattr' here, to manage the case where '__del__()' is called - # on a partically initiallized instance that raised an exception during - # the call to '__init__()'. - if getattr(self, "_state", None) == ClientState.OPENED: # noqa: B009 - self.close() - - -class AsyncClient(BaseClient): - """ - An asynchronous HTTP client, with connection pooling, HTTP/2, redirects, - cookie persistence, etc. - - Usage: - - ```python - >>> async with httpx.AsyncClient() as client: - >>> response = await client.get('https://example.org') - ``` - - **Parameters:** - - * **auth** - *(optional)* An authentication class to use when sending - requests. - * **params** - *(optional)* Query parameters to include in request URLs, as - a string, dictionary, or sequence of two-tuples. - * **headers** - *(optional)* Dictionary of HTTP headers to include when - sending requests. - * **cookies** - *(optional)* Dictionary of Cookie items to include when - sending requests. - * **verify** - *(optional)* SSL certificates (a.k.a CA bundle) used to - verify the identity of requested hosts. Either `True` (default CA bundle), - a path to an SSL certificate file, or `False` (disable verification). - * **cert** - *(optional)* An SSL certificate used by the requested host - to authenticate the client. Either a path to an SSL certificate file, or - two-tuple of (certificate file, key file), or a three-tuple of (certificate - file, key file, password). - * **http2** - *(optional)* A boolean indicating if HTTP/2 support should be - enabled. Defaults to `False`. - * **proxies** - *(optional)* A dictionary mapping HTTP protocols to proxy - URLs. - * **timeout** - *(optional)* The timeout configuration to use when sending - requests. - * **limits** - *(optional)* The limits configuration to use. - * **max_redirects** - *(optional)* The maximum number of redirect responses - that should be followed. - * **base_url** - *(optional)* A URL to use as the base when building - request URLs. - * **transport** - *(optional)* A transport class to use for sending requests - over the network. - * **app** - *(optional)* An ASGI application to send requests to, - rather than sending actual network requests. - * **trust_env** - *(optional)* Enables or disables usage of environment - variables for configuration. - """ - - def __init__( - self, - *, - auth: AuthTypes = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - verify: VerifyTypes = True, - cert: CertTypes = None, - http1: bool = True, - http2: bool = False, - proxies: ProxiesTypes = None, - mounts: typing.Mapping[str, AsyncBaseTransport] = None, - timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, - limits: Limits = DEFAULT_LIMITS, - max_redirects: int = DEFAULT_MAX_REDIRECTS, - event_hooks: typing.Mapping[str, typing.List[typing.Callable]] = None, - base_url: URLTypes = "", - transport: AsyncBaseTransport = None, - app: typing.Callable = None, - trust_env: bool = True, - ): - super().__init__( - auth=auth, - params=params, - headers=headers, - cookies=cookies, - timeout=timeout, - max_redirects=max_redirects, - event_hooks=event_hooks, - base_url=base_url, - trust_env=trust_env, - ) - - if http2: - try: - import h2 # noqa - except ImportError: # pragma: nocover - raise ImportError( - "Using http2=True, but the 'h2' package is not installed. " - "Make sure to install httpx using `pip install httpx[http2]`." - ) from None - - allow_env_proxies = trust_env and app is None and transport is None - proxy_map = self._get_proxy_map(proxies, allow_env_proxies) - - self._transport = self._init_transport( - verify=verify, - cert=cert, - http1=http1, - http2=http2, - limits=limits, - transport=transport, - app=app, - trust_env=trust_env, - ) - - self._mounts: typing.Dict[URLPattern, typing.Optional[AsyncBaseTransport]] = { - URLPattern(key): None - if proxy is None - else self._init_proxy_transport( - proxy, - verify=verify, - cert=cert, - http1=http1, - http2=http2, - limits=limits, - trust_env=trust_env, - ) - for key, proxy in proxy_map.items() - } - if mounts is not None: - self._mounts.update( - {URLPattern(key): transport for key, transport in mounts.items()} - ) - self._mounts = dict(sorted(self._mounts.items())) - - def _init_transport( - self, - verify: VerifyTypes = True, - cert: CertTypes = None, - http1: bool = True, - http2: bool = False, - limits: Limits = DEFAULT_LIMITS, - transport: AsyncBaseTransport = None, - app: typing.Callable = None, - trust_env: bool = True, - ) -> AsyncBaseTransport: - if transport is not None: - return transport - - if app is not None: - return ASGITransport(app=app) - - return AsyncHTTPTransport( - verify=verify, - cert=cert, - http1=http1, - http2=http2, - limits=limits, - trust_env=trust_env, - ) - - def _init_proxy_transport( - self, - proxy: Proxy, - verify: VerifyTypes = True, - cert: CertTypes = None, - http1: bool = True, - http2: bool = False, - limits: Limits = DEFAULT_LIMITS, - trust_env: bool = True, - ) -> AsyncBaseTransport: - return AsyncHTTPTransport( - verify=verify, - cert=cert, - http2=http2, - limits=limits, - trust_env=trust_env, - proxy=proxy, - ) - - def _transport_for_url(self, url: URL) -> AsyncBaseTransport: - """ - Returns the transport instance that should be used for a given URL. - This will either be the standard connection pool, or a proxy. - """ - for pattern, transport in self._mounts.items(): - if pattern.matches(url): - return self._transport if transport is None else transport - - return self._transport - - async def request( - self, - method: str, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Build and send a request. - - Equivalent to: - - ```python - request = client.build_request(...) - response = await client.send(request, ...) - ``` - - See `AsyncClient.build_request()`, `AsyncClient.send()` - and [Merging of configuration][0] for how the various parameters - are merged with client-level configuration. - - [0]: /advanced/#merging-of-configuration - """ - request = self.build_request( - method=method, - url=url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - ) - response = await self.send( - request, auth=auth, allow_redirects=allow_redirects, timeout=timeout - ) - return response - - @asynccontextmanager - async def stream( - self, - method: str, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> typing.AsyncIterator[Response]: - """ - Alternative to `httpx.request()` that streams the response body - instead of loading it into memory at once. - - **Parameters**: See `httpx.request`. - - See also: [Streaming Responses][0] - - [0]: /quickstart#streaming-responses - """ - request = self.build_request( - method=method, - url=url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - ) - response = await self.send( - request=request, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - stream=True, - ) - try: - yield response - finally: - await response.aclose() - - async def send( - self, - request: Request, - *, - stream: bool = False, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a request. - - The request is sent as-is, unmodified. - - Typically you'll want to build one with `AsyncClient.build_request()` - so that any client-level configuration is merged into the request, - but passing an explicit `httpx.Request()` is supported as well. - - See also: [Request instances][0] - - [0]: /advanced/#request-instances - """ - if self._state == ClientState.CLOSED: - raise RuntimeError("Cannot send a request, as the client has been closed.") - - self._state = ClientState.OPENED - timeout = ( - self.timeout if isinstance(timeout, UseClientDefault) else Timeout(timeout) - ) - allow_redirects = ( - self.allow_redirects - if isinstance(allow_redirects, UseClientDefault) - else allow_redirects - ) - - auth = self._build_request_auth(request, auth) - - response = await self._send_handling_auth( - request, - auth=auth, - timeout=timeout, - allow_redirects=allow_redirects, - history=[], - ) - try: - if not stream: - await response.aread() - - return response - - except Exception as exc: # pragma: no cover - await response.aclose() - raise exc - - async def _send_handling_auth( - self, - request: Request, - auth: Auth, - timeout: Timeout, - allow_redirects: bool, - history: typing.List[Response], - ) -> Response: - auth_flow = auth.async_auth_flow(request) - try: - request = await auth_flow.__anext__() - - while True: - response = await self._send_handling_redirects( - request, - timeout=timeout, - allow_redirects=allow_redirects, - history=history, - ) - try: - try: - next_request = await auth_flow.asend(response) - except StopAsyncIteration: - return response - - response.history = list(history) - await response.aread() - request = next_request - history.append(response) - - except Exception as exc: - await response.aclose() - raise exc - finally: - await auth_flow.aclose() - - async def _send_handling_redirects( - self, - request: Request, - timeout: Timeout, - allow_redirects: bool, - history: typing.List[Response], - ) -> Response: - while True: - if len(history) > self.max_redirects: - raise TooManyRedirects( - "Exceeded maximum allowed redirects.", request=request - ) - - for hook in self._event_hooks["request"]: - await hook(request) - - response = await self._send_single_request(request, timeout) - try: - for hook in self._event_hooks["response"]: - await hook(response) - - response.history = list(history) - - if not response.is_redirect: - return response - - request = self._build_redirect_request(request, response) - history = history + [response] - - if allow_redirects: - await response.aread() - else: - response.next_request = request - return response - - except Exception as exc: - await response.aclose() - raise exc - - async def _send_single_request( - self, request: Request, timeout: Timeout - ) -> Response: - """ - Sends a single request, without handling any redirections. - """ - transport = self._transport_for_url(request.url) - timer = Timer() - await timer.async_start() - - if not isinstance(request.stream, AsyncByteStream): - raise RuntimeError( - "Attempted to send an sync request with an AsyncClient instance." - ) - - with request_context(request=request): - ( - status_code, - headers, - stream, - extensions, - ) = await transport.handle_async_request( - request.method.encode(), - request.url.raw, - headers=request.headers.raw, - stream=request.stream, - extensions={"timeout": timeout.as_dict()}, - ) - - response = Response( - status_code, - headers=headers, - stream=stream, - extensions=extensions, - request=request, - ) - - response.stream = BoundAsyncStream(stream, response=response, timer=timer) - self.cookies.extract_cookies(response) - - status = f"{response.status_code} {response.reason_phrase}" - response_line = f"{response.http_version} {status}" - logger.debug(f'HTTP Request: {request.method} {request.url} "{response_line}"') - - return response - - async def get( - self, - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `GET` request. - - **Parameters**: See `httpx.request`. - """ - return await self.request( - "GET", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - async def options( - self, - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send an `OPTIONS` request. - - **Parameters**: See `httpx.request`. - """ - return await self.request( - "OPTIONS", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - async def head( - self, - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `HEAD` request. - - **Parameters**: See `httpx.request`. - """ - return await self.request( - "HEAD", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - async def post( - self, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `POST` request. - - **Parameters**: See `httpx.request`. - """ - return await self.request( - "POST", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - async def put( - self, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `PUT` request. - - **Parameters**: See `httpx.request`. - """ - return await self.request( - "PUT", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - async def patch( - self, - url: URLTypes, - *, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `PATCH` request. - - **Parameters**: See `httpx.request`. - """ - return await self.request( - "PATCH", - url, - content=content, - data=data, - files=files, - json=json, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - async def delete( - self, - url: URLTypes, - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - auth: typing.Union[AuthTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - allow_redirects: typing.Union[bool, UseClientDefault] = USE_CLIENT_DEFAULT, - timeout: typing.Union[TimeoutTypes, UseClientDefault] = USE_CLIENT_DEFAULT, - ) -> Response: - """ - Send a `DELETE` request. - - **Parameters**: See `httpx.request`. - """ - return await self.request( - "DELETE", - url, - params=params, - headers=headers, - cookies=cookies, - auth=auth, - allow_redirects=allow_redirects, - timeout=timeout, - ) - - async def aclose(self) -> None: - """ - Close transport and proxies. - """ - if self._state != ClientState.CLOSED: - self._state = ClientState.CLOSED - - await self._transport.aclose() - for proxy in self._mounts.values(): - if proxy is not None: - await proxy.aclose() - - async def __aenter__(self: U) -> U: - if self._state != ClientState.UNOPENED: - msg = { - ClientState.OPENED: "Cannot open a client instance more than once.", - ClientState.CLOSED: "Cannot reopen a client instance, once it has been closed.", - }[self._state] - raise RuntimeError(msg) - - self._state = ClientState.OPENED - - await self._transport.__aenter__() - for proxy in self._mounts.values(): - if proxy is not None: - await proxy.__aenter__() - return self - - async def __aexit__( - self, - exc_type: typing.Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - self._state = ClientState.CLOSED - - await self._transport.__aexit__(exc_type, exc_value, traceback) - for proxy in self._mounts.values(): - if proxy is not None: - await proxy.__aexit__(exc_type, exc_value, traceback) - - def __del__(self) -> None: - # We use 'getattr' here, to manage the case where '__del__()' is called - # on a partically initiallized instance that raised an exception during - # the call to '__init__()'. - if getattr(self, "_state", None) == ClientState.OPENED: # noqa: B009 - # Unlike the sync case, we cannot silently close the client when - # it is garbage collected, because `.aclose()` is an async operation, - # but `__del__` is not. - # - # For this reason we require explicit close management for - # `AsyncClient`, and issue a warning on unclosed clients. - # - # The context managed style is usually preferable, because it neatly - # ensures proper resource cleanup: - # - # async with httpx.AsyncClient() as client: - # ... - # - # However, an explicit call to `aclose()` is also sufficient: - # - # client = httpx.AsyncClient() - # try: - # ... - # finally: - # await client.aclose() - warnings.warn( - f"Unclosed {self!r}. " - "See https://www.python-httpx.org/async/#opening-and-closing-clients " - "for details." - ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_compat.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_compat.py deleted file mode 100644 index 15e915a9..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_compat.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -The _compat module is used for code which requires branching between different -Python environments. It is excluded from the code coverage checks. -""" -import ssl -import sys - -# `contextlib.asynccontextmanager` exists from Python 3.7 onwards. -# For 3.6 we require the `async_generator` package for a backported version. -try: - from contextlib import asynccontextmanager # type: ignore -except ImportError: - from async_generator import asynccontextmanager # type: ignore # noqa - -# Brotli support is optional -# The C bindings in `brotli` are recommended for CPython. -# The CFFI bindings in `brotlicffi` are recommended for PyPy and everything else. -try: - import brotlicffi as brotli -except ImportError: # pragma: nocover - try: - import brotli - except ImportError: - brotli = None - -if sys.version_info >= (3, 10) or ( - sys.version_info >= (3, 7) and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0, 7) -): - - def set_minimum_tls_version_1_2(context: ssl.SSLContext) -> None: - # The OP_NO_SSL* and OP_NO_TLS* become deprecated in favor of - # 'SSLContext.minimum_version' from Python 3.7 onwards, however - # this attribute is not available unless the ssl module is compiled - # with OpenSSL 1.1.0g or newer. - # https://docs.python.org/3.10/library/ssl.html#ssl.SSLContext.minimum_version - # https://docs.python.org/3.7/library/ssl.html#ssl.SSLContext.minimum_version - context.minimum_version = ssl.TLSVersion.TLSv1_2 - - -else: - - def set_minimum_tls_version_1_2(context: ssl.SSLContext) -> None: - # If 'minimum_version' isn't available, we configure these options with - # the older deprecated variants. - context.options |= ssl.OP_NO_SSLv2 - context.options |= ssl.OP_NO_SSLv3 - context.options |= ssl.OP_NO_TLSv1 - context.options |= ssl.OP_NO_TLSv1_1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_config.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_config.py deleted file mode 100644 index 927a67c2..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_config.py +++ /dev/null @@ -1,349 +0,0 @@ -import os -import ssl -import typing -from base64 import b64encode -from pathlib import Path - -import certifi - -from ._compat import set_minimum_tls_version_1_2 -from ._models import URL, Headers -from ._types import CertTypes, HeaderTypes, TimeoutTypes, URLTypes, VerifyTypes -from ._utils import get_ca_bundle_from_env, get_logger - -DEFAULT_CIPHERS = ":".join( - [ - "ECDHE+AESGCM", - "ECDHE+CHACHA20", - "DHE+AESGCM", - "DHE+CHACHA20", - "ECDH+AESGCM", - "DH+AESGCM", - "ECDH+AES", - "DH+AES", - "RSA+AESGCM", - "RSA+AES", - "!aNULL", - "!eNULL", - "!MD5", - "!DSS", - ] -) - - -logger = get_logger(__name__) - - -class UnsetType: - pass # pragma: nocover - - -UNSET = UnsetType() - - -def create_ssl_context( - cert: CertTypes = None, - verify: VerifyTypes = True, - trust_env: bool = True, - http2: bool = False, -) -> ssl.SSLContext: - return SSLConfig( - cert=cert, verify=verify, trust_env=trust_env, http2=http2 - ).ssl_context - - -class SSLConfig: - """ - SSL Configuration. - """ - - DEFAULT_CA_BUNDLE_PATH = Path(certifi.where()) - - def __init__( - self, - *, - cert: CertTypes = None, - verify: VerifyTypes = True, - trust_env: bool = True, - http2: bool = False, - ): - self.cert = cert - self.verify = verify - self.trust_env = trust_env - self.http2 = http2 - self.ssl_context = self.load_ssl_context() - - def load_ssl_context(self) -> ssl.SSLContext: - logger.trace( - f"load_ssl_context " - f"verify={self.verify!r} " - f"cert={self.cert!r} " - f"trust_env={self.trust_env!r} " - f"http2={self.http2!r}" - ) - - if self.verify: - return self.load_ssl_context_verify() - return self.load_ssl_context_no_verify() - - def load_ssl_context_no_verify(self) -> ssl.SSLContext: - """ - Return an SSL context for unverified connections. - """ - context = self._create_default_ssl_context() - context.check_hostname = False - context.verify_mode = ssl.CERT_NONE - self._load_client_certs(context) - return context - - def load_ssl_context_verify(self) -> ssl.SSLContext: - """ - Return an SSL context for verified connections. - """ - if self.trust_env and self.verify is True: - ca_bundle = get_ca_bundle_from_env() - if ca_bundle is not None: - self.verify = ca_bundle - - if isinstance(self.verify, ssl.SSLContext): - # Allow passing in our own SSLContext object that's pre-configured. - context = self.verify - self._load_client_certs(context) - return context - elif isinstance(self.verify, bool): - ca_bundle_path = self.DEFAULT_CA_BUNDLE_PATH - elif Path(self.verify).exists(): - ca_bundle_path = Path(self.verify) - else: - raise IOError( - "Could not find a suitable TLS CA certificate bundle, " - "invalid path: {}".format(self.verify) - ) - - context = self._create_default_ssl_context() - context.verify_mode = ssl.CERT_REQUIRED - context.check_hostname = True - - # Signal to server support for PHA in TLS 1.3. Raises an - # AttributeError if only read-only access is implemented. - try: - context.post_handshake_auth = True # type: ignore - except AttributeError: # pragma: nocover - pass - - # Disable using 'commonName' for SSLContext.check_hostname - # when the 'subjectAltName' extension isn't available. - try: - context.hostname_checks_common_name = False # type: ignore - except AttributeError: # pragma: nocover - pass - - if ca_bundle_path.is_file(): - logger.trace(f"load_verify_locations cafile={ca_bundle_path!s}") - context.load_verify_locations(cafile=str(ca_bundle_path)) - elif ca_bundle_path.is_dir(): - logger.trace(f"load_verify_locations capath={ca_bundle_path!s}") - context.load_verify_locations(capath=str(ca_bundle_path)) - - self._load_client_certs(context) - - return context - - def _create_default_ssl_context(self) -> ssl.SSLContext: - """ - Creates the default SSLContext object that's used for both verified - and unverified connections. - """ - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - set_minimum_tls_version_1_2(context) - context.options |= ssl.OP_NO_COMPRESSION - context.set_ciphers(DEFAULT_CIPHERS) - - if ssl.HAS_ALPN: - alpn_idents = ["http/1.1", "h2"] if self.http2 else ["http/1.1"] - context.set_alpn_protocols(alpn_idents) - - if hasattr(context, "keylog_filename"): # pragma: nocover (Available in 3.8+) - keylogfile = os.environ.get("SSLKEYLOGFILE") - if keylogfile and self.trust_env: - context.keylog_filename = keylogfile # type: ignore - - return context - - def _load_client_certs(self, ssl_context: ssl.SSLContext) -> None: - """ - Loads client certificates into our SSLContext object - """ - if self.cert is not None: - if isinstance(self.cert, str): - ssl_context.load_cert_chain(certfile=self.cert) - elif isinstance(self.cert, tuple) and len(self.cert) == 2: - ssl_context.load_cert_chain(certfile=self.cert[0], keyfile=self.cert[1]) - elif isinstance(self.cert, tuple) and len(self.cert) == 3: - ssl_context.load_cert_chain( - certfile=self.cert[0], - keyfile=self.cert[1], - password=self.cert[2], # type: ignore - ) - - -class Timeout: - """ - Timeout configuration. - - **Usage**: - - Timeout(None) # No timeouts. - Timeout(5.0) # 5s timeout on all operations. - Timeout(None, connect=5.0) # 5s timeout on connect, no other timeouts. - Timeout(5.0, connect=10.0) # 10s timeout on connect. 5s timeout elsewhere. - Timeout(5.0, pool=None) # No timeout on acquiring connection from pool. - # 5s timeout elsewhere. - """ - - def __init__( - self, - timeout: typing.Union[TimeoutTypes, UnsetType] = UNSET, - *, - connect: typing.Union[None, float, UnsetType] = UNSET, - read: typing.Union[None, float, UnsetType] = UNSET, - write: typing.Union[None, float, UnsetType] = UNSET, - pool: typing.Union[None, float, UnsetType] = UNSET, - ): - if isinstance(timeout, Timeout): - # Passed as a single explicit Timeout. - assert connect is UNSET - assert read is UNSET - assert write is UNSET - assert pool is UNSET - self.connect = timeout.connect # type: typing.Optional[float] - self.read = timeout.read # type: typing.Optional[float] - self.write = timeout.write # type: typing.Optional[float] - self.pool = timeout.pool # type: typing.Optional[float] - elif isinstance(timeout, tuple): - # Passed as a tuple. - self.connect = timeout[0] - self.read = timeout[1] - self.write = None if len(timeout) < 3 else timeout[2] - self.pool = None if len(timeout) < 4 else timeout[3] - elif not ( - isinstance(connect, UnsetType) - or isinstance(read, UnsetType) - or isinstance(write, UnsetType) - or isinstance(pool, UnsetType) - ): - self.connect = connect - self.read = read - self.write = write - self.pool = pool - else: - if isinstance(timeout, UnsetType): - raise ValueError( - "httpx.Timeout must either include a default, or set all " - "four parameters explicitly." - ) - self.connect = timeout if isinstance(connect, UnsetType) else connect - self.read = timeout if isinstance(read, UnsetType) else read - self.write = timeout if isinstance(write, UnsetType) else write - self.pool = timeout if isinstance(pool, UnsetType) else pool - - def as_dict(self) -> typing.Dict[str, typing.Optional[float]]: - return { - "connect": self.connect, - "read": self.read, - "write": self.write, - "pool": self.pool, - } - - def __eq__(self, other: typing.Any) -> bool: - return ( - isinstance(other, self.__class__) - and self.connect == other.connect - and self.read == other.read - and self.write == other.write - and self.pool == other.pool - ) - - def __repr__(self) -> str: - class_name = self.__class__.__name__ - if len({self.connect, self.read, self.write, self.pool}) == 1: - return f"{class_name}(timeout={self.connect})" - return ( - f"{class_name}(connect={self.connect}, " - f"read={self.read}, write={self.write}, pool={self.pool})" - ) - - -class Limits: - """ - Configuration for limits to various client behaviors. - - **Parameters:** - - * **max_connections** - The maximum number of concurrent connections that may be - established. - * **max_keepalive_connections** - Allow the connection pool to maintain - keep-alive connections below this point. Should be less than or equal - to `max_connections`. - """ - - def __init__( - self, - *, - max_connections: int = None, - max_keepalive_connections: int = None, - keepalive_expiry: typing.Optional[float] = 5.0, - ): - self.max_connections = max_connections - self.max_keepalive_connections = max_keepalive_connections - self.keepalive_expiry = keepalive_expiry - - def __eq__(self, other: typing.Any) -> bool: - return ( - isinstance(other, self.__class__) - and self.max_connections == other.max_connections - and self.max_keepalive_connections == other.max_keepalive_connections - and self.keepalive_expiry == other.keepalive_expiry - ) - - def __repr__(self) -> str: - class_name = self.__class__.__name__ - return ( - f"{class_name}(max_connections={self.max_connections}, " - f"max_keepalive_connections={self.max_keepalive_connections}, " - f"keepalive_expiry={self.keepalive_expiry})" - ) - - -class Proxy: - def __init__(self, url: URLTypes, *, headers: HeaderTypes = None): - url = URL(url) - headers = Headers(headers) - - if url.scheme not in ("http", "https"): - raise ValueError(f"Unknown scheme for proxy URL {url!r}") - - if url.username or url.password: - headers.setdefault( - "Proxy-Authorization", - self._build_auth_header(url.username, url.password), - ) - # Remove userinfo from the URL authority, e.g.: - # 'username:password@proxy_host:proxy_port' -> 'proxy_host:proxy_port' - url = url.copy_with(username=None, password=None) - - self.url = url - self.headers = headers - - def _build_auth_header(self, username: str, password: str) -> str: - userpass = (username.encode("utf-8"), password.encode("utf-8")) - token = b64encode(b":".join(userpass)).decode() - return f"Basic {token}" - - def __repr__(self) -> str: - return f"Proxy(url={str(self.url)!r}, headers={dict(self.headers)!r})" - - -DEFAULT_TIMEOUT_CONFIG = Timeout(timeout=5.0) -DEFAULT_LIMITS = Limits(max_connections=100, max_keepalive_connections=20) -DEFAULT_MAX_REDIRECTS = 20 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_content.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_content.py deleted file mode 100644 index 86f3c7c2..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_content.py +++ /dev/null @@ -1,207 +0,0 @@ -import inspect -import warnings -from json import dumps as json_dumps -from typing import ( - Any, - AsyncIterable, - AsyncIterator, - Dict, - Iterable, - Iterator, - Tuple, - Union, -) -from urllib.parse import urlencode - -from ._exceptions import StreamClosed, StreamConsumed -from ._multipart import MultipartStream -from ._transports.base import AsyncByteStream, SyncByteStream -from ._types import RequestContent, RequestData, RequestFiles, ResponseContent -from ._utils import peek_filelike_length, primitive_value_to_str - - -class ByteStream(AsyncByteStream, SyncByteStream): - def __init__(self, stream: bytes) -> None: - self._stream = stream - - def __iter__(self) -> Iterator[bytes]: - yield self._stream - - async def __aiter__(self) -> AsyncIterator[bytes]: - yield self._stream - - -class IteratorByteStream(SyncByteStream): - def __init__(self, stream: Iterable[bytes]): - self._stream = stream - self._is_stream_consumed = False - self._is_generator = inspect.isgenerator(stream) - - def __iter__(self) -> Iterator[bytes]: - if self._is_stream_consumed and self._is_generator: - raise StreamConsumed() - - self._is_stream_consumed = True - for part in self._stream: - yield part - - -class AsyncIteratorByteStream(AsyncByteStream): - def __init__(self, stream: AsyncIterable[bytes]): - self._stream = stream - self._is_stream_consumed = False - self._is_generator = inspect.isasyncgen(stream) - - async def __aiter__(self) -> AsyncIterator[bytes]: - if self._is_stream_consumed and self._is_generator: - raise StreamConsumed() - - self._is_stream_consumed = True - async for part in self._stream: - yield part - - -class UnattachedStream(AsyncByteStream, SyncByteStream): - """ - If a request or response is serialized using pickle, then it is no longer - attached to a stream for I/O purposes. Any stream operations should result - in `httpx.StreamClosed`. - """ - - def __iter__(self) -> Iterator[bytes]: - raise StreamClosed() - - async def __aiter__(self) -> AsyncIterator[bytes]: - raise StreamClosed() - yield b"" # pragma: nocover - - -def encode_content( - content: Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]] -) -> Tuple[Dict[str, str], Union[SyncByteStream, AsyncByteStream]]: - - if isinstance(content, (bytes, str)): - body = content.encode("utf-8") if isinstance(content, str) else content - content_length = len(body) - headers = {"Content-Length": str(content_length)} if body else {} - return headers, ByteStream(body) - - elif isinstance(content, Iterable): - content_length_or_none = peek_filelike_length(content) - - if content_length_or_none is None: - headers = {"Transfer-Encoding": "chunked"} - else: - headers = {"Content-Length": str(content_length_or_none)} - return headers, IteratorByteStream(content) # type: ignore - - elif isinstance(content, AsyncIterable): - headers = {"Transfer-Encoding": "chunked"} - return headers, AsyncIteratorByteStream(content) - - raise TypeError(f"Unexpected type for 'content', {type(content)!r}") - - -def encode_urlencoded_data( - data: dict, -) -> Tuple[Dict[str, str], ByteStream]: - plain_data = [] - for key, value in data.items(): - if isinstance(value, (list, tuple)): - plain_data.extend([(key, primitive_value_to_str(item)) for item in value]) - else: - plain_data.append((key, primitive_value_to_str(value))) - body = urlencode(plain_data, doseq=True).encode("utf-8") - content_length = str(len(body)) - content_type = "application/x-www-form-urlencoded" - headers = {"Content-Length": content_length, "Content-Type": content_type} - return headers, ByteStream(body) - - -def encode_multipart_data( - data: dict, files: RequestFiles, boundary: bytes = None -) -> Tuple[Dict[str, str], MultipartStream]: - multipart = MultipartStream(data=data, files=files, boundary=boundary) - headers = multipart.get_headers() - return headers, multipart - - -def encode_text(text: str) -> Tuple[Dict[str, str], ByteStream]: - body = text.encode("utf-8") - content_length = str(len(body)) - content_type = "text/plain; charset=utf-8" - headers = {"Content-Length": content_length, "Content-Type": content_type} - return headers, ByteStream(body) - - -def encode_html(html: str) -> Tuple[Dict[str, str], ByteStream]: - body = html.encode("utf-8") - content_length = str(len(body)) - content_type = "text/html; charset=utf-8" - headers = {"Content-Length": content_length, "Content-Type": content_type} - return headers, ByteStream(body) - - -def encode_json(json: Any) -> Tuple[Dict[str, str], ByteStream]: - body = json_dumps(json).encode("utf-8") - content_length = str(len(body)) - content_type = "application/json" - headers = {"Content-Length": content_length, "Content-Type": content_type} - return headers, ByteStream(body) - - -def encode_request( - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: Any = None, - boundary: bytes = None, -) -> Tuple[Dict[str, str], Union[SyncByteStream, AsyncByteStream]]: - """ - Handles encoding the given `content`, `data`, `files`, and `json`, - returning a two-tuple of (, ). - """ - if data is not None and not isinstance(data, dict): - # We prefer to seperate `content=` - # for raw request content, and `data=
` for url encoded or - # multipart form content. - # - # However for compat with requests, we *do* still support - # `data=` usages. We deal with that case here, treating it - # as if `content=<...>` had been supplied instead. - message = "Use 'content=<...>' to upload raw bytes/text content." - warnings.warn(message, DeprecationWarning) - return encode_content(data) - - if content is not None: - return encode_content(content) - elif files: - return encode_multipart_data(data or {}, files, boundary) - elif data: - return encode_urlencoded_data(data) - elif json is not None: - return encode_json(json) - - return {}, ByteStream(b"") - - -def encode_response( - content: ResponseContent = None, - text: str = None, - html: str = None, - json: Any = None, -) -> Tuple[Dict[str, str], Union[SyncByteStream, AsyncByteStream]]: - """ - Handles encoding the given `content`, returning a two-tuple of - (, ). - """ - if content is not None: - return encode_content(content) - elif text is not None: - return encode_text(text) - elif html is not None: - return encode_html(html) - elif json is not None: - return encode_json(json) - - return {}, ByteStream(b"") diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_decoders.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_decoders.py deleted file mode 100644 index 5081c86f..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_decoders.py +++ /dev/null @@ -1,333 +0,0 @@ -""" -Handlers for Content-Encoding. - -See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding -""" -import codecs -import io -import typing -import zlib - -from ._compat import brotli -from ._exceptions import DecodingError - - -class ContentDecoder: - def decode(self, data: bytes) -> bytes: - raise NotImplementedError() # pragma: nocover - - def flush(self) -> bytes: - raise NotImplementedError() # pragma: nocover - - -class IdentityDecoder(ContentDecoder): - """ - Handle unencoded data. - """ - - def decode(self, data: bytes) -> bytes: - return data - - def flush(self) -> bytes: - return b"" - - -class DeflateDecoder(ContentDecoder): - """ - Handle 'deflate' decoding. - - See: https://stackoverflow.com/questions/1838699 - """ - - def __init__(self) -> None: - self.first_attempt = True - self.decompressor = zlib.decompressobj() - - def decode(self, data: bytes) -> bytes: - was_first_attempt = self.first_attempt - self.first_attempt = False - try: - return self.decompressor.decompress(data) - except zlib.error as exc: - if was_first_attempt: - self.decompressor = zlib.decompressobj(-zlib.MAX_WBITS) - return self.decode(data) - raise DecodingError(str(exc)) from exc - - def flush(self) -> bytes: - try: - return self.decompressor.flush() - except zlib.error as exc: # pragma: nocover - raise DecodingError(str(exc)) from exc - - -class GZipDecoder(ContentDecoder): - """ - Handle 'gzip' decoding. - - See: https://stackoverflow.com/questions/1838699 - """ - - def __init__(self) -> None: - self.decompressor = zlib.decompressobj(zlib.MAX_WBITS | 16) - - def decode(self, data: bytes) -> bytes: - try: - return self.decompressor.decompress(data) - except zlib.error as exc: - raise DecodingError(str(exc)) from exc - - def flush(self) -> bytes: - try: - return self.decompressor.flush() - except zlib.error as exc: # pragma: nocover - raise DecodingError(str(exc)) from exc - - -class BrotliDecoder(ContentDecoder): - """ - Handle 'brotli' decoding. - - Requires `pip install brotlipy`. See: https://brotlipy.readthedocs.io/ - or `pip install brotli`. See https://github.com/google/brotli - Supports both 'brotlipy' and 'Brotli' packages since they share an import - name. The top branches are for 'brotlipy' and bottom branches for 'Brotli' - """ - - def __init__(self) -> None: - if brotli is None: # pragma: nocover - raise ImportError( - "Using 'BrotliDecoder', but neither of the 'brotlicffi' or 'brotli' " - "packages have been installed. " - "Make sure to install httpx using `pip install httpx[brotli]`." - ) from None - - self.decompressor = brotli.Decompressor() - self.seen_data = False - if hasattr(self.decompressor, "decompress"): - # The 'brotlicffi' package. - self._decompress = self.decompressor.decompress # pragma: nocover - else: - # The 'brotli' package. - self._decompress = self.decompressor.process # pragma: nocover - - def decode(self, data: bytes) -> bytes: - if not data: - return b"" - self.seen_data = True - try: - return self._decompress(data) - except brotli.error as exc: - raise DecodingError(str(exc)) from exc - - def flush(self) -> bytes: - if not self.seen_data: - return b"" - try: - if hasattr(self.decompressor, "finish"): - # Only available in the 'brotlicffi' package. - - # As the decompressor decompresses eagerly, this - # will never actually emit any data. However, it will potentially throw - # errors if a truncated or damaged data stream has been used. - self.decompressor.finish() # pragma: nocover - return b"" - except brotli.error as exc: # pragma: nocover - raise DecodingError(str(exc)) from exc - - -class MultiDecoder(ContentDecoder): - """ - Handle the case where multiple encodings have been applied. - """ - - def __init__(self, children: typing.Sequence[ContentDecoder]) -> None: - """ - 'children' should be a sequence of decoders in the order in which - each was applied. - """ - # Note that we reverse the order for decoding. - self.children = list(reversed(children)) - - def decode(self, data: bytes) -> bytes: - for child in self.children: - data = child.decode(data) - return data - - def flush(self) -> bytes: - data = b"" - for child in self.children: - data = child.decode(data) + child.flush() - return data - - -class ByteChunker: - """ - Handles returning byte content in fixed-size chunks. - """ - - def __init__(self, chunk_size: int = None) -> None: - self._buffer = io.BytesIO() - self._chunk_size = chunk_size - - def decode(self, content: bytes) -> typing.List[bytes]: - if self._chunk_size is None: - return [content] - - self._buffer.write(content) - if self._buffer.tell() >= self._chunk_size: - value = self._buffer.getvalue() - chunks = [ - value[i : i + self._chunk_size] - for i in range(0, len(value), self._chunk_size) - ] - if len(chunks[-1]) == self._chunk_size: - self._buffer.seek(0) - self._buffer.truncate() - return chunks - else: - self._buffer.seek(0) - self._buffer.write(chunks[-1]) - self._buffer.truncate() - return chunks[:-1] - else: - return [] - - def flush(self) -> typing.List[bytes]: - value = self._buffer.getvalue() - self._buffer.seek(0) - self._buffer.truncate() - return [value] if value else [] - - -class TextChunker: - """ - Handles returning text content in fixed-size chunks. - """ - - def __init__(self, chunk_size: int = None) -> None: - self._buffer = io.StringIO() - self._chunk_size = chunk_size - - def decode(self, content: str) -> typing.List[str]: - if self._chunk_size is None: - return [content] - - self._buffer.write(content) - if self._buffer.tell() >= self._chunk_size: - value = self._buffer.getvalue() - chunks = [ - value[i : i + self._chunk_size] - for i in range(0, len(value), self._chunk_size) - ] - if len(chunks[-1]) == self._chunk_size: - self._buffer.seek(0) - self._buffer.truncate() - return chunks - else: - self._buffer.seek(0) - self._buffer.write(chunks[-1]) - self._buffer.truncate() - return chunks[:-1] - else: - return [] - - def flush(self) -> typing.List[str]: - value = self._buffer.getvalue() - self._buffer.seek(0) - self._buffer.truncate() - return [value] if value else [] - - -class TextDecoder: - """ - Handles incrementally decoding bytes into text - """ - - def __init__(self, encoding: str = "utf-8"): - self.decoder = codecs.getincrementaldecoder(encoding)(errors="replace") - - def decode(self, data: bytes) -> str: - return self.decoder.decode(data) - - def flush(self) -> str: - return self.decoder.decode(b"", True) - - -class LineDecoder: - """ - Handles incrementally reading lines from text. - - Uses universal line decoding, supporting any of `\n`, `\r`, or `\r\n` - as line endings, normalizing to `\n`. - """ - - def __init__(self) -> None: - self.buffer = "" - - def decode(self, text: str) -> typing.List[str]: - lines = [] - - if text and self.buffer and self.buffer[-1] == "\r": - if text.startswith("\n"): - # Handle the case where we have an "\r\n" split across - # our previous input, and our new chunk. - lines.append(self.buffer[:-1] + "\n") - self.buffer = "" - text = text[1:] - else: - # Handle the case where we have "\r" at the end of our - # previous input. - lines.append(self.buffer[:-1] + "\n") - self.buffer = "" - - while text: - num_chars = len(text) - for idx in range(num_chars): - char = text[idx] - next_char = None if idx + 1 == num_chars else text[idx + 1] - if char == "\n": - lines.append(self.buffer + text[: idx + 1]) - self.buffer = "" - text = text[idx + 1 :] - break - elif char == "\r" and next_char == "\n": - lines.append(self.buffer + text[:idx] + "\n") - self.buffer = "" - text = text[idx + 2 :] - break - elif char == "\r" and next_char is not None: - lines.append(self.buffer + text[:idx] + "\n") - self.buffer = "" - text = text[idx + 1 :] - break - elif next_char is None: - self.buffer += text - text = "" - break - - return lines - - def flush(self) -> typing.List[str]: - if self.buffer.endswith("\r"): - # Handle the case where we had a trailing '\r', which could have - # been a '\r\n' pair. - lines = [self.buffer[:-1] + "\n"] - elif self.buffer: - lines = [self.buffer] - else: - lines = [] - self.buffer = "" - return lines - - -SUPPORTED_DECODERS = { - "identity": IdentityDecoder, - "gzip": GZipDecoder, - "deflate": DeflateDecoder, - "br": BrotliDecoder, -} - - -if brotli is None: - SUPPORTED_DECODERS.pop("br") # pragma: nocover diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_exceptions.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_exceptions.py deleted file mode 100644 index b6e59aa0..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_exceptions.py +++ /dev/null @@ -1,339 +0,0 @@ -""" -Our exception hierarchy: - -* HTTPError - x RequestError - + TransportError - - TimeoutException - · ConnectTimeout - · ReadTimeout - · WriteTimeout - · PoolTimeout - - NetworkError - · ConnectError - · ReadError - · WriteError - · CloseError - - ProtocolError - · LocalProtocolError - · RemoteProtocolError - - ProxyError - - UnsupportedProtocol - + DecodingError - + TooManyRedirects - + RequestBodyUnavailable - x HTTPStatusError -* InvalidURL -* CookieConflict -* StreamError - x StreamConsumed - x StreamClosed - x ResponseNotRead - x RequestNotRead -""" -import contextlib -import typing - -if typing.TYPE_CHECKING: - from ._models import Request, Response # pragma: nocover - - -class HTTPError(Exception): - """ - Base class for `RequestError` and `HTTPStatusError`. - - Useful for `try...except` blocks when issuing a request, - and then calling `.raise_for_status()`. - - For example: - - ``` - try: - response = httpx.get("https://www.example.com") - response.raise_for_status() - except httpx.HTTPError as exc: - print(f"HTTP Exception for {exc.request.url} - {exc}") - ``` - """ - - def __init__(self, message: str) -> None: - super().__init__(message) - - -class RequestError(HTTPError): - """ - Base class for all exceptions that may occur when issuing a `.request()`. - """ - - def __init__(self, message: str, *, request: "Request" = None) -> None: - super().__init__(message) - # At the point an exception is raised we won't typically have a request - # instance to associate it with. - # - # The 'request_context' context manager is used within the Client and - # Response methods in order to ensure that any raised exceptions - # have a `.request` property set on them. - self._request = request - - @property - def request(self) -> "Request": - if self._request is None: - raise RuntimeError("The .request property has not been set.") - return self._request - - @request.setter - def request(self, request: "Request") -> None: - self._request = request - - -class TransportError(RequestError): - """ - Base class for all exceptions that occur at the level of the Transport API. - """ - - -# Timeout exceptions... - - -class TimeoutException(TransportError): - """ - The base class for timeout errors. - - An operation has timed out. - """ - - -class ConnectTimeout(TimeoutException): - """ - Timed out while connecting to the host. - """ - - -class ReadTimeout(TimeoutException): - """ - Timed out while receiving data from the host. - """ - - -class WriteTimeout(TimeoutException): - """ - Timed out while sending data to the host. - """ - - -class PoolTimeout(TimeoutException): - """ - Timed out waiting to acquire a connection from the pool. - """ - - -# Core networking exceptions... - - -class NetworkError(TransportError): - """ - The base class for network-related errors. - - An error occurred while interacting with the network. - """ - - -class ReadError(NetworkError): - """ - Failed to receive data from the network. - """ - - -class WriteError(NetworkError): - """ - Failed to send data through the network. - """ - - -class ConnectError(NetworkError): - """ - Failed to establish a connection. - """ - - -class CloseError(NetworkError): - """ - Failed to close a connection. - """ - - -# Other transport exceptions... - - -class ProxyError(TransportError): - """ - An error occurred while establishing a proxy connection. - """ - - -class UnsupportedProtocol(TransportError): - """ - Attempted to make a request to an unsupported protocol. - - For example issuing a request to `ftp://www.example.com`. - """ - - -class ProtocolError(TransportError): - """ - The protocol was violated. - """ - - -class LocalProtocolError(ProtocolError): - """ - A protocol was violated by the client. - - For example if the user instantiated a `Request` instance explicitly, - failed to include the mandatory `Host:` header, and then issued it directly - using `client.send()`. - """ - - -class RemoteProtocolError(ProtocolError): - """ - The protocol was violated by the server. - - For exaample, returning malformed HTTP. - """ - - -# Other request exceptions... - - -class DecodingError(RequestError): - """ - Decoding of the response failed, due to a malformed encoding. - """ - - -class TooManyRedirects(RequestError): - """ - Too many redirects. - """ - - -# Client errors - - -class HTTPStatusError(HTTPError): - """ - The response had an error HTTP status of 4xx or 5xx. - - May be raised when calling `response.raise_for_status()` - """ - - def __init__( - self, message: str, *, request: "Request", response: "Response" - ) -> None: - super().__init__(message) - self.request = request - self.response = response - - -class InvalidURL(Exception): - """ - URL is improperly formed or cannot be parsed. - """ - - def __init__(self, message: str) -> None: - super().__init__(message) - - -class CookieConflict(Exception): - """ - Attempted to lookup a cookie by name, but multiple cookies existed. - - Can occur when calling `response.cookies.get(...)`. - """ - - def __init__(self, message: str) -> None: - super().__init__(message) - - -# Stream exceptions... - -# These may occur as the result of a programming error, by accessing -# the request/response stream in an invalid manner. - - -class StreamError(RuntimeError): - """ - The base class for stream exceptions. - - The developer made an error in accessing the request stream in - an invalid way. - """ - - def __init__(self, message: str) -> None: - super().__init__(message) - - -class StreamConsumed(StreamError): - """ - Attempted to read or stream content, but the content has already - been streamed. - """ - - def __init__(self) -> None: - message = ( - "Attempted to read or stream some content, but the content has " - "already been streamed. For requests, this could be due to passing " - "a generator as request content, and then receiving a redirect " - "response or a secondary request as part of an authentication flow." - "For responses, this could be due to attempting to stream the response " - "content more than once." - ) - super().__init__(message) - - -class StreamClosed(StreamError): - """ - Attempted to read or stream response content, but the request has been - closed. - """ - - def __init__(self) -> None: - message = ( - "Attempted to read or stream content, but the stream has " "been closed." - ) - super().__init__(message) - - -class ResponseNotRead(StreamError): - """ - Attempted to access streaming response content, without having called `read()`. - """ - - def __init__(self) -> None: - message = "Attempted to access streaming response content, without having called `read()`." - super().__init__(message) - - -class RequestNotRead(StreamError): - """ - Attempted to access streaming request content, without having called `read()`. - """ - - def __init__(self) -> None: - message = "Attempted to access streaming request content, without having called `read()`." - super().__init__(message) - - -@contextlib.contextmanager -def request_context(request: "Request" = None) -> typing.Iterator[None]: - """ - A context manager that can be used to attach the given request context - to any `RequestError` exceptions that are raised within the block. - """ - try: - yield - except RequestError as exc: - if request is not None: - exc.request = request - raise exc diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_models.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_models.py deleted file mode 100644 index c86d37d9..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_models.py +++ /dev/null @@ -1,1862 +0,0 @@ -import cgi -import datetime -import email.message -import json as jsonlib -import typing -import urllib.request -from collections.abc import MutableMapping -from http.cookiejar import Cookie, CookieJar -from urllib.parse import parse_qs, quote, unquote, urlencode - -import charset_normalizer -import idna -import rfc3986 -import rfc3986.exceptions - -from ._content import ByteStream, UnattachedStream, encode_request, encode_response -from ._decoders import ( - SUPPORTED_DECODERS, - ByteChunker, - ContentDecoder, - IdentityDecoder, - LineDecoder, - MultiDecoder, - TextChunker, - TextDecoder, -) -from ._exceptions import ( - CookieConflict, - HTTPStatusError, - InvalidURL, - RequestNotRead, - ResponseNotRead, - StreamClosed, - StreamConsumed, - request_context, -) -from ._status_codes import codes -from ._transports.base import AsyncByteStream, SyncByteStream -from ._types import ( - CookieTypes, - HeaderTypes, - PrimitiveData, - QueryParamTypes, - RawURL, - RequestContent, - RequestData, - RequestFiles, - ResponseContent, - URLTypes, -) -from ._utils import ( - guess_json_utf, - is_known_encoding, - normalize_header_key, - normalize_header_value, - obfuscate_sensitive_headers, - parse_header_links, - primitive_value_to_str, -) - - -class URL: - """ - url = httpx.URL("HTTPS://jo%40email.com:a%20secret@müller.de:1234/pa%20th?search=ab#anchorlink") - - assert url.scheme == "https" - assert url.username == "jo@email.com" - assert url.password == "a secret" - assert url.userinfo == b"jo%40email.com:a%20secret" - assert url.host == "müller.de" - assert url.raw_host == b"xn--mller-kva.de" - assert url.port == 1234 - assert url.netloc == b"xn--mller-kva.de:1234" - assert url.path == "/pa th" - assert url.query == b"?search=ab" - assert url.raw_path == b"/pa%20th?search=ab" - assert url.fragment == "anchorlink" - - The components of a URL are broken down like this: - - https://jo%40email.com:a%20secret@müller.de:1234/pa%20th?search=ab#anchorlink - [scheme] [ username ] [password] [ host ][port][ path ] [ query ] [fragment] - [ userinfo ] [ netloc ][ raw_path ] - - Note that: - - * `url.scheme` is normalized to always be lowercased. - - * `url.host` is normalized to always be lowercased. Internationalized domain - names are represented in unicode, without IDNA encoding applied. For instance: - - url = httpx.URL("http://中国.icom.museum") - assert url.host == "中国.icom.museum" - url = httpx.URL("http://xn--fiqs8s.icom.museum") - assert url.host == "中国.icom.museum" - - * `url.raw_host` is normalized to always be lowercased, and is IDNA encoded. - - url = httpx.URL("http://中国.icom.museum") - assert url.raw_host == b"xn--fiqs8s.icom.museum" - url = httpx.URL("http://xn--fiqs8s.icom.museum") - assert url.raw_host == b"xn--fiqs8s.icom.museum" - - * `url.port` is either None or an integer. URLs that include the default port for - "http", "https", "ws", "wss", and "ftp" schemes have their port normalized to `None`. - - assert httpx.URL("http://example.com") == httpx.URL("http://example.com:80") - assert httpx.URL("http://example.com").port is None - assert httpx.URL("http://example.com:80").port is None - - * `url.userinfo` is raw bytes, without URL escaping. Usually you'll want to work with - `url.username` and `url.password` instead, which handle the URL escaping. - - * `url.raw_path` is raw bytes of both the path and query, without URL escaping. - This portion is used as the target when constructing HTTP requests. Usually you'll - want to work with `url.path` instead. - - * `url.query` is raw bytes, without URL escaping. A URL query string portion can only - be properly URL escaped when decoding the parameter names and values themselves. - """ - - def __init__( - self, url: typing.Union["URL", str, RawURL] = "", **kwargs: typing.Any - ) -> None: - if isinstance(url, (str, tuple)): - if isinstance(url, tuple): - raw_scheme, raw_host, port, raw_path = url - scheme = raw_scheme.decode("ascii") - host = raw_host.decode("ascii") - if host and ":" in host and host[0] != "[": - # it's an IPv6 address, so it should be enclosed in "[" and "]" - # ref: https://tools.ietf.org/html/rfc2732#section-2 - # ref: https://tools.ietf.org/html/rfc3986#section-3.2.2 - host = f"[{host}]" - port_str = "" if port is None else f":{port}" - path = raw_path.decode("ascii") - url = f"{scheme}://{host}{port_str}{path}" - - try: - self._uri_reference = rfc3986.iri_reference(url).encode() - except rfc3986.exceptions.InvalidAuthority as exc: - raise InvalidURL(message=str(exc)) from None - - if self.is_absolute_url: - # We don't want to normalize relative URLs, since doing so - # removes any leading `../` portion. - self._uri_reference = self._uri_reference.normalize() - elif isinstance(url, URL): - self._uri_reference = url._uri_reference - else: - raise TypeError( - f"Invalid type for url. Expected str or httpx.URL, got {type(url)}: {url!r}" - ) - - # Perform port normalization, following the WHATWG spec for default ports. - # - # See: - # * https://tools.ietf.org/html/rfc3986#section-3.2.3 - # * https://url.spec.whatwg.org/#url-miscellaneous - # * https://url.spec.whatwg.org/#scheme-state - default_port = { - "ftp": ":21", - "http": ":80", - "https": ":443", - "ws": ":80", - "wss": ":443", - }.get(self._uri_reference.scheme, "") - authority = self._uri_reference.authority or "" - if default_port and authority.endswith(default_port): - authority = authority[: -len(default_port)] - self._uri_reference = self._uri_reference.copy_with(authority=authority) - - if kwargs: - self._uri_reference = self.copy_with(**kwargs)._uri_reference - - @property - def scheme(self) -> str: - """ - The URL scheme, such as "http", "https". - Always normalised to lowercase. - """ - return self._uri_reference.scheme or "" - - @property - def raw_scheme(self) -> bytes: - """ - The raw bytes representation of the URL scheme, such as b"http", b"https". - Always normalised to lowercase. - """ - return self.scheme.encode("ascii") - - @property - def userinfo(self) -> bytes: - """ - The URL userinfo as a raw bytestring. - For example: b"jo%40email.com:a%20secret". - """ - userinfo = self._uri_reference.userinfo or "" - return userinfo.encode("ascii") - - @property - def username(self) -> str: - """ - The URL username as a string, with URL decoding applied. - For example: "jo@email.com" - """ - userinfo = self._uri_reference.userinfo or "" - return unquote(userinfo.partition(":")[0]) - - @property - def password(self) -> str: - """ - The URL password as a string, with URL decoding applied. - For example: "a secret" - """ - userinfo = self._uri_reference.userinfo or "" - return unquote(userinfo.partition(":")[2]) - - @property - def host(self) -> str: - """ - The URL host as a string. - Always normalized to lowercase, with IDNA hosts decoded into unicode. - - Examples: - - url = httpx.URL("http://www.EXAMPLE.org") - assert url.host == "www.example.org" - - url = httpx.URL("http://中国.icom.museum") - assert url.host == "中国.icom.museum" - - url = httpx.URL("http://xn--fiqs8s.icom.museum") - assert url.host == "中国.icom.museum" - - url = httpx.URL("https://[::ffff:192.168.0.1]") - assert url.host == "::ffff:192.168.0.1" - """ - host: str = self._uri_reference.host or "" - - if host and ":" in host and host[0] == "[": - # it's an IPv6 address - host = host.lstrip("[").rstrip("]") - - if host.startswith("xn--"): - host = idna.decode(host) - - return host - - @property - def raw_host(self) -> bytes: - """ - The raw bytes representation of the URL host. - Always normalized to lowercase, and IDNA encoded. - - Examples: - - url = httpx.URL("http://www.EXAMPLE.org") - assert url.raw_host == b"www.example.org" - - url = httpx.URL("http://中国.icom.museum") - assert url.raw_host == b"xn--fiqs8s.icom.museum" - - url = httpx.URL("http://xn--fiqs8s.icom.museum") - assert url.raw_host == b"xn--fiqs8s.icom.museum" - - url = httpx.URL("https://[::ffff:192.168.0.1]") - assert url.raw_host == b"::ffff:192.168.0.1" - """ - host: str = self._uri_reference.host or "" - - if host and ":" in host and host[0] == "[": - # it's an IPv6 address - host = host.lstrip("[").rstrip("]") - - return host.encode("ascii") - - @property - def port(self) -> typing.Optional[int]: - """ - The URL port as an integer. - - Note that the URL class performs port normalization as per the WHATWG spec. - Default ports for "http", "https", "ws", "wss", and "ftp" schemes are always - treated as `None`. - - For example: - - assert httpx.URL("http://www.example.com") == httpx.URL("http://www.example.com:80") - assert httpx.URL("http://www.example.com:80").port is None - """ - port = self._uri_reference.port - return int(port) if port else None - - @property - def netloc(self) -> bytes: - """ - Either `` or `:` as bytes. - Always normalized to lowercase, and IDNA encoded. - - This property may be used for generating the value of a request - "Host" header. - """ - host = self._uri_reference.host or "" - port = self._uri_reference.port - netloc = host.encode("ascii") - if port: - netloc = netloc + b":" + port.encode("ascii") - return netloc - - @property - def path(self) -> str: - """ - The URL path as a string. Excluding the query string, and URL decoded. - - For example: - - url = httpx.URL("https://example.com/pa%20th") - assert url.path == "/pa th" - """ - path = self._uri_reference.path or "/" - return unquote(path) - - @property - def query(self) -> bytes: - """ - The URL query string, as raw bytes, excluding the leading b"?". - - This is neccessarily a bytewise interface, because we cannot - perform URL decoding of this representation until we've parsed - the keys and values into a QueryParams instance. - - For example: - - url = httpx.URL("https://example.com/?filter=some%20search%20terms") - assert url.query == b"filter=some%20search%20terms" - """ - query = self._uri_reference.query or "" - return query.encode("ascii") - - @property - def params(self) -> "QueryParams": - """ - The URL query parameters, neatly parsed and packaged into an immutable - multidict representation. - """ - return QueryParams(self._uri_reference.query) - - @property - def raw_path(self) -> bytes: - """ - The complete URL path and query string as raw bytes. - Used as the target when constructing HTTP requests. - - For example: - - GET /users?search=some%20text HTTP/1.1 - Host: www.example.org - Connection: close - """ - path = self._uri_reference.path or "/" - if self._uri_reference.query is not None: - path += "?" + self._uri_reference.query - return path.encode("ascii") - - @property - def fragment(self) -> str: - """ - The URL fragments, as used in HTML anchors. - As a string, without the leading '#'. - """ - return unquote(self._uri_reference.fragment or "") - - @property - def raw(self) -> RawURL: - """ - The URL in the raw representation used by the low level - transport API. See `BaseTransport.handle_request`. - - Provides the (scheme, host, port, target) for the outgoing request. - """ - return ( - self.raw_scheme, - self.raw_host, - self.port, - self.raw_path, - ) - - @property - def is_absolute_url(self) -> bool: - """ - Return `True` for absolute URLs such as 'http://example.com/path', - and `False` for relative URLs such as '/path'. - """ - # We don't use `.is_absolute` from `rfc3986` because it treats - # URLs with a fragment portion as not absolute. - # What we actually care about is if the URL provides - # a scheme and hostname to which connections should be made. - return bool(self._uri_reference.scheme and self._uri_reference.host) - - @property - def is_relative_url(self) -> bool: - """ - Return `False` for absolute URLs such as 'http://example.com/path', - and `True` for relative URLs such as '/path'. - """ - return not self.is_absolute_url - - def copy_with(self, **kwargs: typing.Any) -> "URL": - """ - Copy this URL, returning a new URL with some components altered. - Accepts the same set of parameters as the components that are made - available via properties on the `URL` class. - - For example: - - url = httpx.URL("https://www.example.com").copy_with(username="jo@gmail.com", password="a secret") - assert url == "https://jo%40email.com:a%20secret@www.example.com" - """ - allowed = { - "scheme": str, - "username": str, - "password": str, - "userinfo": bytes, - "host": str, - "port": int, - "netloc": bytes, - "path": str, - "query": bytes, - "raw_path": bytes, - "fragment": str, - "params": object, - } - - # Step 1 - # ====== - # - # Perform type checking for all supported keyword arguments. - for key, value in kwargs.items(): - if key not in allowed: - message = f"{key!r} is an invalid keyword argument for copy_with()" - raise TypeError(message) - if value is not None and not isinstance(value, allowed[key]): - expected = allowed[key].__name__ - seen = type(value).__name__ - message = f"Argument {key!r} must be {expected} but got {seen}" - raise TypeError(message) - - # Step 2 - # ====== - # - # Consolidate "username", "password", "userinfo", "host", "port" and "netloc" - # into a single "authority" keyword, for `rfc3986`. - if "username" in kwargs or "password" in kwargs: - # Consolidate "username" and "password" into "userinfo". - username = quote(kwargs.pop("username", self.username) or "") - password = quote(kwargs.pop("password", self.password) or "") - userinfo = f"{username}:{password}" if password else username - kwargs["userinfo"] = userinfo.encode("ascii") - - if "host" in kwargs or "port" in kwargs: - # Consolidate "host" and "port" into "netloc". - host = kwargs.pop("host", self.host) or "" - port = kwargs.pop("port", self.port) - - if host and ":" in host and host[0] != "[": - # IPv6 addresses need to be escaped within sqaure brackets. - host = f"[{host}]" - - kwargs["netloc"] = ( - f"{host}:{port}".encode("ascii") - if port is not None - else host.encode("ascii") - ) - - if "userinfo" in kwargs or "netloc" in kwargs: - # Consolidate "userinfo" and "netloc" into authority. - userinfo = (kwargs.pop("userinfo", self.userinfo) or b"").decode("ascii") - netloc = (kwargs.pop("netloc", self.netloc) or b"").decode("ascii") - authority = f"{userinfo}@{netloc}" if userinfo else netloc - kwargs["authority"] = authority - - # Step 3 - # ====== - # - # Wrangle any "path", "query", "raw_path" and "params" keywords into - # "query" and "path" keywords for `rfc3986`. - if "raw_path" in kwargs: - # If "raw_path" is included, then split it into "path" and "query" components. - raw_path = kwargs.pop("raw_path") or b"" - path, has_query, query = raw_path.decode("ascii").partition("?") - kwargs["path"] = path - kwargs["query"] = query if has_query else None - - else: - if kwargs.get("path") is not None: - # Ensure `kwargs["path"] = ` for `rfc3986`. - kwargs["path"] = quote(kwargs["path"]) - - if kwargs.get("query") is not None: - # Ensure `kwargs["query"] = ` for `rfc3986`. - # - # Note that `.copy_with(query=None)` and `.copy_with(query=b"")` - # are subtly different. The `None` style will not include an empty - # trailing "?" character. - kwargs["query"] = kwargs["query"].decode("ascii") - - if "params" in kwargs: - # Replace any "params" keyword with the raw "query" instead. - # - # Ensure that empty params use `kwargs["query"] = None` rather - # than `kwargs["query"] = ""`, so that generated URLs do not - # include an empty trailing "?". - params = kwargs.pop("params") - kwargs["query"] = None if not params else str(QueryParams(params)) - - # Step 4 - # ====== - # - # Ensure any fragment component is quoted. - if kwargs.get("fragment") is not None: - kwargs["fragment"] = quote(kwargs["fragment"]) - - # Step 5 - # ====== - # - # At this point kwargs may include keys for "scheme", "authority", "path", - # "query" and "fragment". Together these constitute the entire URL. - # - # See https://tools.ietf.org/html/rfc3986#section-3 - # - # foo://example.com:8042/over/there?name=ferret#nose - # \_/ \______________/\_________/ \_________/ \__/ - # | | | | | - # scheme authority path query fragment - return URL(self._uri_reference.copy_with(**kwargs).unsplit()) - - def copy_set_param(self, key: str, value: typing.Any = None) -> "URL": - return self.copy_with(params=self.params.set(key, value)) - - def copy_add_param(self, key: str, value: typing.Any = None) -> "URL": - return self.copy_with(params=self.params.add(key, value)) - - def copy_remove_param(self, key: str) -> "URL": - return self.copy_with(params=self.params.remove(key)) - - def copy_merge_params(self, params: QueryParamTypes) -> "URL": - return self.copy_with(params=self.params.merge(params)) - - def join(self, url: URLTypes) -> "URL": - """ - Return an absolute URL, using this URL as the base. - - Eg. - - url = httpx.URL("https://www.example.com/test") - url = url.join("/new/path") - assert url == "https://www.example.com/new/path" - """ - if self.is_relative_url: - # Workaround to handle relative URLs, which otherwise raise - # rfc3986.exceptions.ResolutionError when used as an argument - # in `.resolve_with`. - return ( - self.copy_with(scheme="http", host="example.com") - .join(url) - .copy_with(scheme=None, host=None) - ) - - # We drop any fragment portion, because RFC 3986 strictly - # treats URLs with a fragment portion as not being absolute URLs. - base_uri = self._uri_reference.copy_with(fragment=None) - relative_url = URL(url) - return URL(relative_url._uri_reference.resolve_with(base_uri).unsplit()) - - def __hash__(self) -> int: - return hash(str(self)) - - def __eq__(self, other: typing.Any) -> bool: - return isinstance(other, (URL, str)) and str(self) == str(URL(other)) - - def __str__(self) -> str: - return self._uri_reference.unsplit() - - def __repr__(self) -> str: - class_name = self.__class__.__name__ - url_str = str(self) - if self._uri_reference.userinfo: - # Mask any password component in the URL representation, to lower the - # risk of unintended leakage, such as in debug information and logging. - username = quote(self.username) - url_str = ( - rfc3986.urlparse(url_str) - .copy_with(userinfo=f"{username}:[secure]") - .unsplit() - ) - return f"{class_name}({url_str!r})" - - -class QueryParams(typing.Mapping[str, str]): - """ - URL query parameters, as a multi-dict. - """ - - def __init__(self, *args: QueryParamTypes, **kwargs: typing.Any) -> None: - assert len(args) < 2, "Too many arguments." - assert not (args and kwargs), "Cannot mix named and unnamed arguments." - - value = args[0] if args else kwargs - - items: typing.Sequence[typing.Tuple[str, PrimitiveData]] - if value is None or isinstance(value, (str, bytes)): - value = value.decode("ascii") if isinstance(value, bytes) else value - self._dict = parse_qs(value) - elif isinstance(value, QueryParams): - self._dict = {k: list(v) for k, v in value._dict.items()} - else: - dict_value: typing.Dict[typing.Any, typing.List[typing.Any]] = {} - if isinstance(value, (list, tuple)): - # Convert list inputs like: - # [("a", "123"), ("a", "456"), ("b", "789")] - # To a dict representation, like: - # {"a": ["123", "456"], "b": ["789"]} - for item in value: - dict_value.setdefault(item[0], []).append(item[1]) - else: - # Convert dict inputs like: - # {"a": "123", "b": ["456", "789"]} - # To dict inputs where values are always lists, like: - # {"a": ["123"], "b": ["456", "789"]} - dict_value = { - k: list(v) if isinstance(v, (list, tuple)) else [v] - for k, v in value.items() - } - - # Ensure that keys and values are neatly coerced to strings. - # We coerce values `True` and `False` to JSON-like "true" and "false" - # representations, and coerce `None` values to the empty string. - self._dict = { - str(k): [primitive_value_to_str(item) for item in v] - for k, v in dict_value.items() - } - - def keys(self) -> typing.KeysView: - """ - Return all the keys in the query params. - - Usage: - - q = httpx.QueryParams("a=123&a=456&b=789") - assert list(q.keys()) == ["a", "b"] - """ - return self._dict.keys() - - def values(self) -> typing.ValuesView: - """ - Return all the values in the query params. If a key occurs more than once - only the first item for that key is returned. - - Usage: - - q = httpx.QueryParams("a=123&a=456&b=789") - assert list(q.values()) == ["123", "789"] - """ - return {k: v[0] for k, v in self._dict.items()}.values() - - def items(self) -> typing.ItemsView: - """ - Return all items in the query params. If a key occurs more than once - only the first item for that key is returned. - - Usage: - - q = httpx.QueryParams("a=123&a=456&b=789") - assert list(q.items()) == [("a", "123"), ("b", "789")] - """ - return {k: v[0] for k, v in self._dict.items()}.items() - - def multi_items(self) -> typing.List[typing.Tuple[str, str]]: - """ - Return all items in the query params. Allow duplicate keys to occur. - - Usage: - - q = httpx.QueryParams("a=123&a=456&b=789") - assert list(q.multi_items()) == [("a", "123"), ("a", "456"), ("b", "789")] - """ - multi_items: typing.List[typing.Tuple[str, str]] = [] - for k, v in self._dict.items(): - multi_items.extend([(k, i) for i in v]) - return multi_items - - def get(self, key: typing.Any, default: typing.Any = None) -> typing.Any: - """ - Get a value from the query param for a given key. If the key occurs - more than once, then only the first value is returned. - - Usage: - - q = httpx.QueryParams("a=123&a=456&b=789") - assert q.get("a") == "123" - """ - if key in self._dict: - return self._dict[str(key)][0] - return default - - def get_list(self, key: str) -> typing.List[str]: - """ - Get all values from the query param for a given key. - - Usage: - - q = httpx.QueryParams("a=123&a=456&b=789") - assert q.get_list("a") == ["123", "456"] - """ - return list(self._dict.get(str(key), [])) - - def set(self, key: str, value: typing.Any = None) -> "QueryParams": - """ - Return a new QueryParams instance, setting the value of a key. - - Usage: - - q = httpx.QueryParams("a=123") - q = q.set("a", "456") - assert q == httpx.QueryParams("a=456") - """ - q = QueryParams() - q._dict = dict(self._dict) - q._dict[str(key)] = [primitive_value_to_str(value)] - return q - - def add(self, key: str, value: typing.Any = None) -> "QueryParams": - """ - Return a new QueryParams instance, setting or appending the value of a key. - - Usage: - - q = httpx.QueryParams("a=123") - q = q.add("a", "456") - assert q == httpx.QueryParams("a=123&a=456") - """ - q = QueryParams() - q._dict = dict(self._dict) - q._dict[str(key)] = q.get_list(key) + [primitive_value_to_str(value)] - return q - - def remove(self, key: str) -> "QueryParams": - """ - Return a new QueryParams instance, removing the value of a key. - - Usage: - - q = httpx.QueryParams("a=123") - q = q.remove("a") - assert q == httpx.QueryParams("") - """ - q = QueryParams() - q._dict = dict(self._dict) - q._dict.pop(str(key), None) - return q - - def merge(self, params: QueryParamTypes = None) -> "QueryParams": - """ - Return a new QueryParams instance, updated with. - - Usage: - - q = httpx.QueryParams("a=123") - q = q.merge({"b": "456"}) - assert q == httpx.QueryParams("a=123&b=456") - - q = httpx.QueryParams("a=123") - q = q.merge({"a": "456", "b": "789"}) - assert q == httpx.QueryParams("a=456&b=789") - """ - q = QueryParams(params) - q._dict = {**self._dict, **q._dict} - return q - - def __getitem__(self, key: typing.Any) -> str: - return self._dict[key][0] - - def __contains__(self, key: typing.Any) -> bool: - return key in self._dict - - def __iter__(self) -> typing.Iterator[typing.Any]: - return iter(self.keys()) - - def __len__(self) -> int: - return len(self._dict) - - def __bool__(self) -> bool: - return bool(self._dict) - - def __hash__(self) -> int: - return hash(str(self)) - - def __eq__(self, other: typing.Any) -> bool: - if not isinstance(other, self.__class__): - return False - return sorted(self.multi_items()) == sorted(other.multi_items()) - - def __str__(self) -> str: - return urlencode(self.multi_items()) - - def __repr__(self) -> str: - class_name = self.__class__.__name__ - query_string = str(self) - return f"{class_name}({query_string!r})" - - def update(self, params: QueryParamTypes = None) -> None: - raise RuntimeError( - "QueryParams are immutable since 0.18.0. " - "Use `q = q.merge(...)` to create an updated copy." - ) - - def __setitem__(self, key: str, value: str) -> None: - raise RuntimeError( - "QueryParams are immutable since 0.18.0. " - "Use `q = q.set(key, value)` to create an updated copy." - ) - - -class Headers(typing.MutableMapping[str, str]): - """ - HTTP headers, as a case-insensitive multi-dict. - """ - - def __init__(self, headers: HeaderTypes = None, encoding: str = None) -> None: - if headers is None: - self._list = [] # type: typing.List[typing.Tuple[bytes, bytes, bytes]] - elif isinstance(headers, Headers): - self._list = list(headers._list) - elif isinstance(headers, dict): - self._list = [ - ( - normalize_header_key(k, lower=False, encoding=encoding), - normalize_header_key(k, lower=True, encoding=encoding), - normalize_header_value(v, encoding), - ) - for k, v in headers.items() - ] - else: - self._list = [ - ( - normalize_header_key(k, lower=False, encoding=encoding), - normalize_header_key(k, lower=True, encoding=encoding), - normalize_header_value(v, encoding), - ) - for k, v in headers - ] - - self._encoding = encoding - - @property - def encoding(self) -> str: - """ - Header encoding is mandated as ascii, but we allow fallbacks to utf-8 - or iso-8859-1. - """ - if self._encoding is None: - for encoding in ["ascii", "utf-8"]: - for key, value in self.raw: - try: - key.decode(encoding) - value.decode(encoding) - except UnicodeDecodeError: - break - else: - # The else block runs if 'break' did not occur, meaning - # all values fitted the encoding. - self._encoding = encoding - break - else: - # The ISO-8859-1 encoding covers all 256 code points in a byte, - # so will never raise decode errors. - self._encoding = "iso-8859-1" - return self._encoding - - @encoding.setter - def encoding(self, value: str) -> None: - self._encoding = value - - @property - def raw(self) -> typing.List[typing.Tuple[bytes, bytes]]: - """ - Returns a list of the raw header items, as byte pairs. - """ - return [(raw_key, value) for raw_key, _, value in self._list] - - def keys(self) -> typing.KeysView[str]: - return {key.decode(self.encoding): None for _, key, value in self._list}.keys() - - def values(self) -> typing.ValuesView[str]: - values_dict: typing.Dict[str, str] = {} - for _, key, value in self._list: - str_key = key.decode(self.encoding) - str_value = value.decode(self.encoding) - if str_key in values_dict: - values_dict[str_key] += f", {str_value}" - else: - values_dict[str_key] = str_value - return values_dict.values() - - def items(self) -> typing.ItemsView[str, str]: - """ - Return `(key, value)` items of headers. Concatenate headers - into a single comma seperated value when a key occurs multiple times. - """ - values_dict: typing.Dict[str, str] = {} - for _, key, value in self._list: - str_key = key.decode(self.encoding) - str_value = value.decode(self.encoding) - if str_key in values_dict: - values_dict[str_key] += f", {str_value}" - else: - values_dict[str_key] = str_value - return values_dict.items() - - def multi_items(self) -> typing.List[typing.Tuple[str, str]]: - """ - Return a list of `(key, value)` pairs of headers. Allow multiple - occurences of the same key without concatenating into a single - comma seperated value. - """ - return [ - (key.decode(self.encoding), value.decode(self.encoding)) - for _, key, value in self._list - ] - - def get(self, key: str, default: typing.Any = None) -> typing.Any: - """ - Return a header value. If multiple occurences of the header occur - then concatenate them together with commas. - """ - try: - return self[key] - except KeyError: - return default - - def get_list(self, key: str, split_commas: bool = False) -> typing.List[str]: - """ - Return a list of all header values for a given key. - If `split_commas=True` is passed, then any comma seperated header - values are split into multiple return strings. - """ - get_header_key = key.lower().encode(self.encoding) - - values = [ - item_value.decode(self.encoding) - for _, item_key, item_value in self._list - if item_key.lower() == get_header_key - ] - - if not split_commas: - return values - - split_values = [] - for value in values: - split_values.extend([item.strip() for item in value.split(",")]) - return split_values - - def update(self, headers: HeaderTypes = None) -> None: # type: ignore - headers = Headers(headers) - for key, value in headers.raw: - self[key.decode(headers.encoding)] = value.decode(headers.encoding) - - def copy(self) -> "Headers": - return Headers(self, encoding=self.encoding) - - def __getitem__(self, key: str) -> str: - """ - Return a single header value. - - If there are multiple headers with the same key, then we concatenate - them with commas. See: https://tools.ietf.org/html/rfc7230#section-3.2.2 - """ - normalized_key = key.lower().encode(self.encoding) - - items = [ - header_value.decode(self.encoding) - for _, header_key, header_value in self._list - if header_key == normalized_key - ] - - if items: - return ", ".join(items) - - raise KeyError(key) - - def __setitem__(self, key: str, value: str) -> None: - """ - Set the header `key` to `value`, removing any duplicate entries. - Retains insertion order. - """ - set_key = key.encode(self._encoding or "utf-8") - set_value = value.encode(self._encoding or "utf-8") - lookup_key = set_key.lower() - - found_indexes = [ - idx - for idx, (_, item_key, _) in enumerate(self._list) - if item_key == lookup_key - ] - - for idx in reversed(found_indexes[1:]): - del self._list[idx] - - if found_indexes: - idx = found_indexes[0] - self._list[idx] = (set_key, lookup_key, set_value) - else: - self._list.append((set_key, lookup_key, set_value)) - - def __delitem__(self, key: str) -> None: - """ - Remove the header `key`. - """ - del_key = key.lower().encode(self.encoding) - - pop_indexes = [ - idx - for idx, (_, item_key, _) in enumerate(self._list) - if item_key.lower() == del_key - ] - - if not pop_indexes: - raise KeyError(key) - - for idx in reversed(pop_indexes): - del self._list[idx] - - def __contains__(self, key: typing.Any) -> bool: - header_key = key.lower().encode(self.encoding) - return header_key in [key for _, key, _ in self._list] - - def __iter__(self) -> typing.Iterator[typing.Any]: - return iter(self.keys()) - - def __len__(self) -> int: - return len(self._list) - - def __eq__(self, other: typing.Any) -> bool: - try: - other_headers = Headers(other) - except ValueError: - return False - - self_list = [(key, value) for _, key, value in self._list] - other_list = [(key, value) for _, key, value in other_headers._list] - return sorted(self_list) == sorted(other_list) - - def __repr__(self) -> str: - class_name = self.__class__.__name__ - - encoding_str = "" - if self.encoding != "ascii": - encoding_str = f", encoding={self.encoding!r}" - - as_list = list(obfuscate_sensitive_headers(self.multi_items())) - as_dict = dict(as_list) - - no_duplicate_keys = len(as_dict) == len(as_list) - if no_duplicate_keys: - return f"{class_name}({as_dict!r}{encoding_str})" - return f"{class_name}({as_list!r}{encoding_str})" - - -class Request: - def __init__( - self, - method: typing.Union[str, bytes], - url: typing.Union["URL", str, RawURL], - *, - params: QueryParamTypes = None, - headers: HeaderTypes = None, - cookies: CookieTypes = None, - content: RequestContent = None, - data: RequestData = None, - files: RequestFiles = None, - json: typing.Any = None, - stream: typing.Union[SyncByteStream, AsyncByteStream] = None, - ): - if isinstance(method, bytes): - self.method = method.decode("ascii").upper() - else: - self.method = method.upper() - self.url = URL(url) - if params is not None: - self.url = self.url.copy_merge_params(params=params) - self.headers = Headers(headers) - if cookies: - Cookies(cookies).set_cookie_header(self) - - if stream is None: - headers, stream = encode_request(content, data, files, json) - self._prepare(headers) - self.stream = stream - # Load the request body, except for streaming content. - if isinstance(stream, ByteStream): - self.read() - else: - # There's an important distinction between `Request(content=...)`, - # and `Request(stream=...)`. - # - # Using `content=...` implies automatically populated `Host` and content - # headers, of either `Content-Length: ...` or `Transfer-Encoding: chunked`. - # - # Using `stream=...` will not automatically include *any* auto-populated headers. - # - # As an end-user you don't really need `stream=...`. It's only - # useful when: - # - # * Preserving the request stream when copying requests, eg for redirects. - # * Creating request instances on the *server-side* of the transport API. - self.stream = stream - - def _prepare(self, default_headers: typing.Dict[str, str]) -> None: - for key, value in default_headers.items(): - # Ignore Transfer-Encoding if the Content-Length has been set explicitly. - if key.lower() == "transfer-encoding" and "Content-Length" in self.headers: - continue - self.headers.setdefault(key, value) - - auto_headers: typing.List[typing.Tuple[bytes, bytes]] = [] - - has_host = "Host" in self.headers - has_content_length = ( - "Content-Length" in self.headers or "Transfer-Encoding" in self.headers - ) - - if not has_host and self.url.host: - auto_headers.append((b"Host", self.url.netloc)) - if not has_content_length and self.method in ("POST", "PUT", "PATCH"): - auto_headers.append((b"Content-Length", b"0")) - - self.headers = Headers(auto_headers + self.headers.raw) - - @property - def content(self) -> bytes: - if not hasattr(self, "_content"): - raise RequestNotRead() - return self._content - - def read(self) -> bytes: - """ - Read and return the request content. - """ - if not hasattr(self, "_content"): - assert isinstance(self.stream, typing.Iterable) - self._content = b"".join(self.stream) - if not isinstance(self.stream, ByteStream): - # If a streaming request has been read entirely into memory, then - # we can replace the stream with a raw bytes implementation, - # to ensure that any non-replayable streams can still be used. - self.stream = ByteStream(self._content) - return self._content - - async def aread(self) -> bytes: - """ - Read and return the request content. - """ - if not hasattr(self, "_content"): - assert isinstance(self.stream, typing.AsyncIterable) - self._content = b"".join([part async for part in self.stream]) - if not isinstance(self.stream, ByteStream): - # If a streaming request has been read entirely into memory, then - # we can replace the stream with a raw bytes implementation, - # to ensure that any non-replayable streams can still be used. - self.stream = ByteStream(self._content) - return self._content - - def __repr__(self) -> str: - class_name = self.__class__.__name__ - url = str(self.url) - return f"<{class_name}({self.method!r}, {url!r})>" - - def __getstate__(self) -> typing.Dict[str, typing.Any]: - return { - name: value - for name, value in self.__dict__.items() - if name not in ["stream"] - } - - def __setstate__(self, state: typing.Dict[str, typing.Any]) -> None: - for name, value in state.items(): - setattr(self, name, value) - self.stream = UnattachedStream() - - -class Response: - def __init__( - self, - status_code: int, - *, - headers: HeaderTypes = None, - content: ResponseContent = None, - text: str = None, - html: str = None, - json: typing.Any = None, - stream: typing.Union[SyncByteStream, AsyncByteStream] = None, - request: Request = None, - extensions: dict = None, - history: typing.List["Response"] = None, - ): - self.status_code = status_code - self.headers = Headers(headers) - - self._request: typing.Optional[Request] = request - - # When allow_redirects=False and a redirect is received, - # the client will set `response.next_request`. - self.next_request: typing.Optional[Request] = None - - self.extensions = {} if extensions is None else extensions - self.history = [] if history is None else list(history) - - self.is_closed = False - self.is_stream_consumed = False - - if stream is None: - headers, stream = encode_response(content, text, html, json) - self._prepare(headers) - self.stream = stream - if isinstance(stream, ByteStream): - # Load the response body, except for streaming content. - self.read() - else: - # There's an important distinction between `Response(content=...)`, - # and `Response(stream=...)`. - # - # Using `content=...` implies automatically populated content headers, - # of either `Content-Length: ...` or `Transfer-Encoding: chunked`. - # - # Using `stream=...` will not automatically include any content headers. - # - # As an end-user you don't really need `stream=...`. It's only - # useful when creating response instances having received a stream - # from the transport API. - self.stream = stream - - self._num_bytes_downloaded = 0 - - def _prepare(self, default_headers: typing.Dict[str, str]) -> None: - for key, value in default_headers.items(): - # Ignore Transfer-Encoding if the Content-Length has been set explicitly. - if key.lower() == "transfer-encoding" and "content-length" in self.headers: - continue - self.headers.setdefault(key, value) - - @property - def elapsed(self) -> datetime.timedelta: - """ - Returns the time taken for the complete request/response - cycle to complete. - """ - if not hasattr(self, "_elapsed"): - raise RuntimeError( - "'.elapsed' may only be accessed after the response " - "has been read or closed." - ) - return self._elapsed - - @elapsed.setter - def elapsed(self, elapsed: datetime.timedelta) -> None: - self._elapsed = elapsed - - @property - def request(self) -> Request: - """ - Returns the request instance associated to the current response. - """ - if self._request is None: - raise RuntimeError( - "The request instance has not been set on this response." - ) - return self._request - - @request.setter - def request(self, value: Request) -> None: - self._request = value - - @property - def http_version(self) -> str: - try: - return self.extensions["http_version"].decode("ascii", errors="ignore") - except KeyError: - return "HTTP/1.1" - - @property - def reason_phrase(self) -> str: - try: - return self.extensions["reason_phrase"].decode("ascii", errors="ignore") - except KeyError: - return codes.get_reason_phrase(self.status_code) - - @property - def url(self) -> typing.Optional[URL]: - """ - Returns the URL for which the request was made. - """ - return self.request.url - - @property - def content(self) -> bytes: - if not hasattr(self, "_content"): - raise ResponseNotRead() - return self._content - - @property - def text(self) -> str: - if not hasattr(self, "_text"): - content = self.content - if not content: - self._text = "" - else: - decoder = TextDecoder(encoding=self.encoding or "utf-8") - self._text = "".join([decoder.decode(self.content), decoder.flush()]) - return self._text - - @property - def encoding(self) -> typing.Optional[str]: - """ - Return an encoding to use for decoding the byte content into text. - The priority for determining this is given by... - - * `.encoding = <>` has been set explicitly. - * The encoding as specified by the charset parameter in the Content-Type header. - * The encoding as determined by `charset_normalizer`. - * UTF-8. - """ - if not hasattr(self, "_encoding"): - encoding = self.charset_encoding - if encoding is None or not is_known_encoding(encoding): - encoding = self.apparent_encoding - self._encoding = encoding - return self._encoding - - @encoding.setter - def encoding(self, value: str) -> None: - self._encoding = value - - @property - def charset_encoding(self) -> typing.Optional[str]: - """ - Return the encoding, as specified by the Content-Type header. - """ - content_type = self.headers.get("Content-Type") - if content_type is None: - return None - - _, params = cgi.parse_header(content_type) - if "charset" not in params: - return None - - return params["charset"].strip("'\"") - - @property - def apparent_encoding(self) -> typing.Optional[str]: - """ - Return the encoding, as detemined by `charset_normalizer`. - """ - content = getattr(self, "_content", b"") - if len(content) < 32: - # charset_normalizer will issue warnings if we run it with - # fewer bytes than this cutoff. - return None - match = charset_normalizer.from_bytes(self.content).best() - return None if match is None else match.encoding - - def _get_content_decoder(self) -> ContentDecoder: - """ - Returns a decoder instance which can be used to decode the raw byte - content, depending on the Content-Encoding used in the response. - """ - if not hasattr(self, "_decoder"): - decoders: typing.List[ContentDecoder] = [] - values = self.headers.get_list("content-encoding", split_commas=True) - for value in values: - value = value.strip().lower() - try: - decoder_cls = SUPPORTED_DECODERS[value] - decoders.append(decoder_cls()) - except KeyError: - continue - - if len(decoders) == 1: - self._decoder = decoders[0] - elif len(decoders) > 1: - self._decoder = MultiDecoder(children=decoders) - else: - self._decoder = IdentityDecoder() - - return self._decoder - - @property - def is_error(self) -> bool: - return codes.is_error(self.status_code) - - @property - def is_redirect(self) -> bool: - return codes.is_redirect(self.status_code) and "location" in self.headers - - def raise_for_status(self) -> None: - """ - Raise the `HTTPStatusError` if one occurred. - """ - message = ( - "{0.status_code} {error_type}: {0.reason_phrase} for url: {0.url}\n" - "For more information check: https://httpstatuses.com/{0.status_code}" - ) - - request = self._request - if request is None: - raise RuntimeError( - "Cannot call `raise_for_status` as the request " - "instance has not been set on this response." - ) - - if codes.is_client_error(self.status_code): - message = message.format(self, error_type="Client Error") - raise HTTPStatusError(message, request=request, response=self) - elif codes.is_server_error(self.status_code): - message = message.format(self, error_type="Server Error") - raise HTTPStatusError(message, request=request, response=self) - - def json(self, **kwargs: typing.Any) -> typing.Any: - if self.charset_encoding is None and self.content and len(self.content) > 3: - encoding = guess_json_utf(self.content) - if encoding is not None: - return jsonlib.loads(self.content.decode(encoding), **kwargs) - return jsonlib.loads(self.text, **kwargs) - - @property - def cookies(self) -> "Cookies": - if not hasattr(self, "_cookies"): - self._cookies = Cookies() - self._cookies.extract_cookies(self) - return self._cookies - - @property - def links(self) -> typing.Dict[typing.Optional[str], typing.Dict[str, str]]: - """ - Returns the parsed header links of the response, if any - """ - header = self.headers.get("link") - ldict = {} - if header: - links = parse_header_links(header) - for link in links: - key = link.get("rel") or link.get("url") - ldict[key] = link - return ldict - - @property - def num_bytes_downloaded(self) -> int: - return self._num_bytes_downloaded - - def __repr__(self) -> str: - return f"" - - def __getstate__(self) -> typing.Dict[str, typing.Any]: - return { - name: value - for name, value in self.__dict__.items() - if name not in ["stream", "is_closed", "_decoder"] - } - - def __setstate__(self, state: typing.Dict[str, typing.Any]) -> None: - for name, value in state.items(): - setattr(self, name, value) - self.is_closed = True - self.stream = UnattachedStream() - - def read(self) -> bytes: - """ - Read and return the response content. - """ - if not hasattr(self, "_content"): - self._content = b"".join(self.iter_bytes()) - return self._content - - def iter_bytes(self, chunk_size: int = None) -> typing.Iterator[bytes]: - """ - A byte-iterator over the decoded response content. - This allows us to handle gzip, deflate, and brotli encoded responses. - """ - if hasattr(self, "_content"): - chunk_size = len(self._content) if chunk_size is None else chunk_size - for i in range(0, len(self._content), chunk_size): - yield self._content[i : i + chunk_size] - else: - decoder = self._get_content_decoder() - chunker = ByteChunker(chunk_size=chunk_size) - with request_context(request=self._request): - for raw_bytes in self.iter_raw(): - decoded = decoder.decode(raw_bytes) - for chunk in chunker.decode(decoded): - yield chunk - decoded = decoder.flush() - for chunk in chunker.decode(decoded): - yield chunk - for chunk in chunker.flush(): - yield chunk - - def iter_text(self, chunk_size: int = None) -> typing.Iterator[str]: - """ - A str-iterator over the decoded response content - that handles both gzip, deflate, etc but also detects the content's - string encoding. - """ - decoder = TextDecoder(encoding=self.encoding or "utf-8") - chunker = TextChunker(chunk_size=chunk_size) - with request_context(request=self._request): - for byte_content in self.iter_bytes(): - text_content = decoder.decode(byte_content) - for chunk in chunker.decode(text_content): - yield chunk - text_content = decoder.flush() - for chunk in chunker.decode(text_content): - yield chunk - for chunk in chunker.flush(): - yield chunk - - def iter_lines(self) -> typing.Iterator[str]: - decoder = LineDecoder() - with request_context(request=self._request): - for text in self.iter_text(): - for line in decoder.decode(text): - yield line - for line in decoder.flush(): - yield line - - def iter_raw(self, chunk_size: int = None) -> typing.Iterator[bytes]: - """ - A byte-iterator over the raw response content. - """ - if self.is_stream_consumed: - raise StreamConsumed() - if self.is_closed: - raise StreamClosed() - if not isinstance(self.stream, SyncByteStream): - raise RuntimeError("Attempted to call a sync iterator on an async stream.") - - self.is_stream_consumed = True - self._num_bytes_downloaded = 0 - chunker = ByteChunker(chunk_size=chunk_size) - - with request_context(request=self._request): - for raw_stream_bytes in self.stream: - self._num_bytes_downloaded += len(raw_stream_bytes) - for chunk in chunker.decode(raw_stream_bytes): - yield chunk - - for chunk in chunker.flush(): - yield chunk - - self.close() - - def close(self) -> None: - """ - Close the response and release the connection. - Automatically called if the response body is read to completion. - """ - if not isinstance(self.stream, SyncByteStream): - raise RuntimeError("Attempted to call an sync close on an async stream.") - - if not self.is_closed: - self.is_closed = True - with request_context(request=self._request): - self.stream.close() - - async def aread(self) -> bytes: - """ - Read and return the response content. - """ - if not hasattr(self, "_content"): - self._content = b"".join([part async for part in self.aiter_bytes()]) - return self._content - - async def aiter_bytes(self, chunk_size: int = None) -> typing.AsyncIterator[bytes]: - """ - A byte-iterator over the decoded response content. - This allows us to handle gzip, deflate, and brotli encoded responses. - """ - if hasattr(self, "_content"): - chunk_size = len(self._content) if chunk_size is None else chunk_size - for i in range(0, len(self._content), chunk_size): - yield self._content[i : i + chunk_size] - else: - decoder = self._get_content_decoder() - chunker = ByteChunker(chunk_size=chunk_size) - with request_context(request=self._request): - async for raw_bytes in self.aiter_raw(): - decoded = decoder.decode(raw_bytes) - for chunk in chunker.decode(decoded): - yield chunk - decoded = decoder.flush() - for chunk in chunker.decode(decoded): - yield chunk - for chunk in chunker.flush(): - yield chunk - - async def aiter_text(self, chunk_size: int = None) -> typing.AsyncIterator[str]: - """ - A str-iterator over the decoded response content - that handles both gzip, deflate, etc but also detects the content's - string encoding. - """ - decoder = TextDecoder(encoding=self.encoding or "utf-8") - chunker = TextChunker(chunk_size=chunk_size) - with request_context(request=self._request): - async for byte_content in self.aiter_bytes(): - text_content = decoder.decode(byte_content) - for chunk in chunker.decode(text_content): - yield chunk - text_content = decoder.flush() - for chunk in chunker.decode(text_content): - yield chunk - for chunk in chunker.flush(): - yield chunk - - async def aiter_lines(self) -> typing.AsyncIterator[str]: - decoder = LineDecoder() - with request_context(request=self._request): - async for text in self.aiter_text(): - for line in decoder.decode(text): - yield line - for line in decoder.flush(): - yield line - - async def aiter_raw(self, chunk_size: int = None) -> typing.AsyncIterator[bytes]: - """ - A byte-iterator over the raw response content. - """ - if self.is_stream_consumed: - raise StreamConsumed() - if self.is_closed: - raise StreamClosed() - if not isinstance(self.stream, AsyncByteStream): - raise RuntimeError("Attempted to call an async iterator on an sync stream.") - - self.is_stream_consumed = True - self._num_bytes_downloaded = 0 - chunker = ByteChunker(chunk_size=chunk_size) - - with request_context(request=self._request): - async for raw_stream_bytes in self.stream: - self._num_bytes_downloaded += len(raw_stream_bytes) - for chunk in chunker.decode(raw_stream_bytes): - yield chunk - - for chunk in chunker.flush(): - yield chunk - - await self.aclose() - - async def aclose(self) -> None: - """ - Close the response and release the connection. - Automatically called if the response body is read to completion. - """ - if not isinstance(self.stream, AsyncByteStream): - raise RuntimeError("Attempted to call an async close on an sync stream.") - - if not self.is_closed: - self.is_closed = True - with request_context(request=self._request): - await self.stream.aclose() - - -class Cookies(MutableMapping): - """ - HTTP Cookies, as a mutable mapping. - """ - - def __init__(self, cookies: CookieTypes = None) -> None: - if cookies is None or isinstance(cookies, dict): - self.jar = CookieJar() - if isinstance(cookies, dict): - for key, value in cookies.items(): - self.set(key, value) - elif isinstance(cookies, list): - self.jar = CookieJar() - for key, value in cookies: - self.set(key, value) - elif isinstance(cookies, Cookies): - self.jar = CookieJar() - for cookie in cookies.jar: - self.jar.set_cookie(cookie) - else: - self.jar = cookies - - def extract_cookies(self, response: Response) -> None: - """ - Loads any cookies based on the response `Set-Cookie` headers. - """ - urllib_response = self._CookieCompatResponse(response) - urllib_request = self._CookieCompatRequest(response.request) - - self.jar.extract_cookies(urllib_response, urllib_request) # type: ignore - - def set_cookie_header(self, request: Request) -> None: - """ - Sets an appropriate 'Cookie:' HTTP header on the `Request`. - """ - urllib_request = self._CookieCompatRequest(request) - self.jar.add_cookie_header(urllib_request) - - def set(self, name: str, value: str, domain: str = "", path: str = "/") -> None: - """ - Set a cookie value by name. May optionally include domain and path. - """ - kwargs = { - "version": 0, - "name": name, - "value": value, - "port": None, - "port_specified": False, - "domain": domain, - "domain_specified": bool(domain), - "domain_initial_dot": domain.startswith("."), - "path": path, - "path_specified": bool(path), - "secure": False, - "expires": None, - "discard": True, - "comment": None, - "comment_url": None, - "rest": {"HttpOnly": None}, - "rfc2109": False, - } - cookie = Cookie(**kwargs) # type: ignore - self.jar.set_cookie(cookie) - - def get( # type: ignore - self, name: str, default: str = None, domain: str = None, path: str = None - ) -> typing.Optional[str]: - """ - Get a cookie by name. May optionally include domain and path - in order to specify exactly which cookie to retrieve. - """ - value = None - for cookie in self.jar: - if cookie.name == name: - if domain is None or cookie.domain == domain: - if path is None or cookie.path == path: - if value is not None: - message = f"Multiple cookies exist with name={name}" - raise CookieConflict(message) - value = cookie.value - - if value is None: - return default - return value - - def delete(self, name: str, domain: str = None, path: str = None) -> None: - """ - Delete a cookie by name. May optionally include domain and path - in order to specify exactly which cookie to delete. - """ - if domain is not None and path is not None: - return self.jar.clear(domain, path, name) - - remove = [ - cookie - for cookie in self.jar - if cookie.name == name - and (domain is None or cookie.domain == domain) - and (path is None or cookie.path == path) - ] - - for cookie in remove: - self.jar.clear(cookie.domain, cookie.path, cookie.name) - - def clear(self, domain: str = None, path: str = None) -> None: - """ - Delete all cookies. Optionally include a domain and path in - order to only delete a subset of all the cookies. - """ - args = [] - if domain is not None: - args.append(domain) - if path is not None: - assert domain is not None - args.append(path) - self.jar.clear(*args) - - def update(self, cookies: CookieTypes = None) -> None: # type: ignore - cookies = Cookies(cookies) - for cookie in cookies.jar: - self.jar.set_cookie(cookie) - - def __setitem__(self, name: str, value: str) -> None: - return self.set(name, value) - - def __getitem__(self, name: str) -> str: - value = self.get(name) - if value is None: - raise KeyError(name) - return value - - def __delitem__(self, name: str) -> None: - return self.delete(name) - - def __len__(self) -> int: - return len(self.jar) - - def __iter__(self) -> typing.Iterator[str]: - return (cookie.name for cookie in self.jar) - - def __bool__(self) -> bool: - for _ in self.jar: - return True - return False - - def __repr__(self) -> str: - cookies_repr = ", ".join( - [ - f"" - for cookie in self.jar - ] - ) - - return f"" - - class _CookieCompatRequest(urllib.request.Request): - """ - Wraps a `Request` instance up in a compatibility interface suitable - for use with `CookieJar` operations. - """ - - def __init__(self, request: Request) -> None: - super().__init__( - url=str(request.url), - headers=dict(request.headers), - method=request.method, - ) - self.request = request - - def add_unredirected_header(self, key: str, value: str) -> None: - super().add_unredirected_header(key, value) - self.request.headers[key] = value - - class _CookieCompatResponse: - """ - Wraps a `Request` instance up in a compatibility interface suitable - for use with `CookieJar` operations. - """ - - def __init__(self, response: Response): - self.response = response - - def info(self) -> email.message.Message: - info = email.message.Message() - for key, value in self.response.headers.multi_items(): - # Note that setting `info[key]` here is an "append" operation, - # not a "replace" operation. - # https://docs.python.org/3/library/email.compat32-message.html#email.message.Message.__setitem__ - info[key] = value - return info diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_multipart.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_multipart.py deleted file mode 100644 index 683e6f13..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_multipart.py +++ /dev/null @@ -1,209 +0,0 @@ -import binascii -import io -import os -import typing -from pathlib import Path - -from ._transports.base import AsyncByteStream, SyncByteStream -from ._types import FileContent, FileTypes, RequestFiles -from ._utils import ( - format_form_param, - guess_content_type, - peek_filelike_length, - primitive_value_to_str, - to_bytes, -) - - -class DataField: - """ - A single form field item, within a multipart form field. - """ - - def __init__( - self, name: str, value: typing.Union[str, bytes, int, float, None] - ) -> None: - if not isinstance(name, str): - raise TypeError( - f"Invalid type for name. Expected str, got {type(name)}: {name!r}" - ) - if value is not None and not isinstance(value, (str, bytes, int, float)): - raise TypeError( - f"Invalid type for value. Expected primitive type, got {type(value)}: {value!r}" - ) - self.name = name - self.value: typing.Union[str, bytes] = ( - value if isinstance(value, bytes) else primitive_value_to_str(value) - ) - - def render_headers(self) -> bytes: - if not hasattr(self, "_headers"): - name = format_form_param("name", self.name) - self._headers = b"".join( - [b"Content-Disposition: form-data; ", name, b"\r\n\r\n"] - ) - - return self._headers - - def render_data(self) -> bytes: - if not hasattr(self, "_data"): - self._data = to_bytes(self.value) - - return self._data - - def get_length(self) -> int: - headers = self.render_headers() - data = self.render_data() - return len(headers) + len(data) - - def render(self) -> typing.Iterator[bytes]: - yield self.render_headers() - yield self.render_data() - - -class FileField: - """ - A single file field item, within a multipart form field. - """ - - def __init__(self, name: str, value: FileTypes) -> None: - self.name = name - - fileobj: FileContent - - if isinstance(value, tuple): - try: - filename, fileobj, content_type = value # type: ignore - except ValueError: - filename, fileobj = value # type: ignore - content_type = guess_content_type(filename) - else: - filename = Path(str(getattr(value, "name", "upload"))).name - fileobj = value - content_type = guess_content_type(filename) - - if isinstance(fileobj, str) or isinstance(fileobj, io.StringIO): - raise TypeError(f"Expected bytes or bytes-like object got: {type(fileobj)}") - - self.filename = filename - self.file = fileobj - self.content_type = content_type - self._consumed = False - - def get_length(self) -> int: - headers = self.render_headers() - - if isinstance(self.file, (str, bytes)): - return len(headers) + len(to_bytes(self.file)) - - # Let's do our best not to read `file` into memory. - file_length = peek_filelike_length(self.file) - if file_length is None: - # As a last resort, read file and cache contents for later. - assert not hasattr(self, "_data") - self._data = to_bytes(self.file.read()) - file_length = len(self._data) - - return len(headers) + file_length - - def render_headers(self) -> bytes: - if not hasattr(self, "_headers"): - parts = [ - b"Content-Disposition: form-data; ", - format_form_param("name", self.name), - ] - if self.filename: - filename = format_form_param("filename", self.filename) - parts.extend([b"; ", filename]) - if self.content_type is not None: - content_type = self.content_type.encode() - parts.extend([b"\r\nContent-Type: ", content_type]) - parts.append(b"\r\n\r\n") - self._headers = b"".join(parts) - - return self._headers - - def render_data(self) -> typing.Iterator[bytes]: - if isinstance(self.file, (str, bytes)): - yield to_bytes(self.file) - return - - if hasattr(self, "_data"): - # Already rendered. - yield self._data - return - - if self._consumed: # pragma: nocover - self.file.seek(0) - self._consumed = True - - for chunk in self.file: - yield to_bytes(chunk) - - def render(self) -> typing.Iterator[bytes]: - yield self.render_headers() - yield from self.render_data() - - -class MultipartStream(SyncByteStream, AsyncByteStream): - """ - Request content as streaming multipart encoded form data. - """ - - def __init__(self, data: dict, files: RequestFiles, boundary: bytes = None) -> None: - if boundary is None: - boundary = binascii.hexlify(os.urandom(16)) - - self.boundary = boundary - self.content_type = "multipart/form-data; boundary=%s" % boundary.decode( - "ascii" - ) - self.fields = list(self._iter_fields(data, files)) - - def _iter_fields( - self, data: dict, files: RequestFiles - ) -> typing.Iterator[typing.Union[FileField, DataField]]: - for name, value in data.items(): - if isinstance(value, list): - for item in value: - yield DataField(name=name, value=item) - else: - yield DataField(name=name, value=value) - - file_items = files.items() if isinstance(files, typing.Mapping) else files - for name, value in file_items: - yield FileField(name=name, value=value) - - def iter_chunks(self) -> typing.Iterator[bytes]: - for field in self.fields: - yield b"--%s\r\n" % self.boundary - yield from field.render() - yield b"\r\n" - yield b"--%s--\r\n" % self.boundary - - def iter_chunks_lengths(self) -> typing.Iterator[int]: - boundary_length = len(self.boundary) - # Follow closely what `.iter_chunks()` does. - for field in self.fields: - yield 2 + boundary_length + 2 - yield field.get_length() - yield 2 - yield 2 + boundary_length + 4 - - def get_content_length(self) -> int: - return sum(self.iter_chunks_lengths()) - - # Content stream interface. - - def get_headers(self) -> typing.Dict[str, str]: - content_length = str(self.get_content_length()) - content_type = self.content_type - return {"Content-Length": content_length, "Content-Type": content_type} - - def __iter__(self) -> typing.Iterator[bytes]: - for chunk in self.iter_chunks(): - yield chunk - - async def __aiter__(self) -> typing.AsyncIterator[bytes]: - for chunk in self.iter_chunks(): - yield chunk diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_status_codes.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_status_codes.py deleted file mode 100644 index 100aec64..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_status_codes.py +++ /dev/null @@ -1,143 +0,0 @@ -from enum import IntEnum - - -class codes(IntEnum): - """HTTP status codes and reason phrases - - Status codes from the following RFCs are all observed: - - * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 - * RFC 6585: Additional HTTP Status Codes - * RFC 3229: Delta encoding in HTTP - * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 - * RFC 5842: Binding Extensions to WebDAV - * RFC 7238: Permanent Redirect - * RFC 2295: Transparent Content Negotiation in HTTP - * RFC 2774: An HTTP Extension Framework - * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2) - * RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) - * RFC 7725: An HTTP Status Code to Report Legal Obstacles - * RFC 8297: An HTTP Status Code for Indicating Hints - * RFC 8470: Using Early Data in HTTP - """ - - def __new__(cls, value: int, phrase: str = "") -> "codes": - obj = int.__new__(cls, value) # type: ignore - obj._value_ = value - - obj.phrase = phrase # type: ignore - return obj - - def __str__(self) -> str: - return str(self.value) - - @classmethod - def get_reason_phrase(cls, value: int) -> str: - try: - return codes(value).phrase # type: ignore - except ValueError: - return "" - - @classmethod - def is_redirect(cls, value: int) -> bool: - return value in ( - # 301 (Cacheable redirect. Method may change to GET.) - codes.MOVED_PERMANENTLY, - # 302 (Uncacheable redirect. Method may change to GET.) - codes.FOUND, - # 303 (Client should make a GET or HEAD request.) - codes.SEE_OTHER, - # 307 (Equiv. 302, but retain method) - codes.TEMPORARY_REDIRECT, - # 308 (Equiv. 301, but retain method) - codes.PERMANENT_REDIRECT, - ) - - @classmethod - def is_error(cls, value: int) -> bool: - return 400 <= value <= 599 - - @classmethod - def is_client_error(cls, value: int) -> bool: - return 400 <= value <= 499 - - @classmethod - def is_server_error(cls, value: int) -> bool: - return 500 <= value <= 599 - - # informational - CONTINUE = 100, "Continue" - SWITCHING_PROTOCOLS = 101, "Switching Protocols" - PROCESSING = 102, "Processing" - EARLY_HINTS = 103, "Early Hints" - - # success - OK = 200, "OK" - CREATED = 201, "Created" - ACCEPTED = 202, "Accepted" - NON_AUTHORITATIVE_INFORMATION = 203, "Non-Authoritative Information" - NO_CONTENT = 204, "No Content" - RESET_CONTENT = 205, "Reset Content" - PARTIAL_CONTENT = 206, "Partial Content" - MULTI_STATUS = 207, "Multi-Status" - ALREADY_REPORTED = 208, "Already Reported" - IM_USED = 226, "IM Used" - - # redirection - MULTIPLE_CHOICES = 300, "Multiple Choices" - MOVED_PERMANENTLY = 301, "Moved Permanently" - FOUND = 302, "Found" - SEE_OTHER = 303, "See Other" - NOT_MODIFIED = 304, "Not Modified" - USE_PROXY = 305, "Use Proxy" - TEMPORARY_REDIRECT = 307, "Temporary Redirect" - PERMANENT_REDIRECT = 308, "Permanent Redirect" - - # client error - BAD_REQUEST = 400, "Bad Request" - UNAUTHORIZED = 401, "Unauthorized" - PAYMENT_REQUIRED = 402, "Payment Required" - FORBIDDEN = 403, "Forbidden" - NOT_FOUND = 404, "Not Found" - METHOD_NOT_ALLOWED = 405, "Method Not Allowed" - NOT_ACCEPTABLE = 406, "Not Acceptable" - PROXY_AUTHENTICATION_REQUIRED = 407, "Proxy Authentication Required" - REQUEST_TIMEOUT = 408, "Request Timeout" - CONFLICT = 409, "Conflict" - GONE = 410, "Gone" - LENGTH_REQUIRED = 411, "Length Required" - PRECONDITION_FAILED = 412, "Precondition Failed" - REQUEST_ENTITY_TOO_LARGE = 413, "Request Entity Too Large" - REQUEST_URI_TOO_LONG = 414, "Request-URI Too Long" - UNSUPPORTED_MEDIA_TYPE = 415, "Unsupported Media Type" - REQUESTED_RANGE_NOT_SATISFIABLE = 416, "Requested Range Not Satisfiable" - EXPECTATION_FAILED = 417, "Expectation Failed" - IM_A_TEAPOT = 418, "I'm a teapot" - MISDIRECTED_REQUEST = 421, "Misdirected Request" - UNPROCESSABLE_ENTITY = 422, "Unprocessable Entity" - LOCKED = 423, "Locked" - FAILED_DEPENDENCY = 424, "Failed Dependency" - TOO_EARLY = 425, "Too Early" - UPGRADE_REQUIRED = 426, "Upgrade Required" - PRECONDITION_REQUIRED = 428, "Precondition Required" - TOO_MANY_REQUESTS = 429, "Too Many Requests" - REQUEST_HEADER_FIELDS_TOO_LARGE = 431, "Request Header Fields Too Large" - UNAVAILABLE_FOR_LEGAL_REASONS = 451, "Unavailable For Legal Reasons" - - # server errors - INTERNAL_SERVER_ERROR = 500, "Internal Server Error" - NOT_IMPLEMENTED = 501, "Not Implemented" - BAD_GATEWAY = 502, "Bad Gateway" - SERVICE_UNAVAILABLE = 503, "Service Unavailable" - GATEWAY_TIMEOUT = 504, "Gateway Timeout" - HTTP_VERSION_NOT_SUPPORTED = 505, "HTTP Version Not Supported" - VARIANT_ALSO_NEGOTIATES = 506, "Variant Also Negotiates" - INSUFFICIENT_STORAGE = 507, "Insufficient Storage" - LOOP_DETECTED = 508, "Loop Detected" - NOT_EXTENDED = 510, "Not Extended" - NETWORK_AUTHENTICATION_REQUIRED = 511, "Network Authentication Required" - - -# Include lower-case styles for `requests` compatibility. -for code in codes: - setattr(codes, code._name_.lower(), int(code)) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 3ac70677ec6223d1bfce0441b07c9b78e9ead212..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/base.cpython-39.pyc deleted file mode 100644 index 200b37ad5e1bd4b53d74557c191d81d74a87e8e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8143 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/wsgi.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/__pycache__/wsgi.cpython-39.pyc deleted file mode 100644 index b96470aed5689cd877d113b4cfe98bcf1474677a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4469 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 "Event": - if sniffio.current_async_library() == "trio": - import trio - - return trio.Event() - else: - import asyncio - - return asyncio.Event() - - -class ASGIResponseStream(AsyncByteStream): - def __init__(self, body: typing.List[bytes]) -> None: - self._body = body - - async def __aiter__(self) -> typing.AsyncIterator[bytes]: - yield b"".join(self._body) - - -class ASGITransport(AsyncBaseTransport): - """ - A custom AsyncTransport that handles sending requests directly to an ASGI app. - The simplest way to use this functionality is to use the `app` argument. - - ``` - client = httpx.AsyncClient(app=app) - ``` - - Alternatively, you can setup the transport instance explicitly. - This allows you to include any additional configuration arguments specific - to the ASGITransport class: - - ``` - transport = httpx.ASGITransport( - app=app, - root_path="/submount", - client=("1.2.3.4", 123) - ) - client = httpx.AsyncClient(transport=transport) - ``` - - Arguments: - - * `app` - The ASGI application. - * `raise_app_exceptions` - Boolean indicating if exceptions in the application - should be raised. Default to `True`. Can be set to `False` for use cases - such as testing the content of a client 500 response. - * `root_path` - The root path on which the ASGI application should be mounted. - * `client` - A two-tuple indicating the client IP and port of incoming requests. - ``` - """ - - def __init__( - self, - app: typing.Callable, - raise_app_exceptions: bool = True, - root_path: str = "", - client: typing.Tuple[str, int] = ("127.0.0.1", 123), - ) -> None: - self.app = app - self.raise_app_exceptions = raise_app_exceptions - self.root_path = root_path - self.client = client - - async def handle_async_request( - self, - method: bytes, - url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes], - headers: typing.List[typing.Tuple[bytes, bytes]], - stream: AsyncByteStream, - extensions: dict, - ) -> typing.Tuple[ - int, typing.List[typing.Tuple[bytes, bytes]], AsyncByteStream, dict - ]: - # ASGI scope. - scheme, host, port, full_path = url - path, _, query = full_path.partition(b"?") - scope = { - "type": "http", - "asgi": {"version": "3.0"}, - "http_version": "1.1", - "method": method.decode(), - "headers": [(k.lower(), v) for (k, v) in headers], - "scheme": scheme.decode("ascii"), - "path": unquote(path.decode("ascii")), - "raw_path": path, - "query_string": query, - "server": (host.decode("ascii"), port), - "client": self.client, - "root_path": self.root_path, - } - - # Request. - request_body_chunks = stream.__aiter__() - request_complete = False - - # Response. - status_code = None - response_headers = None - body_parts = [] - response_started = False - response_complete = create_event() - - # ASGI callables. - - async def receive() -> dict: - nonlocal request_complete - - if request_complete: - await response_complete.wait() - return {"type": "http.disconnect"} - - try: - body = await request_body_chunks.__anext__() - except StopAsyncIteration: - request_complete = True - return {"type": "http.request", "body": b"", "more_body": False} - return {"type": "http.request", "body": body, "more_body": True} - - async def send(message: dict) -> None: - nonlocal status_code, response_headers, response_started - - if message["type"] == "http.response.start": - assert not response_started - - status_code = message["status"] - response_headers = message.get("headers", []) - response_started = True - - elif message["type"] == "http.response.body": - assert not response_complete.is_set() - body = message.get("body", b"") - more_body = message.get("more_body", False) - - if body and method != b"HEAD": - body_parts.append(body) - - if not more_body: - response_complete.set() - - try: - await self.app(scope, receive, send) - except Exception: - if self.raise_app_exceptions or not response_complete.is_set(): - raise - - assert response_complete.is_set() - assert status_code is not None - assert response_headers is not None - - stream = ASGIResponseStream(body_parts) - extensions = {} - - return (status_code, response_headers, stream, extensions) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/base.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/base.py deleted file mode 100644 index eb519269..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/base.py +++ /dev/null @@ -1,183 +0,0 @@ -import typing -from types import TracebackType - -T = typing.TypeVar("T", bound="BaseTransport") -A = typing.TypeVar("A", bound="AsyncBaseTransport") - - -class SyncByteStream: - def __iter__(self) -> typing.Iterator[bytes]: - raise NotImplementedError( - "The '__iter__' method must be implemented." - ) # pragma: nocover - yield b"" # pragma: nocover - - def close(self) -> None: - """ - Subclasses can override this method to release any network resources - after a request/response cycle is complete. - - Streaming cases should use a `try...finally` block to ensure that - the stream `close()` method is always called. - - Example: - - status_code, headers, stream, extensions = transport.handle_request(...) - try: - ... - finally: - stream.close() - """ - - def read(self) -> bytes: - """ - Simple cases can use `.read()` as a convience method for consuming - the entire stream and then closing it. - - Example: - - status_code, headers, stream, extensions = transport.handle_request(...) - body = stream.read() - """ - try: - return b"".join([part for part in self]) - finally: - self.close() - - -class AsyncByteStream: - async def __aiter__(self) -> typing.AsyncIterator[bytes]: - raise NotImplementedError( - "The '__aiter__' method must be implemented." - ) # pragma: nocover - yield b"" # pragma: nocover - - async def aclose(self) -> None: - pass - - async def aread(self) -> bytes: - try: - return b"".join([part async for part in self]) - finally: - await self.aclose() - - -class BaseTransport: - def __enter__(self: T) -> T: - return self - - def __exit__( - self, - exc_type: typing.Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - self.close() - - def handle_request( - self, - method: bytes, - url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes], - headers: typing.List[typing.Tuple[bytes, bytes]], - stream: SyncByteStream, - extensions: dict, - ) -> typing.Tuple[ - int, typing.List[typing.Tuple[bytes, bytes]], SyncByteStream, dict - ]: - """ - Send a single HTTP request and return a response. - - At this layer of API we're simply using plain primitives. No `Request` or - `Response` models, no fancy `URL` or `Header` handling. This strict point - of cut-off provides a clear design seperation between the HTTPX API, - and the low-level network handling. - - Developers shouldn't typically ever need to call into this API directly, - since the Client class provides all the higher level user-facing API - niceties. - - In order to properly release any network resources, the response stream - should *either* be consumed immediately, with a call to `stream.read()`, - or else the `handle_request` call should be followed with a try/finally - block to ensuring the stream is always closed. - - Example usage: - - with httpx.HTTPTransport() as transport: - status_code, headers, stream, extensions = transport.handle_request( - method=b'GET', - url=(b'https', b'www.example.com', 443, b'/'), - headers=[(b'Host', b'www.example.com')], - stream=[], - extensions={} - ) - body = stream.read() - print(status_code, headers, body) - - Arguments: - - method: The request method as bytes. Eg. b'GET'. - url: The components of the request URL, as a tuple of `(scheme, host, port, target)`. - The target will usually be the URL path, but also allows for alternative - formulations, such as proxy requests which include the complete URL in - the target portion of the HTTP request, or for "OPTIONS *" requests, which - cannot be expressed in a URL string. - headers: The request headers as a list of byte pairs. - stream: The request body as a bytes iterator. - extensions: An open ended dictionary, including optional extensions to the - core request/response API. Keys may include: - timeout: A dictionary of str:Optional[float] timeout values. - May include values for 'connect', 'read', 'write', or 'pool'. - - Returns a tuple of: - - status_code: The response status code as an integer. Should be in the range 1xx-5xx. - headers: The response headers as a list of byte pairs. - stream: The response body as a bytes iterator. - extensions: An open ended dictionary, including optional extensions to the - core request/response API. Keys are plain strings, and may include: - reason_phrase: The reason-phrase of the HTTP response, as bytes. Eg b'OK'. - HTTP/2 onwards does not include a reason phrase on the wire. - When no key is included, a default based on the status code may - be used. An empty-string reason phrase should not be substituted - for a default, as it indicates the server left the portion blank - eg. the leading response bytes were b"HTTP/1.1 200 ". - http_version: The HTTP version, as bytes. Eg. b"HTTP/1.1". - When no http_version key is included, HTTP/1.1 may be assumed. - """ - raise NotImplementedError( - "The 'handle_request' method must be implemented." - ) # pragma: nocover - - def close(self) -> None: - pass - - -class AsyncBaseTransport: - async def __aenter__(self: A) -> A: - return self - - async def __aexit__( - self, - exc_type: typing.Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - await self.aclose() - - async def handle_async_request( - self, - method: bytes, - url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes], - headers: typing.List[typing.Tuple[bytes, bytes]], - stream: AsyncByteStream, - extensions: dict, - ) -> typing.Tuple[ - int, typing.List[typing.Tuple[bytes, bytes]], AsyncByteStream, dict - ]: - raise NotImplementedError( - "The 'handle_async_request' method must be implemented." - ) # pragma: nocover - - async def aclose(self) -> None: - pass diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/default.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/default.py deleted file mode 100644 index 73401fce..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/default.py +++ /dev/null @@ -1,294 +0,0 @@ -""" -Custom transports, with nicely configured defaults. - -The following additional keyword arguments are currently supported by httpcore... - -* uds: str -* local_address: str -* retries: int -* backend: str ("auto", "asyncio", "trio", "curio", "anyio", "sync") - -Example usages... - -# Disable HTTP/2 on a single specfic domain. -mounts = { - "all://": httpx.HTTPTransport(http2=True), - "all://*example.org": httpx.HTTPTransport() -} - -# Using advanced httpcore configuration, with connection retries. -transport = httpx.HTTPTransport(retries=1) -client = httpx.Client(transport=transport) - -# Using advanced httpcore configuration, with unix domain sockets. -transport = httpx.HTTPTransport(uds="socket.uds") -client = httpx.Client(transport=transport) -""" -import contextlib -import typing -from types import TracebackType - -import httpcore - -from .._config import DEFAULT_LIMITS, Limits, Proxy, create_ssl_context -from .._exceptions import ( - CloseError, - ConnectError, - ConnectTimeout, - LocalProtocolError, - NetworkError, - PoolTimeout, - ProtocolError, - ProxyError, - ReadError, - ReadTimeout, - RemoteProtocolError, - TimeoutException, - UnsupportedProtocol, - WriteError, - WriteTimeout, -) -from .._types import CertTypes, VerifyTypes -from .base import AsyncBaseTransport, AsyncByteStream, BaseTransport, SyncByteStream - -T = typing.TypeVar("T", bound="HTTPTransport") -A = typing.TypeVar("A", bound="AsyncHTTPTransport") - - -@contextlib.contextmanager -def map_httpcore_exceptions() -> typing.Iterator[None]: - try: - yield - except Exception as exc: - mapped_exc = None - - for from_exc, to_exc in HTTPCORE_EXC_MAP.items(): - if not isinstance(exc, from_exc): - continue - # We want to map to the most specific exception we can find. - # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to - # `httpx.ReadTimeout`, not just `httpx.TimeoutException`. - if mapped_exc is None or issubclass(to_exc, mapped_exc): - mapped_exc = to_exc - - if mapped_exc is None: # pragma: nocover - raise - - message = str(exc) - raise mapped_exc(message) from exc - - -HTTPCORE_EXC_MAP = { - httpcore.TimeoutException: TimeoutException, - httpcore.ConnectTimeout: ConnectTimeout, - httpcore.ReadTimeout: ReadTimeout, - httpcore.WriteTimeout: WriteTimeout, - httpcore.PoolTimeout: PoolTimeout, - httpcore.NetworkError: NetworkError, - httpcore.ConnectError: ConnectError, - httpcore.ReadError: ReadError, - httpcore.WriteError: WriteError, - httpcore.CloseError: CloseError, - httpcore.ProxyError: ProxyError, - httpcore.UnsupportedProtocol: UnsupportedProtocol, - httpcore.ProtocolError: ProtocolError, - httpcore.LocalProtocolError: LocalProtocolError, - httpcore.RemoteProtocolError: RemoteProtocolError, -} - - -class ResponseStream(SyncByteStream): - def __init__(self, httpcore_stream: httpcore.SyncByteStream): - self._httpcore_stream = httpcore_stream - - def __iter__(self) -> typing.Iterator[bytes]: - with map_httpcore_exceptions(): - for part in self._httpcore_stream: - yield part - - def close(self) -> None: - with map_httpcore_exceptions(): - self._httpcore_stream.close() - - -class HTTPTransport(BaseTransport): - def __init__( - self, - verify: VerifyTypes = True, - cert: CertTypes = None, - http1: bool = True, - http2: bool = False, - limits: Limits = DEFAULT_LIMITS, - trust_env: bool = True, - proxy: Proxy = None, - uds: str = None, - local_address: str = None, - retries: int = 0, - backend: str = "sync", - ) -> None: - ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env) - - if proxy is None: - self._pool = httpcore.SyncConnectionPool( - ssl_context=ssl_context, - max_connections=limits.max_connections, - max_keepalive_connections=limits.max_keepalive_connections, - keepalive_expiry=limits.keepalive_expiry, - http1=http1, - http2=http2, - uds=uds, - local_address=local_address, - retries=retries, - backend=backend, - ) - else: - self._pool = httpcore.SyncHTTPProxy( - proxy_url=proxy.url.raw, - proxy_headers=proxy.headers.raw, - ssl_context=ssl_context, - max_connections=limits.max_connections, - max_keepalive_connections=limits.max_keepalive_connections, - keepalive_expiry=limits.keepalive_expiry, - http2=http2, - backend=backend, - ) - - def __enter__(self: T) -> T: # Use generics for subclass support. - self._pool.__enter__() - return self - - def __exit__( - self, - exc_type: typing.Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - with map_httpcore_exceptions(): - self._pool.__exit__(exc_type, exc_value, traceback) - - def handle_request( - self, - method: bytes, - url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes], - headers: typing.List[typing.Tuple[bytes, bytes]], - stream: SyncByteStream, - extensions: dict, - ) -> typing.Tuple[ - int, typing.List[typing.Tuple[bytes, bytes]], SyncByteStream, dict - ]: - with map_httpcore_exceptions(): - status_code, headers, byte_stream, extensions = self._pool.handle_request( - method=method, - url=url, - headers=headers, - stream=httpcore.IteratorByteStream(iter(stream)), - extensions=extensions, - ) - - stream = ResponseStream(byte_stream) - - return status_code, headers, stream, extensions - - def close(self) -> None: - self._pool.close() - - -class AsyncResponseStream(AsyncByteStream): - def __init__(self, httpcore_stream: httpcore.AsyncByteStream): - self._httpcore_stream = httpcore_stream - - async def __aiter__(self) -> typing.AsyncIterator[bytes]: - with map_httpcore_exceptions(): - async for part in self._httpcore_stream: - yield part - - async def aclose(self) -> None: - with map_httpcore_exceptions(): - await self._httpcore_stream.aclose() - - -class AsyncHTTPTransport(AsyncBaseTransport): - def __init__( - self, - verify: VerifyTypes = True, - cert: CertTypes = None, - http1: bool = True, - http2: bool = False, - limits: Limits = DEFAULT_LIMITS, - trust_env: bool = True, - proxy: Proxy = None, - uds: str = None, - local_address: str = None, - retries: int = 0, - backend: str = "auto", - ) -> None: - ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env) - - if proxy is None: - self._pool = httpcore.AsyncConnectionPool( - ssl_context=ssl_context, - max_connections=limits.max_connections, - max_keepalive_connections=limits.max_keepalive_connections, - keepalive_expiry=limits.keepalive_expiry, - http1=http1, - http2=http2, - uds=uds, - local_address=local_address, - retries=retries, - backend=backend, - ) - else: - self._pool = httpcore.AsyncHTTPProxy( - proxy_url=proxy.url.raw, - proxy_headers=proxy.headers.raw, - ssl_context=ssl_context, - max_connections=limits.max_connections, - max_keepalive_connections=limits.max_keepalive_connections, - keepalive_expiry=limits.keepalive_expiry, - http2=http2, - backend=backend, - ) - - async def __aenter__(self: A) -> A: # Use generics for subclass support. - await self._pool.__aenter__() - return self - - async def __aexit__( - self, - exc_type: typing.Type[BaseException] = None, - exc_value: BaseException = None, - traceback: TracebackType = None, - ) -> None: - with map_httpcore_exceptions(): - await self._pool.__aexit__(exc_type, exc_value, traceback) - - async def handle_async_request( - self, - method: bytes, - url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes], - headers: typing.List[typing.Tuple[bytes, bytes]], - stream: AsyncByteStream, - extensions: dict, - ) -> typing.Tuple[ - int, typing.List[typing.Tuple[bytes, bytes]], AsyncByteStream, dict - ]: - with map_httpcore_exceptions(): - ( - status_code, - headers, - byte_stream, - extensions, - ) = await self._pool.handle_async_request( - method=method, - url=url, - headers=headers, - stream=httpcore.AsyncIteratorByteStream(stream.__aiter__()), - extensions=extensions, - ) - - stream = AsyncResponseStream(byte_stream) - - return status_code, headers, stream, extensions - - async def aclose(self) -> None: - await self._pool.aclose() diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/mock.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/mock.py deleted file mode 100644 index 8d59b738..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/mock.py +++ /dev/null @@ -1,70 +0,0 @@ -import asyncio -import typing - -from .._models import Request -from .base import AsyncBaseTransport, AsyncByteStream, BaseTransport, SyncByteStream - - -class MockTransport(AsyncBaseTransport, BaseTransport): - def __init__(self, handler: typing.Callable) -> None: - self.handler = handler - - def handle_request( - self, - method: bytes, - url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes], - headers: typing.List[typing.Tuple[bytes, bytes]], - stream: SyncByteStream, - extensions: dict, - ) -> typing.Tuple[ - int, typing.List[typing.Tuple[bytes, bytes]], SyncByteStream, dict - ]: - request = Request( - method=method, - url=url, - headers=headers, - stream=stream, - ) - request.read() - response = self.handler(request) - return ( - response.status_code, - response.headers.raw, - response.stream, - response.extensions, - ) - - async def handle_async_request( - self, - method: bytes, - url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes], - headers: typing.List[typing.Tuple[bytes, bytes]], - stream: AsyncByteStream, - extensions: dict, - ) -> typing.Tuple[ - int, typing.List[typing.Tuple[bytes, bytes]], AsyncByteStream, dict - ]: - request = Request( - method=method, - url=url, - headers=headers, - stream=stream, - ) - await request.aread() - - response = self.handler(request) - - # Allow handler to *optionally* be an `async` function. - # If it is, then the `response` variable need to be awaited to actually - # return the result. - - # https://simonwillison.net/2020/Sep/2/await-me-maybe/ - if asyncio.iscoroutine(response): - response = await response - - return ( - response.status_code, - response.headers.raw, - response.stream, - response.extensions, - ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/wsgi.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/wsgi.py deleted file mode 100644 index 58e8309d..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_transports/wsgi.py +++ /dev/null @@ -1,138 +0,0 @@ -import io -import itertools -import typing -from urllib.parse import unquote - -from .base import BaseTransport, SyncByteStream - - -def _skip_leading_empty_chunks(body: typing.Iterable) -> typing.Iterable: - body = iter(body) - for chunk in body: - if chunk: - return itertools.chain([chunk], body) - return [] - - -class WSGIByteStream(SyncByteStream): - def __init__(self, result: typing.Iterable[bytes]) -> None: - self._result = _skip_leading_empty_chunks(result) - - def __iter__(self) -> typing.Iterator[bytes]: - for part in self._result: - yield part - - -class WSGITransport(BaseTransport): - """ - A custom transport that handles sending requests directly to an WSGI app. - The simplest way to use this functionality is to use the `app` argument. - - ``` - client = httpx.Client(app=app) - ``` - - Alternatively, you can setup the transport instance explicitly. - This allows you to include any additional configuration arguments specific - to the WSGITransport class: - - ``` - transport = httpx.WSGITransport( - app=app, - script_name="/submount", - remote_addr="1.2.3.4" - ) - client = httpx.Client(transport=transport) - ``` - - Arguments: - - * `app` - The ASGI application. - * `raise_app_exceptions` - Boolean indicating if exceptions in the application - should be raised. Default to `True`. Can be set to `False` for use cases - such as testing the content of a client 500 response. - * `script_name` - The root path on which the WSGI application should be mounted. - * `remote_addr` - A string indicating the client IP of incoming requests. - ``` - """ - - def __init__( - self, - app: typing.Callable, - raise_app_exceptions: bool = True, - script_name: str = "", - remote_addr: str = "127.0.0.1", - ) -> None: - self.app = app - self.raise_app_exceptions = raise_app_exceptions - self.script_name = script_name - self.remote_addr = remote_addr - - def handle_request( - self, - method: bytes, - url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes], - headers: typing.List[typing.Tuple[bytes, bytes]], - stream: SyncByteStream, - extensions: dict, - ) -> typing.Tuple[ - int, typing.List[typing.Tuple[bytes, bytes]], SyncByteStream, dict - ]: - wsgi_input = io.BytesIO(b"".join(stream)) - - scheme, host, port, full_path = url - path, _, query = full_path.partition(b"?") - if port is None: - port = {b"http": 80, b"https": 443}[scheme] - - environ = { - "wsgi.version": (1, 0), - "wsgi.url_scheme": scheme.decode("ascii"), - "wsgi.input": wsgi_input, - "wsgi.errors": io.BytesIO(), - "wsgi.multithread": True, - "wsgi.multiprocess": False, - "wsgi.run_once": False, - "REQUEST_METHOD": method.decode(), - "SCRIPT_NAME": self.script_name, - "PATH_INFO": unquote(path.decode("ascii")), - "QUERY_STRING": query.decode("ascii"), - "SERVER_NAME": host.decode("ascii"), - "SERVER_PORT": str(port), - "REMOTE_ADDR": self.remote_addr, - } - for header_key, header_value in headers: - key = header_key.decode("ascii").upper().replace("-", "_") - if key not in ("CONTENT_TYPE", "CONTENT_LENGTH"): - key = "HTTP_" + key - environ[key] = header_value.decode("ascii") - - seen_status = None - seen_response_headers = None - seen_exc_info = None - - def start_response( - status: str, response_headers: list, exc_info: typing.Any = None - ) -> None: - nonlocal seen_status, seen_response_headers, seen_exc_info - seen_status = status - seen_response_headers = response_headers - seen_exc_info = exc_info - - result = self.app(environ, start_response) - - stream = WSGIByteStream(result) - - assert seen_status is not None - assert seen_response_headers is not None - if seen_exc_info and self.raise_app_exceptions: - raise seen_exc_info[1] - - status_code = int(seen_status.split()[0]) - headers = [ - (key.encode("ascii"), value.encode("ascii")) - for key, value in seen_response_headers - ] - extensions = {} - - return (status_code, headers, stream, extensions) diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_types.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_types.py deleted file mode 100644 index 2381996c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_types.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -Type definitions for type checking purposes. -""" - -import ssl -from http.cookiejar import CookieJar -from typing import ( - IO, - TYPE_CHECKING, - AsyncIterable, - Callable, - Dict, - Iterable, - List, - Mapping, - Optional, - Sequence, - Tuple, - Union, -) - -if TYPE_CHECKING: # pragma: no cover - from ._auth import Auth # noqa: F401 - from ._config import Proxy, Timeout # noqa: F401 - from ._models import URL, Cookies, Headers, QueryParams, Request # noqa: F401 - - -PrimitiveData = Optional[Union[str, int, float, bool]] - -RawURL = Tuple[bytes, bytes, Optional[int], bytes] - -URLTypes = Union["URL", str] - -QueryParamTypes = Union[ - "QueryParams", - Mapping[str, Union[PrimitiveData, Sequence[PrimitiveData]]], - List[Tuple[str, PrimitiveData]], - Tuple[Tuple[str, PrimitiveData], ...], - str, - bytes, - None, -] - -HeaderTypes = Union[ - "Headers", - Dict[str, str], - Dict[bytes, bytes], - Sequence[Tuple[str, str]], - Sequence[Tuple[bytes, bytes]], -] - -CookieTypes = Union["Cookies", CookieJar, Dict[str, str], List[Tuple[str, str]]] - -CertTypes = Union[ - # certfile - str, - # (certfile, keyfile) - Tuple[str, Optional[str]], - # (certfile, keyfile, password) - Tuple[str, Optional[str], Optional[str]], -] -VerifyTypes = Union[str, bool, ssl.SSLContext] -TimeoutTypes = Union[ - Optional[float], - Tuple[Optional[float], Optional[float], Optional[float], Optional[float]], - "Timeout", -] -ProxiesTypes = Union[URLTypes, "Proxy", Dict[URLTypes, Union[None, URLTypes, "Proxy"]]] - -AuthTypes = Union[ - Tuple[Union[str, bytes], Union[str, bytes]], - Callable[["Request"], "Request"], - "Auth", - None, -] - -RequestContent = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]] -ResponseContent = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]] - -RequestData = dict - -FileContent = Union[IO[bytes], bytes] -FileTypes = Union[ - # file (or text) - FileContent, - # (filename, file (or text)) - Tuple[Optional[str], FileContent], - # (filename, file (or text), content_type) - Tuple[Optional[str], FileContent, Optional[str]], -] -RequestFiles = Union[Mapping[str, FileTypes], Sequence[Tuple[str, FileTypes]]] diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/_utils.py b/IKEA_scraper/.venv/Lib/site-packages/httpx/_utils.py deleted file mode 100644 index 30ab2ed5..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/httpx/_utils.py +++ /dev/null @@ -1,508 +0,0 @@ -import codecs -import logging -import mimetypes -import netrc -import os -import re -import sys -import time -import typing -from pathlib import Path -from urllib.request import getproxies - -import sniffio - -from ._types import PrimitiveData - -if typing.TYPE_CHECKING: # pragma: no cover - from ._models import URL - - -_HTML5_FORM_ENCODING_REPLACEMENTS = {'"': "%22", "\\": "\\\\"} -_HTML5_FORM_ENCODING_REPLACEMENTS.update( - {chr(c): "%{:02X}".format(c) for c in range(0x00, 0x1F + 1) if c != 0x1B} -) -_HTML5_FORM_ENCODING_RE = re.compile( - r"|".join([re.escape(c) for c in _HTML5_FORM_ENCODING_REPLACEMENTS.keys()]) -) - - -def normalize_header_key( - value: typing.Union[str, bytes], - lower: bool, - encoding: str = None, -) -> bytes: - """ - Coerce str/bytes into a strictly byte-wise HTTP header key. - """ - if isinstance(value, bytes): - bytes_value = value - else: - bytes_value = value.encode(encoding or "ascii") - - return bytes_value.lower() if lower else bytes_value - - -def normalize_header_value( - value: typing.Union[str, bytes], encoding: str = None -) -> bytes: - """ - Coerce str/bytes into a strictly byte-wise HTTP header value. - """ - if isinstance(value, bytes): - return value - return value.encode(encoding or "ascii") - - -def primitive_value_to_str(value: "PrimitiveData") -> str: - """ - Coerce a primitive data type into a string value. - - Note that we prefer JSON-style 'true'/'false' for boolean values here. - """ - if value is True: - return "true" - elif value is False: - return "false" - elif value is None: - return "" - return str(value) - - -def is_known_encoding(encoding: str) -> bool: - """ - Return `True` if `encoding` is a known codec. - """ - try: - codecs.lookup(encoding) - except LookupError: - return False - return True - - -def format_form_param(name: str, value: typing.Union[str, bytes]) -> bytes: - """ - Encode a name/value pair within a multipart form. - """ - if isinstance(value, bytes): - value = value.decode() - - def replacer(match: typing.Match[str]) -> str: - return _HTML5_FORM_ENCODING_REPLACEMENTS[match.group(0)] - - value = _HTML5_FORM_ENCODING_RE.sub(replacer, value) - return f'{name}="{value}"'.encode() - - -# Null bytes; no need to recreate these on each call to guess_json_utf -_null = b"\x00" -_null2 = _null * 2 -_null3 = _null * 3 - - -def guess_json_utf(data: bytes) -> typing.Optional[str]: - # JSON always starts with two ASCII characters, so detection is as - # easy as counting the nulls and from their location and count - # determine the encoding. Also detect a BOM, if present. - sample = data[:4] - if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): - return "utf-32" # BOM included - if sample[:3] == codecs.BOM_UTF8: - return "utf-8-sig" # BOM included, MS style (discouraged) - if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): - return "utf-16" # BOM included - nullcount = sample.count(_null) - if nullcount == 0: - return "utf-8" - if nullcount == 2: - if sample[::2] == _null2: # 1st and 3rd are null - return "utf-16-be" - if sample[1::2] == _null2: # 2nd and 4th are null - return "utf-16-le" - # Did not detect 2 valid UTF-16 ascii-range characters - if nullcount == 3: - if sample[:3] == _null3: - return "utf-32-be" - if sample[1:] == _null3: - return "utf-32-le" - # Did not detect a valid UTF-32 ascii-range character - return None - - -class NetRCInfo: - def __init__(self, files: typing.Optional[typing.List[str]] = None) -> None: - if files is None: - files = [os.getenv("NETRC", ""), "~/.netrc", "~/_netrc"] - self.netrc_files = files - - @property - def netrc_info(self) -> typing.Optional[netrc.netrc]: - if not hasattr(self, "_netrc_info"): - self._netrc_info = None - for file_path in self.netrc_files: - expanded_path = Path(file_path).expanduser() - try: - if expanded_path.is_file(): - self._netrc_info = netrc.netrc(str(expanded_path)) - break - except (netrc.NetrcParseError, IOError): # pragma: nocover - # Issue while reading the netrc file, ignore... - pass - return self._netrc_info - - def get_credentials(self, host: str) -> typing.Optional[typing.Tuple[str, str]]: - if self.netrc_info is None: - return None - - auth_info = self.netrc_info.authenticators(host) - if auth_info is None or auth_info[2] is None: - return None - return (auth_info[0], auth_info[2]) - - -def get_ca_bundle_from_env() -> typing.Optional[str]: - if "SSL_CERT_FILE" in os.environ: - ssl_file = Path(os.environ["SSL_CERT_FILE"]) - if ssl_file.is_file(): - return str(ssl_file) - if "SSL_CERT_DIR" in os.environ: - ssl_path = Path(os.environ["SSL_CERT_DIR"]) - if ssl_path.is_dir(): - return str(ssl_path) - return None - - -def parse_header_links(value: str) -> typing.List[typing.Dict[str, str]]: - """ - Returns a list of parsed link headers, for more info see: - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link - The generic syntax of those is: - Link: < uri-reference >; param1=value1; param2="value2" - So for instance: - Link; '; type="image/jpeg",;' - would return - [ - {"url": "http:/.../front.jpeg", "type": "image/jpeg"}, - {"url": "http://.../back.jpeg"}, - ] - :param value: HTTP Link entity-header field - :return: list of parsed link headers - """ - links: typing.List[typing.Dict[str, str]] = [] - replace_chars = " '\"" - value = value.strip(replace_chars) - if not value: - return links - for val in re.split(", *<", value): - try: - url, params = val.split(";", 1) - except ValueError: - url, params = val, "" - link = {"url": url.strip("<> '\"")} - for param in params.split(";"): - try: - key, value = param.split("=") - except ValueError: - break - link[key.strip(replace_chars)] = value.strip(replace_chars) - links.append(link) - return links - - -SENSITIVE_HEADERS = {"authorization", "proxy-authorization"} - - -def obfuscate_sensitive_headers( - items: typing.Iterable[typing.Tuple[typing.AnyStr, typing.AnyStr]] -) -> typing.Iterator[typing.Tuple[typing.AnyStr, typing.AnyStr]]: - for k, v in items: - if to_str(k.lower()) in SENSITIVE_HEADERS: - v = to_bytes_or_str("[secure]", match_type_of=v) - yield k, v - - -_LOGGER_INITIALIZED = False -TRACE_LOG_LEVEL = 5 - - -class Logger(logging.Logger): - # Stub for type checkers. - def trace(self, message: str, *args: typing.Any, **kwargs: typing.Any) -> None: - ... # pragma: nocover - - -def get_logger(name: str) -> Logger: - """ - Get a `logging.Logger` instance, and optionally - set up debug logging based on the HTTPX_LOG_LEVEL environment variable. - """ - global _LOGGER_INITIALIZED - - if not _LOGGER_INITIALIZED: - _LOGGER_INITIALIZED = True - logging.addLevelName(TRACE_LOG_LEVEL, "TRACE") - - log_level = os.environ.get("HTTPX_LOG_LEVEL", "").upper() - if log_level in ("DEBUG", "TRACE"): - logger = logging.getLogger("httpx") - logger.setLevel(logging.DEBUG if log_level == "DEBUG" else TRACE_LOG_LEVEL) - handler = logging.StreamHandler(sys.stderr) - handler.setFormatter( - logging.Formatter( - fmt="%(levelname)s [%(asctime)s] %(name)s - %(message)s", - datefmt="%Y-%m-%d %H:%M:%S", - ) - ) - logger.addHandler(handler) - - logger = logging.getLogger(name) - - def trace(message: str, *args: typing.Any, **kwargs: typing.Any) -> None: - logger.log(TRACE_LOG_LEVEL, message, *args, **kwargs) - - logger.trace = trace # type: ignore - - return typing.cast(Logger, logger) - - -def port_or_default(url: "URL") -> typing.Optional[int]: - if url.port is not None: - return url.port - return {"http": 80, "https": 443}.get(url.scheme) - - -def same_origin(url: "URL", other: "URL") -> bool: - """ - Return 'True' if the given URLs share the same origin. - """ - return ( - url.scheme == other.scheme - and url.host == other.host - and port_or_default(url) == port_or_default(other) - ) - - -def get_environment_proxies() -> typing.Dict[str, typing.Optional[str]]: - """Gets proxy information from the environment""" - - # urllib.request.getproxies() falls back on System - # Registry and Config for proxies on Windows and macOS. - # We don't want to propagate non-HTTP proxies into - # our configuration such as 'TRAVIS_APT_PROXY'. - proxy_info = getproxies() - mounts: typing.Dict[str, typing.Optional[str]] = {} - - for scheme in ("http", "https", "all"): - if proxy_info.get(scheme): - hostname = proxy_info[scheme] - mounts[f"{scheme}://"] = ( - hostname if "://" in hostname else f"http://{hostname}" - ) - - no_proxy_hosts = [host.strip() for host in proxy_info.get("no", "").split(",")] - for hostname in no_proxy_hosts: - # See https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html for details - # on how names in `NO_PROXY` are handled. - if hostname == "*": - # If NO_PROXY=* is used or if "*" occurs as any one of the comma - # seperated hostnames, then we should just bypass any information - # from HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and always ignore - # proxies. - return {} - elif hostname: - # NO_PROXY=.google.com is marked as "all://*.google.com, - # which disables "www.google.com" but not "google.com" - # NO_PROXY=google.com is marked as "all://*google.com, - # which disables "www.google.com" and "google.com". - # (But not "wwwgoogle.com") - mounts[f"all://*{hostname}"] = None - - return mounts - - -def to_bytes(value: typing.Union[str, bytes], encoding: str = "utf-8") -> bytes: - return value.encode(encoding) if isinstance(value, str) else value - - -def to_str(value: typing.Union[str, bytes], encoding: str = "utf-8") -> str: - return value if isinstance(value, str) else value.decode(encoding) - - -def to_bytes_or_str(value: str, match_type_of: typing.AnyStr) -> typing.AnyStr: - return value if isinstance(match_type_of, str) else value.encode() - - -def unquote(value: str) -> str: - return value[1:-1] if value[0] == value[-1] == '"' else value - - -def guess_content_type(filename: typing.Optional[str]) -> typing.Optional[str]: - if filename: - return mimetypes.guess_type(filename)[0] or "application/octet-stream" - return None - - -def peek_filelike_length(stream: typing.Any) -> typing.Optional[int]: - """ - Given a file-like stream object, return its length in number of bytes - without reading it into memory. - """ - try: - # Is it an actual file? - fd = stream.fileno() - # Yup, seems to be an actual file. - length = os.fstat(fd).st_size - except (AttributeError, OSError): - # No... Maybe it's something that supports random access, like `io.BytesIO`? - try: - # Assuming so, go to end of stream to figure out its length, - # then put it back in place. - offset = stream.tell() - length = stream.seek(0, os.SEEK_END) - stream.seek(offset) - except (AttributeError, OSError): - # Not even that? Sorry, we're doomed... - return None - - return length - - -class Timer: - async def _get_time(self) -> float: - library = sniffio.current_async_library() - if library == "trio": - import trio - - return trio.current_time() - elif library == "curio": # pragma: nocover - import curio - - return await curio.clock() - - import asyncio - - return asyncio.get_event_loop().time() - - def sync_start(self) -> None: - self.started = time.perf_counter() - - async def async_start(self) -> None: - self.started = await self._get_time() - - def sync_elapsed(self) -> float: - now = time.perf_counter() - return now - self.started - - async def async_elapsed(self) -> float: - now = await self._get_time() - return now - self.started - - -class URLPattern: - """ - A utility class currently used for making lookups against proxy keys... - - # Wildcard matching... - >>> pattern = URLPattern("all") - >>> pattern.matches(httpx.URL("http://example.com")) - True - - # Witch scheme matching... - >>> pattern = URLPattern("https") - >>> pattern.matches(httpx.URL("https://example.com")) - True - >>> pattern.matches(httpx.URL("http://example.com")) - False - - # With domain matching... - >>> pattern = URLPattern("https://example.com") - >>> pattern.matches(httpx.URL("https://example.com")) - True - >>> pattern.matches(httpx.URL("http://example.com")) - False - >>> pattern.matches(httpx.URL("https://other.com")) - False - - # Wildcard scheme, with domain matching... - >>> pattern = URLPattern("all://example.com") - >>> pattern.matches(httpx.URL("https://example.com")) - True - >>> pattern.matches(httpx.URL("http://example.com")) - True - >>> pattern.matches(httpx.URL("https://other.com")) - False - - # With port matching... - >>> pattern = URLPattern("https://example.com:1234") - >>> pattern.matches(httpx.URL("https://example.com:1234")) - True - >>> pattern.matches(httpx.URL("https://example.com")) - False - """ - - def __init__(self, pattern: str) -> None: - from ._models import URL - - if pattern and ":" not in pattern: - raise ValueError( - f"Proxy keys should use proper URL forms rather " - f"than plain scheme strings. " - f'Instead of "{pattern}", use "{pattern}://"' - ) - - url = URL(pattern) - self.pattern = pattern - self.scheme = "" if url.scheme == "all" else url.scheme - self.host = "" if url.host == "*" else url.host - self.port = url.port - if not url.host or url.host == "*": - self.host_regex: typing.Optional[typing.Pattern[str]] = None - else: - if url.host.startswith("*."): - # *.example.com should match "www.example.com", but not "example.com" - domain = re.escape(url.host[2:]) - self.host_regex = re.compile(f"^.+\\.{domain}$") - elif url.host.startswith("*"): - # *example.com should match "www.example.com" and "example.com" - domain = re.escape(url.host[1:]) - self.host_regex = re.compile(f"^(.+\\.)?{domain}$") - else: - # example.com should match "example.com" but not "www.example.com" - domain = re.escape(url.host) - self.host_regex = re.compile(f"^{domain}$") - - def matches(self, other: "URL") -> bool: - if self.scheme and self.scheme != other.scheme: - return False - if ( - self.host - and self.host_regex is not None - and not self.host_regex.match(other.host) - ): - return False - if self.port is not None and self.port != other.port: - return False - return True - - @property - def priority(self) -> tuple: - """ - The priority allows URLPattern instances to be sortable, so that - we can match from most specific to least specific. - """ - # URLs with a port should take priority over URLs without a port. - port_priority = 0 if self.port is not None else 1 - # Longer hostnames should match first. - host_priority = -len(self.host) - # Longer schemes should match first. - scheme_priority = -len(self.scheme) - return (port_priority, host_priority, scheme_priority) - - def __hash__(self) -> int: - return hash(self.pattern) - - def __lt__(self, other: "URLPattern") -> bool: - return self.priority < other.priority - - def __eq__(self, other: typing.Any) -> bool: - return isinstance(other, URLPattern) and self.pattern == other.pattern diff --git a/IKEA_scraper/.venv/Lib/site-packages/httpx/py.typed b/IKEA_scraper/.venv/Lib/site-packages/httpx/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/__init__.cpython-39.pyc index 700f1362ccfce44b5b5b421ec8ef366ac631c6d8..810509c625c0cce7ac38797f1735c8f04c9ad858 100644 GIT binary patch delta 26 gcmdnZwwsMRk(ZZ?0SID^yf$*5Vq$cge2pm;08iTnivR!s delta 26 gcmdnZwwsMRk(ZZ?0SIg^J8a}W#l+|``5IFy098T;{{R30 diff --git a/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/codec.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/codec.cpython-39.pyc index 23eb6677a806c5bb397206caf7ba17d8c9305ed2..ad29083cc1848c8c730453df99c064dd8f0ed063 100644 GIT binary patch delta 27 hcmZ1_wn~gUk(ZZ?0SID^yf$)MGBLVsc4d0X0RT{41`hxL delta 27 hcmZ1_wn~gUk(ZZ?0SIg^J8a~(WMXvL?8@|%0{~Vy27>?q diff --git a/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/compat.cpython-39.pyc index 98ac4cb5a81e892107336fe9c7b3489ae607e1fd..c3dd6677f6f6801eba7afd2df4c0c433f172c7ac 100644 GIT binary patch delta 25 fcmbQiI)jxvk(ZZ?0SID^ye4uVW^~(l{v;y+MA-(E delta 25 fcmbQiI)jxvk(ZZ?0SIg^J51z0%;>W5{7FUtNy-NZ diff --git a/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/core.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/core.cpython-39.pyc index 0574c214ded7b854ced6bf616cdd9a6d8741a0a7..2176c596ae16e3a70e2d3f78a35d4bd5a59306b1 100644 GIT binary patch delta 27 hcmZ4EzQ&z9k(ZZ?0SID^yf$*DGBLVsE@ZM+1OQuD20Q=& delta 27 hcmZ4EzQ&z9k(ZZ?0SIg^J8a}mWny&MT*zdt2moO-2Cx7C diff --git a/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-39.pyc index b910a3dc424ec02a93af2d81f5caf2c2e4c9aa00..f5d39febba507adddb4dab233e03bab054e11066 100644 GIT binary patch delta 29 jcmaF1hVj`NM(#vjUM>b8h&A%s$UWPi(QWf`|NU$LhQA2w delta 29 jcmaF1hVj`NM(#vjUM>b8u(|B8k$bj3qs!*y{`=VgjG75w diff --git a/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/intranges.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/intranges.cpython-39.pyc index da9b7bb4693c08527f4ef19106dbcf6714f11808..fa03a6f08d2093da74f41d88f27635e5b497fdb1 100644 GIT binary patch delta 27 hcmdnMw}Fp4k(ZZ?0SID^yf$**U}kjN{Dj$u830!72CV=9 delta 27 hcmdnMw}Fp4k(ZZ?0SIg^J8a~>!OZBg`3bWRGXPx22O$6e diff --git a/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/package_data.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/package_data.cpython-39.pyc index a05f78d91a1196a6742f301016fbadc84400efbf..5568620d627f7cac153d4208abc4ac7c1df4e221 100644 GIT binary patch delta 24 ecmdnbxSx?bk(ZZ?0SID^ye4u7FuF~QNd^EwIR$M1 delta 24 ecmdnbxSx?bk(ZZ?0SIg^J51ybV04)nlMDbvwguq; diff --git a/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/uts46data.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/idna/__pycache__/uts46data.cpython-39.pyc index 530ba60bd7a31b2d9a7223de875a5e33885a0d51..dca2423c50925b01516f0aefc28a53ebfa5753f4 100644 GIT binary patch delta 37 rcmaF!=UM>b8h&A%s$o-F#(XE+_tDTFBaXS|m(_I4q-Y*JC delta 37 rcmaF!=UM>b8u(|B8k^3Jfqf0XvS34IM<904Crn?3J=c)?5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/__pycache__/__init__.cpython-39.pyc index e95128686ca90718dafc2b1844ef2d79acf8518d..6b75f13c475d2bf2249706747bdf214a6235051c 100644 GIT binary patch delta 11 ScmZ3_xSnx>2cz3W&olrRF$2H= delta 11 ScmZ3_xSnx>2cyeG&olrRDFeO$ diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/__pycache__/fixer_util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/__pycache__/fixer_util.cpython-39.pyc index eaf59f8d8d8c7f3db44b3cd0a0868653ad89c3f4..12448e25705cd5b8d02fbf8b2bd367a5efbc507a 100644 GIT binary patch delta 14 VcmdlLyDN6XMpj0*&6`*`GyyRs1$O`d delta 14 VcmdlLyDN6XMpj0b&6`*`GyyRg1$6)b diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/__pycache__/main.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/__pycache__/main.cpython-39.pyc index 9771582c72882efc0f73835994bffa59e4b7be89..123ea95b7100f46c7a8231408e1c9c03cd94edc3 100644 GIT binary patch delta 14 VcmccUbhBTww=1l1qoB%M81=#=q delta 14 VcmccUbhBTwg=1l1qoB%L{1=j!o diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/__init__.cpython-39.pyc index bc8b5b8642100857ee3ca60fc79a0bfc4800f09d..82c41010015c799953aecc06b9dd30e27afefe39 100644 GIT binary patch delta 13 Ucmdnbzn_1D2RozNWKZ@o03h!KJOBUy delta 13 Ucmdnbzn_1D2Roz7WKZ@o03hWAIsgCw diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_UserDict.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_UserDict.cpython-39.pyc index 03a75ea6dd902fb32a61b0cd9edc51336a8b57f8..165c01c1c669b127b42efa0e8be59577a3622ae4 100644 GIT binary patch delta 14 VcmdlWxIu6O9}}b7W`3rHYycss1N8s^ delta 14 VcmdlWxIu6O9}}a?W`3rHYycsg1M>g? diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_absolute_import.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_absolute_import.cpython-39.pyc index 0682d8aa671b7f9652dbb39d64bb405a325339e0..d1a30a31e431ae163730b289a709ffbe8d3288ff 100644 GIT binary patch delta 14 Wcmdldyia(;RaQo~&DU68FarQC3kB@} delta 14 Wcmdldyia(;RaQoq&DU68FarQB{{`y+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_add__future__imports_except_unicode_literals.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_add__future__imports_except_unicode_literals.cpython-39.pyc index 7fe6c542bb1443850f7cdd90fff22d095f6f1e98..40c8c4778dcbeb272e30e26599e1f6fce2d1d427 100644 GIT binary patch delta 14 Vcmdnbv7ci@Jrkqb<_4zyi~uM~1pEL1 delta 14 Vcmdnbv7ci@JrkqL<_4zyi~uM;1o{8~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_basestring.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_basestring.cpython-39.pyc index cb6acbc6580e65a85d79d016e92f6944b3cd4f69..e158377111865a1008597361819c7a85876a56ea 100644 GIT binary patch delta 14 VcmZ3(wuWuPE=EST&AS;3838DS1o!{| delta 14 VcmZ3(wuWuPE=ER|&AS;3838DG1oi*` diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_bytes.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_bytes.cpython-39.pyc index 5e48112b5870f35a0ae2df4f9ca3d94beeb35d00..0cd7e1d26cef95cc1dc4e8cdff59c08b9716ca04 100644 GIT binary patch delta 14 VcmbQkF^6MAFB7BN=02uAMgS!c1fc)` delta 14 VcmbQkF^6MAFB7B7=02uAMgS!Q1fKu^ diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_cmp.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_cmp.cpython-39.pyc index ab0377d5aad8d2cea7691df90fbca007b6b99fed..0f794c702663a0fe3d187a8f8e87526fe316e456 100644 GIT binary patch delta 14 WcmX@fagt-h5++8s%}be9V4ULWP8RU03GiG9V4U5WP8RU03GE6;s5{u diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_division_safe.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_division_safe.cpython-39.pyc index 5cfe87759d61cee9f2a1cda57a956bbdeb93e151..d3db4577db5b08b650430f7f3eeee9f704d5b7b4 100644 GIT binary patch delta 14 VcmaDM{z8019y6oc=6vQ#4gf5L1q}cI delta 14 VcmaDM{z8019y6oM=6vQ#4gf591q%QG diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_execfile.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_execfile.cpython-39.pyc index 9b6b68324eb366225f29ea44160f69e90ce05a65..108203bff1dd46b86c570b9985f4a2ea0c1df19c 100644 GIT binary patch delta 14 VcmdnQwTWv(Gc%*x<`(94i~uJ^1m6Gv delta 14 VcmdnQwTWv(Gc%*h<`(94i~uJ&1l<4t diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_future_builtins.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_future_builtins.cpython-39.pyc index 8e6b0717a616095dfd6849a08a6ac172e99be515..06b8fd311bdc83b203f6cc167c99f579640e3919 100644 GIT binary patch delta 14 Vcmcb>dx3YuIVMK8&F7gISpY2t1q%QG delta 14 Vcmcb>dx3YuIVMJz&F7gISpY2h1qlEE diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_future_standard_library.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_future_standard_library.cpython-39.pyc index d46d1c01431a991a7ed218a5a836284e85e3370e..a4d508845b7659411716dbf553f7a5b152959a73 100644 GIT binary patch delta 14 VcmdnTv5#ZJIwnT9&Fh)^838IY1t9<&6k<-838OW1y}$8 delta 14 VcmX@aafoBXB_>9f&6k<-838OK1y%q6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_metaclass.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_metaclass.cpython-39.pyc index 40c009aee6b07b27ce78808c9e5ba778af897a01..5425a0d01ebbdb522e98a643990987d2ecee0123 100644 GIT binary patch delta 14 WcmZ3hyH;Ni31lIrn delta 14 VcmaDV{#1N}0}G?eW=EDK>;Nh?1l0fl diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_object.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_object.cpython-39.pyc index 4c1e42b455a5266b675a65920a305fa240609607..47c29096087fee09467ea63730bf121f595a0efb 100644 GIT binary patch delta 14 VcmdnYwwZ0iEk;JS&9@mN7y&A%1uXyo delta 14 VcmdnYwwZ0iEk;I{&9@mN7y&Ar1uFmm diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_oldstr_wrap.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_oldstr_wrap.cpython-39.pyc index 947708ae4eff39c1d04a837ef3167cc119a16f26..843b2aeeb3e0eeb6d8815738389f2be2233935ea 100644 GIT binary patch delta 14 Wcmeyt^@D4}6lO-Z%~P2lGXelFs0G3R delta 14 Wcmeyt^@D4}6lO-3%~P2lGXelFoCUxD diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_order___future__imports.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_order___future__imports.cpython-39.pyc index e59cb89c50493ad71f45e89b9b25695865f91a5a..ed77c62f0b387148ee8f31b10a2c26537acdfcbe 100644 GIT binary patch delta 14 VcmbQvF`Z*WGZUlR<`$;Oi~uAS1c(3t delta 14 VcmbQvF`Z*WGZUlB<`$;Oi~uAG1cm?r diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_print.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_print.cpython-39.pyc index 59a16a1e41d639eae8aaca6bd1f61a33bfd4c220..0796a418ee396c42cd829f572e26e4cb5e8412a7 100644 GIT binary patch delta 14 VcmaDW^j2tt5-X$IW@T0{762$`1V#V= delta 14 VcmaDW^j2tt5-X$2W@T0{762$)1VjJ; diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_print_with_import.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_print_with_import.cpython-39.pyc index d05c6dca5409f02c9a21eff3e395da111ad6f642..082aa4155a84e0b21bc971987a72151ef5d0d36e 100644 GIT binary patch delta 14 VcmX@cevEyC0~4d$W=E!0MgS#21W*6~ delta 14 VcmX@cevEyC0~4dmW=E!0MgS!>1Wo_| diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_raise.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_raise.cpython-39.pyc index 2b787977735a0362abbc83961ebafb5f897c841d..05eec284ab286542ec6978328348bbbf1cdb203b 100644 GIT binary patch delta 14 VcmX>ld`fsjE*qoU<~+6-W&kMe1gii5 delta 14 VcmX>ld`fsjE*qoE<~+6-W&kMS1gQW3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_remove_old__future__imports.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libfuturize/fixes/__pycache__/fix_remove_old__future__imports.cpython-39.pyc index 3cd525b6b2e6e6997eca4d9a4b963a9ccc83ead3..bd9db0d7d6f443f379ed8a9cff5e5a244b82bca3 100644 GIT binary patch delta 14 VcmaFD`Gj+W3p1nJW>@C@C diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/__pycache__/__init__.cpython-39.pyc index 7096771ef709422ce47d7caf6ee2038037015ec9..2e18d51fe5eb214042836e07699e0bf142fa06ab 100644 GIT binary patch delta 11 ScmdnUxRG&!2cz3W&kO(;TLZ=b delta 11 ScmdnUxRG&!2cyeG&kO(;Qv<{R diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/__pycache__/main.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/__pycache__/main.cpython-39.pyc index 9135c75abe831e027f4d93bcd4a635e60ffbf76f..a19fc5da4196a6da6aaa1d5a76ea4f2d3fd13460 100644 GIT binary patch delta 14 VcmbQBH$iWMKR=_}<^cW!>;NS@1gii5 delta 14 VcmbQBH$iWMKR=_(<^cW!>;NS%1gQW3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/__init__.cpython-39.pyc index cc2b61db754e0f0b01d515c8c3a1fafaff406ea8..f29073fe24eebcd5188223af3f8b36f90a965820 100644 GIT binary patch delta 13 UcmX@dc8+bsZ6-#y$#I|pW;W(ki~t~u1K9uo delta 14 VcmdnMxq)*7D>I|ZW;W(ki~t~i1J?im diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_add_future_standard_library_import.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_add_future_standard_library_import.cpython-39.pyc index 33e73f1ca8d5ee62386404ff689bba6383868c4e..27f8aa77bef9185f15265af2d44f027c4f159dc1 100644 GIT binary patch delta 14 VcmaFK{*rxz4HKi=W?QB;i~uO<1hoJF delta 14 VcmaFK{*rxz4HKiwW?QB;i~uOz1hW7D diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_annotations.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_annotations.cpython-39.pyc index 088306b0ed5c9d6ef05bb170a13fff648b28df7f..28dfc35ebca26dd637debb13bba75e8fcf6bbcb8 100644 GIT binary patch delta 14 VcmbQsJC}EZ9V4ULW_!jsRsbP51K|Jw delta 14 VcmbQsJC}EZ9V4U5W_!jsRsbO^1K$7u diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_division.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_division.cpython-39.pyc index c6f129a074cd1ab73f5a0c8a6717abb8ebda18e6..791800c26a76faecb7e22a228197185a6a337991 100644 GIT binary patch delta 14 VcmX@lb)IX(b4EtD%`X_!nE@`T1(*N; delta 14 VcmX@lb)IX(b4Es&%`X_!nE@`H1(pB+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_features.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_features.cpython-39.pyc index 41c95938a19895c08a35c8a739792142bac33dc0..68ae53bfc4a81eadff8056d0d8ebcb479ab13b29 100644 GIT binary patch delta 14 Vcmca5cuQ~t6DyZ^A`Tg>;NgF1$F=c delta 14 VcmZqIZ`a?jnV->R^A`Tg>;Ng31#|!a diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_kwargs.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_kwargs.cpython-39.pyc index b26ad65c5fe4686e2569f93fb771304d89e2b684..642f5492592018370aab1b17ec15710ab49e81e5 100644 GIT binary patch delta 14 VcmdljyIXcc3Jas#=2Vt2E&wOU1dIRx delta 14 VcmdljyIXcc3Jasl=2Vt2E&wOI1d0Fv diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_memoryview.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_memoryview.cpython-39.pyc index 050bad99f9868b5b70af5e7978d79f2c75a47343..26b5fa1656785b436042a54cb4ac3b0594340330 100644 GIT binary patch delta 14 VcmZ3=zLb4~1rwv&W=p0VMgSpA1LXh! delta 14 VcmZ3=zLb4~1rwvoW=p0VMgSo}1LFVy diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_metaclass.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_metaclass.cpython-39.pyc index 26783da4a27b8f73462eb3916af0dcfb48d2bdaf..932b21fc9cc299e370fbe1cda6d3d4417c042d6b 100644 GIT binary patch delta 14 VcmaFK|B`=0ATy)e<{;+jEC4E=1m6Gv delta 14 VcmaFK|B`=0ATy)O<{;+jEC4E!1l<4t diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_newstyle.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_newstyle.cpython-39.pyc index ee98c0a328b3bc9f314c7ab9ccc0a9ced43e8f86..1a5634ba40c420097f31fea8cd7332642d082397 100644 GIT binary patch delta 14 VcmX@ad5CjEDE_ws$HM5g*`H+(BLE=v1Umo# delta 14 VcmeC?>E_ws$HM5c*`H+(BLE=j1UUcz diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_printfunction.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_printfunction.cpython-39.pyc index 4e4a55e5e0148e3ed298e5df4a6b7f51150f8c6f..25831dbea9d09a821776105a7d5e90a32ea6b926 100644 GIT binary patch delta 14 VcmZ3+wv27VUPeZ@&HETL7y&2!1nB?( delta 14 VcmZ3+wv27VUPeZj&HETL7y&2o1m^$% diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_raise.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_raise.cpython-39.pyc index 4258caaa7159b8fda2677dfcf59eec9a968ddd8f..7ee2e67664ddd022f79bf03e7f438ac5c25d9f75 100644 GIT binary patch delta 14 VcmX@Yb%blfL1sp`&4-wq7y&Ei1ycY3 delta 14 VcmX@Yb%blfL1spm&4-wq7y&EW1yKM1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_raise_.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_raise_.cpython-39.pyc index 0b481353c3921ae47f449d20ee220299909c3577..7c4f45d4ae0560d31f80aa0e21879cbc5fca192c 100644 GIT binary patch delta 14 VcmX@aeTaL54GW{&W?Pn4MgS!n1WW(` delta 14 VcmX@aeTaL54GW{oW?Pn4MgS!b1WEt^ diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_throw.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_throw.cpython-39.pyc index 0df0c9154dd37736e408617f4141028bd80c322a..1a6af5330eabb7bb8ee99ae07cd78250d063fc39 100644 GIT binary patch delta 14 Vcmdnaxt()^3NxeIW>w}%i~u5}1PuTH delta 14 Vcmdnaxt()^3Nxe2W>w}%i~u5-1PcHF diff --git a/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_unpacking.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/libpasteurize/fixes/__pycache__/fix_unpacking.cpython-39.pyc index 4252a9c03108fd2afebff201c40b6abd4921087c..c2884e972efb4523a2c1ff1494399de8cf91299c 100644 GIT binary patch delta 14 VcmZ3ivsh str: - pass - - -__version__ = "2.0.1" - -_striptags_re = re.compile(r"(|<[^>]*>)") - - -def _simple_escaping_wrapper(name: str) -> t.Callable[..., "Markup"]: - orig = getattr(str, name) - - @functools.wraps(orig) - def wrapped(self: "Markup", *args: t.Any, **kwargs: t.Any) -> "Markup": - args = _escape_argspec(list(args), enumerate(args), self.escape) # type: ignore - _escape_argspec(kwargs, kwargs.items(), self.escape) - return self.__class__(orig(self, *args, **kwargs)) - - return wrapped - - -class Markup(str): - """A string that is ready to be safely inserted into an HTML or XML - document, either because it was escaped or because it was marked - safe. - - Passing an object to the constructor converts it to text and wraps - it to mark it safe without escaping. To escape the text, use the - :meth:`escape` class method instead. - - >>> Markup("Hello, World!") - Markup('Hello, World!') - >>> Markup(42) - Markup('42') - >>> Markup.escape("Hello, World!") - Markup('Hello <em>World</em>!') - - This implements the ``__html__()`` interface that some frameworks - use. Passing an object that implements ``__html__()`` will wrap the - output of that method, marking it safe. - - >>> class Foo: - ... def __html__(self): - ... return 'foo' - ... - >>> Markup(Foo()) - Markup('foo') - - This is a subclass of :class:`str`. It has the same methods, but - escapes their arguments and returns a ``Markup`` instance. - - >>> Markup("%s") % ("foo & bar",) - Markup('foo & bar') - >>> Markup("Hello ") + "" - Markup('Hello <foo>') - """ - - __slots__ = () - - def __new__( - cls, base: t.Any = "", encoding: t.Optional[str] = None, errors: str = "strict" - ) -> "Markup": - if hasattr(base, "__html__"): - base = base.__html__() - - if encoding is None: - return super().__new__(cls, base) - - return super().__new__(cls, base, encoding, errors) - - def __html__(self) -> "Markup": - return self - - def __add__(self, other: t.Union[str, "HasHTML"]) -> "Markup": - if isinstance(other, str) or hasattr(other, "__html__"): - return self.__class__(super().__add__(self.escape(other))) - - return NotImplemented - - def __radd__(self, other: t.Union[str, "HasHTML"]) -> "Markup": - if isinstance(other, str) or hasattr(other, "__html__"): - return self.escape(other).__add__(self) - - return NotImplemented - - def __mul__(self, num: int) -> "Markup": - if isinstance(num, int): - return self.__class__(super().__mul__(num)) - - return NotImplemented # type: ignore - - __rmul__ = __mul__ - - def __mod__(self, arg: t.Any) -> "Markup": - if isinstance(arg, tuple): - arg = tuple(_MarkupEscapeHelper(x, self.escape) for x in arg) - else: - arg = _MarkupEscapeHelper(arg, self.escape) - - return self.__class__(super().__mod__(arg)) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({super().__repr__()})" - - def join(self, seq: t.Iterable[t.Union[str, "HasHTML"]]) -> "Markup": - return self.__class__(super().join(map(self.escape, seq))) - - join.__doc__ = str.join.__doc__ - - def split( # type: ignore - self, sep: t.Optional[str] = None, maxsplit: int = -1 - ) -> t.List["Markup"]: - return [self.__class__(v) for v in super().split(sep, maxsplit)] - - split.__doc__ = str.split.__doc__ - - def rsplit( # type: ignore - self, sep: t.Optional[str] = None, maxsplit: int = -1 - ) -> t.List["Markup"]: - return [self.__class__(v) for v in super().rsplit(sep, maxsplit)] - - rsplit.__doc__ = str.rsplit.__doc__ - - def splitlines(self, keepends: bool = False) -> t.List["Markup"]: # type: ignore - return [self.__class__(v) for v in super().splitlines(keepends)] - - splitlines.__doc__ = str.splitlines.__doc__ - - def unescape(self) -> str: - """Convert escaped markup back into a text string. This replaces - HTML entities with the characters they represent. - - >>> Markup("Main » About").unescape() - 'Main » About' - """ - from html import unescape - - return unescape(str(self)) - - def striptags(self) -> str: - """:meth:`unescape` the markup, remove tags, and normalize - whitespace to single spaces. - - >>> Markup("Main »\tAbout").striptags() - 'Main » About' - """ - stripped = " ".join(_striptags_re.sub("", self).split()) - return Markup(stripped).unescape() - - @classmethod - def escape(cls, s: t.Any) -> "Markup": - """Escape a string. Calls :func:`escape` and ensures that for - subclasses the correct type is returned. - """ - rv = escape(s) - - if rv.__class__ is not cls: - return cls(rv) - - return rv - - for method in ( - "__getitem__", - "capitalize", - "title", - "lower", - "upper", - "replace", - "ljust", - "rjust", - "lstrip", - "rstrip", - "center", - "strip", - "translate", - "expandtabs", - "swapcase", - "zfill", - ): - locals()[method] = _simple_escaping_wrapper(method) - - del method - - def partition(self, sep: str) -> t.Tuple["Markup", "Markup", "Markup"]: - l, s, r = super().partition(self.escape(sep)) - cls = self.__class__ - return cls(l), cls(s), cls(r) - - def rpartition(self, sep: str) -> t.Tuple["Markup", "Markup", "Markup"]: - l, s, r = super().rpartition(self.escape(sep)) - cls = self.__class__ - return cls(l), cls(s), cls(r) - - def format(self, *args: t.Any, **kwargs: t.Any) -> "Markup": - formatter = EscapeFormatter(self.escape) - return self.__class__(formatter.vformat(self, args, kwargs)) - - def __html_format__(self, format_spec: str) -> "Markup": - if format_spec: - raise ValueError("Unsupported format specification for Markup.") - - return self - - -class EscapeFormatter(string.Formatter): - __slots__ = ("escape",) - - def __init__(self, escape: t.Callable[[t.Any], Markup]) -> None: - self.escape = escape - super().__init__() - - def format_field(self, value: t.Any, format_spec: str) -> str: - if hasattr(value, "__html_format__"): - rv = value.__html_format__(format_spec) - elif hasattr(value, "__html__"): - if format_spec: - raise ValueError( - f"Format specifier {format_spec} given, but {type(value)} does not" - " define __html_format__. A class that defines __html__ must define" - " __html_format__ to work with format specifiers." - ) - rv = value.__html__() - else: - # We need to make sure the format spec is str here as - # otherwise the wrong callback methods are invoked. - rv = string.Formatter.format_field(self, value, str(format_spec)) - return str(self.escape(rv)) - - -_ListOrDict = t.TypeVar("_ListOrDict", list, dict) - - -def _escape_argspec( - obj: _ListOrDict, iterable: t.Iterable[t.Any], escape: t.Callable[[t.Any], Markup] -) -> _ListOrDict: - """Helper for various string-wrapped functions.""" - for key, value in iterable: - if isinstance(value, str) or hasattr(value, "__html__"): - obj[key] = escape(value) - - return obj - - -class _MarkupEscapeHelper: - """Helper for :meth:`Markup.__mod__`.""" - - __slots__ = ("obj", "escape") - - def __init__(self, obj: t.Any, escape: t.Callable[[t.Any], Markup]) -> None: - self.obj = obj - self.escape = escape - - def __getitem__(self, item: t.Any) -> "_MarkupEscapeHelper": - return _MarkupEscapeHelper(self.obj[item], self.escape) - - def __str__(self) -> str: - return str(self.escape(self.obj)) - - def __repr__(self) -> str: - return str(self.escape(repr(self.obj))) - - def __int__(self) -> int: - return int(self.obj) - - def __float__(self) -> float: - return float(self.obj) - - -# circular import -try: - from ._speedups import escape as escape - from ._speedups import escape_silent as escape_silent - from ._speedups import soft_str as soft_str - from ._speedups import soft_unicode -except ImportError: - from ._native import escape as escape - from ._native import escape_silent as escape_silent # noqa: F401 - from ._native import soft_str as soft_str # noqa: F401 - from ._native import soft_unicode # noqa: F401 diff --git a/IKEA_scraper/.venv/Lib/site-packages/markupsafe/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/markupsafe/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index b14513c40ad0152fcfadf9dff502f59e5eb8b35d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10679 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 VI2_*M@aQoMM>>7S;R5U0e*pqIboT%N diff --git a/IKEA_scraper/.venv/Lib/site-packages/markupsafe/__pycache__/_native.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/markupsafe/__pycache__/_native.cpython-39.pyc deleted file mode 100644 index 150067513530e308e637012b6e298818309ec1c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2326 zcmZ`*-EJF26y9C0ovo9U5}+zVLZcwXvD6wBxWNrpON&II4X9~_6j|7lopHR)de_X1 z9bAR0a?2ZV(caOQ;3c@*Tdw*FrBJ>zv##C0m3C%4d;aE}?>l3@zFzn6?EQ6_uScHu zH~m-ASRlNEe48}V_r1t}L*7zshgW#ceA9jszDkoSy2r2%D0p?It?OYQpc8;}Yy3}`za_^hk0moh$>JebJT_8k*6(li`{yz3xT)i&22DH@_^{dUvm~oCJfy3Q zO0q+CoR}f|`u5Em7c?JWSN=4SSuAyn-O=PE(JUFTSw3Nzl!BR@i9{oUnKLARHW1>5 zjgrHmVR4=ro@7i<;^A_1*diaTy4AWquo2`3cV%qYkZVMU0DHZm8Ku1*;v7jc%*A<@ z7={31o~H0k$3W!PgiAe}@^m6egljz+x%hahBo{MwfYZ>C2Dw^x-X0@oBc|KzO2*0% za4JY6_^DK;v@%Z+d6hcmV<}qJb=&!dK5NG*9Jl)p75%x2%_-%$)MEx|a>_+CKjjmD z>t1z>kH(jt_?>&<)}g^-2aA*z4Sf6P)6cQmw5!i9HLJx6QpJr?ikP5k7>WwYSga_A ziATN)vH8eTXD~gvb*Sw~KI-np!#q#B*T4PhN>9fMXHwnPRA$rejpU%K z6C*E-d3?kVrS6U_(kX)<_cCshscemBMa>~=elhlDcADbl4cn{fMi4z0OyP5wqc2!~W(~ti(zV!a>KJ1swNz87Z3_6Cc%nF^A325nl6=&XVDtbe zq+Y|Z(n)O1xQ2C}>6|2vlQcyjG=jPWR_YMiQJy$^oKsx*R+7+#a)|Da8-Z?Ht>%jmuw-B867^rNpASs$jYbv*7RtDf z>WNM=Z8&j)GERu2&+jpYAHo-2>iy!M_;+#V8r)hU z{H@}9?j8eTs=JCVzk5G6tdmKW#JP|S+ujc(sH0@Y%NFfKaKr`yMzTB=j6S-mqGn2t z@+k_6d&3cEk2?7$t&6S46d7*fI?fs&rE)6MW>`eWTxGzHE<#!r8`mT-7^7|F*$?iM zJtOEu9a5d6;Uy-mEyw*O1oUYP9?}!~0a{$}v{q9eV5hlS)XZ!QcZF{X&l0q#T*+p( v-4)SyWuvj|bH$+iTHPh5*1hF$v@^=ZB$XXXpr$`TQLt9oICt*M#=HLmiK}-u diff --git a/IKEA_scraper/.venv/Lib/site-packages/markupsafe/_native.py b/IKEA_scraper/.venv/Lib/site-packages/markupsafe/_native.py deleted file mode 100644 index 6f7eb7a8..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/markupsafe/_native.py +++ /dev/null @@ -1,75 +0,0 @@ -import typing as t - -from . import Markup - - -def escape(s: t.Any) -> Markup: - """Replace the characters ``&``, ``<``, ``>``, ``'``, and ``"`` in - the string with HTML-safe sequences. Use this if you need to display - text that might contain such characters in HTML. - - If the object has an ``__html__`` method, it is called and the - return value is assumed to already be safe for HTML. - - :param s: An object to be converted to a string and escaped. - :return: A :class:`Markup` string with the escaped text. - """ - if hasattr(s, "__html__"): - return Markup(s.__html__()) - - return Markup( - str(s) - .replace("&", "&") - .replace(">", ">") - .replace("<", "<") - .replace("'", "'") - .replace('"', """) - ) - - -def escape_silent(s: t.Optional[t.Any]) -> Markup: - """Like :func:`escape` but treats ``None`` as the empty string. - Useful with optional values, as otherwise you get the string - ``'None'`` when the value is ``None``. - - >>> escape(None) - Markup('None') - >>> escape_silent(None) - Markup('') - """ - if s is None: - return Markup() - - return escape(s) - - -def soft_str(s: t.Any) -> str: - """Convert an object to a string if it isn't already. This preserves - a :class:`Markup` string rather than converting it back to a basic - string, so it will still be marked as safe and won't be escaped - again. - - >>> value = escape("") - >>> value - Markup('<User 1>') - >>> escape(str(value)) - Markup('&lt;User 1&gt;') - >>> escape(soft_str(value)) - Markup('<User 1>') - """ - if not isinstance(s, str): - return str(s) - - return s - - -def soft_unicode(s: t.Any) -> str: - import warnings - - warnings.warn( - "'soft_unicode' has been renamed to 'soft_str'. The old name" - " will be removed in MarkupSafe 2.1.", - DeprecationWarning, - stacklevel=2, - ) - return soft_str(s) diff --git a/IKEA_scraper/.venv/Lib/site-packages/markupsafe/_speedups.cp39-win_amd64.pyd b/IKEA_scraper/.venv/Lib/site-packages/markupsafe/_speedups.cp39-win_amd64.pyd deleted file mode 100644 index af5e727c136aa9d2ff78d54fc117f457465485f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/markupsafe/_speedups.pyi b/IKEA_scraper/.venv/Lib/site-packages/markupsafe/_speedups.pyi deleted file mode 100644 index f673240f..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/markupsafe/_speedups.pyi +++ /dev/null @@ -1,9 +0,0 @@ -from typing import Any -from typing import Optional - -from . import Markup - -def escape(s: Any) -> Markup: ... -def escape_silent(s: Optional[Any]) -> Markup: ... -def soft_str(s: Any) -> str: ... -def soft_unicode(s: Any) -> str: ... diff --git a/IKEA_scraper/.venv/Lib/site-packages/markupsafe/py.typed b/IKEA_scraper/.venv/Lib/site-packages/markupsafe/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/past/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/past/__pycache__/__init__.cpython-39.pyc index 874b84aaa2f9a3592c9e081f94628a58fc366f0a..85826d1e5ee58e1a302b99ba386d4bc876722721 100644 GIT binary patch delta 13 UcmZ23v0P%qL2gF3$%nX80VKNx2LJ#7 delta 13 UcmZ23v0P%qL2gEu$%nX80VJ^n1poj5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/past/builtins/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/past/builtins/__pycache__/__init__.cpython-39.pyc index e4b9b7bc7da95d7c154b06686eb0722250691861..854648125d48a8aa55423f77a4499674acc94ea6 100644 GIT binary patch delta 13 Ucmcb`bBkxgT~gbUgbUtd0KMA8zx4#&2O3RaRLA^=>|6d delta 14 WcmX>td0KMA8zx4V&2O3RaRLA^-3B!P diff --git a/IKEA_scraper/.venv/Lib/site-packages/past/translation/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/past/translation/__pycache__/__init__.cpython-39.pyc index 8713601c493147001e807fc82f2a40d7217e90e5..4aeb7cce2f131a13517e5835f18c099f3ef9fd27 100644 GIT binary patch delta 14 WcmbOlJ~e#9T`oqq&G)#rD*ym6n+7QW delta 14 WcmbOlJ~e#9T`oqK&G)#rD*ym6j|L|I diff --git a/IKEA_scraper/.venv/Lib/site-packages/past/types/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/past/types/__pycache__/__init__.cpython-39.pyc index b848938edd0daf04452d0799c01927c93d30294c..778ddefaa0a31f74a9dd67ee69967856b157b2d4 100644 GIT binary patch delta 13 Ucmey#_LFVHS0+Zc$={fo0W9bR`v3p{ delta 13 Ucmey#_LFVHS0+Z6$={fo0W97H`2YX_ diff --git a/IKEA_scraper/.venv/Lib/site-packages/past/types/__pycache__/basestring.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/past/types/__pycache__/basestring.cpython-39.pyc index 3b2ed3d146a49da3fa18fb2d2b0deaf320440cd3..904126a6b2bce44669697920bb350ef8f09330da 100644 GIT binary patch delta 14 VcmZ3+wTx?nD-)yJW;dn>OaLQ61bhGh delta 14 VcmZ3+wTx?nD-)y3W;dn>OaLP_1bP4f diff --git a/IKEA_scraper/.venv/Lib/site-packages/past/types/__pycache__/olddict.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/past/types/__pycache__/olddict.cpython-39.pyc index ced2d755103dae54107dc43afc8aaf5419c7bf13..c213a357cd954dadd1e59851db30972be16fbd2c 100644 GIT binary patch delta 14 VcmX>ubX;hIH#4K#W*_F?tNubX;hIH#4KlW*_F?tNAaRLA_9|hk4 delta 14 WcmaDR_DpQUX+}nu&1V>AaRLA_69wG> diff --git a/IKEA_scraper/.venv/Lib/site-packages/past/utils/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/past/utils/__pycache__/__init__.cpython-39.pyc index 3bf569fd35103c10de5f11ac4b866b61361d2825..51d1d20fb7f072e077facab51d9c271d60847e43 100644 GIT binary patch delta 14 Vcmew${y}_$KO3Xl<^Z+@tN<)71qlEE delta 14 Vcmew${y}_$KO3XV<^Z+@tN<(`1qT2C diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip-21.2.4.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/pip-21.2.4.dist-info/RECORD index f281b58b..69a6d77d 100644 --- a/IKEA_scraper/.venv/Lib/site-packages/pip-21.2.4.dist-info/RECORD +++ b/IKEA_scraper/.venv/Lib/site-packages/pip-21.2.4.dist-info/RECORD @@ -1,6 +1,6 @@ -../../Scripts/pip.exe,sha256=c3no0m2aCd7EIUIMixBRIaEjE6isbaMWhS56D247o2Y,106372 -../../Scripts/pip3.9.exe,sha256=c3no0m2aCd7EIUIMixBRIaEjE6isbaMWhS56D247o2Y,106372 -../../Scripts/pip3.exe,sha256=c3no0m2aCd7EIUIMixBRIaEjE6isbaMWhS56D247o2Y,106372 +../../Scripts/pip.exe,sha256=qXm-yZs8MVXaxT2K8EqkFlIwi3kaYIHmBzoF8HTgKd8,106372 +../../Scripts/pip3.9.exe,sha256=qXm-yZs8MVXaxT2K8EqkFlIwi3kaYIHmBzoF8HTgKd8,106372 +../../Scripts/pip3.exe,sha256=qXm-yZs8MVXaxT2K8EqkFlIwi3kaYIHmBzoF8HTgKd8,106372 pip-21.2.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 pip-21.2.4.dist-info/LICENSE.txt,sha256=I6c2HCsVgQKLxiO52ivSSZeryqR4Gs5q1ESjeUT42uE,1090 pip-21.2.4.dist-info/METADATA,sha256=PGCimuD-VsKv664Ne_9navMt6I9Ym_rm5p_u6Ykgfd4,4165 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/__pycache__/__init__.cpython-39.pyc index ef808a85db9192e0a1920018bcdd432fb5de680f..b43ce31a16d60291e7a6ac15e14169387aeab059 100644 GIT binary patch delta 26 gcmaFQ@}7k|k(ZZ?0SMfTyf$(#Vq|oiypHi809O+R;s5{u delta 26 gcmaFQ@}7k|k(ZZ?0SNRjJ8a}$#K`C}c^%_H09^bBU;qFB diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/__pycache__/__main__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/__pycache__/__main__.cpython-39.pyc index cdb60c6e580ac0837cf5cc68b1b7add1242cbff4..4c38432d52cc35768a445df58bdc6fee70b34137 100644 GIT binary patch delta 26 gcmX@ia+rlXk(ZZ?0SMfTyf$+0XJmAne44QW08eoSdjJ3c delta 26 gcmX@ia+rlXk(ZZ?0SNRjJ8b0M&&cR9`7~n%099HB`2YX_ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-39.pyc index 1a6891bedb9bb6e8097b1dd5f19d299248ee6dfb..796bfd103adce1eeccc607128826329bfcff023e 100644 GIT binary patch delta 27 hcmaFC`ht}^k(ZZ?0SMfTyf$(lWMp*Pe3ns~5ddAI29E#$ delta 27 hcmaFC`ht}^k(ZZ?0SNRjJ8a}W$jIoj`7EO}BLHLy2MquK diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-39.pyc index 79da0e26b4ec5a1a3869b195c277270d7d764c00..3536e4bc456c0abf7a6331acbbc3e590bc0bf46a 100644 GIT binary patch delta 27 hcmezE_S=m+k(ZZ?0SMfTyf$*HvM{=BHe~UV2LNW`22ub3 delta 27 hcmezE_S=m+k(ZZ?0SNRjJ8a}uWnpyLY{=pz4*+dR2G9Ti diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-39.pyc index 3d110e990231d2954a41a5e535b86da7c8d98ae7..4f7912461c8c2348b41fb1e32bf5993f0c8ea7dd 100644 GIT binary patch delta 27 hcmbPbJIj_kk(ZZ?0SMfTyf$*PFf+Ps7GUm@1^`en1$F=c delta 27 hcmbPbJIj_kk(ZZ?0SNRjJ8a};VP@X}2KfL0 delta 27 hcmbPSHMxpAk(ZZ?0SNRjJ8a}`VPmjD0& diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-39.pyc index 035050828fdf5d7600a352a353bad181c40ec8d8..c932fa26b29a83dd9f0d66deeacb616628648be3 100644 GIT binary patch delta 27 hcmew^^<9cPk(ZZ?0SMfTyf$*LWMp*Pyp{0~HvnYm2Uq|A delta 27 hcmew^^<9cPk(ZZ?0SNRjJ8a}$$;jxkc`M@~ZUAdg2i5=p diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-39.pyc index 545c19f880827bbc7be334e2fb6b580868f224fd..cb46863bc71d9f386d17bac41cc2cfe800381e4a 100644 GIT binary patch delta 27 hcmaE@_*#)Wk(ZZ?0SMfTyf$(tFfqDq&S9$O0{~yD27Ukl delta 27 hcmaE@_*#)Wk(ZZ?0SNRjJ8a}mU}ALHoWoSl2LNUf2K)d3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-39.pyc index 5b23c972e528eaaed7dfa497087c5e259730029b..70730503d75d5f25e9f30a3e000ec741d8b0a631 100644 GIT binary patch delta 27 hcmX@>aMpo4k(ZZ?0SMfTyf$(lU}1FIe1@e_8USRc2U7q5 delta 27 hcmX@>aMpo4k(ZZ?0SNRjJ8a}Wz{2RV`3y^=GyrQ32hjik diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-39.pyc index af44a400f71558777fec1e07fa993e756741e950..b9b84756ac31100a98473c9bc2aba2e1e5b5248a 100644 GIT binary patch delta 24 ecmeBR>R{qdR{qdb8a5M7S$nC_(=(gF9uh|m-dK3qP delta 29 jcmcb(p7G*(M(#vjUM>b8(7)`kk=u!n(PgtAU$Z9wfO`l5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-39.pyc index 6d00d4cc97b42658eed7cbd674e19105530822b3..32d299afb0ece5b2bac7de34ea72d7a91612d760 100644 GIT binary patch delta 27 hcmey*`Ja!^r5e`30jmGXQGW2X_Df diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-39.pyc index 14e9d05fe0593f38f54feceace06f030ef800275..0080805d5e0cd23f396d384ad5a72d4af22d39b3 100644 GIT binary patch delta 27 hcmX@bb&88Sk(ZZ?0SMfTyf$)|GBdhuZe%{m2mn?a26q4e delta 27 hcmX@bb&88Sk(ZZ?0SNRjJ8a}GWoC5Q+{k>A5dd6*2K4{{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-39.pyc index f5fa54d3469ac323e28791363912be67d93d0a91..7133909f9b305084b6677b218957e2f5057fcdd5 100644 GIT binary patch delta 27 hcmaDZ@LYg9k(ZZ?0SMfTyf$(dGBdhuu4R730svh+2H5}r delta 27 hcmaDZ@LYg9k(ZZ?0SF8(J8a}GWM*{PT+9551ps5Q2Uq|A diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-39.pyc index 1d1feb311d69569e4dfe55664ea6e9a162e774a2..e79c437da5194a9694f2fc9970dc08c3ef15416d 100644 GIT binary patch delta 27 hcmX@_d)}8jk(ZZ?0SMfTyf$)gV`g;Qe2AG>831N12JZj> delta 27 hcmX@_d)}8jk(ZZ?0SF8(J8b0M#?0ul`4BU&G5~C$2W|iW diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-39.pyc index 0782c8c900818d3118a8e856d99d489abadcf79d..4a55017afa655ecf91d4d76aff350834f5b838c3 100644 GIT binary patch delta 27 hcmdmOz1x~Qk(ZZ?0SMfTyf$(lVPx<(~x<(~sk(ZZ?0SMfTyf$(RGBLVsmSxfu1OQZY1x)|| delta 27 hcmX@6c1(>sk(ZZ?0SF8(J8a|@WMXvLEX$-R2mo5?1??&X20;J- delta 27 hcmbQvGo6P!k(ZZ?0SF8(J8a~>%*^Pr`98A+6985{2EYIS diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/completion.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/completion.cpython-39.pyc index 44147250bbb3735dfe1805c2e560d91801f369f8..f5cc787e9a59de245878ca727b68790c515f6a30 100644 GIT binary patch delta 27 hcmdlXu|tA8k(ZZ?0SMfTyf$)su`{}D4r71B0svEC20Z`( delta 27 hcmdlXu|tA8k(ZZ?0SF8(J8b0kVrO*O9LD~L1pryr2D|_O diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-39.pyc index 026a14609ea032fc360ffe26da690f94b2394246..620e4d81748afd52a1c03f9b1dfe1f904f4954f2 100644 GIT binary patch delta 27 hcmeBo?04i& delta 27 hcmZoLX)xhVFF*OEEta0{~Fa1{weW diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/download.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/download.cpython-39.pyc index 16335b5bc7d79b94640cc07d1a19e64561d981da..8fe3a4c682a5ac408ea20535d84b927264086eec 100644 GIT binary patch delta 27 hcmeB{@0RCI bYk5X$YEJS*LCMVyjB{8R-8SE4O=1B6QF|Du delta 72 zcmdllvR{Ndk(ZZ?0SF8(J51#Mt{TOal383*l$lgol6s4^JR>zV=N4CSYDsB9Nq&A# b@h#?p%!1^Jf|8pZ80WAsx@^A7n#2MCYT6km diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/hash.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/hash.cpython-39.pyc index d0e51ade8005c6d0aefb3ad6779bb91ae6ca3a0f..276b1fe2aeba764c5901815f0cca05b2f3f51d35 100644 GIT binary patch delta 27 hcmX>pa8iIfk(ZZ?0SMfTyf$*TF*CYtp2WPJ1prsi29y8* delta 27 hcmX>pa8iIfk(ZZ?0SF8(J8a}`V`g;OJc)Tb3jkh32NM7Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/help.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/help.cpython-39.pyc index 2feb75d257a4b03beb617d854e4455b174038dd3..52c7efd0c91d3069757461bcef6fde7228af7ebc 100644 GIT binary patch delta 27 hcmeC@>gVE40suwU1#JKT delta 27 hcmeC@>gVE4FF*YcM}&1OQA+1?&I- diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/index.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/index.cpython-39.pyc index b4d1ba3907747f7a67182fab078f329b1ee388b9..bad1c4bb34da307dd8fcee3f47a8aa5008db6e04 100644 GIT binary patch delta 27 hcmZ3ayhxclk(ZZ?0SMfTyf$*5W?^*Oe4XVq4**wH2NVDR delta 27 hcmZ3ayhxclk(ZZ?0SF8(J8a}W&BExi`8vyK9spg+2a^B* diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-39.pyc index 96a89f797ffb941771f6b1e94e941a2b0d94c305..b4b4b6bcf12d5efd3c4f9bea6d62e51ab6efd5eb 100644 GIT binary patch delta 29 jcmey+$@rm@kvox>mx}=i+>E?7ax1ejx^32HJ7@<0cV!1! delta 29 jcmey+$@rm@kvox>mx}=i3@$rt5blI%WcF+z0ecA`v diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/list.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/list.cpython-39.pyc index 17af596e62cf67f998c01af021e67742066d78ca..df4058522910aa0ba3ba8990977e0e3b1904272d 100644 GIT binary patch delta 27 hcmccTd(W3Uk(ZZ?0SMfTyf$)|vM{=BZe)p70sv-}2HXGu delta 27 hcmccTd(W3Uk(ZZ?0SF8(J8a}GWnpyL+{hBE1OROc2U`FD diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/search.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/search.cpython-39.pyc index 2921743bdb6c149013febb12d9d3d989cdb3419d..8b6ae7aa2f83d0b4e1bca35808e16d338519571e 100644 GIT binary patch delta 27 hcmdn3xm%Mvk(ZZ?0SMfTyf$*DF*CYtE@Ji+1OQiR1_=NF delta 27 hcmdn3xm%Mvk(ZZ?0SF8(J8a}mV`g;OT*T}t2moE*28aLv diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/show.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/show.cpython-39.pyc index 80dba6412df5c3ae11169b5363fd45360b646c8d..423712c9478db31a1a0e63c5a42e3f2c40d95046 100644 GIT binary patch delta 27 hcmdnwxXF<_k(ZZ?0SMfTyf$+GWoC5S%*nD+1^`~a2EhOT delta 27 hcmdnwxXF<_k(ZZ?0SF8(J8b0s%gpGqnUiIu3;<;`2S5M- diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-39.pyc index 1da6a22f30fc38d699a3839bf36a574a51331325..cb3bdfcd0d008cb5f56238d231e4156de7dbd9e3 100644 GIT binary patch delta 27 hcmbOzF;Rj$k(ZZ?0SMfTyf$+0U}bdMe1z4P4FFHg1~dQw delta 27 hcmbOzF;Rj$k(ZZ?0SF8(J8b0M!OG~e`3S2o8vs^92D1PF diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-39.pyc index d2ac84fc04b5c3d542a3bcdf3f009373bfa5f051..b1b6a1921e2b016084dc958fa8c105e816cca256 100644 GIT binary patch delta 27 hcmeyO`bCvHk(ZZ?0SMfTyf$)A=VWx-yqGhP698oW2H^kz delta 27 hcmeyO`bCvHk(ZZ?0SF8(J8a~h&dKPqc`;`oCje`52VejI diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-39.pyc index a2d9e9add5637ab7a45fa733845913f88d451064..9b7e9e5406c78992e8255f3e2ae3e2180ca9cd13 100644 GIT binary patch delta 27 hcmbQtHkpk(k(ZZ?0SMfTyf$)oGcvkup3Ydq2mnfz1>67t delta 27 hcmbQtHkpk(k(ZZ?0SF8(J8b0cW@L2PJe{$I5dcvN23r6C diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-39.pyc index 4f3eb1b0e659eb610e1cbb3561a4edaf6e4d6bdf..2da0ab0995c54754d0db93f563951abd2cfe0db4 100644 GIT binary patch delta 27 hcmeyx_lu7^k(ZZ?0SMfTyf$**WM*{R{FHerGXP~#2Xz1d delta 27 hcmeyx_lu7^k(ZZ?0SF8(J8a~>$;{}o`6=^MW&mr(2lM~{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-39.pyc index 40482e42396c83dc4699397b5a595cd728a47b57..43c1ff7a0b7e1ab68ec1dc24f3642f009d5ffce4 100644 GIT binary patch delta 27 hcmcb}d6APlk(ZZ?0SMfTyf$((GBLVs=4Cp<1OQQ81(g5* delta 27 hcmcb}d6APlk(ZZ?0SF8(J8a};WMXvL%*%9y2>@5p1{44Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-39.pyc index d9da550455b12a5653ea29f468ee52689e99c4d1..973d68370427b759377367f827668eeb28df9a35 100644 GIT binary patch delta 27 hcmaDa{a%_ok(ZZ?0SMfTyf$(lVq$dLe2z(x8vtX82HgMv delta 27 hcmaDa{a%_ok(ZZ?0SF8(J8a}W#Kh>b`5coXHvnn=2V4LE diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-39.pyc index f680ebd2149c8e6fcb1bdb38a4433951cba3b8b5..aa3d92fcfcf2800a906ea1152c21946c92d746c5 100644 GIT binary patch delta 27 hcmZ3$vw(*?k(ZZ?0SMfTyf$*1F*CYtc4EHA1OQ6!1-}3Q delta 27 hcmZ3$vw(*?k(ZZ?0SF8(J8a}OV`g;O?8JPJ2>?-K20j1) diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-39.pyc index ef732987ce4078272eee7d7a9d154285c7b5bd2c..8b13ce9cdf846a39fc262a89e0b3d885100433f1 100644 GIT binary patch delta 24 ecmcb`c#Dxck(ZZ?0SMfTye4udFuG05$pZjHp#`@9 delta 24 ecmcb`c#Dxck(ZZ?0SF8(J51zGV04+7lLr7vmj*Tf diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-39.pyc index 3093527caa0a7c63084f0d287eadb900a05eb721..6527e9a70e5ae6727f5357da7932faf1e938507f 100644 GIT binary patch delta 45 xcmX?BbF79tk(ZZ?0SMfTyf$+4ura!AmSA&ar*c0u0ss#?4I2Oe delta 45 xcmX?BbF79tk(ZZ?0SF8(J8b0UVPkaJEWzf;%EOXTQc`e>6+{+qPUU`R1OOg{4VnM| diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-39.pyc index 836f5c16cf8dc31795d8941dbde98ecdb8b580b9..b4a63c95a4353cd757c50d48642762bb7bd1f895 100644 GIT binary patch delta 29 jcmX?boAJPHM(#vjUM>b8a5M7S$Q{GM=(ah7BO(<5fL{mF delta 29 jcmX?boAJPHM(#vjUM>b8Fu3fnkvoQi(PeW6M?@+BhSUgA diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-39.pyc index 8706cca97c92c23a386caf11fd4426c4dfc0686d..84e710aeef594ea65573cf42c409df15f4844cce 100644 GIT binary patch delta 27 hcmeCT=(pfbAtQpJH;A1OQdl27v$o delta 27 hcmeCT=(pfboJ2>@J52LJ#7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-39.pyc index 76b8d6e01ecb5f9d7e2c1ab4e5a0fd9990828a50..bb592ec37893e882fa1d0f12635e46f0ada3fc16 100644 GIT binary patch delta 27 hcmdnvx5tk=k(ZZ?0SMfTyf$**WMy>Q{FF6Z5ddWI2VDRF delta 27 hcmdnvx5tk=k(ZZ?0SF8(J8a~>$;#-m`6+9-A^>Y<2iyPv diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-39.pyc index 5e91d8b8116201d44128b26ab9cd642cd08789d3..941310d0a22276dc48527081ed3e4c71e0e204fa 100644 GIT binary patch delta 27 hcmdm}vQdRQk(ZZ?0SMfTyf$(lWMy>Qe3mtZ2LM@42D<@)W2Uh?9 delta 27 hcmaFk`Noqwk(ZZ?0SF8(J8a~>#Kh>b`5qIW5&&}_2i5=p diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-39.pyc index 2d611d783327fcafdad7846a63e8bb71f69022c7..a0536900d95421adc3824744a362061ddbde95c2 100644 GIT binary patch delta 27 hcmeA)=rrI?q diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-39.pyc index b0f87e30d18f57ff3540081fdfb4e20a322324e4..3e49ff0af5c804ee04a2db4e7b37197fcbc0c140 100644 GIT binary patch delta 24 ecmeyv_=k}@k(ZZ?0SMfTye4utGP+Id%?AKW#s)qB delta 24 ecmeyv_=k}@k(ZZ?0SF8(J51zmWOSL>n-2g`yav4h diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-39.pyc index b3ecba251b869e93becae9f752b58a4a54511865..d78e909a2875ea7bd7be67e07d1612c5bccda3ca 100644 GIT binary patch delta 27 hcmbQiJ%gJ&k(ZZ?0SMfTyf$)sF)_Mr4r6j+1^`Ik1vmfz delta 27 hcmbQiJ%gJ&k(ZZ?0SF8(J8b0kVq$dJ9LD6t3;<751-AeI diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-39.pyc index b763aa5fab72611d075dfe2e7bb6d9ddf9275ed1..6355745bcda8edded25b64c0592a03cbe226536f 100644 GIT binary patch delta 27 hcmZoSZ#U;oNoX=#y0RU6l1^xg4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-39.pyc index 2b7cb398a0b8e2bd81636b6336c5cb5e22600053..aeca69e03ddd4a5cb0cffe99210b220c0038a4b6 100644 GIT binary patch delta 27 hcmX@ld7hIyk(ZZ?0SMfTyf$+CGBLVsj$|rh0svGs1=|1s delta 27 hcmX@ld7hIyk(ZZ?0SF8(J8b0kWny&M9LZG11OQs923i0B diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-39.pyc index 3591b82da9a0e53ff47714af00427314a1b76dc8..34ef729dd12ebd5b812f02fc0293687ee4fa6748 100644 GIT binary patch delta 27 hcmeAU=nmjcCCUt++4B002|t1}Xpm delta 27 hcmeAU=nmjcNJe|p(5ddMy2G{@q diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-39.pyc index 9c0818386fe9b2bb620aa65501bbbca15648d6d8..3130f2c0505c90bdaf2dd87c809f0b13feaeaeb8 100644 GIT binary patch delta 27 gcmeB|?w96HSQuS4hp||40sv5|1;zjX diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-39.pyc index e0a52110001cfa0a16960b8e03a9de98f09d4d2f..06de43d321f3fe3135349e31803b1a2ce446d1c2 100644 GIT binary patch delta 27 hcmeyy^Noi)k(ZZ?0SMfTyf$(lWnpyNe34}-BLHJU2T=e3 delta 27 hcmeyy^Noi)k(ZZ?0SF8(J8a}W%EIWf`6A0wMgVEI2hacj diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-39.pyc index 29c42d083155a0816e63cf0193bb6eea4964257e..b3148e44720cd6b5404c450fb2baea9da5c6d8b2 100644 GIT binary patch delta 27 hcmX>jbw-Lik(ZZ?0SMfTyf$*5VPkaLe1olo4FFw=2LAv6 delta 27 hcmX>jbw-Lik(ZZ?0SF8(J8a}W!^Y^c`374F8vtYf2Yvtm diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-39.pyc index 48bee713200998ff262e61db2cff859c99d1c095..4fcf37f45ed0f1d2c697e5ca11a4398ddc19fefa 100644 GIT binary patch delta 27 hcmaE(_(qXCk(ZZ?0SMfTyf$(tvM{=B&Sk0R0RUhB27~|r delta 27 hcmaE(_(qXCk(ZZ?0SF8(J8a}mWMOpKoXb+r0{~`p2Lk{A diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-39.pyc index ca5cfb758b52a2a107cf1f80e6a09ac8c5c4fd59..16d7a1c19d2351819ea5db320a6fae3c2739c05e 100644 GIT binary patch delta 24 ecmeys_<@l-k(ZZ?0SMfTye4v&FuF}_C;$LSHwFy= delta 24 ecmeys_<@l-k(ZZ?0SF8(J51y*VRV_;Pyhfb2rdXPw delta 27 hcmeCR>b2rdkc1Vmnk(ZZ?0SMfTyf$*5Wn^^Qe3LPg698I$2Gall delta 27 hcmX>kc1Vmnk(ZZ?0SF8(J8a}W%gE@m`6go~Cjemb2T}k4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-39.pyc index 2fc595d3bcff509c653fd669516c236eb7e2da48..5d98dd9236ca89d63bec6dc85f69e746336cbc1c 100644 GIT binary patch delta 27 hcmcbwbzh4+k(ZZ?0SMfTyf$)2Gc&qvPG|lh2moKZ2J8R; delta 27 hcmcbwbzh4+k(ZZ?0SF8(J8a~RW@dERoX-415CCQ{2WtQT diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-39.pyc index adf6b96d4698c76e610d557e9575607a09c05017..657a3a615e2164017102e3b45325a3bae72cf9cd 100644 GIT binary patch delta 27 hcmbQ}IMIfy delta 27 hcmbQ}IMI#>D8d`4Q84SpZ;!2ebeH diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-39.pyc index bc99f816db1674b93db89ed2f4d9cfabd2ef0a60..8b15529ba025086302a5358587b2dd3be2733c8d 100644 GIT binary patch delta 27 hcmZ1xv?7Q*k(ZZ?0SMfTyf$**Vr6vO{EXE}831992P^;p delta 27 hcmZ1xv?7Q*k(ZZ?0SF8(J8a~>#meZi`5CK|G5}};2de-8 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-39.pyc index d313b7d4b1ba76a53919ce27c16f116f0b58c160..fd6ee27bbf98c7da4e194400f831f77d53e9991d 100644 GIT binary patch delta 27 hcmeC;?&9W7?`B2NwVU diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-39.pyc index 734b6c34113e55c0fcf1b0d3a03944ba198378b4..4a24405e23ee24fbf4ba04874da2e48f953e88d7 100644 GIT binary patch delta 27 hcmey)|DB&Zk(ZZ?0SMfTyf$+4GBdhumSn!i0svbc1|t9f delta 27 hcmey)|DB&Zk(ZZ?0SF8(J8b0UWoC5QEXjP21pr}_2BH7} diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-39.pyc index f55d66caa5873cb523cb2314e8f30347dea5b773..399cc53726dd2110700563c97f5e6cc750350145 100644 GIT binary patch delta 24 ecmdnPxQCHDk(ZZ?0SMfTye4wnGP+IlECv8RDg`P%+8$42moMB26g}d delta 27 hcmeyu@r8psk(ZZ?0SF8(J8b0s&BW-knVmV85ddbw2K4{{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-39.pyc index 65d3f34bad243c36dbc14e55313778254d5237a6..f30673436f65571e421cb9663334f85501d83eae 100644 GIT binary patch delta 27 hcmeyx_lu7^k(ZZ?0SMfTyf$+CF)_Mrj$%?^1pr-71?m6* delta 27 hcmeyx_lu7^k(ZZ?0SF8(J8b0kV`6mK9L1!-3IJoo25A5Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-39.pyc index 59d2c5eceeffaecabfba1d756fdbb4de51cb6999..bd049e42d013d9d7360e762f9887c059d5f8b569 100644 GIT binary patch delta 27 hcmcc5ai4=bk(ZZ?0SMfTyf$+GVq$dL%*Gta2mo8u1~vcy delta 27 hcmcc5ai4=bk(ZZ?0SF8(J8b0s#l+~cnTgVE4gVE4AtQ?_xT}1prM#273Si delta 27 hcmZpWZjk0q;kMa0CM(#vjUM>b8a5M7S$lb}t=(c$(+a?bHcnJsj delta 29 jcmX>;kMa0CM(#vjUM>b8Fu3fnk-L+P(Pi^gwoM)Yetrme diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-39.pyc index e6df7ae720d67ea85b50dbe925a07664c5d04406..f18b75e33f9cadbced08e8af7a848709fe8ee6b1 100644 GIT binary patch delta 27 hcmew^{9Twkk(ZZ?0SMfTyf$(tGBLVs&SmOi2LNAs27mwn delta 27 hcmew^{9Twkk(ZZ?0SF8(J8a}mWMXvLoXgb34gh8E2LAv6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-39.pyc index 0d59d46af1e9a03a5e43b647bcddaca892aeaebd..b3365d051dfceb0b194eb35dd40ade12ebd2800c 100644 GIT binary patch delta 27 hcmbOnJvo{?k(ZZ?0SMfTyf$)gVqb8a5M7S$Supx=(bst-O~pEe6I&2 delta 29 jcmeygjPcVlM(#vjUM>b8Fu3fnkz1CX(PgtHyQdETgCqx| diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-39.pyc index 28b23c6dab23c2034cae9d82d7bbb0e9ead52b53..daf94b52ef8090f1e1e3841b5120e412ac2e2a8b 100644 GIT binary patch delta 27 hcmZqBYtZ9P<1%Lnm delta 27 hcmZqBYtZ9PFF*^D%!C1^`bT1^)m5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-39.pyc index 9bec50b0b3875b4781c119a93b88ea69f4d74f3f..d27b5e359df922bda8fc73607d4c6395dc8e45aa 100644 GIT binary patch delta 27 hcmZ3lxL%Pvk(ZZ?0SMfTyf$+GU}ALJ%)-2y7XVj`24VmJ delta 27 hcmZ3lxL%Pvk(ZZ?0SF8(J8b0s!NlmYnT2^ZF92Qv2H^kz diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-39.pyc index d7fb86e4fd870aa57d37ac56a47716cd6e138f86..865416dbbf9d6c25dc91c002b967b97b2d10e983 100644 GIT binary patch delta 36 qcmX>!iSf`RM(#vjUM>b8a5M7S$Zg5W=(gFF^}Qow)Mit6UM2vnCJ6)p delta 36 qcmX>!iSf`RM(#vjUM>b8Fu3fnk=v4$(PgtM>w8DWTboVYd6@vY6bb_X diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-39.pyc index f7dbfb618b1369b0377e4db607e887d6656f7220..507366f6ae5ec76df585207f0e6fecfa526b9571 100644 GIT binary patch delta 24 ecmdnPxQCHDk(ZZ?0SMfTye4wnGP+IlECv8RDg`@U{2BiQ1 delta 27 hcmeyx{)?SEk(ZZ?0SF8(J8a~h!^r5ec?Dw-698ti2P6Oh diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-39.pyc index 3d8f5b82dac650f374c85216e1d93b2300f30f0e..21e2b4eaed4103912d54a98362aa057060f65f08 100644 GIT binary patch delta 24 ecmX@ic$kqpk(ZZ?0SMfTye4wnGP+IltO5W(a|KTT delta 24 ecmX@ic$kqpk(ZZ?0SF8(J51!ZWptV7Sp@(@X$8&z diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-39.pyc index b3d3d4d3415f0efab73a6577236e159615e9f096..089a63ad97065b0a05158f5c2d204bc77c39aabc 100644 GIT binary patch delta 105 zcmcZxkvWhIDYDqSUZ{YT(PFcL#C8rwv&}aYe(?eT Dr>7w& delta 105 zcmcZmnWmeUnwpZD@{7MDU$;21 zB(pfJQWqq3i#0VdJ+)}_EAAa^yyigtZbcSAGNj0C^Ln8IRz|bU3KH8n7|l1|Q250Q E0M0BSr2qf` diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-39.pyc index 9dd9c574b0083854d68f01d3fbc56eaa474ea86e..47772f7cfb220ce8cd4c7c71e0d98d115a679057 100644 GIT binary patch delta 24 ecmX@kc$|?tk(ZZ?0SMfTye4wnGP+IltOEc*F9llw delta 24 ecmX@kc$|?tk(ZZ?0SF8(J51!ZWptV7SqA_`B?a05 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-39.pyc index 6e44cbd9e936e627c937f964d42f901b4bce72be..37bc8242716ce19f71cf72a72b8d0b8051ca5976 100644 GIT binary patch delta 27 hcmX?aa^8eHk(ZZ?0SMfTyf$)oGcmetp3byG8~|Wi2Lu2B delta 27 hcmX?aa^8eHk(ZZ?0SF8(J8b0cW@2>NJe_HWH~?nP2ZI0r diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-39.pyc index 6acbe77c0062b427fa56648f25ff58c255530cfd..8faa08fe3bf0f62dd21613c490fe5d72769896d7 100644 GIT binary patch delta 29 jcmcaKh4Io9M(#vjUM>b8a5M7S$o-my(QWg0mS|T1e1`~O delta 29 jcmcaKh4Io9M(#vjUM>b8Fu3fnk^40Zqs!*+EYYq2g8T^J diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-39.pyc index c3ccc7c0458a53cbcc2bcb68f01a77052d045d9d..edb3d13f3549975ec074219efeadf5665326efd5 100644 GIT binary patch delta 28 icmeC4z}P*3kvox>mx}=i+>E?7a(`iCblb$v?Fay39R`g6 delta 28 icmeC4z}P*3kvox>mx}=i3@$rtck(ZZ?0SMfTyf$*zurRu9?qJd30{~Vc1_1y7 delta 27 hcmdm@xck(ZZ?0SF8(J8a~xVPSOH+`*#52LN1`27mwn diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-39.pyc index c4377d7ee2f73b1737066517745e674fc2f60c06..296b73fc67a2ef6085aa55afee760434cb7cce76 100644 GIT binary patch delta 27 hcmca delta 27 hcmaFD{e+u4k(ZZ?0SF8(J8a}GW@2>NT+fus3;1hfDE delta 27 hcmZ3vP#G>?q M#G>NV$-=Cs0qY79@&Et; delta 58 zcmcb|eUF#K`Ef`5vP*vlK^SQF=jQQE}=m_VVKN%%aq^TWkfD NB^mj7lZ9DN0|5U66LA0l diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-39.pyc index 85f654de5fd432ee126d8c67ddd77d3fc5994152..a1d5eb71b8b685d25c36cbc0cdd3621980ac20cf 100644 GIT binary patch delta 46 zcmZowXjR}&<{9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-39.pyc index 532d59f608038656be36eb0d4b10dd0a79e2eccd..13f919abf38b3ba8fdf5acc5a2f8d08d47ed5792 100644 GIT binary patch delta 26 gcmeyy{EeAAk(ZZ?0SMfTyf$)6GcvkOR%bj908)Yl?f?J) delta 26 gcmeyy{EeAAk(ZZ?0SF8(J8a~ZW@L1ktj>5I09beiZ2$lO diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-39.pyc index 2787d226c697e6d0e6f26d5453aa1aea6a47f98a..822f284cd007ccfa1024ac0f5ca3c877a90fb6e5 100644 GIT binary patch delta 27 hcmbO#K2@AMk(ZZ?0SMfTyf$(RFfqDqmSL*o1OP}K1rq=O delta 27 hcmbO#K2@AMk(ZZ?0SF8(J8a|@U}ALHEW=dE2>?!#1(E;& diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-39.pyc index 2d7c5a512b81b2415b0911fcd56df7fb3268c12e..6892e48c4ac97aa28a31781f99c0a9703ea762e9 100644 GIT binary patch delta 27 hcmbQjH-(Qok(ZZ?0SMfTyf$+0V`6mMe2U471prQ(1}6Xj delta 27 hcmbQjH-(Qok(ZZ?0SF8(J8b0M$HeHe`4p2E3jkFQ2BrW2 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-39.pyc index 238de4dfeeb20b178bd540e881c95c2fc8d39a18..7f5ddd0b6c326ff4955d9ab3db8c1c41285e6dde 100644 GIT binary patch delta 27 hcmX@Wae#w6k(ZZ?0SMfTyf$+4Ff+PsmSEOk1OQDK1nd9+ delta 27 hcmX@Wae#w6k(ZZ?0SF8(J8b0UVPfz!}fz!}FF*w=j1w0sv2)20s7* diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-39.pyc index 296c64fbdc03eb3affb679033fea8ba17023bb0b..2d069ec3158fbd686fab296e5dee710494d5a8a8 100644 GIT binary patch delta 26 gcmeC>>gD22>gD22JzRpJBEY002>m21)<` delta 27 hcmeCw=+xj&1prW#1uFmm delta 27 hcmX@gbCicWk(ZZ?0SF8(J8a}OVPtgK?7+y%3IJCL1*!l5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-39.pyc index f05fb1a461923db001a8963bc3bc2e8c0751fdd2..e5436e1170730062f9d6f383ed9b61fdc30be3c0 100644 GIT binary patch delta 27 hcmeyZ_FIiRk(ZZ?0SMfTyf$*@GBdhuu4HBs003j421x(_ delta 27 hcmeyZ_FIiRk(ZZ?0SF8(J8b06WoC5QT*=HN003$g2FL&a diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-39.pyc index e044839cd03ce87ae3cb5c866a624c00ac1942c2..83f6c159e064f6cd16c1c1aa694804d117290b38 100644 GIT binary patch delta 26 gcmdnPzK5MVk(ZZ?0SMfTyf$(lWny%je39uj08e2C^Z)<= delta 26 gcmdnPzK5MVk(ZZ?0SF8(J8a}W%Eah0`6AP609989a{vGU diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-39.pyc index 1fea39c3c27c713abb2a541f5b8d2415bd5c5937..fee91ad74bfb4775f3d78fc6d7a044273360364a 100644 GIT binary patch delta 27 hcmX@(cE*i6k(ZZ?0SMfTyf$)&F*CYtPGWu~4*+2Z2J`>` delta 27 hcmX@(cE*i6k(ZZ?0SF8(J8a|*V`g;OoW%S}9sp;32Xg=b diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-39.pyc index 00cf8ad9bc68e8e70b11d121583d74ef6c20afe0..4d5f7b8da30990ee0a59b91906022f535c97f8c8 100644 GIT binary patch delta 29 jcmbQSl5xgLM(#vjUM>b8a5M7S$o+(k(QWewwiUhrbjJu{ delta 29 jcmbQSl5xgLM(#vjUM>b8Fu3fnk^2c7qs!(GY%6>Ldpro? diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-39.pyc index 99a2b51107c10c2e756eaff7f4a71349d438b027..0e2e3fe7979f2f90fff52e9dcb0d0f76101cd41c 100644 GIT binary patch delta 27 hcmcc5cb|_tk(ZZ?0SMfTyf$**Wn^^Q{F1SZ6#!qi2POaj delta 27 hcmcc5cb|_tk(ZZ?0SF8(J8a~>%gE@m`6Xi+D*$FJ2c-Z2 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-39.pyc index 5ba8d9c4fea6a713fb3b99cd7a1ef460f3f7e2fd..9cf2abfe9d313a57a99d0c1ec6cd200b0e87c1c9 100644 GIT binary patch delta 27 hcmX>vd|sG4k(ZZ?0SMfTyf$*5V`g;Qe2e)jD*#=>2Xz1d delta 27 hcmX>vd|sG4k(ZZ?0SF8(J8a}W$IR%m`4;n6Rsdu-2lM~{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/parallel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/parallel.cpython-39.pyc index a56ed72273956faee75cb15031c920274988a07c..2d5b0edd7a2ca344f5fd3674d00feccc94e59741 100644 GIT binary patch delta 27 hcmca2enp%+k(ZZ?0SMfTyf$(_XJK^P{F&t;8vtOp2dDr5 delta 27 hcmca2enp%+k(ZZ?0SF8(J8a~B&cf)j`7_HyHUMWV2qypl diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/pkg_resources.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/pkg_resources.cpython-39.pyc index 016fab9dd361178583588ba793b96515d33af06f..d72e4adccb6f0305586a0fabaf083366cfc7faca 100644 GIT binary patch delta 27 hcmZ3>yOx(bk(ZZ?0SMfTyf$+8FfzJrp1~-}3II@k1-$?O delta 27 hcmZ3>yOx(bk(ZZ?0SF8(J8b0cVPtgKJcCh`6#!QA20Q=& diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-39.pyc index af62e225840a218c42bc45f90e742cef602254a4..5781131a39590f7654fab45f11ede04453fa9e36 100644 GIT binary patch delta 27 gcmeAa?-b`w diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-39.pyc index 6e29a2078bbeb579daf8424d15f110204485f0f2..ffec17d9f044df8462a6f5c9eeb4fc5d5184c923 100644 GIT binary patch delta 27 hcmdm`vrC6Nk(ZZ?0SMfTyf$*TGBLVsp2)OP7yw!p2CD!7 delta 27 hcmdm`vrC6Nk(ZZ?0SF8(J8a}`Wny&MJdtUoFaThS2Pyyn diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-39.pyc index a1d40458faba90ab1637044adc85c413749b5b28..1b99a21626d19a51d82a89d2b8020764a54e0ffa 100644 GIT binary patch delta 27 hcmZ2&y4sXGk(ZZ?0SMfTyf$)AVPbUKynu;Y0svT81|$Fg delta 27 hcmZ2&y4sXGk(ZZ?0SF8(J8a~h!o=vZc>xo*1OQ&m2BQD~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-39.pyc index 29143f967cfd62362b5c43555bf320c19ac462fb..8f5e47a18f4e942a15abb38e31f4639047664a37 100644 GIT binary patch delta 27 hcmX?ZbliwLk(ZZ?0SMfTyf$+GU}ALJ%);y}1^{0722}t6 delta 27 hcmX?ZbliwLk(ZZ?0SF8(J8b0s!NlmYnT6R|3;<N+|Q)Q2>@9&237z7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-39.pyc index 4bddfdb2155f10386fd12f1aeb938a57e6aa821a..d067b24bfbfba980fdd31a2b8fbe4662e6e4f128 100644 GIT binary patch delta 27 hcmdlTy*rvak(ZZ?0SMfTyf$**WoC5S{F3>SCIDz-2mAm4 delta 27 hcmdlTy*rvak(ZZ?0SF8(J8a~>%gpGq`6cruO#p7#2zvkk diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-39.pyc index 937dfd05f08c0932e3c1fd6706dd20fc44035695..69ca51521c573acd2767bb60602b6fd82407b385 100644 GIT binary patch delta 27 hcmbQQGGB!|k(ZZ?0SMfTyf$(lW@2>Pe4Z(Q9{^Q)27~|r delta 27 hcmbQQGGB!|k(ZZ?0SF8(J8a}W%*5!j`8-nqKLA_r2Lk{A diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-39.pyc index cdaae715dc997f4169886ab8a45723fd52e6e574..cda74566f8bede7b662acad3e6b19d6a81af9ddc 100644 GIT binary patch delta 27 hcmbPeH_?tek(ZZ?0SMfTyf$(#U}kjNyoNbd8UR)>26+Gg delta 27 hcmbPeH_?tek(ZZ?0SF8(J8a}$z|82fc@1-_Gyq(s2KWE~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-39.pyc index 8dfa7b180e4aadd643566a3b20242f4a50e856a5..4fa99aa1f9ee3a9666fd9995207c0fe76b3b138b 100644 GIT binary patch delta 29 jcmbO-gK^3XM(#vjUM>b8a5M7S$i0M_(QWev<`fSAYb8Fu3fnk$VXtc3O-(k(ZZ?0SMfTyf$*Du`s%AE@HXK1^`$T28sXx delta 27 hcmX>tc3O-(k(ZZ?0SF8(J8a}mV_|gJT*Pvd4FFz=2MGWG diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/__pycache__/appdirs.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/__pycache__/appdirs.cpython-39.pyc index 9f5f4099c1d1494264226ef7a68ba7cdc80d24af..f21708b1ca75a06342fc47d57cf96fd35d0c0df6 100644 GIT binary patch delta 28 icmeBQ&e*@4kvox>mx}=i+>E?7ayK(Gx-IT!4gdgULmx}=i3@$rtE?7a&PBiblZHG%efT*Y>)@9 delta 29 jcmZo$z|^*Yi93;(mx}=i3@$rtb8a5M7S$Zamg=+^8k)$T0C2*ga=ou!yxOaK7p`wIU6 delta 41 ucmZ2|jc@feKJG+bUM>b8Fu3fnk=tB~(WTj0s@++N5r~<#J4-RYm;eCtWD9-( diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/__pycache__/six.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/__pycache__/six.cpython-39.pyc index af4aea1df6d5f1c1b811e43ac39386f138ebb868..4cfe7d519be7b8a39c4fafd059980531eb7e1d4c 100644 GIT binary patch delta 36 qcmaEJjq%MjM(#vjUM>b8a5M7S$URGd(QWfGfz)8esLebn3G4vSrV5Mz delta 36 rcmaEJjq%MjM(#vjUM>b8Fu3fnk$aW^qs!)H0;$1_w>I;nB(MVj-INQ9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-39.pyc index a89cac8f935397ca09df2769fa97028ff2c3dd25..7bd0d0b673c100d9940112395b0ec94828c85bdb 100644 GIT binary patch delta 26 gcmbQsGM9xrk(ZZ?0SMfTyf$)AVq|oiJdd#+07e}J+yDRo delta 26 gcmbQsGM9xrk(ZZ?0SF8(J8a~h#K`C}c^+du08A4GTL1t6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-39.pyc index 898e5339fb395bc2e038056cd803e242d2cb0f0c..18cc992688c2db51870eb3916d5f6fa3faef3752 100644 GIT binary patch delta 27 hcmbQmGmD2ik(ZZ?0SMfTyf$(-F*3Ss?qlp>0RT+f1@`~| delta 27 hcmbQmGmD2ik(ZZ?0SF8(J8a}`Vq|pL+{f6%0svD`26g}d diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-39.pyc index 266ffbf6b60b119e68f43d85922f773e70071607..e1e51c430857660461f2c9501d9a1cd084d902c4 100644 GIT binary patch delta 27 hcmew@{#%?ok(ZZ?0SMfTyf$)gVPbUKe1OTC698nb2I&9* delta 27 hcmew@{#%?ok(ZZ?0SF8(J8b0M!o=vZ`2dqOCje_A2WS8Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-39.pyc index 4d8edd43ab9745aec31d66e34b1b3ef0c296416d..affead7ab491348d96104cb2ee6b87715578fff4 100644 GIT binary patch delta 27 hcmbQnH;s=wk(ZZ?0SMfTyf$)IGBUbtZe^Uv3II$61?K<& delta 27 hcmbQnH;s=wk(ZZ?0SF8(J8a~xWMp*N+{!qS6#!Ct24(;N diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-39.pyc index 659a4e37182f81cbe6b9c74fe21ca7b795ccb7f3..6de51af947de52a57c9259d71a2036d00af39fed 100644 GIT binary patch delta 26 gcmaFF`iPY~k(ZZ?0SMfTyf$*%GcmeN_GX$608m#2+yDRo delta 26 gcmaFF`iPY~k(ZZ?0SF8(J8a~(XJT}j?9DVC09H)~TL1t6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-39.pyc index 6fa97bacac00dad2ba8fd0c79c912cd7b8adb4ec..fbe864e367feb9367bee1ce50812d5323911562b 100644 GIT binary patch delta 27 hcmX?YbJ~VGk(ZZ?0SMfTyf$*TGcmetp3JmE8USGG2M7QF delta 27 hcmX?YbJ~VGk(ZZ?0SF8(J8a}`XJT~OJeg^SGyrE`2ZsOv diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-39.pyc index f8e040e8e1e906cf57ce7a31ce8c2d9a550531d7..c2a5488c15286686d4edf698734216c269669a9b 100644 GIT binary patch delta 27 hcmew?@L7O6k(ZZ?0SMfTyf$+GW@2>P%+8#{3IJiN28RFu delta 27 hcmew?@L7O6k(ZZ?0SF8(J8b0s&BW-knVmU@6#!@;2L=ED diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-39.pyc index e3181a92c08ce828b1e718e760445d5c34b0206f..102268e885517ee3fa70035864a8c9164c042d28 100644 GIT binary patch delta 27 hcmcbva$SWxk(ZZ?0SMfTyf$*@F*3Ssu423^003Q?2G#%o delta 27 hcmcbva$SWxk(ZZ?0SF8(J8b06V`OyMT*Y`-003kT2UP$7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-39.pyc index c3d6886bf2239b574e22ddd906b23874d37cf3b7..d871cc07a7ed51d97578d5aeede4cd47aff16f72 100644 GIT binary patch delta 27 hcmeyS@J)d`k(ZZ?0SMfTyf$)sFfzJr4q;T{2LNBV1_S^A delta 27 hcmeyS@J)d`k(ZZ?0SF8(J8b0kU}SXJ9Kxu?4*+H@27>?q diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-39.pyc index 1a97bf051b8166e6c9703c86f63e9aad3fa421a4..113efbefb4299ea30d6ff4134dc38b1ad189e871 100644 GIT binary patch delta 26 gcmbQqI+K+x&3jkr72Cx7C diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-39.pyc index 7cfafabf3251130020a7563173ea96bef981870a..926e9c53cff727c31f5c8f783e8934448cfa9222 100644 GIT binary patch delta 27 hcmbQrGnI!sk(ZZ?0SMfTyf$)MF*3Ssc4Iux0su(01)u-` delta 27 hcmbQrGnI!sk(ZZ?0SF8(J8a~(Vq|pL?8bPW1prSf1|I+b diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-39.pyc index b02d1b27157582920cd1d88a91050d077c454b1a..47e2f5ebc3303d993a8ac937a1e86b613eb7e9f9 100644 GIT binary patch delta 24 ecmeBX>Sp3jSp3jM3kCWB diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-39.pyc index 769de77cb981cd2000cb80aa6052bc2578a858f9..c0c012bc26f77316b7847b7864d4769552e1b4af 100644 GIT binary patch delta 26 gcmdnPyoZ@Pk(ZZ?0SMfTyf$*1FfzJLc3`Xl07vcxSpWb4 delta 26 gcmdnPyoZ@Pk(ZZ?0SF8(J8a}OVPtff?7&z908Qit*Z=?k diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-39.pyc index e1b442a231c17d58286d2fa4e8690fad05618fd0..baa098ef2a8762bd58971409c30d7cd3c27cc0fd 100644 GIT binary patch delta 27 hcmey*{hymVk(ZZ?0SMfTyf$*LW@L2Ryq(d51ps2Y2F(Bf delta 27 hcmey*{hymVk(ZZ?0SF8(J8a}$&B*Aoc{`&A3jk>^2TT9} diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-39.pyc index dca940b418a658cb4682f008960c85f3ceada69e..08270959a64e38c00653f40ff7f03ef2d70f16d3 100644 GIT binary patch delta 27 hcmaFN_n416k(ZZ?0SMfTyf$)IF)_MrZezO30svfC2G9Ti delta 27 hcmaFN_n416k(ZZ?0SF8(J8a~xVq$dJ+{Sd51ps2r2TuS1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-39.pyc index 9f5d517c12bebdf657d6f2d7ddff98696c6dcc0e..3ace88272979f371f91cabaf5fb10d52436ed663 100644 GIT binary patch delta 28 icmZ2lgpM(#vjUM>b8a5M7S$h{lgpM(#vjUM>b8Fu3fnk$Xudqs!zCnMDA70|@Q_ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-39.pyc index b315bd732f3ebf08e833efdc016be47423d1c1e9..595d8de545f015c548f6be4e68e6d0b418567755 100644 GIT binary patch delta 27 hcmaFL@sxu*k(ZZ?0SMfTyf$(_WMp*P{FbqT2>@UC2Q2^q delta 27 hcmaFL@sxu*k(ZZ?0SF8(J8a~B$jIoj`7L7w698sy2dn@9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-39.pyc index 8b0386efcabb801c2ea3969cffe1155dc834a9e9..d4734e1f5d85bc10e03d1b9f5120c5095360a4eb 100644 GIT binary patch delta 27 hcmX?XaM*x5k(ZZ?0SMfTyf$+GWM*{R%*tXX0svjl21Wn? delta 27 hcmX?XaM*x5k(ZZ?0SF8(J8b0s$;{}onU%#(1OQ}22E_mX diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-39.pyc index d3d70b637a06df20d78863b1e3c23443c7807243..2caafb279ee84768f91d07b3dbcb127c38a98979 100644 GIT binary patch delta 27 hcmX>jct(&rk(ZZ?0SMfTyf$+0W@L2Re4LS$9ROL^22%h4 delta 27 hcmX>jct(&rk(ZZ?0SF8(J8b0M&B*Ao`8XphI{;uz2GRfk diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-39.pyc index 4be0fd247d0541b658a3a132a5801429af733204..fe0e41572c0a74ec05547d6afe9794a0b16a66e6 100644 GIT binary patch delta 27 hcmbOvJxQ87k(ZZ?0SMfTyf$(#XJmBSyqWPnHvmw#2B`o5 delta 27 hcmbOvJxQ87k(ZZ?0SF8(J8a}$&dBJpc{AgEZU9#-2Pgml diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-39.pyc index c02a3bf348d1b222f14bce12c8c563e054d23a06..68e873d7074852a77eaeb0c89dbdeb2de45424e5 100644 GIT binary patch delta 27 hcmcaAc2$f!k(ZZ?0SMfTyf$)su`#-B4rBYz0svVM295v# delta 27 hcmcaAc2$f!k(ZZ?0SF8(J8b0kVq@Y}2Soq? delta 27 hcmaFE@rHvtk(ZZ?0SF8(J8a~B!pP{d`2%AO698xk2gCpX diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-39.pyc index 80471eab725bd55bef66da3fc6fd3de7eac1803a..6dc176a894336a610f98c25082f80366c8fce607 100644 GIT binary patch delta 27 hcmX>va$bZxk(ZZ?0SMfTyf$+4GBLVsmSi&H002^<1vdZy delta 27 hcmX>va$bZxk(ZZ?0SF8(J8b0UWny&MEXicX0RUMR1-1YH diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-39.pyc index f97845066c787b02ff2a73c574142ec5acb32675..378be0ec425661576a528d041965792be6caf4f5 100644 GIT binary patch delta 27 hcmX>gazKPTk(ZZ?0SMfTyf$(Ru`s%AmSa(30{~CL1rY!M delta 27 hcmX>gazKPTk(ZZ?0SF8(J8a|@VqtXIEXSh61^`w!1&{y$ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-39.pyc index f9d099894aec91453dfad9065e4c66eef56879c3..b29437073d4e509fc859265d904ad6d43d06cdcb 100644 GIT binary patch delta 26 gcmZ2zzR;XIk(ZZ?0SMfTyf$(#l45k5yiV#f08)Af5C8xG delta 26 gcmZ2zzR;XIk(ZZ?0SF8(J8a}$B*o}5d7ac}09bGbj{pDw diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-39.pyc index dc328c5f8019ee9693964d62236eea13eb480ddd..2f488057dd57d5c33180eb7ea277b97ca112ba30 100644 GIT binary patch delta 27 gcmZn@ZWHECyjZUo09RiI+5i9m delta 26 gcmbOhH!Y4kk(ZZ?0SF8(J8a~huE*#yd9hwG09{oFSpWb4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-39.pyc index f40aa00fbb1a866dc78ecdb1caa2de5d5b9ed351..b367e6357dfc50c85b479008932980bc267abd5b 100644 GIT binary patch delta 27 hcmaFM@s@)-k(ZZ?0SMfTyf$(_VPtgM{DHBS2>@Zq2S@+_ delta 27 hcmaFM@s@)-k(ZZ?0SF8(J8a~B!pP{d`2%Au698yF2gd*a diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-39.pyc index b02ccbd28f2e1a51d6a442cdd0cee6e47cabe14b..cdf5f2f306c8d6b5f2b5710b6b9904ad6465a48d 100644 GIT binary patch delta 28 icmZ2>g>l&xM(#vjUM>b8a5M7S$h|z1(QWeP%whm|0|g>l&xM(#vjUM>b8Fu3fnk$ZV2qs!#YnZ*Eo`3U_0 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-39.pyc index c87dd508de076ebf38da91abc390b65b8d0fe8e8..476237e9600e2522838cc50c6b9f388f67325bc8 100644 GIT binary patch delta 27 hcmaFM@s@)-k(ZZ?0SMfTyf$(_VPtgM{DHBS2>@Zq2S@+_ delta 27 hcmaFM@s@)-k(ZZ?0SF8(J8a~B!pP{d`2%Au698yF2gd*a diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-39.pyc index 2b0b6a6ab7947f8b373b7524b5b76ced21234886..8721cf36cfcf91789730344e4b43e0ea45bfe383 100644 GIT binary patch delta 28 icmbO=m2uWoM(#vjUM>b8a5M7S$Svi?=r&o+s{{aH)drCO delta 28 icmbO=m2uWoM(#vjUM>b8Fu3fnkz2}((PgrlR|x=T%Lfnu diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-39.pyc index 8642ccadf0afe7b1cfd508a77847474cb2ea0a86..a2fdde3c040bdb677468b4b1ced66b1d731cae58 100644 GIT binary patch delta 27 hcmey$@s)!+k(ZZ?0SMfTyf$(_XJmBS{F$+d2>@f72V(#L delta 27 hcmey$@s)!+k(ZZ?0SF8(J8a~B&dBJp`7>h^698%t2jTz# diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-39.pyc index e5f4ee106fa67991ea6a41609ac080bc600c2421..37a089556a21b0a66194ee13d17b108203bd5f52 100644 GIT binary patch delta 27 hcmX>ken^}ken^}b8a5M7S$o(;t(QWeI&_V!#YY8X- delta 28 icmaF2hVk7RM(#vjUM>b8Fu3fnk^5sPqs!#Kp@jg4VF{-I diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-39.pyc index 3340f4cbe59190465808b28048f5131be6f6b696..eb381f4976a25ac46e19cdcdd877fc7b5a9cd6d0 100644 GIT binary patch delta 29 jcmcb=lb8a5M7S$nDb8Fu3fnk=wnU(PeXRdk;4NhV%&2 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-39.pyc index 054ad45389624ca8f218bd4f9a8a81fcc09b90fd..aa63bec50b0d3c9e34980f6e049119f4b456b787 100644 GIT binary patch delta 29 jcmZ3vigD#CM(#vjUM>b8a5M7S$X#f_=(f4mV2ug@ba@BQ delta 29 jcmZ3vigD#CM(#vjUM>b8Fu3fnk-N}<(PeY3!5S3+dhQ5L diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-39.pyc index 425453067670b1dd63eb85880813666de8f42ffe..d92ece03e6752720c9510f2caafe59d9bc677018 100644 GIT binary patch delta 29 jcmex6pYiW}M(#vjUM>b8a5M7S$nC1j=(agfca0JNf!_!L delta 29 jcmex6pYiW}M(#vjUM>b8Fu3fnk=s?5(PeX>?iwWkh*SuG diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-39.pyc index 90af566ab8b5c594109353462331cfc25709a663..3e7bad5e29e654980c522894581887afa34017fc 100644 GIT binary patch delta 29 jcmX@Ofbrl0M(#vjUM>b8a5M7S$h}OL(QWf4-F_tidE*E$ delta 29 jcmX@Ofbrl0M(#vjUM>b8Fu3fnk$aggqs!(^y8TK3fLI8x diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-39.pyc index c2dd8c1d83a4d9ee005df299fa065c073bfb87bf..887638c6eb2da07fd099d9cbbcb1337cf2586d7d 100644 GIT binary patch delta 29 jcmeyglJV0@M(#vjUM>b8a5M7S$Zci7=(gF-V2ug@fhY&@ delta 29 jcmeyglJV0@M(#vjUM>b8Fu3fnk=x3E(Pgun!5S3+hn)y; diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-39.pyc index aeb09f71053278b6a49159d9bfae314496e79c53..2dd17a18b704bbad762d6d4844b5c5337295424e 100644 GIT binary patch delta 29 jcmaERmhtUbM(#vjUM>b8a5M7S$bH_D(QWf>OCenVj#3EP delta 29 jcmaERmhtUbM(#vjUM>b8Fu3fnk^8(Qqs!*omO{D!l*b8K diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-39.pyc index f66bbb87fc0cea94b0f23f3afee51163c6b485fa..d4777fbb716d17c8880ba1c24bb13e4f3566942f 100644 GIT binary patch delta 29 jcmeykkn!U}M(#vjUM>b8a5M7S$Q_}_=(agUuU82GfO!Y@ delta 29 jcmeykkn!U}M(#vjUM>b8Fu3fnkvl?<(PeXrUat}WhVBS; diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-39.pyc index d9c1d675443c4692adfe61501b67b539485cf285..df4785e59ac7252b7f9b44630cb34b18544ee4a2 100644 GIT binary patch delta 29 jcmcb(fbrr2M(#vjUM>b8a5M7S$h}pU(QWfV-3dwnei#UE delta 29 jcmcb(fbrr2M(#vjUM>b8Fu3fnk$bByqs!)lx)YQDgpCO9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-39.pyc index 996fd0c2aec7f096ce910f3b58b2ac8188ae500a..60aa9365588663cd9b29754a71bbe8731e09b658 100644 GIT binary patch delta 27 gcmZn?ZxZKDrcvg@*k(ZZ?0SMfTyf$+GXJmBS%*}L&4FFpE2ATi> delta 27 hcmX>rcvg@*k(ZZ?0SF8(J8b0s&&cSqnVabl8vtQ&2N?hW diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-39.pyc index 961ee83b9bc7f3212286ca5433a86db78878cb8f..642e34c69a3fb46987b121e4c3086177f2afa32f 100644 GIT binary patch delta 27 hcmaFF@rZ*vk(ZZ?0SMfTyf$)YFfqDqE@67d2mo3w2CM)8 delta 27 hcmaFF@rZ*vk(ZZ?0SF8(J8b06U}ALHT*CB@5ddJK2P*&o diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-39.pyc index 3cc1e1a843543614e6e724bad4a6f0bdd31e0529..c15012a4badb2eeb62cc9bf6e917fba839aca41b 100644 GIT binary patch delta 27 hcmcaxb+?K;k(ZZ?0SMfTyf$(#v}SbMyw-XHBLH+s2rK{q delta 27 hcmcaxb+?K;k(ZZ?0SF8(J8a}$XwB%dd9C#ZMgV%g2&(`9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-39.pyc index f4ce0555e27ba8f3eac896031f9d2d5b18f7519a..3ba2bbb6570bad2fb38b39093d3e63a3f62dd66d 100644 GIT binary patch delta 27 hcmZ1^u}FeDk(ZZ?0SMfTyf$)MGc&qvc4xlL0RT<#1?T_( delta 27 hcmZ1^u}FeDk(ZZ?0SF8(J8a~(W@dER?9P0f0{~QI24?^O diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-39.pyc index 07b8b010ed1d5359b1e672efb47687fbcf2c6a01..95a33c85afb5fdea166eb589f5469476aff19dcb 100644 GIT binary patch delta 27 hcmbQuJDZm~k(ZZ?0SMfTyf$*%u`s%A_F@TS0su*N1v~%% delta 27 hcmbQuJDZm~k(ZZ?0SF8(J8a~(V_|gJ?8Oqu1OQL#1-k$M diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-39.pyc index 1ecbc42d9f76aa6ae82a1dd4ecf313d8e2fbb530..0bf524c3b6c0e9d6db9f2d26e1833ed63d90b2af 100644 GIT binary patch delta 27 hcmZ1_yh@lmk(ZZ?0SMfTyf$*@GBLVsu4FP~2LMmN1*HH0 delta 27 hcmZ1_yh@lmk(ZZ?0SF8(J8b06Wny&MT*+j}4ggj)1|$Fg diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-39.pyc index a928fdfd14e9d5847bdfcbee0cd097764363f216..d0af7ea742d2d7576ae2b8d0a7fe77f4dc2b69bf 100644 GIT binary patch delta 27 hcmdm|yHA%pk(ZZ?0SMfTyf$)AW@B{QJfBTo003I!2220| delta 27 hcmdm|yHA%pk(ZZ?0SF8(J8a~h%*N=lc|M!G003cF2Fm~d diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-39.pyc index d324e79af51dcdb00b83f73c13e58f38cc710a8f..d7d392390ab8504c94ae60cbd93e7a5d82a3a0bb 100644 GIT binary patch delta 27 hcmdnbzn`Bwk(ZZ?0SMfTyf$+GU}SXL%)+#r6#!RN24nyL delta 27 hcmdnbzn`Bwk(ZZ?0SF8(J8b0s!N};cnT2ULD*#=}2IBw# diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-39.pyc index 902d6378f6163b9a2a8656d375fc792c92c182a5..7444ba734baabd554af7d60047965b78cad81ef7 100644 GIT binary patch delta 26 gcmZ3-ypEYWk(ZZ?0SMfTyf$(hGBUbNwq+~?07V7`EC2ui delta 26 gcmZ3-ypEYWk(ZZ?0SF8(J8a}OWMp)iY|B^(080D?s{jB1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-39.pyc index 9dd5f573e8a5939f170b92da6dbaa5f341c64a8b..48a359574249602df46e97f56d08465745eaae6a 100644 GIT binary patch delta 24 ecmdnZxSNqXk(ZZ?0SMfTye4wnGP+IlECK*M`vo@u delta 24 ecmdnZxSNqXk(ZZ?0SF8(J51!ZWptV7Sp)z=@ddU3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-39.pyc index d6d3890db7a63b82b4f5cd3f7f9555ad46ad2ba3..ff2df08253facd5a80a17d15e8d1aaadc5257b86 100644 GIT binary patch delta 27 hcmew<@>7I6k(ZZ?0SMfTyf$+8vM{=Bp2_ln6#!!p2Q~lz delta 27 hcmew<@>7I6k(ZZ?0SF8(J8b0cWnpyLJd@=CD*$PQ2ekkI diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-39.pyc index 32d7aabb290f6ef3c1823198d305eeb712f7035c..db6629b694d817650c5dea1f06491e943b04718d 100644 GIT binary patch delta 24 ecmX@Wcz}^Rk(ZZ?0SMfTye4wnGP+IlEC&ES<^@Io delta 24 ecmX@Wcz}^Rk(ZZ?0SF8(J51!ZWptV7Sq=b0+y%t| diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-39.pyc index 9a2f269717a75657a5de054634d77bbb3f9ca376..f2ba5caf140fa6006a10d4fa0c0d978108c8b8f2 100644 GIT binary patch delta 27 hcmext``MN|k(ZZ?0SMfTyf$(#07ef5JOBUy delta 26 gcmdnYyqTFhk(ZZ?0SF8(J8a}OVq|ogY{ys%089l1y8r+H diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-39.pyc index 3bc0e232a92cea0751934a12074785f78e7a0653..f9b7aaff20d055df233ce4131cf053c51ca82e07 100644 GIT binary patch delta 27 hcmbOtIYp8?k(ZZ?0SMfTyf$(#W@L2Ryq@tX7XVO_2BrW2 delta 27 hcmbOtIYp8?k(ZZ?0SF8(J8a}$%*g1nc|GG(E&x{t2PFUi diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-39.pyc index a2a9151643f605c3b303ace95d6a042b400a6a65..44a760e6a314a0e0633ce45861cdc15f19d48441 100644 GIT binary patch delta 27 hcmZp(X|v%@AtQzhaV+1^`wW29N*% delta 27 hcmZp(X|v%@vO$GAk(ZZ?0SMfTyf$*jFfzJr&R{$t002~(22TJ0 delta 27 hcmdm>vO$GAk(ZZ?0SF8(J8a~RVPtgKoWXcP003JK2F?Hg diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-39.pyc index 516b98d3903b409f8cbf045bad8f7d52eba2bcd3..475b6d73f3b988ba802ff1a3b10178f51ca35fc3 100644 GIT binary patch delta 27 hcmbQiF@u9Uk(ZZ?0SMfTyf$(RGBUbtmSz0S1OP_L1$F=c delta 27 hcmbQiF@u9Uk(ZZ?0SF8(J8a|@WMp*NEX(+t2>?w$1@!;` diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-39.pyc index 441f840dc5d50a88bf6ebc7282cb1962caa8e6d9..4d3435cd78f4c4668916ed5471474a893ca55c6a 100644 GIT binary patch delta 36 rcmbRCn{nE2M(#vjUM>b8a5M7S$UTLF(QWer4)$WksLd;?-!TFJ!#WEK delta 36 rcmbRCn{nE2M(#vjUM>b8Fu3fnk$VaUqs!(69PGu6w>Gb+e#Zy^&?pQF diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-39.pyc index c84bfd5d2eb656d4d2bbde37a2265311d8c2b0a6..51ae90e217b3ae4c1af8ef3ac1f92ea6086c8fcc 100644 GIT binary patch delta 29 jcmaEHn(4)9ChkODUM>b8a5M7S$gRuD=(gFCb^QVWgg*!} delta 29 jcmaEHn(4)9ChkODUM>b8Fu3fnkz1FQ(PgtG>-q%%inIu^ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-39.pyc index 31357b99f20ffa4f44539ff562aa301ac752f3a1..6e1d48657f0849bccac32140918d5c95a85ec9b3 100644 GIT binary patch delta 29 jcmZo{XKZX|`XwV1F delta 29 jcmZo{XKZX|Z$$`A diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-39.pyc index 951f0e4cd61f8859b94d998773d37863390db0c6..bd39e53754223a707af5012fb0c034857f0a0e95 100644 GIT binary patch delta 29 jcmaF5is|VpChkODUM>b8a5M7S$o-C$(QWfD*6e-&h4~2= delta 29 jcmaF5is|VpChkODUM>b8Fu3fnk^3Dhqs!)Btl9kljBW{* diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-39.pyc index f15f30c6c760ed6b416d3c6e7067ae2cbada7152..298b513d048bb575a8f7e003419a1f5201f70a8c 100644 GIT binary patch delta 27 hcmX@%f5M+Tk(ZZ?0SMfTyf$*bV`g;Q{EPXVG5~3Q2o?YU delta 27 hcmX@%f5M+Tk(ZZ?0SF8(J8a~B$IR%m`4{s!WdLvU2$cW; diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-39.pyc index fb2ba57cb05c13235c4bc40cbb196783558d4ce2..1446f92acbfe9e39d580bd7f6f30627e7e8e4946 100644 GIT binary patch delta 27 hcmX@3bVi9gk(ZZ?0SMfTyf$)AWMp*PJeP4jKLA`~2Gall delta 27 hcmX@3bVi9gk(ZZ?0SF8(J8a~h$jIojc`oC6egIb8a5M7S$j#5f=(bs!Wk)gqexV1P delta 29 jcmcb7p7HW|M(#vjUM>b8Fu3fnk(-}|(PgtV%Z_9Kg%$`K diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-39.pyc index 86b38ace5444c89c1453908367c5caf09e9251b8..82c6f81eb909cb707b63072bf42c15f94c315f75 100644 GIT binary patch delta 27 hcmewr`YV(>k(ZZ?0SMfTyf$)+Ff+PsR$#uR4ghJ~2I2q! delta 27 hcmewr`YV(>k(ZZ?0SF8(J8a|@VPbb~cPVk(ZZ?0SMfTyf$*{vNF1DwqzAi0{~#S1^EB~ delta 27 hcmX>bb~cPVk(ZZ?0SF8(J8b0EWo2~PY{@F31^{O*26zAf diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-39.pyc index fa760fd1083ccb2cc0b908bf1b664ded26f445e9..7f560ce70d4c69fbfa885e89265a95ffcc8c76b7 100644 GIT binary patch delta 29 jcmaDoi~02|X6{5@UM>b8a5M7S$o-Ft(QPvqcj6%cflmlo delta 29 jcmaDoi~02|X6{5@UM>b8Fu3fnk^3JPqswM4?!-d?hr|fj diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-39.pyc index dd543d6076d35cf18eafb6e49350cfc85b102ff1..87813164d9f08f835e69035fddc4f4823fa7aec8 100644 GIT binary patch delta 29 jcmex7kMZ+7M(#vjUM>b8a5M7S$Q{7K=(ahAMcf+zeNP8N delta 29 jcmex7kMZ+7M(#vjUM>b8Fu3fnkvo8e(PeWCi?}xcgTx2I diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-39.pyc index f1478a67cb8b1678427e7cf912041a69a1f3ccd5..7a54b9c3a1cf1581c5ef6411cc605e03da519213 100644 GIT binary patch delta 29 jcmX?eh4IW4M(#vjUM>b8a5M7S$o-L((QWfzR{sb8Fu3fnk^3Vnqs!*Mto|tgk5UPB diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-39.pyc index c07c9061180b392bdd5fbe6bf676fa2413789724..97a8bb5c967f36664ee5fccf3d00e6ad7c1ee51c 100644 GIT binary patch delta 26 gcmcc3e4Cj&k(ZZ?0SMfTyf$)&GcvkOPG+nC08e=Z*#H0l delta 26 gcmcc3e4Cj&k(ZZ?0SF8(J8a|*XJmAloXl7O099`WSO5S3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-39.pyc index 0e740e5b2930edee6a704d7a337ce03ced20eda5..6adee6e10a69d4173de41c7eb245a9b05aed7404 100644 GIT binary patch delta 27 hcmX@kah!uYk(ZZ?0SMfTyf$)AWMp*PJeP456985;27>?q delta 27 hcmX@kah!uYk(ZZ?0SF8(J8a~h$jIojc`oBBCIDQi2Lb>9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-39.pyc index 14373a7bd3e9bae66984ff288237085ede395ec2..1cb466fcba714f88aeafbedbb36661953d369303 100644 GIT binary patch delta 29 jcmZ3wl5y!uM(#vjUM>b8a5M7S$i0}A(QWg3)^C0Qbk_(+ delta 29 jcmZ3wl5y!uM(#vjUM>b8Fu3fnk$W*Kqs!*?tl#_qdrSz% diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-39.pyc index 45787e1c3fbc59a94759a7d466b0cbaec5396aa8..053d48202a456d2967489b007dd07b412179ef20 100644 GIT binary patch delta 27 hcmca!bG?Q;k(ZZ?0SMfTyf$*HurRu9HegY=0sv{|25bNT delta 27 hcmca!bG?Q;k(ZZ?0SF8(J8a}uVPSOHY`~&!1pshc2I~L- diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-39.pyc index 470f313d4df5797684468093870075d86d761052..59d728a05a37e38e60fad594c96b80928ff793ea 100644 GIT binary patch delta 29 jcmZpE#oYXgnLCk}mx}=i+>E?7a_?qmblZHK-R3O-d))}4 delta 29 jcmZpE#oYXgnLCk}mx}=i3@$rtH?~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-39.pyc index f058f3abfaa289a905ec3e932f7070622662e13c..c76bdfb913aa99c928b721e806ff826d71d5f8da 100644 GIT binary patch delta 26 gcmeC<>f_>0f_>0b8a5M7S$j!;j=(bsuIWZ6beEJ6+ delta 29 jcmeyig7Mo5M(#vjUM>b8Fu3fnk(-m5(PgtJb7CL>gKr0% diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-39.pyc index ac6a73c2dccc38e99eb1d6a550006d6b5ac8c500..ae405cdcd2baa42a9b124818f9a2c85900e86be4 100644 GIT binary patch delta 29 jcmZ3wjcMsNChkODUM>b8a5M7S$bFKH(QWfpwty)Bc&-Rh delta 29 jcmZ3wjcMsNChkODUM>b8Fu3fnk^3YYqs!*2YyndMeE?7a=Rrnx@`_hJ~bZzYm5jS delta 29 jcmbQ!#xkdkg*%a#mx}=i3@$rt_1R_;VzUM>b8a5M7S$i11B(XDwu>-PPuj5CdSSd;T}@{4Y<6lYeYZcnjf H6xRX(w|5YT delta 52 zcmex;jP>_1R_;VzUM>b8Fu3fnk$W>Mqf7IC*6sUQ8D|>vuoP!jrQTvq&dpcv6r%k(ZZ?0SMfTyf$((F)_Mr=40B;1^`h^1(E;& delta 27 hcmX>pcv6r%k(ZZ?0SF8(J8a};Vq$dJ%*V8w4FFfc1`z-N diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-39.pyc index 2640f0c713acd6bbda56df65e8203cf0712b77a1..f831924d2b3821d86daabba66bc3e35b7cd39324 100644 GIT binary patch delta 24 ecmX@Wcz}^Rk(ZZ?0SMfTye4wnGP+IlEC&ES<^@Io delta 24 ecmX@Wcz}^Rk(ZZ?0SF8(J51!ZWptV7Sq=b0+y%t| diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-39.pyc index 0c52b583b413ee5dd1411311ae9745f8f9a68c87..91af01e9a305038a559a8943ae3c20085f0fe101 100644 GIT binary patch delta 27 hcmZ3)wTO#5k(ZZ?0SMfUyf$)6FfqDqR$=?(R1|R?c diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-39.pyc index e8ab5343a8c96f047db6fb82dba3be25ad59f895..1f92ed0b8129ada676d2b8e199ccb27c917a1a2f 100644 GIT binary patch delta 27 hcmcb|c8`rak(ZZ?0SMfUyf$)6FfzJrR$;Va0svEm1xx?{ delta 27 hcmcb|c8`rak(ZZ?0SF8(J8a~ZU}SXJtiou;1OQp=12L3IJDT1)%@{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-39.pyc index 9e0a5674b7459c28fb5d6759ddceb157293ad63b..317e39500f0d0dfb3540e917f1f5a56546dcb479 100644 GIT binary patch delta 26 gcmdlavPpzHk(ZZ?0SMfUyf$)wVPbUK#B9V408a1)#{d8T delta 26 gcmdlavPpzHk(ZZ?0SF8(J8b0s!o=vZiP?x9094rqMF0Q* diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-39.pyc index 3587bebbc73db2ffdd0c4f95d14a75843e9c3347..35d67cf842af93faa27caf7727c00e8fe85666c0 100644 GIT binary patch delta 27 hcmX>sdRUY@k(ZZ?0SMfUyf$(lVq|pNe2(!e2LM|Y2T1?` delta 27 hcmX>sdRUY@k(ZZ?0SF8(J8a}W#K`Ef`5fa{4gg_%2gd*a diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-39.pyc index 84dce3da5db479f33ae8e1658ecd3cd361562c36..f9b3674916e7073171acb8702f1cde589078f9a2 100644 GIT binary patch delta 29 jcmaFY%=oUEkvox>mx}=i+>N|8a_bu~x^1>L*enPDcjyOv delta 29 jcmaFY%=oUEkvox>mx}=i3@$rtb%BdJk(ZZ?0SMfUyf$*nFf+Ps)?n6P0sv8)1u_5t delta 27 hcmcb>b%BdJk(ZZ?0SF8(J8a~ZVP@M071S4>Hq)$ delta 26 gcmZ3;zL1?ek(ZZ?0SF8(J8b0UWM*`kEXv#i07s_JzRKVVj50su=r1_1y7 delta 27 hcmZqVY2@Kf#?9!m`4P7iBLHoU2b%x@ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-39.pyc index 603089cb16115fb49edc37ac817ffc733052e852..adfbd93c51552133151f8a0baa4f3cbbb7d2f1b0 100644 GIT binary patch delta 27 hcmZ1zu_l5$k(ZZ?0SMfUyf$)|Ff+PsZeU)c0RUeu2H*ey delta 27 hcmZ1zu_l5$k(ZZ?0SF8(J8a}GVP0{~@|2VMXG diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-39.pyc index ee7e9e0d831b685ea625a866b02d4929554e7505..a3d5e92bfdb97dd8c2ea097dc9130314b066f69f 100644 GIT binary patch delta 27 hcmaFr`P7p;k(ZZ?0SMfUyf$)gVq$dLypKs;2>@x{2O|Ig delta 27 hcmaFr`P7p;k(ZZ?0SF8(J8b0M#Kh>bc^{Ly5&&>T2cZA} diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-39.pyc index ca714dcb4d31bf3d7255427bd5c465c093544f42..11858ddeec2515aa25da9f442690349cb8ca1bb6 100644 GIT binary patch delta 27 hcmZ1)vowY~k(ZZ?0SMfUyf$*jurRu9&S2TA2>@Mx2EG6Q delta 27 hcmZ1)vowY~k(ZZ?0SF8(J8a~RVPSOHoWZhJ698l82Rr}( diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-39.pyc index b29ef655e5098645fa7738ee8dd49807a827d88b..be930aba191f6f2e798e982dc97d3c5bd679c8d6 100644 GIT binary patch delta 27 hcmX?-dL)%Qk(ZZ?0SMfUyf$(du`s%Au48f20{~^h2FL&a delta 27 hcmX?-dL)%Qk(ZZ?0SF8(J8a}GVqtXIT*u<32LNm-2Sxw@ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-39.pyc index f22cc0db991f9e46d6318490d355c6534762864a..a8e10b0c70491001a6d069b35cbc9dce1cdc32a5 100644 GIT binary patch delta 27 hcmbOxKTV!Hk(ZZ?0SMfUyf$(turs=C&SBT$002#w1%Lnm delta 27 hcmbOxKTV!Hk(ZZ?0SF8(J8a}mU}tpMoWrig0RU6}1^xg4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-39.pyc index 2f29324d643074c11f7ec37ffc2258d58973a269..1d0e89e8b734e82e7f6d64805652b71f874a8e84 100644 GIT binary patch delta 27 hcmX?WcGiqLk(ZZ?0SMfUyf$*1Ff+Psc3|d}003IA1+M@A delta 27 hcmX?WcGiqLk(ZZ?0SF8(J8a}OVPW5{8dH(OOgj5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-39.pyc index 25b5b052b69fcba561e3b9870e74cec6ab4af792..69372e06b549b202c92ae9fd73873ecc6141a14f 100644 GIT binary patch delta 27 hcmdntzQdh6k(ZZ?0SMfUyf$*DGBLVsE@X071OQyD21)<` delta 27 hcmdntzQdh6k(ZZ?0SF8(J8a}mWny&MT*&0E2moUf2FL&a diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-39.pyc index 07b39ae1288e6b9f5e5134d75393b38611f05db5..afd89d933d1a4a279e9185932ce822d1a8aadafe 100644 GIT binary patch delta 29 jcmeyghVj!HM(#vjUM>b8a5wVW$UWPi(QWf`|I=&$h&KrN delta 29 jcmeyghVj!HM(#vjUM>b8Fu3fnk$bj3qs!*y{-@ahj-Cm3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-39.pyc index b6e9d0c8f5b9a0ce955f989955e22fa9b1a26454..881cfbb78f6b00104b1a8931fb49f673c58d049d 100644 GIT binary patch delta 27 hcmdnPw}+2Ak(ZZ?0SMfUyf$**U}kjN{De7z830&72D<!OZBg`3Z9bGXP$v2RQ%$ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-39.pyc index 6f7f580e52749a90c2bca195ec78ad6115788281..36981d92485d2dc83231d2456e3f1d25242cc548 100644 GIT binary patch delta 24 ecmX@jc$$$rk(ZZ?0SMfUye4u7FuF~Q$p-*Idj)#{ delta 24 ecmX@jc$$$rk(ZZ?0SF8(J51ybV04)nlMet!W(D~G diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-39.pyc index 1e69f7e5e07f020799bfa7d49bb8333af8acb01b..93df27eb2447703101964e4f49b3de3b4f7c41d5 100644 GIT binary patch delta 37 rcmezTmE-eQ4(>!=UM>b8a5wVW$o-F#(XE+_tDTFBaXS|m(@O&Y-?s`^ delta 37 rcmezTmE-eQ4(>!=UM>b8Fu3fnk^3Jfqf0XvS34IM<904Crk4f)>JAFk diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-39.pyc index 3f788db8ed1a2dd60465d9a9a8c1445eccbdcb8f..0f538d56e49c4bcd24b2971ee60e03c1a649e0ab 100644 GIT binary patch delta 27 hcmeyz^^c1?k(ZZ?0SMfUyf$(hGcmetwr8?u1^`?_1=0Wj delta 27 hcmeyz^^c1?k(ZZ?0SF8(J8a}OW@2>NY|muR3;<%O22cP1 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-39.pyc index 1211c28db4f17fd8eb30f5e4c4d93a99e117140b..b6ed1859890db13961be2552900916f3c3813834 100644 GIT binary patch delta 24 ecmcb_c!`lak(ZZ?0SMfUye4u-FuF}l$pZjF`~{c* delta 24 ecmcb_c!`lak(ZZ?0SF8(J51z`V04+7k_P}s=LQx4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-39.pyc index 9286f9d05fbed7b15b2a088cdc9ca5bc237e0ab5..51e4113c738cfbbe00e7cc8acbe3f2425e4859f9 100644 GIT binary patch delta 27 hcmdnOw}p>8k(ZZ?0SMfUyf$*bWMp*P{FTw36#!Q^2C@JE delta 27 hcmdnOw}p>8k(ZZ?0SF8(J8a~B$;jxk`75J6D*#=d2QUBt diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-39.pyc index aa59ab9f840e1cf22df4e03b0d38a36ffc7196c9..0eefb60edf89bcdc9746f69a194ab951da990e7e 100644 GIT binary patch delta 27 hcmZoLY%t_bb8a5wVW$Q{DO=(ah5>0c@Ug*pg> delta 29 jcmcb2f$`o2M(#vjUM>b8Fu3fnkvoKm(PeW2)4x;zi=hbt diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-39.pyc index dab6b885a6ce59d1c8d436588cbd459669251029..02e6c12be053749b000c6673b1c84c74ffdc041a 100644 GIT binary patch delta 26 gcmX@ca*TyLk(ZZ?0SMfUyf$+0WMp)ke3Y>f08iTne*gdg delta 26 gcmX@ca*TyLk(ZZ?0SF8(J8b0M$;jw3`6y!}09C{W{Qv*} diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-39.pyc index 59d0da997b26db01326c9402bd97e6f4a30fb82e..109cda6184152095749939ea02bcd38663e271fb 100644 GIT binary patch delta 26 gcmdnSyp5SVk(ZZ?0SMfUyf$)MFfzJLc3~_607mfzOaK4? delta 26 gcmdnSyp5SVk(ZZ?0SF8(J8a~(U}SWe?7~nI600oH|WB>pF delta 84 zcmexn@y&uek(ZZ?0SF8(J8a}OWoC5Q?8y9-Q=PTg*wUcl7JFi1QF4Zv$t~7`f@C1Y h4yJNaZ?RQan8ll!Z1&~t=V40(>Mx4f{77;N696s!8Rh^0 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-39.pyc index 98756f15ccbd87f8c59c5803a317de81ddbd9ac5..38629b42fafeeb362c1fd1abbb3d9cb1fbfca32d 100644 GIT binary patch delta 27 hcmeyV{8O1bk(ZZ?0SMfUyf$(_WMXvN{FaG_9{^~a2QL5s delta 27 hcmeyV{8O1bk(ZZ?0SF8(J8a~B$i(Qf`7IL(ij`4j7BIRJE?2-g4r diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-39.pyc index 78a7a2bb341710b7c98e91a3c2d1ecb885d0283d..f38487f41616ce470ec602e8205ed16b4729528d 100644 GIT binary patch delta 27 hcmew-_fL*Hk(ZZ?0SMfUyf$)cvM{=BHf8bT1^{2$1^fU2 delta 27 hcmew-_fL*Hk(ZZ?0SF8(J8b0EWMOpKY|7%v4FG0A26_Mh diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc index 489dcb78daa3a379b065ecf7117f0c865ef8d015..c7a86c433a1d19b8c93d85f7abe6ff237a89640d 100644 GIT binary patch delta 29 jcmdnBmT}iwM(#vjUM>b8a5wVW$nDC^=(ahKIWrglbV~;^ delta 29 jcmdnBmT}iwM(#vjUM>b8Fu3fnk=vD-(PeWWb7n9Ada?(w diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-39.pyc index e8be85646010eb558c7d9009984983f38f0645f4..20cde55240d5f91dd72fa8051fe10088a701e4cc 100644 GIT binary patch delta 56 zcmewv|1+LDk(ZZ?0SMfUyf$*{vN5`Cwq#o?EwBVARI~_0%mWcCHh)tT<6(^2%&Yf? F5dfo54+sDN delta 56 zcmewv|1+LDk(ZZ?0SF8(J8b0EWn*;NY{|A(T3`iGsAvg@m04PGq2to FMgY4_5C#AM diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-39.pyc index ea53f2e48291f079c34fce39b34726676b99b89e..1900f4ac1a5229f2d748443c2c3110e16578f855 100644 GIT binary patch delta 27 hcmbO%Gg*c^k(ZZ?0SMfUyf$*@GBLVsu4J0U4FFBL1@`~| delta 27 hcmbO%Gg*c^k(ZZ?0SF8(J8b06Wny&MT*)+x8vs-x26X@c diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-39.pyc index 300d4f52c594a401e9a2da6558954015411926d0..808730cbfd9c192b504aaa300030e797451cd6d6 100644 GIT binary patch delta 27 hcmcbSb|Z~Dk(ZZ?0SMfUyf$)QXJK^P{FtRw4*+k22kQU; delta 27 hcmcbSb|Z~Dk(ZZ?0SF8(J8a~>&cf)j`7ukW9sqUf2x$NS diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-39.pyc index a075bf6686ae1bf2f24654692f0deb29b179c1f8..6c57006784118ecdd49ac55db184ece2f0d800ac 100644 GIT binary patch delta 24 ecmdnUw2_HBk(ZZ?0SMfUye4vQVRV~#pb!8+9R?Es delta 24 ecmdnUw2_HBk(ZZ?0SF8(J51!>!ss&bKp_A{2nLY= diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-39.pyc index 29f6b6bb33006ead61724864d71250fd41c9d756..b5f3b60d29f6b3b9b46bb2a0d2f4f2da4af36b9e 100644 GIT binary patch delta 27 hcmew){YjcTk(ZZ?0SMfUyf$*5V`6mMe2Ynf8vtaz2J-*_ delta 27 hcmew){YjcTk(ZZ?0SF8(J8a}W$HeHe`4*D|HvnrS2XO!Z diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-39.pyc index 6e31d3974124ed598467e9e2cd240a3cd6c7bef7..38e4b34fb72890766b2d4f3ed437e7e2242bd038 100644 GIT binary patch delta 27 hcmeyX{#Ttlk(ZZ?0SMfUyf$*1vopGFc4ptj0{~+p2A}`{ delta 27 hcmeyX{#Ttlk(ZZ?0SF8(J8a}OXJ>TT?99H42LNe_2Oa2ABW< delta 27 hcmeBX?`G#tVjXRN-mx}=i+>N|8a$n?ObZfrLv;8g)qf04c)OMvN#)GT?|EvsW delta 41 ucmaFd&-S>VjXRN-mx}=i3@$rtua$JNvk(ZZ?0SMfUyf$)AVPbUKyntyrI{;YA2BrW2 delta 27 hcmX>ua$JNvk(ZZ?0SF8(J8a~h!o=vZc>&XMb^u>82P6Oh diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-39.pyc index 06bd1987683eab84eea68d504db639d8c77405c6..c697f2121d58173ce04e415ba28c8d5fcce1a863 100644 GIT binary patch delta 27 hcmdnVy_1_ek(ZZ?0SMfUyf$(NGBUbtj%AEt0RT`Y1)=}| delta 27 hcmdnVy_1_ek(ZZ?0SF8(J8a|*WMp*N9LpHP0svNx1|R?c diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-39.pyc index 8ef67b378b557364ea2725a53ce80669dd85adb0..489fa5266f6e7792d002f76a8111eba41dfe2358 100644 GIT binary patch delta 27 hcmaFH^^A)f_>0AtQ&tWQJ0su;&1>OJv delta 27 hcmeC<>f_>0mx}=i+>N|8a!+PublW_ib(swSa+(Lc delta 29 jcmX@w!g#cWkvox>mx}=i3@$rtoOYvc>xGI diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-39.pyc index 96e2c493c4f3a1c1e29449f9e398c789d2aa2b56..d0c8f9857cf2d64ffe0b1a5a4d3f8773e0c12afe 100644 GIT binary patch delta 27 hcmdmPvfYF`k(ZZ?0SMfUyf$(_;AV8&{D#|`4**|T2O9tY delta 27 hcmdmPvfYF`k(ZZ?0SF8(J8a~Bz|H8g`3<)>9{^>*2bll> diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-39.pyc index ce3c432ef515889b324d0162358da2f79fb8abba..91eb5622a7f631b2d51de7ba71180302acb9c1fa 100644 GIT binary patch delta 27 hcmZp6YMMb8a5wVW$Q{qh=(ahVRoDdpefb8Fu3fnkvpE1(PeWstFQ|Igk%TR diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-39.pyc index 23f04695f4b167dacdd73ed05178b1d89911e47e..c2de08f62709794b3affd483d4da730a86531490 100644 GIT binary patch delta 27 hcmbQLHC2l{k(ZZ?0SMfUyf$)+vM{=BR%H1i002!j1qc2tZzk(ZZ?0SMfUyf$(Rurj)BmSNRo0{~Gs1tkCg delta 27 hcmX>qc2tZzk(ZZ?0SF8(J8a|@U}bdKEW@hF1^`!{1)~4} diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-39.pyc index 8148c1da4cf9d5fc61fb4ae56ca18be1856c8b1d..6c4ed09311fa0d5bee02f5611ba8280a23be0361 100644 GIT binary patch delta 27 hcmcb{evO?wk(ZZ?0SMfUyf$*zGcvku?q>960svQZ1|0wZ delta 27 hcmcb{evO?wk(ZZ?0SF8(J8a~xXJmBQ+|B6C1OQ#z2Aco? diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-39.pyc index 1315d2c4c8e934807242e10a0b3e81e1915445dd..6922912ce1aab78444ed41d90509d84ebd3ade53 100644 GIT binary patch delta 29 jcmeC%&)B!0kvox>mx}=i+>N|8a<5@yblbdx?OFr?bj%1u delta 29 jcmeC%&)B!0kvox>mx}=i3@$rtmx}=i+>N|8a<{TEx^14w_QMSTYJ3N@ delta 29 jcmeC2&Dc4ckvox>mx}=i3@$rtb8a5wVW$bFri(QWf%cEex*btDJu delta 29 jcmbQTjd990M(#vjUM>b8Fu3fnk^4G3qs!*U?1sSrdy5Ea diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-39.pyc index 930d847f283a934a845dad7ec0d8ebbd245a4c33..cc28132dbe226d4e33355a2d8ef0d756f2ddf7f8 100644 GIT binary patch delta 26 gcmcb{a*c&Mk(ZZ?0SMfUyf$)QWMp)ke3!8j08{%0#{d8T delta 26 gcmcb{a*c&Mk(ZZ?0SF8(J8a~>$jIn2`7UE609oV*MF0Q* diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-39.pyc index 7b94e6a06b6f829b1814edef35ae24803fdd617e..e519d4b618ccaaf2bf53539a7206cdd8ba5f2595 100644 GIT binary patch delta 27 hcmexn^v#Gnk(ZZ?0SMfUyf$*nF)_Mr)?)Gz2LNG@1_=NF delta 27 hcmexn^v#Gnk(ZZ?0SF8(J8a~ZV`6mKti|Lb4ghEN28RFu diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-39.pyc index 4c5e34b1a431a04abad981185c3f6d6aeb04f695..4b36b0f33cca7fe9e1e84b47cf3e152b3e5beb62 100644 GIT binary patch delta 27 hcmew+_)U;Ik(ZZ?0SMfUyf$)2F*3SsPGg+F4gg-325|rY delta 27 hcmew+_)U;Ik(ZZ?0SF8(J8a~RVq|pLoW?kT9ROtg2JZj> diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-39.pyc index 8353760c666b6d56e5c26b78d3bece4952f292b7..76b53e935e31bdf97ef2069f595d19ff4defac34 100644 GIT binary patch delta 27 hcmZ2kwz7;nk(ZZ?0SMfUyf$*bWMXvN{FTYX0sv`q2bKT; delta 27 hcmZ2kwz7;nk(ZZ?0SF8(J8a~B$;9Zg`74u&1psf_2owMS diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-39.pyc index a9226689059416c60db485b5838c27f4b9ec4aae..4cb66d9756c880b75541d9711c00cfb567d1fb17 100644 GIT binary patch delta 27 hcmaEE@!Wztk(ZZ?0SMfUyf$**XJmBS{F<>w3IJ);2dV%7 delta 27 hcmaEE@!Wztk(ZZ?0SF8(J8a~>&&cSq`88vW6aa8L2q*vm diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-39.pyc index bcd503d0c4d08440984b1ebb74036dae5df6f361..b860ec8dd66708336c65948854b69dbadd130155 100644 GIT binary patch delta 24 ecmX@ec#x4hk(ZZ?0SMfUye4wnGP+IltN;K%AO%VQ delta 24 ecmX@ec#x4hk(ZZ?0SF8(J51!ZWptV7Spfh<3kApk diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-39.pyc index d704e7a40a42ee8df288e2662e97586036e6c445..9d6826ba8c6a79844ca9d74f636021cb4d714fb1 100644 GIT binary patch delta 24 ecmaFQ^qz@3k(ZZ?0SMfUye4wrVRW1Lq8$KCmj?9! delta 24 ecmaFQ^qz@3k(ZZ?0SF8(J51!h!{{>cMLPgdf(LT| diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-39.pyc index ee69ce836c06966ca6590dde5a9f7cdb8a63ab47..a4e7f5368969f07fed09c419a8f5cf0454262d3e 100644 GIT binary patch delta 27 gcmeCL@2}@h*n! delta 27 hcmX@kd7P6wk(ZZ?0SF8(J8b06Wn^^OT*>Ii3;63;OJv diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-39.pyc index 39dd4bf04f594b85a3910076c9edd25bb50f7228..41bd89563fcbfe1be20f5f74c5b4128d1572b019 100644 GIT binary patch delta 27 hcmX@aafpLEk(ZZ?0SMfUyf$*HF*3SsHewWD1^`Z+1q%QG delta 27 hcmX@aafpLEk(ZZ?0SF8(J8a}uV`OyMY{V$Q3;9k(ZZ?0SMfUyf$*DF*3SsE@ISU1^`Q91!n*N delta 27 hcmZ3$xqy>9k(ZZ?0SF8(J8a}mV`OyMT*Roy3;Ru@k(ZZ?0SMfUyf$(>F)_Mr_G9`c4**^p2EzaV delta 27 hcmX@&a>Ru@k(ZZ?0SF8(J8a~3Vq$dJ?8o#?9sp#52SES; diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-39.pyc index 1b79bddb473ed1bcf5015c8fd464e0e713149849..82a0d6c26b473cd5c62f653dca0818bfd613c1ee 100644 GIT binary patch delta 27 hcmeBC>`~-S`~-SO0RU2U1-AeI delta 27 hcmX@XdxDock(ZZ?0SF8(J8a}OW@2>NY|qrm0svUt1~mWx diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-39.pyc index 4f327da8b9ba9098a1ccbf452632635ff90bf536..e0da748c7a680b6ee4d397df4884b7e7dae2ee1f 100644 GIT binary patch delta 27 hcmeCN>#^fb#^fb69)%P@VA0RUB923P<9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-39.pyc index dbd15b8e3ccc49b09d5318af911a0723c6b64b79..a5e8407208696ec072bbb3ede82101225789e47d 100644 GIT binary patch delta 25 fcmey&^qGk}k(ZZ?0SMfUye4vgWpta&$XEmbQM3jf delta 25 fcmey&^qGk}k(ZZ?0SF8(J51#M%IGqgk+BE>R~-hM diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-39.pyc index 7695ef9dab94e984493b4c9651f8802e813c0083..4375f22ad5b161f3d3d4edaff9826e99316d4228 100644 GIT binary patch delta 55 zcmcarf2*E5k(ZZ?0SMfUyf$)2urj)BPGL6) diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-39.pyc index e0d00b6653074cffdef05015922966a93ba6c7be..629c4b49305e95d0ecec7c4e741e502d472e4cf4 100644 GIT binary patch delta 27 gcmZn_Y!&2Amx}=i+>N|8a*MJvx@}fu&x`;7Yjy^s delta 29 jcmeC$&)Bt}kvox>mx}=i3@$rt@>b2fqLS delta 27 hcmews^(~4!k(ZZ?0SF8(J8a}GU}kjLT*LfJ699E-2t5D* diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-39.pyc index 2a7c9c00ada7415e31d286e2cc6a180e61b078f7..b8f395a424f89758113027271099119bb2e77877 100644 GIT binary patch delta 27 hcmca9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-39.pyc index af68c6470782c5565351271a8725b1b25e9e4f63..4d2b67db6ffc2e97c344b1a2580d401b3a0d08c2 100644 GIT binary patch delta 27 hcmX>kdPtNzk(ZZ?0SMfUyf$(_XJmBS{F(7Q2LN1l2WtQT delta 27 hcmX>kdPtNzk(ZZ?0SF8(J8a~B&dBJp`7`5r4gg}^2k8I+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-39.pyc index 3fee2dc61ee43f8a0f0157dec2289befa747878a..e3ab28acf0be6d549100537a450859fccfb1751a 100644 GIT binary patch delta 27 hcmdl|wxx_ak(ZZ?0SMfUyf$)gb8a5wVW$UTFZ(QWe*<{iEOejx}? delta 29 jcmcb!i1E%MM(#vjUM>b8Fu3fnk$VO+qs!(c%sYGmgop^u diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-39.pyc index d65a874f46bd23e33ef5199a041f1de1979d0368..75325d4fb7b6df44b203bcfb9dfc899a744e34f9 100644 GIT binary patch delta 24 ecmdnbxSx?bk(ZZ?0SMfUye4wnGP+IlECT>O!UaSC delta 24 ecmdnbxSx?bk(ZZ?0SF8(J51!ZWptV7Sq1<@tp&mW diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-39.pyc index c8846dffb362a7fd2a250494b3553a0e57e7be49..2db4b75b30772626da2ff68a30a31c8ea7429b7b 100644 GIT binary patch delta 27 gcmZqXZsz7r!{EZ_>8~|mV2Xg=b delta 27 hcmX@%aKeE*k(ZZ?0SF8(J8a~B#lh&Z`5Q-&H~?$}2k`&^ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-39.pyc index a5b092e9b45d34ad660b87d2835a7f52ce4a1a86..8afdaaa65a0efae0e492d5761b17753944c55472 100644 GIT binary patch delta 27 hcmZ1^vq*+Jk(ZZ?0SMfUyf$*1urj)Bc3^$P0RT>q1?~U< delta 27 hcmZ1^vq*+Jk(ZZ?0SF8(J8a}OVP$mL?7;en0{~R^25bNT diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-39.pyc index 5d3a9f063e291a8e0bb5a75b57f1d4da71495dc0..b34a86b03a6c99261e3432835889a7591f084282 100644 GIT binary patch delta 27 hcmaD<`KXdRk(ZZ?0SMfUyf$**<79N({EG935de1G2*dyY delta 27 hcmaD<`KXdRk(ZZ?0SF8(J8a~>$I0lj`4#66BLICw2|@q> diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-39.pyc index be3c63756530bf2caf900d03ecc7ca27c06c1c96..93d40aea365fffc452f7c15f01fba47da740e651 100644 GIT binary patch delta 29 jcmeBM&Dgh^kvox>mx}=i+>N|8a%b=}x@|7umvRFDYz+q3 delta 29 jcmeBM&Dgh^kvox>mx}=i3@$rt2LNe;2QUBt delta 27 hcmeyZ{ac$mk(ZZ?0SF8(J8a}W$jRuk`7Ea%4*+lJ2d)4B diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-39.pyc index e541f6749d4b9a8c52999728a990199a48fb6961..cc3867bce3ef4b982afb682d8cb3057d0a2a0398 100644 GIT binary patch delta 24 ecmcb>c!7~Sk(ZZ?0SMfUye4wnGP+IlYzF{A;RSa9 delta 24 ecmcb>c!7~Sk(ZZ?0SF8(J51!ZWptV7*$x0k%mwuT diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-39.pyc index c24a62b4b1c7ac70a071015e677a4f99d094c7a9..af2c21fc4ada1bb7b3ad978355ffdc1422c59513 100644 GIT binary patch delta 27 hcmcZ|d^?ysk(ZZ?0SMfUyf$)g7GQMSyk9^@5&&va2Q2^q delta 27 hcmcZ|d^?ysk(ZZ?0SF8(J8b0MEWqfpdB1>+Bmi)^2de-8 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-39.pyc index 7ec89ccea95c5185acf34de8d52d602f5012425d..ad26680a53cea985c52e15b30c3d7b3601f2f2a3 100644 GIT binary patch delta 27 hcmX@(e#V_Uk(ZZ?0SMfUyf$)+u`s%AR$^Ht4**@01~~u# delta 27 hcmX@(e#V_Uk(ZZ?0SF8(J8a|@V_|gJti-ZP9spzd2DbnJ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-39.pyc index 92b7cf6626c8f068ed20ed802ea7bc0276271ef1..1dab6cdcc32fed876ba058ad6124d4c950f29dde 100644 GIT binary patch delta 24 ecmdnUw2_HBk(ZZ?0SMfUye4w5Vsx9htr`G7*9Hjy delta 24 ecmdnUw2_HBk(ZZ?0SF8(J51zW#pp6|TQvYg!Ul%` diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-39.pyc index 8ddbc53d7fe0b31b194058aa626826428325b71a..d49115c95fedc7fc4578f1c61d54697bc09697a0 100644 GIT binary patch delta 36 qcmdmfopJkhM(#vjUM>b8a5wVW$URGd(QWfGftp~(sLjeLQ`iB-ND7Al delta 36 rcmdmfopJkhM(#vjUM>b8Fu3fnk$aW^qs!)H0yV*mw>B%MOkoEA(IE?k diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-39.pyc index 68e7c150c8a6522de54e0faad298b5335c351e47..92a7b4d044b4123003d96e29f403637e749840a5 100644 GIT binary patch delta 24 ecmX@bc#4rbk(ZZ?0SMfUye4wnGP+IlYy<#6#|32o delta 24 ecmX@bc#4rbk(ZZ?0SF8(J51!ZWptV7*$4ndvIXM+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-39.pyc index f7eb69675c08d5c833dbab5c0b42d633c7601c61..a44645b9f8e4cd26697741fcc04c22738a733a55 100644 GIT binary patch delta 27 hcmbQjHHC{ik(ZZ?0SMfUyf$**WoC5S{E}Il5dcp;20j1) delta 27 hcmbQjHHC{ik(ZZ?0SF8(J8a~>%gpGq`6aV9BLG#T2D|_O diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-39.pyc index d48361bb1dd7218b5c433e7525272beec64715c2..bbeaeb0cc268ace3cd80f880e5d24d74ca35f4ce 100644 GIT binary patch delta 26 gcmdnOvW0~^k(ZZ?0SMfUyf$)oF*3SMp2j#207`EL8UO$Q delta 26 gcmdnOvW0~^k(ZZ?0SF8(J8b0cVq|ogJdJT408m&4m;e9( diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-39.pyc index 32868e6ab832d3e3d75f1e59b6c28314494f629f..0925268a2b7e7a5d4c42b97da35d6933fe7af438 100644 GIT binary patch delta 27 hcmcaFd0&z{k(ZZ?0SMfUyf$*DGBUbtE@aH(1^`>h21@_{ delta 27 hcmcaFd0&z{k(ZZ?0SF8(J8a}mWn^^OT*#Qm4FF;=2FU;b diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-39.pyc index 5d4c8baed2ffbf1f8a5d465e1060213e91a62b4d..0db85e8075275def23d50a43c4c15721b790721f 100644 GIT binary patch delta 26 gcmX@hah8KSk(ZZ?0SMfUyf$+0VP^;e2Jk(ZZ?0SMfUyf$)kF*CYt7GqB50svim1^;e2Jk(ZZ?0SF8(J8b0UVrF#NEXJJ91ps5>22B6} diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-39.pyc index 16062017ecf2782a990e7b25a6219334386721af..698ad41289afbfc41292d4b422aceab281a25d3e 100644 GIT binary patch delta 27 hcmdnVwUdiGk(ZZ?0SMfUyf$*rWny&Oypm}G697~}25bNT delta 27 hcmdnVwUdiGk(ZZ?0SF8(J8a~h%f#ric_q^XCIDKf2I>F+ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-39.pyc index e6c80e6b7e66d2c51efbffac775c11d830407355..452a856d11c692edb131747b8388909ff465920f 100644 GIT binary patch delta 27 hcmZ3$v4Dd+k(ZZ?0SMfUyf$*%GBUbt_GG-y1OQ5G1-k$M delta 27 hcmZ3$v4Dd+k(ZZ?0SF8(J8a~(Wn^^O?8$hY2>?*j1~~u# diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-39.pyc index aaf4035738c919cedf131973147e7246cfc9f2f2..172fda8f4dc9c102794d3a04bd3d430721880930 100644 GIT binary patch delta 27 hcmew&^+k$1k(ZZ?0SMfUyf$(>vopGF_GedR0{~ty1@Qm? delta 27 hcmew&^+k$1k(ZZ?0SF8(J8a~3W@mKS?9Z;s1^{H225$fW diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-39.pyc index 53e08961b6ac639f9886729a0e96f7a9c6287397..2cf8eca5e7e9299516514e0f2d4180e2260e7bc0 100644 GIT binary patch delta 27 hcmZ1~v{Z;Yk(ZZ?0SMfUyf$*DGBLVsE@axm1^`br1`GfI delta 27 hcmZ1~v{Z;Yk(ZZ?0SF8(J8a}mWny&MT*$PA4FFY~28sXx diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-39.pyc index 470dea593beeaeab471241604f62c484e6d5e2e4..2fecb72a0ea5629c0ad37a5803f8ccac37be83fc 100644 GIT binary patch delta 27 hcmcaoeWjW^k(ZZ?0SMfUyf$)&F*CYtPGT;y0sw3~2ND1P delta 27 hcmcaoeWjW^k(ZZ?0SF8(J8a|*V`g;OoWxvY1psoQ2ao^& diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-39.pyc index 74c5438314ab2aa486b9529b86bc01a878a491ff..08ae3969890f044bf6a8f1b517abe6572b5946bb 100644 GIT binary patch delta 27 hcmdlRu{VM{k(ZZ?0SMfUyf$(Rurj)BmSI&?2LN1*1+oAD delta 27 hcmdlRu{VM{k(ZZ?0SF8(J8a|@U}bdKEW@g(4gg~F1~32s diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-39.pyc index 620b7bee802316456593acbe5c54c057da8cb70d..ecaf5b8cdc67595e03c657cf72c868de2f2b4d2e 100644 GIT binary patch delta 27 hcmca)b;*i5k(ZZ?0SMfUyf$((u`;@C=3{k{003Hb1(*N; delta 27 hcmca)b;*i5k(ZZ?0SF8(J8a};Vr6vM%*W~?0RUj!1{MGS diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-39.pyc index 14956d5c14e72a33d0026f600a0c925e46968b81..d3070b3b9179efe40db457f9705de742497e804e 100644 GIT binary patch delta 27 hcmaFu`r4H{k(ZZ?0SMfUyf$(d@-ez?uI0-U0RU(P2KE2| delta 27 hcmaFu`r4H{k(ZZ?0SF8(J8a}Gdc@66yWdLTk2lD^` diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-39.pyc index 1f3c858a9ec40c61bd504149e0d89af7d61c32a4..edaee3a7c7cb3539e41233a55e5ccaf7aa03f285 100644 GIT binary patch delta 27 hcmdlYu|@m02L%8C delta 27 hcmew=`&E`Zk(ZZ?0SF8(J8a}W!NcgX`3jFB698;Y2ZI0r diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-39.pyc index efec6676b263f4641bbda10b85fe9aa14deb3c69..15d4217761e2ccea852d0fafd51200730189ed13 100644 GIT binary patch delta 27 hcmaFO_nMD8k(ZZ?0SMfUyf$*LXJmBSyqj?YD*#|q2OR(a delta 27 hcmaFO_nMD8k(ZZ?0SF8(J8a}$&&cSqc{k$*Rsd$Y2b%x@ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-39.pyc index a9d891bde1ecb37333a4ce7a7894e13a5367189d..8aae444e206d479a6469495d875a12a84d827a67 100644 GIT binary patch delta 27 hcmX@Eeq5b9k(ZZ?0SMfUyf$)AWny&OypTyv5CB`223G(8 delta 27 hcmX@Eeq5b9k(ZZ?0SF8(J8a~h%Eaihc_EXUAOKqmBk(ZZ?0SMfUyf$*TF)_Mrp2T#K9ROY#2J8R; delta 27 hcmaDX@>qmBk(ZZ?0SF8(J8a}`V`6mKJc;QdI{;*W2WkKS diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/__pycache__/__init__.cpython-39.pyc index 99dac3f2f5261c333307284562fbd3844762edad..e6ede39721548f78782d059cc89ead7f99a7d7cd 100644 GIT binary patch delta 33 ncmX>b8;5PEw$Q{YU=+>OdvptoE@l`bdk&_6_ delta 33 ncmX>b8;JfUwkvo!y(WN<+XL~9Sb8;5PEw$UU8h(QWf$o?>SJYbOUp delta 29 jcmbQXfN|OaM(#vjUM>b8;JfUwk$XB1qs!*SJjKoca{33{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-39.pyc index 31628de8b22cd8f410baab8cbd3ae1e6c6af06b1..caed1f438dd5e2ae67c62afb8b46b0dad5158456 100644 GIT binary patch delta 37 scmeypgy;7X9_~b5UM>b8;5PEw$bCkJ(XIK0O#2NP#_cy`m==Ep0NkGpkpKVy delta 37 scmeypgy;7X9_~b5UM>b8;JfUwk^77cqf7G*nf4npjN5O>FfINH0O>LfDF6Tf diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-39.pyc index 3bda69f8b405fa228794aadbdd0b60f72d8aa6e9..4e8622f4a30850092a6d45b08620a7a62757bc86 100644 GIT binary patch delta 26 gcmdnXx|fwZk(ZZ?0SLH_yf$*HFfqDKHel)n07UBr7XSbN delta 26 gcmdnXx|fwZk(ZZ?0SNdmJ8a}uVPbTdY{1kD08AzYuK)l5 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-39.pyc index 5b9f7c409ed0a1cd1a583888d3bf6512b6cac3c7..68703ec11ed0281decf24ee2298989c3b63b9b67 100644 GIT binary patch delta 26 gcmZ3?vY3TCk(ZZ?0SLH_yf$*rWMp)kyp*vH07RArx&QzG delta 26 gcmZ3?vY3TCk(ZZ?0SNdmJ8a~h$;jw3c`0KZ087yZQUCw| diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-39.pyc index bc88ad90699dcac911019cc2ce4bea4ea1583c99..9e2f66ac637b620ba953a20e7c377ce65137c189 100644 GIT binary patch delta 27 hcmey#@soo)k(ZZ?0SLH_yf$*XGBLVs4rJ0`0svS|1(W~) delta 27 hcmey#@soo)k(ZZ?0SNdmJ8a~3Wny&M9LS`>1OQ+l1}p#o diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-39.pyc index 0b7b17b2cac4b98e25a8bed089ca8ad355d17a6c..c6de3bd16ea5e004cca9a6f977c76e76134c3683 100644 GIT binary patch delta 27 hcmcaCc3F%&k(ZZ?0SLH_yf$(tF*3Ss&SQMa2>@0=24DaH delta 27 hcmcaCc3F%&k(ZZ?0SNdmJ8a}mVq|pLoX7Z-698Tl2KWE~ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_typing.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_typing.cpython-39.pyc index 7ae9bd0ce0fc1282f5ad09cac1b8c070844b0a62..5bb6e2ea747558c352ac5ad7791a4ac7bb9e8b2c 100644 GIT binary patch delta 26 gcmcb_eTkbpk(ZZ?0SLH_yf$+GU}1Ed%))vO08o|&I{*Lx delta 26 gcmcb_eTkbpk(ZZ?0SNdmJ8b0s!NTY=nT7Qn09Vll(*OVf diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-39.pyc index 5a37aa884a8e0bebe5f3ce04d40ebd042eff97a5..d3c9c243b3729c20e23d6eab39dcd58c9504dd52 100644 GIT binary patch delta 27 hcmccRam#}{k(ZZ?0SLH_yf$(_V`X&P{E0O~4ghCs2YLVi delta 27 hcmccRam#}{k(ZZ?0SNdmJ8a~B#>(ij`4ek~8~|@V2oeAQ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-39.pyc index c2bed71f0adc20a94746bf52b6e68d70eadd5504..d9ddf2c9745c2ba34e7c7d7bc72f27052ffcd4f3 100644 GIT binary patch delta 27 hcmew?|5=_pk(ZZ?0SLH_yf$*rVPSOJyn@A>8vtNq29y8* delta 27 hcmew?|5=_pk(ZZ?0SNdmJ8a~h!@}sYc?F9%Hvnih2P^;p diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc index 8397dcd35f0c8146d0bd733982d65c40eb9d8254..2e7901086e0cf435830c95fbfb03ff1d0614c2a7 100644 GIT binary patch delta 29 jcmaF1fbrP^M(#vjUM>b8;5PEw$Zf&Q=(gE~S;-dwc8Lbf delta 29 jcmaF1fbrP^M(#vjUM>b8;JfUwk=ufq(Pgs>vyv|Weq0A- diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/tags.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/tags.cpython-39.pyc index 4f4faecc00bff8b784a313d70189a93e3124017e..f026372dbbfcae80855d10e5b57b71631d259668 100644 GIT binary patch delta 70 zcmaFc#`w04kvox>mx}=ixQ)Cva(`fAbld!gX}hWN8lX_oG9Yn_wbmx}=i_%1ta|K=(70_({@v3IYtJCqGdqwB6%R|7HhGwr9s6l W_Qb@Z?_W1#bWV diff --git a/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-39.pyc index bf41ffc76fd13359ef5b61ce67380265575b22ce..22c9534a094264409681e558f59bb8ca7b460fe1 100644 GIT binary patch delta 24 ecmdnVw3CTDk(ZZ?0SLH_ye4wbVRW0gVj=)OSq0Ys delta 24 ecmdnVw3CTDk(ZZ?0SNdmJ51!B!{{<`#Y6x^Vg_#j diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/__init__.cpython-39.pyc index 445ccb9ce9916bb47d6497261a15239eed743609..df6f64864f695318d86e03709898db0dcda427a7 100644 GIT binary patch delta 27 hcmca2d_|Z$k(ZZ?0SHu$yf$(#W@dETyq;N=4FFjx1~~u# delta 27 hcmca2d_|Z$k(ZZ?0SH_#J8a}$%*^Prc|Ef#8vtUH2JQd= diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/_ast_gen.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/_ast_gen.cpython-39.pyc index 64ff98922e67ad4ecc2f7d31414f82f59e4aa9c8..1aeb62f1a150088ce1bed3ebfff0d024516bd778 100644 GIT binary patch delta 27 hcmaFv|J!pP{d`2i!l8US>12kZa< diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/_build_tables.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/_build_tables.cpython-39.pyc index c1fb0d584ba6cb49e1915038bb44c3a5b9d7b6b3..d3ccfed4f00433e8cd2d5a55d0674970b8234a62 100644 GIT binary patch delta 26 gcmbQpGLeNlk(ZZ?0SHu$yf$(-F*3SM?qh5Q06}a8hX4Qo delta 26 gcmbQpGLeNlk(ZZ?0SH_#J8a}`Vq|og+{f4q07@VRJOBUy diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/ast_transforms.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/ast_transforms.cpython-39.pyc index 49ba8f5fe707d3f5855e681ae5c25c0c1b3e2301..1939840723a0f0d72971fe02ec9764c38e2cb005 100644 GIT binary patch delta 27 hcmaDT{7{%Xk(ZZ?0SHu$yf$*LXJ>TVyqjH(2>@J_25b8P&M+}$X&p~=(f3rb8aJ}rXk-LC}(PeWD%f}V~gyabb diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/c_generator.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/c_generator.cpython-39.pyc index 2bd618304b0144a8a6d2a84cb889d0f8699dfa22..0bac1ddc426fa7d2c574e069702de498039d8187 100644 GIT binary patch delta 29 jcmccE#CWlZkvox>mx}=iRE@kga#t`jx@~S@K5GjAal!|j delta 29 jcmccE#CWlZkvox>mx}=iTrWFpb8P&M+}$So?&=(br=*yttze{%<` delta 29 jcmcb7gZc6eX6{5@UM>b8aJ}rXky})l(Pguuu+dEbh};NZ diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/lextab.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/lextab.cpython-39.pyc index b7290c8d122b068fb1a463a4d90c01a28bd52160..3872d257ea5f0965e91ae01291eb02e6387805ba 100644 GIT binary patch delta 26 gcmZ3iwOETgk(ZZ?0SHu$yf$(#6=8InyiueG08T3gQUCw| delta 26 gcmZ3iwOETgk(ZZ?0SH_#J8a}$D#GY8d80@X09M}z2LJ#7 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/plyparser.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/plyparser.cpython-39.pyc index 1b3e7552d872431e8f09170eb6d7501edf8fdb22..706bee4692fc19e2669af81711c907ec68322675 100644 GIT binary patch delta 27 hcmX@2azuqYk(ZZ?0SHu$yf$+GU}SXL%);a#003FK1_uBD delta 27 hcmX@2azuqYk(ZZ?0SH_#J8b0s!N};cnT5$g003hn2D|_O diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/yacctab.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/__pycache__/yacctab.cpython-39.pyc index 1d955ad7c1ea9b5981421af74bcfee8225c5e930..a4b867c1cfff993f41b45c48d6dbc3ace2ac863b 100644 GIT binary patch delta 35 pcmaFxi{rsB4(>!=UM>b8P&M*u!=UM>b8aJ}r%$lc1#xRsk}w+*Aq^y4;6GXc?d3jF{8 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/__init__.cpython-39.pyc index 78f52d49051238e64ec7d8d7dacb141cea48fa8a..3b9c1787d04ae0883b7cbc2e64f55c13634e2f08 100644 GIT binary patch delta 24 ecmaFF_=u4^k(ZZ?0SHu$ye4wzFuF~w$N~UG0tLDN delta 24 ecmaFF_=u4^k(ZZ?0SH_#J51!xVRV^Tkp%!uN(OHL diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/cpp.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/cpp.cpython-39.pyc index 7819a40daa9ff35888f51e0cd3dea8bb7e9ccf38..99b97e6cc37d321a481ce6afe5bc5488abc38a13 100644 GIT binary patch delta 27 hcmZ2oySkP;k(ZZ?0SHu$yf$)AWMXvNJeP^j1^{H82DAVG delta 27 hcmZ2oySkP;k(ZZ?0SH_#J8a~h$i(Qfc`g&54FGNi2WbER diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/ctokens.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/ctokens.cpython-39.pyc index 7ff24f2cab68ac41bafd7ece8ac60d4f1d95599f..2c024eb85ebdb6d70d6e7acdd8432b5f8449d941 100644 GIT binary patch delta 27 hcmbO)FkgT>k(ZZ?0SHu$yf$)ourRu9p2E`23;<0<1^55} delta 27 hcmbO)FkgT>k(ZZ?0SH_#J8b0cU}1FGJcXs3830zU2CV=9 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/lex.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/lex.cpython-39.pyc index e0f92a9c3f9529181efb448db92ec3480ba5d3d8..4f122449c7a3fecca93f1ff93034062b2e69f686 100644 GIT binary patch delta 29 jcmZ3poN>)^M(#vjUM>b8P&M+}$SuLd=(bsfsUr{oY!?Qp delta 29 jcmZ3poN>)^M(#vjUM>b8aJ}rXkz0a^(Pgs=Q%4{Gb$|z6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/yacc.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/yacc.cpython-39.pyc index c8a01416879129aae7e06b4612476f3b1496a0c2..59602036e12acf39ca7a0b6e0d7827d93b5312bc 100644 GIT binary patch delta 29 jcmaDqm-+o%X6{5@UM>b8P&M+}$SuIk=(bsg`SNK1d4mVm delta 29 jcmaDqm-+o%X6{5@UM>b8aJ}rXkz0V7(Pgs?^X1b3g6s&3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/ygen.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/pycparser/ply/__pycache__/ygen.cpython-39.pyc index b49974253f1a29beeb56918a0f435ed211be707b..b77dd717cd8dc0a93a6ed4bde540f138c8536b83 100644 GIT binary patch delta 27 hcmey%`P3IJbZ28aLv delta 27 hcmey%`2R#4) diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/__init__.cpython-39.pyc index fa4db24c363ad740bfa11c9e69fce4ab74528722..7de450c3badb23c4dd29b8919771acdfdc016333 100644 GIT binary patch delta 27 hcmbOzH&Ko|k(ZZ?0SMxayf$(>b1=GX_UAan1^`WQ1?m6* delta 27 hcmbOzH&Ko|k(ZZ?0SIg_J8a~3=3sQ$?9XwC4FFR<23-IE diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/__version__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/__version__.cpython-39.pyc index e396467b4a4326873158a08ec31808a9b7abb850..c1f1d31f25ea50575b83e78a24e7975f185bf71d 100644 GIT binary patch delta 26 gcmbQvGM$Axk(ZZ?0SMxayf$)AW@L1mJfE=w07g0mAtQ&tXbq0su*91=0Wj delta 27 hcmZqTYU1Kf diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/adapters.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/adapters.cpython-39.pyc index b453d06d4c1a6337e1d7edcd60832de1f70ad83d..44a6f694e79aba14ebc4baa0d47042fe615bc0e7 100644 GIT binary patch delta 29 jcmey^%=odHkvox>mx}=i;*GpEa!+PublW_iHOK}4e1Qkn delta 29 jcmey^%=odHkvox>mx}=iY%e=(i009*nGaR2}S diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/compat.cpython-39.pyc index 214edc37d72adc9e50537a0eb25e20d3b6d3088a..9f3f0ca12a1f5d53468e22ad66421a7ccf88b25e 100644 GIT binary patch delta 26 gcmbQuJDZm~k(ZZ?0SMxayf$**V`X%k{EBrW08B^*)c^nh delta 26 gcmbQuJDZm~k(ZZ?0SIg_J8a~>$I9q3`4#I%08yd`NB{r; diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/cookies.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/cookies.cpython-39.pyc index 42e9c11f64cd4c49265323cb9da9bc46f8562a49..f688d8226addeaaa1c80c46fbb92a18961c91ce1 100644 GIT binary patch delta 29 jcmew~iSg4UM(#vjUM>b8h&S@u$Q{qh=(ahVmE8pZe4z(R delta 29 jcmew~iSg4UM(#vjUM>b8u)XZCkvpE1(PeWsE4vE-f^G-C diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/exceptions.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/exceptions.cpython-39.pyc index c8ebdbed04d597da80ca791ae6706ee01b84512e..1c8989819d202e9bc84a9d7665a988ae15c60a7e 100644 GIT binary patch delta 27 hcmeyX`B#%Wk(ZZ?0SMxayf$)+vM{=BR%E#&003h{2ABW< delta 27 hcmeyX`B#%Wk(ZZ?0SIg_J8a|@WnpyLtjKal003za2MYiI diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/help.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/help.cpython-39.pyc index 18115c2f0fd26f681bc84b760786307730999b8a..b9afc1f31e280b2f41077216490174246280e3f0 100644 GIT binary patch delta 27 hcmZ1~wp5Hek(ZZ?0SMxayf$*Pu`;@C7Gf1<0{}}|1k(Tj delta 27 hcmZ1~wp5Hek(ZZ?0SIg_J8a};V`X&NEW|3z1^`he1x5e> diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/hooks.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/hooks.cpython-39.pyc index f099c12da8098d32af649774c378bd6f651580ac..05d070e5b14c34d5d891a88954b0a6c53d2837e0 100644 GIT binary patch delta 27 hcmX@beu|wtk(ZZ?0SMxayf$*zGcvku?q;-S0svM#1`z-N delta 27 hcmX@beu|wtk(ZZ?0SIg_J8a~xXJmBQ+|6ju1OQwK27~|r diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/models.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/models.cpython-39.pyc index 27ef112e86b42dd455b98791d57057c4d2521092..449bc6b5e5e32d624d10fc2ae05b4ce405f79868 100644 GIT binary patch delta 29 jcmdnBk8#&NM(#vjUM>b8h&S@u$i0S*(QWe%wx$RGezOQ( delta 29 jcmdnBk8#&NM(#vjUM>b8u)XZCk$Vjrqs!(UY)ugWgn$Uq diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/packages.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/packages.cpython-39.pyc index 92d42062a13baa7ba0ba424594da2ba666b87f19..e9d0fca1e8230218d78a025c8bdc98b36a4778d7 100644 GIT binary patch delta 26 gcmZ3=x|EeWk(ZZ?0SMxayf$)6FfqDKR$*!c07LHu7XSbN delta 26 gcmZ3=x|EeWk(ZZ?0SIg_J8a~ZU}AKctisd?07*#&iU0rr diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/sessions.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/sessions.cpython-39.pyc index 2e7a5e8865466ee9ae80562a01b198e9bbf038fd..a9f22d1f438fb2f118f4933437d72438e35d9b50 100644 GIT binary patch delta 29 jcmex6i}CL)M(#vjUM>b8h&S@u$lc1u=(c$x+Z#6kglh<< delta 29 jcmex6i}CL)M(#vjUM>b8u)XZCk-L?R(Pi^Qwl{77iZ}@w diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/status_codes.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/status_codes.cpython-39.pyc index 0fad92f2d549ecbac783f76918185e6a75dac75d..7c3087d69d023882528c826b456d0286a8298939 100644 GIT binary patch delta 27 hcmeyZ@LPd9k(ZZ?0SMxayf$*T@G`n>p1}K>2>@p=2Xg=b delta 27 hcmeyZ@LPd9k(ZZ?0SIg_J8a}`;bnB$Jc0K$698=d2j&0( diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/structures.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/structures.cpython-39.pyc index c9c40829304ecf1258af389562ad9ceb6e7099c9..ad97f589eb44620af3ae011924919ce22ac8bf59 100644 GIT binary patch delta 27 hcmcbibVG?dk(ZZ?0SMxayf$(_Vr6vO{Ejt?8vtYM2W0>N delta 27 hcmcbibVG?dk(ZZ?0SIg_J8a~B#LDQh`5kK(Hvnn52iO1r diff --git a/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/utils.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/requests/__pycache__/utils.cpython-39.pyc index ea99b60e2c37ee5b0280482e74ba7d7c5bad9f98..33e7734a6500ae705726ec0635198d2a9c85397d 100644 GIT binary patch delta 29 jcmeyfmGRG3M(#vjUM>b8h&S@u$bFri(QWf%cFAA>jAsbC delta 29 jcmeyfmGRG3M(#vjUM>b8u)XZCk^4G3qs!*U?2^F%k~9e| diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/AUTHORS.rst b/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/AUTHORS.rst deleted file mode 100644 index 54cb3c9e..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/AUTHORS.rst +++ /dev/null @@ -1,14 +0,0 @@ -Development Lead ----------------- - -- Ian Stapleton Cordasco - -Contributors ------------- - -- Thomas Weißschuh -- Kostya Esmukov -- Derek Higgins -- Victor Stinner -- Viktor Haag -- Seth Michael Larson diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/INSTALLER b/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/LICENSE b/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/LICENSE deleted file mode 100644 index 72ce24cf..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2014 Ian Cordasco, Rackspace - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/METADATA b/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/METADATA deleted file mode 100644 index 2ddcde04..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/METADATA +++ /dev/null @@ -1,230 +0,0 @@ -Metadata-Version: 2.1 -Name: rfc3986 -Version: 1.5.0 -Summary: Validating URI References per RFC 3986 -Home-page: http://rfc3986.readthedocs.io -Author: Ian Stapleton Cordasco -Author-email: graffatcolmingov@gmail.com -License: Apache 2.0 -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Natural Language :: English -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Provides-Extra: idna2008 -Requires-Dist: idna ; extra == 'idna2008' - -rfc3986 -======= - -A Python implementation of `RFC 3986`_ including validation and authority -parsing. - -Installation ------------- - -Use pip to install ``rfc3986`` like so:: - - pip install rfc3986 - -License -------- - -`Apache License Version 2.0`_ - -Example Usage -------------- - -The following are the two most common use cases envisioned for ``rfc3986``. - -Replacing ``urlparse`` -`````````````````````` - -To parse a URI and receive something very similar to the standard library's -``urllib.parse.urlparse`` - -.. code-block:: python - - from rfc3986 import urlparse - - ssh = urlparse('ssh://user@git.openstack.org:29418/openstack/glance.git') - print(ssh.scheme) # => ssh - print(ssh.userinfo) # => user - print(ssh.params) # => None - print(ssh.port) # => 29418 - -To create a copy of it with new pieces you can use ``copy_with``: - -.. code-block:: python - - new_ssh = ssh.copy_with( - scheme='https' - userinfo='', - port=443, - path='/openstack/glance' - ) - print(new_ssh.scheme) # => https - print(new_ssh.userinfo) # => None - # etc. - -Strictly Parsing a URI and Applying Validation -`````````````````````````````````````````````` - -To parse a URI into a convenient named tuple, you can simply: - -.. code-block:: python - - from rfc3986 import uri_reference - - example = uri_reference('http://example.com') - email = uri_reference('mailto:user@domain.com') - ssh = uri_reference('ssh://user@git.openstack.org:29418/openstack/keystone.git') - -With a parsed URI you can access data about the components: - -.. code-block:: python - - print(example.scheme) # => http - print(email.path) # => user@domain.com - print(ssh.userinfo) # => user - print(ssh.host) # => git.openstack.org - print(ssh.port) # => 29418 - -It can also parse URIs with unicode present: - -.. code-block:: python - - uni = uri_reference(b'http://httpbin.org/get?utf8=\xe2\x98\x83') # ☃ - print(uni.query) # utf8=%E2%98%83 - -With a parsed URI you can also validate it: - -.. code-block:: python - - if ssh.is_valid(): - subprocess.call(['git', 'clone', ssh.unsplit()]) - -You can also take a parsed URI and normalize it: - -.. code-block:: python - - mangled = uri_reference('hTTp://exAMPLe.COM') - print(mangled.scheme) # => hTTp - print(mangled.authority) # => exAMPLe.COM - - normal = mangled.normalize() - print(normal.scheme) # => http - print(mangled.authority) # => example.com - -But these two URIs are (functionally) equivalent: - -.. code-block:: python - - if normal == mangled: - webbrowser.open(normal.unsplit()) - -Your paths, queries, and fragments are safe with us though: - -.. code-block:: python - - mangled = uri_reference('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth') - normal = mangled.normalize() - assert normal == 'hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth' - assert normal == 'http://example.com/Some/reallY/biZZare/pAth' - assert normal != 'http://example.com/some/really/bizzare/path' - -If you do not actually need a real reference object and just want to normalize -your URI: - -.. code-block:: python - - from rfc3986 import normalize_uri - - assert (normalize_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth') == - 'http://example.com/Some/reallY/biZZare/pAth') - -You can also very simply validate a URI: - -.. code-block:: python - - from rfc3986 import is_valid_uri - - assert is_valid_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth') - -Requiring Components -~~~~~~~~~~~~~~~~~~~~ - -You can validate that a particular string is a valid URI and require -independent components: - -.. code-block:: python - - from rfc3986 import is_valid_uri - - assert is_valid_uri('http://localhost:8774/v2/resource', - require_scheme=True, - require_authority=True, - require_path=True) - - # Assert that a mailto URI is invalid if you require an authority - # component - assert is_valid_uri('mailto:user@example.com', require_authority=True) is False - -If you have an instance of a ``URIReference``, you can pass the same arguments -to ``URIReference#is_valid``, e.g., - -.. code-block:: python - - from rfc3986 import uri_reference - - http = uri_reference('http://localhost:8774/v2/resource') - assert uri.is_valid(require_scheme=True, - require_authority=True, - require_path=True) - - # Assert that a mailto URI is invalid if you require an authority - # component - mailto = uri_reference('mailto:user@example.com') - assert uri.is_valid(require_authority=True) is False - -Alternatives ------------- - -- `rfc3987 `_ - - This is a direct competitor to this library, with extra features, - licensed under the GPL. - -- `uritools `_ - - This can parse URIs in the manner of RFC 3986 but provides no validation and - only recently added Python 3 support. - -- Standard library's `urlparse`/`urllib.parse` - - The functions in these libraries can only split a URI (valid or not) and - provide no validation. - -Contributing ------------- - -This project follows and enforces the Python Software Foundation's `Code of -Conduct `_. - -If you would like to contribute but do not have a bug or feature in mind, feel -free to email Ian and find out how you can help. - -The git repository for this project is maintained at -https://github.com/python-hyper/rfc3986 - -.. _RFC 3986: http://tools.ietf.org/html/rfc3986 -.. _Apache License Version 2.0: https://www.apache.org/licenses/LICENSE-2.0 - - diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/RECORD deleted file mode 100644 index 592828dc..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/RECORD +++ /dev/null @@ -1,33 +0,0 @@ -rfc3986-1.5.0.dist-info/AUTHORS.rst,sha256=QjlDdMHiNeQv1lPqHeGQ4OtiEPCwFafJLu7t23AXDHo,223 -rfc3986-1.5.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -rfc3986-1.5.0.dist-info/LICENSE,sha256=wN3OM7-sSApmveQMWQ7eJkekyKcp3LDSzkbAFEc9Xdg,564 -rfc3986-1.5.0.dist-info/METADATA,sha256=qkuCB_ifgypthNS6-M-IOKli-F3YPR8xzOOXPHEu2Wo,6458 -rfc3986-1.5.0.dist-info/RECORD,, -rfc3986-1.5.0.dist-info/WHEEL,sha256=Z-nyYpwrcSqxfdux5Mbn_DQ525iP7J2DG3JgGvOYyTQ,110 -rfc3986-1.5.0.dist-info/top_level.txt,sha256=Z10Qesb0UV9AbxlTIV9AnOAwk-343WnE85K8xfN4OmA,8 -rfc3986/__init__.py,sha256=Yc1nYWLNwBn1XUCt3lPMC6cPD3S82FKPPc4IpTaFjCE,1591 -rfc3986/__pycache__/__init__.cpython-39.pyc,, -rfc3986/__pycache__/_mixin.cpython-39.pyc,, -rfc3986/__pycache__/abnf_regexp.cpython-39.pyc,, -rfc3986/__pycache__/api.cpython-39.pyc,, -rfc3986/__pycache__/builder.cpython-39.pyc,, -rfc3986/__pycache__/compat.cpython-39.pyc,, -rfc3986/__pycache__/exceptions.cpython-39.pyc,, -rfc3986/__pycache__/iri.cpython-39.pyc,, -rfc3986/__pycache__/misc.cpython-39.pyc,, -rfc3986/__pycache__/normalizers.cpython-39.pyc,, -rfc3986/__pycache__/parseresult.cpython-39.pyc,, -rfc3986/__pycache__/uri.cpython-39.pyc,, -rfc3986/__pycache__/validators.cpython-39.pyc,, -rfc3986/_mixin.py,sha256=iFnLyRbd-QMQv9LlYwglAt-vNA4CxpBhnZMu-XyKP4w,13280 -rfc3986/abnf_regexp.py,sha256=hTIxwQQcngkTmmDn0T0m0_6dZZIiMovYEsITUrZIL3Q,9121 -rfc3986/api.py,sha256=UzjPnQ4_G0ludMVXEeq6CVYmFQ55rDpKvHakGZMxVe8,3887 -rfc3986/builder.py,sha256=vuI6u7B3UQbVrh47xDF7X5sducTxzkLQeuvW7vPavok,12757 -rfc3986/compat.py,sha256=51xDR7kfVhaM7GqTLmw-lQY4jv2mw2MbCNuBnG4PnbA,1644 -rfc3986/exceptions.py,sha256=dFYnm-TabVYpWUEPXqtGp8xfSg1wWYk09TaUjCetWYI,3847 -rfc3986/iri.py,sha256=BX1nFD0JyZnUfAHxDFqyz0hN8J-YfKxIhYJLyBZGAZo,5520 -rfc3986/misc.py,sha256=bye9xhySD_GshuL_MD0VTledl6jBw_ErG8kXtTNXzXQ,4163 -rfc3986/normalizers.py,sha256=f6oLvNUadxZDJDtx3JvqF_exGGD7PvLaibYQBUfh2NE,5294 -rfc3986/parseresult.py,sha256=NvbPpPzuuputHpJc4J2cjcNy6B7c6rscFqzSnksDWmc,14742 -rfc3986/uri.py,sha256=LYNAlr2ujVfCa6jcV8o1I1hOuviuuXsSRHpST2DyvAw,5225 -rfc3986/validators.py,sha256=qcvNnrpk2el-otJN-ZRGZ0PE4xaSEP97lKREXG_YtpM,13839 diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/WHEEL b/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/WHEEL deleted file mode 100644 index 01b8fc7d..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.36.2) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/top_level.txt b/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/top_level.txt deleted file mode 100644 index af30258c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986-1.5.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -rfc3986 diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__init__.py deleted file mode 100644 index a052299c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -An implementation of semantics and validations described in RFC 3986. - -See http://rfc3986.readthedocs.io/ for detailed documentation. - -:copyright: (c) 2014 Rackspace -:license: Apache v2.0, see LICENSE for details -""" - -from .api import iri_reference -from .api import IRIReference -from .api import is_valid_uri -from .api import normalize_uri -from .api import uri_reference -from .api import URIReference -from .api import urlparse -from .parseresult import ParseResult - -__title__ = "rfc3986" -__author__ = "Ian Stapleton Cordasco" -__author_email__ = "graffatcolmingov@gmail.com" -__license__ = "Apache v2.0" -__copyright__ = "Copyright 2014 Rackspace; 2016 Ian Stapleton Cordasco" -__version__ = "1.5.0" - -__all__ = ( - "ParseResult", - "URIReference", - "IRIReference", - "is_valid_uri", - "normalize_uri", - "uri_reference", - "iri_reference", - "urlparse", - "__title__", - "__author__", - "__author_email__", - "__license__", - "__copyright__", - "__version__", -) diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index e1d5d264ba6ee1fb9df4bf0c19ae2f5c4aec39fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1039 zcmZ`&O=}x55Z(2+cWuW>p@$xdjy1IFd^Bn6mJ;KpU>ZWO=|wCEWhHw>c2|oe8{%{S zO#e_1J{5ZEU+AH9v`LIpT8VwU88M^Ln_1d!dk(DczlZcy&2fHMV|$grIE7Dt0bmYx zn9E9uo0f3NwY&_xjLQYD0I%Rm!K=WlxLWWU@EWcaybipM>jiHBZ{SA3n@KbEum{}3 zKJ#&lwQ!rYaffyA4%@+9*2TMQck1-^R^Pl~hD4etJms08M#v1w8PYtZnGumjG-GH< z6TylzjTqOF5?7odk)g@Q5juMF`XunYDd#9QCLi?sY8Dkv#VIo}XEM@(kbN|h3c?K) z2}FZ;vAGiB2a(Kgl$gh6fSyG?bhv-;5>04yt#cZ2Z;*(HXPOVt5bT(vqTO4{Z5C~<1x+9)KC!FfV?BA7}b$nJ((*yn^6Gtvh!aFIUHMzjTpf?@wfReyx7I#E|H)rH2#$mOUPm=S3{|&KwotK9wE$D|a$B<=HB*U#O`H5pPSkzm@VWv@EnObS&%u*b8U^Reg2TBkQ#A>+-`Oyu67) z?@+-A%QT!uv6M+T{&Y4ZFv2wFDh!r9TZZT2D%8U87cg1Zbk22n*SS6+A`^y?Air5R a-ldW)68^pm`SnwPO0(rY*rkfQ*`+@XUnN2S diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/_mixin.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/_mixin.cpython-39.pyc deleted file mode 100644 index 24ad82b4ed2e993a20ec7b246efc14dc14c1bcc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10623 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 M8|b8(3~JDS0g>yT!~g&Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/api.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/api.cpython-39.pyc deleted file mode 100644 index f31c35de49e8a3aa07e16608c708f9b54ae2c0e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3679 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 QqTNs-8RMcpDgTB40hc*qSO5S3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/compat.cpython-39.pyc deleted file mode 100644 index 34f0afd3a78f51e373cc3f1f7fda7b8a825f503e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1197 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 Z2F0%MV diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/iri.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/iri.cpython-39.pyc deleted file mode 100644 index 0f96799d6c98ccf6db39a678029e7a51c23182e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4430 zcma)9-*4N-9p@b>ijrl=b=suufQ{(7wZc%sj?@^ZJbQnhBj(5kqmT2(24B5o82_Zs?B$^IK1%)-s>tw+h($bMJ??R4L}p|qX3z30-L9Zr@hZA) zqiuV(ZdcK+dR5(a&~`kB8N&v4swFkA_KA^Ru?$h)Pnkh?gt1SJlrI~7J`P!i{_VMDzs4RGg)5*4Crz z_t)=>wvZwXu_6iby!9=PWi(k)PlKL_)BwxAW#y0^X1#u(=%siXiaza>qi6NvJj8P@ z&15e~;-QcIlP)-(MN}Q_9#n6LUrA;<{90yvVeVK(K z8c3lx$onFU+p%8j-v40Dz4nXi@41_hf^2ZD^-lR6x7BjfOo^2hy^21)1(T6T`CzwK z+B41}Y$~3R7(%uK7%WI5w-@ZY{VdPp-DKYlJ3+b!Tc^`~$n@=jfTjRY<+XaPb|k~!xt|c zc5=3m)AY$jdZm-Eq2vnHh#hc+TCqbeUmY1;K4O104tV;Z9yJen9t{_1d~A)_F=his zT9%LmGGi1h%byV_K<5Ey|zX%F9jS09th=4 zz(R*Y2Jexrq5B}!0fsS+5Sab>^1+);@~_X|L8DnK>Tw>Yxe5R@MMa~Eyoytm)}3q1 ztmo%S!mdSaYrijUOPR^ShO_npRago`g#$eSlYGBv7FI5jc2Us+cs2d-A)Gd5S-p(i z3)}a_Bj3MCN_-WS!7Wy24HV86@#M^6i>LgwUL9V3&Lp%hB;Y%{s7+SU79n3!MwgMd zcgOvkm${4c|jC;%vnBrZtbd+)B*f=l| zv}VL!p_;#9D0^H*%S0cuCq3&zuTu8lDmD&p2Q}#D9$~2)XyiI~6*8{InY|eC;||i8 z@U(4CXIA?=E^rif(y!=rQe^GvTDb^yYfH-|YF(y^ z(4gr^GD~5rj1E`&%N#a7^Ah=EdR^O-*`OcAp^^l;#bTL*dsC!51gEw7}@*C&QO#57?TC$&K$p(-ivujvb$|E`Vsn z<=4-^h6aXQR!l!%S9}bAItIXe!I0O%j*gr^8&TzeV~r)f$R1a8#;-=skwar+JF<`2 zEkG1O7)GktiOG?2#x?4p)Q@>oy9&>|im#$Sr)PXU;!#~SsDH?=8t>tqn(r>4e`!Rs z7ExY6SwaDa`jWi15&Roodt2vs%Ive}pQQVX+5QZ|W;}MiWKugjag+u-JMMY9){~P2 z*&nV#d3I-Kk|=&hb3fbJnfi-(s$}2-UFTLh zxKH9FnWZdGV%2fiZ*8o;yS#jTM(9bHkr;mITJoHGQ1pB-NK2BUI)R!npxhNf*rCW% zXR$+KXw276ITeU@fL_39+%o31Tr!9W9a48n9^H6KLockIa93hH7r!tQ-jZ^{iVKd} znk8h@ea^#om27wp5z`qP!}YankVINe@Z${UA~U@~YI)<#kVLX*^i1oNg0R`6K@1jI zY6e;Bdzpd)grZ*4T%~^!j*O8(j(y1Fhr=t1A%h!Z^O$}b5Ex&YpCCMuuMq_Mcg`~Q z*nVbos}w+Gh8|%~v$ApFbCeti_j4+g)x zTlkbsNE@o6o~!7ZFY%L-6Nw8_Fg99V*yW~0CCQ!$S=7jJH4%^%2;eQQr;qV>5v`sP zJq@rpibXb&uVcTk?S^n1L^36l-Bq?3OA)G-&(9yb5)Qx!(RTHjMVC46mXQvBXj z^<(x-tN)n&jX$zBOTn64gTMSKrlS2bJcz4G{87pG(3z3Gej|xsekeu{ z=vPGIzJt^goBKr;m+hL;eT@McwyHJjb6$!}lKzf~2IN^g|M5A%-h?lBryCe)$^K z$e+-{In4`t0>31Y&b;~*#r)*ABNRz8`SmD`euY-*(-LEIQF2n2V_J2~G)@;TIZKYo zS>v)M%*_S)0p8*(8S;w;>Rb{G$m>**vuL|&dQsYmOd`qP#oW4vI&ENY0Y>uIKE8YJ z7g77;t zrk@}fPeACAC|Ktr9p3{i%z5u~ECN_+fyI5mY_L8A{pLtdgT929&_|pbA@e++aL+6tx2^bf0sh`$4Cu|=kJ5Ev#9A5cFptH9yJr$wRib|Q+B8862`cs-cEJRUJnz8-X7(+x=CnylZH!x zPAIE}ZFp$5ZOiO2v#M*uB6=-s6JD$9U|!2>HeiL{IuS} z9qi4R{a(u@cJJ6zprV%N`?inCu@`I*v)O?}86QeCv4e?SH!R$?J2q5JQH=KYr|mg{ zjW?ip-+?w^a)>RX-h%Q`6iAogU~O-CbA5TU^tcZ!+iAEPFIP`9PcoYfYq_+y@$%kj zW}Ta?fg3OHpJq1G=i=VEm>$S`wXX(p?d$X)2-*^5nr{y>qz7|*OLV!mxkMq=O}3^7 zF@V-5XqqU{mDd;W)FsxY(Zf&~BnLuwU^x*E;8pAkQ0Bfa4B@GC zBE6C<=}bJ8Pb5n`k=amM(xNcrSt5*1xB3 z9!|Sf3g_ZoPsqr`548{6nM4?sArR@g2wMr5a0 zu0Tiy+EqY-Qci7Rx3M2U8}qpXFvf?o1=8zL}sl?)Ek9|89f79iHFaKfrZ%sT8Y6Hf7&( z{;Ezb33yw);N#&xlZ{!hD1k)@1f_@)loe5txcupl_(k~1AW}q9BlSqK$cq7h{%vC|kq5k;0!qm3fi?xCzwYPGX8*CM&} z>{7OvCD7LCrH2B&_Cy|i>7UR)WKIQo^0_wwiTis)QKA$yK$n=WH*eqm=6%g$I6GTn zc>eX>M);3+82dLZrXLH7&(N~Jpp&e|B$uMaYg}5=Zi%*4vpB=t!Q8Idn7h*ZhSePD z%NdNWEXhk4Jz18s7=1Y>=P}O61$h}`NiNDO7%$0p>&2Y1-O-_^YjrdKRg$8>`*w zVca>~{dKaxnL^ay6EN6k=$ zQ68&I&zKHbHUwthUNv`=l)q37b^B9g}4o5;R9%S+CAd~O>6faNgy@dHWd;c)*wQ1bl zFw0(~N}l32pc|<=gR0(ze1bRO{Q-CrmenbE*Du1OgOf{c64Rg1ul(bu!3BdR!azNaDoPNdi`tDY9Z&Ec!YEdB=8B~*W6<7-=hsS;5Lmx+L9c2K zjO%FGd+3-b^Ah)Y$#vff;eID9_gi7jeJh+f>y|LQ-}8afY<3Or7f5Oaj*2*kss;?P zjnR1WjkBXuc0+<}P7YrYY8Ef+D=KcMhjCq|c|D7twkfy5Cv4)qfO|TEY5O7GH~Ewa z1f1}>`Y|Z~8|=dOz#5P@&x3s4i`CHt7oCB`)lV?{ zzX82>9#BJtMlBOeY6U_mY$h8QK}|*Vgypw*Wg1rn>;C-8?>1H+gsY9)tDk)J_4?o( zP>Llwh>4|-Fv(%qaV){eh@t!Jt6LN~Lu-V@2Y*Lu$I2P8kr=S&pcw7`aii4=PFyiK z%f><0OnWUE?8iZ`i|y4Y%wkzBl>$5ukR{@mVH>IbgJ5rOdF8{fk)|v6AFPD?%X@oM z@8&(#i6s&svZG<#IAPrQ9E?>Xt>S7ci*r4{v-N0mYx~J*M0pfSVXLLRBr_mXfOBfc z%qy1Wnf6T3#hK>q3tBdQ5rIE5^^P-#5c2ur*k8_Rl46;f(d0LnKv$@GC=)$p&>(5@ z_5c?kCd9^R9RYkXjBJET}U#wO8)>^e%@wAh5TM6#g5O$|j z)=j&*l;xqyGb+8bn{;sJ<=V&Ym|{OmlTO7}YmlY=30CccROwKWWo-6OOpxn&kE!xF(NQGi7Cas~ ze*}FZB53W5*RZ81tf4Ehb07wG?!96IC-hFa&ER9%x=~?-ZR?cv?@Qh#V&|JF1xxydu;rxgV7Z8Eu zF|<#{Hul5#&T^uaoN;T7^o5N7_Nz z`ZU%Sss!!InBa{szWMDhx9dBbPwHFSn_u4Fy06{%Wlp~0qJBU`Vr>qis`yl8rZ(GC zN&U1mC&w9s*Ow=E;DnOt8R8uyT1>L~Ifhu)E{!G2I@mN%v`wtqr@juH7hFs)jM>jV z{x=}XsD@(XX|~`CZ*9BG=Y%U3#R4)!nd6$}<+s8ralvm0wL@oE)LtD|U{tSbp<)v> zMvq1xrtUUHq@s#UQQc$iWpm$|J4R7L*B(DiCO+k9dQIXSj6g{=Q++x+MG h#XLx+8nC&KdZ29ijz5d$_)Gqb@A+QI^2`46e*w>3dyxPD diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/parseresult.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/parseresult.cpython-39.pyc deleted file mode 100644 index 247d93ca11284c51a8f6681a54ee93d37b803b16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9930 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 diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/uri.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/uri.cpython-39.pyc deleted file mode 100644 index 681aab95164b8bbdfd8b6de65714eda395167cb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4239 zcma)9TW{OQ6(%W)qGVf1lkGNH6kB$IwkyIYAOjKZ>Jx-;opM zM6-0tW(+hLC9#u?74`9F_da7|##tO-$J7^M_!WfI271f`tzDIo0Kdy`F<-ICSDfve76X66w(-61i#|bTI2g zv1D-w4l;4}m=i`EhfEJa7t+TezQo+#p;GW%FkbLhj0%a^^E44mIKGrT+M7#s#|c+E z#>sS=JR?a-+er+u1)0lN0z&9Qwhc!F6IfJ{HynR1Ckc<_VKIiCCPnx2IpZaH%>8{r zL3Q0qg3+jCsJ7)-X9W$C`Ohcr%?#!WzQw|U-xF_i->W@4+18D#-xcu zrMhYKgejB)d^Pq;Kv$rzrG2w^5T*#?&6vd;qBc*gJeMakb!f%^&0NV(mN^oIaJ}x_ zd+_wex&vQF=ceO_A;N1N8vf4%$nBO7P>xtc=kXi3kQu+!Ubg3Qyzx=cY2+6heR^AX z#U>i5NqwQ67^lWUTj=S9P+u77CA6*deYEDHeP$hZ7S^KUwH6&D665H-EzS_S0f(49 zBS_TAVS8X^Z81+7=X6Te@jR^Yyv#=8OhN?fft|I2smQE6C}-VDyO~KonzfaGWOfNb zzDA5%oQ=QKv##eURCylng8cH6pO1DP98P2s?{Gw@WVZ7#m?X(`=iVoG?|35MK1A6W z!n>dD{3hDl5s_pYsUJM?_nFw?^HC21`5ziG!td|T0s6GQy|s4tDv z)?If4 zsl71HbY-Ovwx|Z-==Rs<>ANz>T)km<~swb*~*9dmHDdKj%J`YL*BXK=8C{)t6q@lm~M+hr~Ix@}N4AV>zNbWj*YvGXtwt3C zHGGP?>{*0#S{?^s>!>`ec#k+)ezXLsYBJLX=M;W8RsHVyiWj_=sx^L&$Te2HI!@SS z9M4ROw1^uBkXgUxKyieBgZ7`Ri7Kq{3q-w8Q>!R*5fduZ40Qe->Qj7a;H+EiImARB zB31}urrv*LwE7Bi=D&~LUD9Z^DWHH`J`^N~y$TX8I#N5;7jWe><5-u*K?@iI)=t}J z8XQ|&v_kzdwZ>&lTBjZKS{P$>F*27%?R}y|Bg3@mAz`5FLF;G0P7?B99?Q&aoC8sfGd4emw#*geT=f6=grjDEmH5Q z=TVf+qc3ITFbP0zi)kW-N_zY}{bAnSQ9%GRg%AAGufcl*)9Jc`urs(LCn*gwgY@KXxwg3`Nre$`k- IR=}_IUsyS?{Qv*} diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/validators.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/__pycache__/validators.cpython-39.pyc deleted file mode 100644 index 26eeb4f20d86e9a359edaaa3766faa2c863baff8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12923 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 CN8&R8 diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/_mixin.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/_mixin.py deleted file mode 100644 index 46e200e2..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/_mixin.py +++ /dev/null @@ -1,373 +0,0 @@ -"""Module containing the implementation of the URIMixin class.""" -import warnings - -from . import exceptions as exc -from . import misc -from . import normalizers -from . import validators - - -class URIMixin(object): - """Mixin with all shared methods for URIs and IRIs.""" - - __hash__ = tuple.__hash__ - - def authority_info(self): - """Return a dictionary with the ``userinfo``, ``host``, and ``port``. - - If the authority is not valid, it will raise a - :class:`~rfc3986.exceptions.InvalidAuthority` Exception. - - :returns: - ``{'userinfo': 'username:password', 'host': 'www.example.com', - 'port': '80'}`` - :rtype: dict - :raises rfc3986.exceptions.InvalidAuthority: - If the authority is not ``None`` and can not be parsed. - """ - if not self.authority: - return {"userinfo": None, "host": None, "port": None} - - match = self._match_subauthority() - - if match is None: - # In this case, we have an authority that was parsed from the URI - # Reference, but it cannot be further parsed by our - # misc.SUBAUTHORITY_MATCHER. In this case it must not be a valid - # authority. - raise exc.InvalidAuthority(self.authority.encode(self.encoding)) - - # We had a match, now let's ensure that it is actually a valid host - # address if it is IPv4 - matches = match.groupdict() - host = matches.get("host") - - if ( - host - and misc.IPv4_MATCHER.match(host) - and not validators.valid_ipv4_host_address(host) - ): - # If we have a host, it appears to be IPv4 and it does not have - # valid bytes, it is an InvalidAuthority. - raise exc.InvalidAuthority(self.authority.encode(self.encoding)) - - return matches - - def _match_subauthority(self): - return misc.SUBAUTHORITY_MATCHER.match(self.authority) - - @property - def host(self): - """If present, a string representing the host.""" - try: - authority = self.authority_info() - except exc.InvalidAuthority: - return None - return authority["host"] - - @property - def port(self): - """If present, the port extracted from the authority.""" - try: - authority = self.authority_info() - except exc.InvalidAuthority: - return None - return authority["port"] - - @property - def userinfo(self): - """If present, the userinfo extracted from the authority.""" - try: - authority = self.authority_info() - except exc.InvalidAuthority: - return None - return authority["userinfo"] - - def is_absolute(self): - """Determine if this URI Reference is an absolute URI. - - See http://tools.ietf.org/html/rfc3986#section-4.3 for explanation. - - :returns: ``True`` if it is an absolute URI, ``False`` otherwise. - :rtype: bool - """ - return bool(misc.ABSOLUTE_URI_MATCHER.match(self.unsplit())) - - def is_valid(self, **kwargs): - """Determine if the URI is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param bool require_scheme: Set to ``True`` if you wish to require the - presence of the scheme component. - :param bool require_authority: Set to ``True`` if you wish to require - the presence of the authority component. - :param bool require_path: Set to ``True`` if you wish to require the - presence of the path component. - :param bool require_query: Set to ``True`` if you wish to require the - presence of the query component. - :param bool require_fragment: Set to ``True`` if you wish to require - the presence of the fragment component. - :returns: ``True`` if the URI is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn( - "Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning, - ) - validators = [ - (self.scheme_is_valid, kwargs.get("require_scheme", False)), - (self.authority_is_valid, kwargs.get("require_authority", False)), - (self.path_is_valid, kwargs.get("require_path", False)), - (self.query_is_valid, kwargs.get("require_query", False)), - (self.fragment_is_valid, kwargs.get("require_fragment", False)), - ] - return all(v(r) for v, r in validators) - - def authority_is_valid(self, require=False): - """Determine if the authority component is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param bool require: - Set to ``True`` to require the presence of this component. - :returns: - ``True`` if the authority is valid. ``False`` otherwise. - :rtype: - bool - """ - warnings.warn( - "Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning, - ) - try: - self.authority_info() - except exc.InvalidAuthority: - return False - - return validators.authority_is_valid( - self.authority, - host=self.host, - require=require, - ) - - def scheme_is_valid(self, require=False): - """Determine if the scheme component is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param str require: Set to ``True`` to require the presence of this - component. - :returns: ``True`` if the scheme is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn( - "Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning, - ) - return validators.scheme_is_valid(self.scheme, require) - - def path_is_valid(self, require=False): - """Determine if the path component is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param str require: Set to ``True`` to require the presence of this - component. - :returns: ``True`` if the path is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn( - "Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning, - ) - return validators.path_is_valid(self.path, require) - - def query_is_valid(self, require=False): - """Determine if the query component is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param str require: Set to ``True`` to require the presence of this - component. - :returns: ``True`` if the query is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn( - "Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning, - ) - return validators.query_is_valid(self.query, require) - - def fragment_is_valid(self, require=False): - """Determine if the fragment component is valid. - - .. deprecated:: 1.1.0 - - Use the Validator object instead. - - :param str require: Set to ``True`` to require the presence of this - component. - :returns: ``True`` if the fragment is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn( - "Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning, - ) - return validators.fragment_is_valid(self.fragment, require) - - def normalized_equality(self, other_ref): - """Compare this URIReference to another URIReference. - - :param URIReference other_ref: (required), The reference with which - we're comparing. - :returns: ``True`` if the references are equal, ``False`` otherwise. - :rtype: bool - """ - return tuple(self.normalize()) == tuple(other_ref.normalize()) - - def resolve_with(self, base_uri, strict=False): - """Use an absolute URI Reference to resolve this relative reference. - - Assuming this is a relative reference that you would like to resolve, - use the provided base URI to resolve it. - - See http://tools.ietf.org/html/rfc3986#section-5 for more information. - - :param base_uri: Either a string or URIReference. It must be an - absolute URI or it will raise an exception. - :returns: A new URIReference which is the result of resolving this - reference using ``base_uri``. - :rtype: :class:`URIReference` - :raises rfc3986.exceptions.ResolutionError: - If the ``base_uri`` is not an absolute URI. - """ - if not isinstance(base_uri, URIMixin): - base_uri = type(self).from_string(base_uri) - - if not base_uri.is_absolute(): - raise exc.ResolutionError(base_uri) - - # This is optional per - # http://tools.ietf.org/html/rfc3986#section-5.2.1 - base_uri = base_uri.normalize() - - # The reference we're resolving - resolving = self - - if not strict and resolving.scheme == base_uri.scheme: - resolving = resolving.copy_with(scheme=None) - - # http://tools.ietf.org/html/rfc3986#page-32 - if resolving.scheme is not None: - target = resolving.copy_with( - path=normalizers.normalize_path(resolving.path) - ) - else: - if resolving.authority is not None: - target = resolving.copy_with( - scheme=base_uri.scheme, - path=normalizers.normalize_path(resolving.path), - ) - else: - if resolving.path is None: - if resolving.query is not None: - query = resolving.query - else: - query = base_uri.query - target = resolving.copy_with( - scheme=base_uri.scheme, - authority=base_uri.authority, - path=base_uri.path, - query=query, - ) - else: - if resolving.path.startswith("/"): - path = normalizers.normalize_path(resolving.path) - else: - path = normalizers.normalize_path( - misc.merge_paths(base_uri, resolving.path) - ) - target = resolving.copy_with( - scheme=base_uri.scheme, - authority=base_uri.authority, - path=path, - query=resolving.query, - ) - return target - - def unsplit(self): - """Create a URI string from the components. - - :returns: The URI Reference reconstituted as a string. - :rtype: str - """ - # See http://tools.ietf.org/html/rfc3986#section-5.3 - result_list = [] - if self.scheme: - result_list.extend([self.scheme, ":"]) - if self.authority: - result_list.extend(["//", self.authority]) - if self.path: - result_list.append(self.path) - if self.query is not None: - result_list.extend(["?", self.query]) - if self.fragment is not None: - result_list.extend(["#", self.fragment]) - return "".join(result_list) - - def copy_with( - self, - scheme=misc.UseExisting, - authority=misc.UseExisting, - path=misc.UseExisting, - query=misc.UseExisting, - fragment=misc.UseExisting, - ): - """Create a copy of this reference with the new components. - - :param str scheme: - (optional) The scheme to use for the new reference. - :param str authority: - (optional) The authority to use for the new reference. - :param str path: - (optional) The path to use for the new reference. - :param str query: - (optional) The query to use for the new reference. - :param str fragment: - (optional) The fragment to use for the new reference. - :returns: - New URIReference with provided components. - :rtype: - URIReference - """ - attributes = { - "scheme": scheme, - "authority": authority, - "path": path, - "query": query, - "fragment": fragment, - } - for key, value in list(attributes.items()): - if value is misc.UseExisting: - del attributes[key] - uri = self._replace(**attributes) - uri.encoding = self.encoding - return uri diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/abnf_regexp.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/abnf_regexp.py deleted file mode 100644 index a2e7ee7a..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/abnf_regexp.py +++ /dev/null @@ -1,282 +0,0 @@ -# -*- coding: utf-8 -*- -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module for the regular expressions crafted from ABNF.""" - -import sys - -# https://tools.ietf.org/html/rfc3986#page-13 -GEN_DELIMS = GENERIC_DELIMITERS = ":/?#[]@" -GENERIC_DELIMITERS_SET = set(GENERIC_DELIMITERS) -# https://tools.ietf.org/html/rfc3986#page-13 -SUB_DELIMS = SUB_DELIMITERS = "!$&'()*+,;=" -SUB_DELIMITERS_SET = set(SUB_DELIMITERS) -# Escape the '*' for use in regular expressions -SUB_DELIMITERS_RE = r"!$&'()\*+,;=" -RESERVED_CHARS_SET = GENERIC_DELIMITERS_SET.union(SUB_DELIMITERS_SET) -ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" -DIGIT = "0123456789" -# https://tools.ietf.org/html/rfc3986#section-2.3 -UNRESERVED = UNRESERVED_CHARS = ALPHA + DIGIT + r"._!-~" -UNRESERVED_CHARS_SET = set(UNRESERVED_CHARS) -NON_PCT_ENCODED_SET = RESERVED_CHARS_SET.union(UNRESERVED_CHARS_SET) -# We need to escape the '-' in this case: -UNRESERVED_RE = r"A-Za-z0-9._~\-" - -# Percent encoded character values -PERCENT_ENCODED = PCT_ENCODED = "%[A-Fa-f0-9]{2}" -PCHAR = "([" + UNRESERVED_RE + SUB_DELIMITERS_RE + ":@]|%s)" % PCT_ENCODED - -# NOTE(sigmavirus24): We're going to use more strict regular expressions -# than appear in Appendix B for scheme. This will prevent over-eager -# consuming of items that aren't schemes. -SCHEME_RE = "[a-zA-Z][a-zA-Z0-9+.-]*" -_AUTHORITY_RE = "[^\\\\/?#]*" -_PATH_RE = "[^?#]*" -_QUERY_RE = "[^#]*" -_FRAGMENT_RE = ".*" - -# Extracted from http://tools.ietf.org/html/rfc3986#appendix-B -COMPONENT_PATTERN_DICT = { - "scheme": SCHEME_RE, - "authority": _AUTHORITY_RE, - "path": _PATH_RE, - "query": _QUERY_RE, - "fragment": _FRAGMENT_RE, -} - -# See http://tools.ietf.org/html/rfc3986#appendix-B -# In this case, we name each of the important matches so we can use -# SRE_Match#groupdict to parse the values out if we so choose. This is also -# modified to ignore other matches that are not important to the parsing of -# the reference so we can also simply use SRE_Match#groups. -URL_PARSING_RE = ( - r"(?:(?P{scheme}):)?(?://(?P{authority}))?" - r"(?P{path})(?:\?(?P{query}))?" - r"(?:#(?P{fragment}))?" -).format(**COMPONENT_PATTERN_DICT) - - -# ######################### -# Authority Matcher Section -# ######################### - -# Host patterns, see: http://tools.ietf.org/html/rfc3986#section-3.2.2 -# The pattern for a regular name, e.g., www.google.com, api.github.com -REGULAR_NAME_RE = REG_NAME = "((?:{0}|[{1}])*)".format( - "%[0-9A-Fa-f]{2}", SUB_DELIMITERS_RE + UNRESERVED_RE -) -# The pattern for an IPv4 address, e.g., 192.168.255.255, 127.0.0.1, -IPv4_RE = r"([0-9]{1,3}\.){3}[0-9]{1,3}" -# Hexadecimal characters used in each piece of an IPv6 address -HEXDIG_RE = "[0-9A-Fa-f]{1,4}" -# Least-significant 32 bits of an IPv6 address -LS32_RE = "({hex}:{hex}|{ipv4})".format(hex=HEXDIG_RE, ipv4=IPv4_RE) -# Substitutions into the following patterns for IPv6 patterns defined -# http://tools.ietf.org/html/rfc3986#page-20 -_subs = {"hex": HEXDIG_RE, "ls32": LS32_RE} - -# Below: h16 = hexdig, see: https://tools.ietf.org/html/rfc5234 for details -# about ABNF (Augmented Backus-Naur Form) use in the comments -variations = [ - # 6( h16 ":" ) ls32 - "(%(hex)s:){6}%(ls32)s" % _subs, - # "::" 5( h16 ":" ) ls32 - "::(%(hex)s:){5}%(ls32)s" % _subs, - # [ h16 ] "::" 4( h16 ":" ) ls32 - "(%(hex)s)?::(%(hex)s:){4}%(ls32)s" % _subs, - # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 - "((%(hex)s:)?%(hex)s)?::(%(hex)s:){3}%(ls32)s" % _subs, - # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 - "((%(hex)s:){0,2}%(hex)s)?::(%(hex)s:){2}%(ls32)s" % _subs, - # [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 - "((%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s" % _subs, - # [ *4( h16 ":" ) h16 ] "::" ls32 - "((%(hex)s:){0,4}%(hex)s)?::%(ls32)s" % _subs, - # [ *5( h16 ":" ) h16 ] "::" h16 - "((%(hex)s:){0,5}%(hex)s)?::%(hex)s" % _subs, - # [ *6( h16 ":" ) h16 ] "::" - "((%(hex)s:){0,6}%(hex)s)?::" % _subs, -] - -IPv6_RE = "(({0})|({1})|({2})|({3})|({4})|({5})|({6})|({7})|({8}))".format( - *variations -) - -IPv_FUTURE_RE = r"v[0-9A-Fa-f]+\.[%s]+" % ( - UNRESERVED_RE + SUB_DELIMITERS_RE + ":" -) - -# RFC 6874 Zone ID ABNF -ZONE_ID = "(?:[" + UNRESERVED_RE + "]|" + PCT_ENCODED + ")+" - -IPv6_ADDRZ_RFC4007_RE = IPv6_RE + "(?:(?:%25|%)" + ZONE_ID + ")?" -IPv6_ADDRZ_RE = IPv6_RE + "(?:%25" + ZONE_ID + ")?" - -IP_LITERAL_RE = r"\[({0}|{1})\]".format( - IPv6_ADDRZ_RFC4007_RE, - IPv_FUTURE_RE, -) - -# Pattern for matching the host piece of the authority -HOST_RE = HOST_PATTERN = "({0}|{1}|{2})".format( - REG_NAME, - IPv4_RE, - IP_LITERAL_RE, -) -USERINFO_RE = ( - "^([" + UNRESERVED_RE + SUB_DELIMITERS_RE + ":]|%s)+" % (PCT_ENCODED) -) -PORT_RE = "[0-9]{1,5}" - -# #################### -# Path Matcher Section -# #################### - -# See http://tools.ietf.org/html/rfc3986#section-3.3 for more information -# about the path patterns defined below. -segments = { - "segment": PCHAR + "*", - # Non-zero length segment - "segment-nz": PCHAR + "+", - # Non-zero length segment without ":" - "segment-nz-nc": PCHAR.replace(":", "") + "+", -} - -# Path types taken from Section 3.3 (linked above) -PATH_EMPTY = "^$" -PATH_ROOTLESS = "%(segment-nz)s(/%(segment)s)*" % segments -PATH_NOSCHEME = "%(segment-nz-nc)s(/%(segment)s)*" % segments -PATH_ABSOLUTE = "/(%s)?" % PATH_ROOTLESS -PATH_ABEMPTY = "(/%(segment)s)*" % segments -PATH_RE = "^(%s|%s|%s|%s|%s)$" % ( - PATH_ABEMPTY, - PATH_ABSOLUTE, - PATH_NOSCHEME, - PATH_ROOTLESS, - PATH_EMPTY, -) - -FRAGMENT_RE = QUERY_RE = ( - "^([/?:@" + UNRESERVED_RE + SUB_DELIMITERS_RE + "]|%s)*$" % PCT_ENCODED -) - -# ########################## -# Relative reference matcher -# ########################## - -# See http://tools.ietf.org/html/rfc3986#section-4.2 for details -RELATIVE_PART_RE = "(//%s%s|%s|%s|%s)" % ( - COMPONENT_PATTERN_DICT["authority"], - PATH_ABEMPTY, - PATH_ABSOLUTE, - PATH_NOSCHEME, - PATH_EMPTY, -) - -# See http://tools.ietf.org/html/rfc3986#section-3 for definition -HIER_PART_RE = "(//%s%s|%s|%s|%s)" % ( - COMPONENT_PATTERN_DICT["authority"], - PATH_ABEMPTY, - PATH_ABSOLUTE, - PATH_ROOTLESS, - PATH_EMPTY, -) - -# ############### -# IRIs / RFC 3987 -# ############### - -# Only wide-unicode gets the high-ranges of UCSCHAR -if sys.maxunicode > 0xFFFF: # pragma: no cover - IPRIVATE = u"\uE000-\uF8FF\U000F0000-\U000FFFFD\U00100000-\U0010FFFD" - UCSCHAR_RE = ( - u"\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF" - u"\U00010000-\U0001FFFD\U00020000-\U0002FFFD" - u"\U00030000-\U0003FFFD\U00040000-\U0004FFFD" - u"\U00050000-\U0005FFFD\U00060000-\U0006FFFD" - u"\U00070000-\U0007FFFD\U00080000-\U0008FFFD" - u"\U00090000-\U0009FFFD\U000A0000-\U000AFFFD" - u"\U000B0000-\U000BFFFD\U000C0000-\U000CFFFD" - u"\U000D0000-\U000DFFFD\U000E1000-\U000EFFFD" - ) -else: # pragma: no cover - IPRIVATE = u"\uE000-\uF8FF" - UCSCHAR_RE = u"\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF" - -IUNRESERVED_RE = u"A-Za-z0-9\\._~\\-" + UCSCHAR_RE -IPCHAR = u"([" + IUNRESERVED_RE + SUB_DELIMITERS_RE + u":@]|%s)" % PCT_ENCODED - -isegments = { - "isegment": IPCHAR + u"*", - # Non-zero length segment - "isegment-nz": IPCHAR + u"+", - # Non-zero length segment without ":" - "isegment-nz-nc": IPCHAR.replace(":", "") + u"+", -} - -IPATH_ROOTLESS = u"%(isegment-nz)s(/%(isegment)s)*" % isegments -IPATH_NOSCHEME = u"%(isegment-nz-nc)s(/%(isegment)s)*" % isegments -IPATH_ABSOLUTE = u"/(?:%s)?" % IPATH_ROOTLESS -IPATH_ABEMPTY = u"(?:/%(isegment)s)*" % isegments -IPATH_RE = u"^(?:%s|%s|%s|%s|%s)$" % ( - IPATH_ABEMPTY, - IPATH_ABSOLUTE, - IPATH_NOSCHEME, - IPATH_ROOTLESS, - PATH_EMPTY, -) - -IREGULAR_NAME_RE = IREG_NAME = u"(?:{0}|[{1}])*".format( - u"%[0-9A-Fa-f]{2}", SUB_DELIMITERS_RE + IUNRESERVED_RE -) - -IHOST_RE = IHOST_PATTERN = u"({0}|{1}|{2})".format( - IREG_NAME, - IPv4_RE, - IP_LITERAL_RE, -) - -IUSERINFO_RE = ( - u"^(?:[" + IUNRESERVED_RE + SUB_DELIMITERS_RE + u":]|%s)+" % (PCT_ENCODED) -) - -IFRAGMENT_RE = ( - u"^(?:[/?:@" - + IUNRESERVED_RE - + SUB_DELIMITERS_RE - + u"]|%s)*$" % PCT_ENCODED -) -IQUERY_RE = ( - u"^(?:[/?:@" - + IUNRESERVED_RE - + SUB_DELIMITERS_RE - + IPRIVATE - + u"]|%s)*$" % PCT_ENCODED -) - -IRELATIVE_PART_RE = u"(//%s%s|%s|%s|%s)" % ( - COMPONENT_PATTERN_DICT["authority"], - IPATH_ABEMPTY, - IPATH_ABSOLUTE, - IPATH_NOSCHEME, - PATH_EMPTY, -) - -IHIER_PART_RE = u"(//%s%s|%s|%s|%s)" % ( - COMPONENT_PATTERN_DICT["authority"], - IPATH_ABEMPTY, - IPATH_ABSOLUTE, - IPATH_ROOTLESS, - PATH_EMPTY, -) diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/api.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/api.py deleted file mode 100644 index 1e098b34..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/api.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Module containing the simple and functional API for rfc3986. - -This module defines functions and provides access to the public attributes -and classes of rfc3986. -""" - -from .iri import IRIReference -from .parseresult import ParseResult -from .uri import URIReference - - -def uri_reference(uri, encoding="utf-8"): - """Parse a URI string into a URIReference. - - This is a convenience function. You could achieve the same end by using - ``URIReference.from_string(uri)``. - - :param str uri: The URI which needs to be parsed into a reference. - :param str encoding: The encoding of the string provided - :returns: A parsed URI - :rtype: :class:`URIReference` - """ - return URIReference.from_string(uri, encoding) - - -def iri_reference(iri, encoding="utf-8"): - """Parse a IRI string into an IRIReference. - - This is a convenience function. You could achieve the same end by using - ``IRIReference.from_string(iri)``. - - :param str iri: The IRI which needs to be parsed into a reference. - :param str encoding: The encoding of the string provided - :returns: A parsed IRI - :rtype: :class:`IRIReference` - """ - return IRIReference.from_string(iri, encoding) - - -def is_valid_uri(uri, encoding="utf-8", **kwargs): - """Determine if the URI given is valid. - - This is a convenience function. You could use either - ``uri_reference(uri).is_valid()`` or - ``URIReference.from_string(uri).is_valid()`` to achieve the same result. - - :param str uri: The URI to be validated. - :param str encoding: The encoding of the string provided - :param bool require_scheme: Set to ``True`` if you wish to require the - presence of the scheme component. - :param bool require_authority: Set to ``True`` if you wish to require the - presence of the authority component. - :param bool require_path: Set to ``True`` if you wish to require the - presence of the path component. - :param bool require_query: Set to ``True`` if you wish to require the - presence of the query component. - :param bool require_fragment: Set to ``True`` if you wish to require the - presence of the fragment component. - :returns: ``True`` if the URI is valid, ``False`` otherwise. - :rtype: bool - """ - return URIReference.from_string(uri, encoding).is_valid(**kwargs) - - -def normalize_uri(uri, encoding="utf-8"): - """Normalize the given URI. - - This is a convenience function. You could use either - ``uri_reference(uri).normalize().unsplit()`` or - ``URIReference.from_string(uri).normalize().unsplit()`` instead. - - :param str uri: The URI to be normalized. - :param str encoding: The encoding of the string provided - :returns: The normalized URI. - :rtype: str - """ - normalized_reference = URIReference.from_string(uri, encoding).normalize() - return normalized_reference.unsplit() - - -def urlparse(uri, encoding="utf-8"): - """Parse a given URI and return a ParseResult. - - This is a partial replacement of the standard library's urlparse function. - - :param str uri: The URI to be parsed. - :param str encoding: The encoding of the string provided. - :returns: A parsed URI - :rtype: :class:`~rfc3986.parseresult.ParseResult` - """ - return ParseResult.from_string(uri, encoding, strict=False) diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/builder.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/builder.py deleted file mode 100644 index 8fc178c6..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/builder.py +++ /dev/null @@ -1,389 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2017 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module containing the logic for the URIBuilder object.""" -from . import compat -from . import normalizers -from . import uri -from . import uri_reference - - -class URIBuilder(object): - """Object to aid in building up a URI Reference from parts. - - .. note:: - - This object should be instantiated by the user, but it's recommended - that it is not provided with arguments. Instead, use the available - method to populate the fields. - - """ - - def __init__( - self, - scheme=None, - userinfo=None, - host=None, - port=None, - path=None, - query=None, - fragment=None, - ): - """Initialize our URI builder. - - :param str scheme: - (optional) - :param str userinfo: - (optional) - :param str host: - (optional) - :param int port: - (optional) - :param str path: - (optional) - :param str query: - (optional) - :param str fragment: - (optional) - """ - self.scheme = scheme - self.userinfo = userinfo - self.host = host - self.port = port - self.path = path - self.query = query - self.fragment = fragment - - def __repr__(self): - """Provide a convenient view of our builder object.""" - formatstr = ( - "URIBuilder(scheme={b.scheme}, userinfo={b.userinfo}, " - "host={b.host}, port={b.port}, path={b.path}, " - "query={b.query}, fragment={b.fragment})" - ) - return formatstr.format(b=self) - - @classmethod - def from_uri(cls, reference): - """Initialize the URI builder from another URI. - - Takes the given URI reference and creates a new URI builder instance - populated with the values from the reference. If given a string it will - try to convert it to a reference before constructing the builder. - """ - if not isinstance(reference, uri.URIReference): - reference = uri_reference(reference) - return cls( - scheme=reference.scheme, - userinfo=reference.userinfo, - host=reference.host, - port=reference.port, - path=reference.path, - query=reference.query, - fragment=reference.fragment, - ) - - def add_scheme(self, scheme): - """Add a scheme to our builder object. - - After normalizing, this will generate a new URIBuilder instance with - the specified scheme and all other attributes the same. - - .. code-block:: python - - >>> URIBuilder().add_scheme('HTTPS') - URIBuilder(scheme='https', userinfo=None, host=None, port=None, - path=None, query=None, fragment=None) - - """ - scheme = normalizers.normalize_scheme(scheme) - return URIBuilder( - scheme=scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=self.path, - query=self.query, - fragment=self.fragment, - ) - - def add_credentials(self, username, password): - """Add credentials as the userinfo portion of the URI. - - .. code-block:: python - - >>> URIBuilder().add_credentials('root', 's3crete') - URIBuilder(scheme=None, userinfo='root:s3crete', host=None, - port=None, path=None, query=None, fragment=None) - - >>> URIBuilder().add_credentials('root', None) - URIBuilder(scheme=None, userinfo='root', host=None, - port=None, path=None, query=None, fragment=None) - """ - if username is None: - raise ValueError("Username cannot be None") - userinfo = normalizers.normalize_username(username) - - if password is not None: - userinfo = "{}:{}".format( - userinfo, - normalizers.normalize_password(password), - ) - - return URIBuilder( - scheme=self.scheme, - userinfo=userinfo, - host=self.host, - port=self.port, - path=self.path, - query=self.query, - fragment=self.fragment, - ) - - def add_host(self, host): - """Add hostname to the URI. - - .. code-block:: python - - >>> URIBuilder().add_host('google.com') - URIBuilder(scheme=None, userinfo=None, host='google.com', - port=None, path=None, query=None, fragment=None) - - """ - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=normalizers.normalize_host(host), - port=self.port, - path=self.path, - query=self.query, - fragment=self.fragment, - ) - - def add_port(self, port): - """Add port to the URI. - - .. code-block:: python - - >>> URIBuilder().add_port(80) - URIBuilder(scheme=None, userinfo=None, host=None, port='80', - path=None, query=None, fragment=None) - - >>> URIBuilder().add_port(443) - URIBuilder(scheme=None, userinfo=None, host=None, port='443', - path=None, query=None, fragment=None) - - """ - port_int = int(port) - if port_int < 0: - raise ValueError( - "ports are not allowed to be negative. You provided {}".format( - port_int, - ) - ) - if port_int > 65535: - raise ValueError( - "ports are not allowed to be larger than 65535. " - "You provided {}".format( - port_int, - ) - ) - - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port="{}".format(port_int), - path=self.path, - query=self.query, - fragment=self.fragment, - ) - - def add_path(self, path): - """Add a path to the URI. - - .. code-block:: python - - >>> URIBuilder().add_path('sigmavirus24/rfc3985') - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path='/sigmavirus24/rfc3986', query=None, fragment=None) - - >>> URIBuilder().add_path('/checkout.php') - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path='/checkout.php', query=None, fragment=None) - - """ - if not path.startswith("/"): - path = "/{}".format(path) - - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=normalizers.normalize_path(path), - query=self.query, - fragment=self.fragment, - ) - - def extend_path(self, path): - """Extend the existing path value with the provided value. - - .. versionadded:: 1.5.0 - - .. code-block:: python - - >>> URIBuilder(path="/users").extend_path("/sigmavirus24") - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path='/users/sigmavirus24', query=None, fragment=None) - - >>> URIBuilder(path="/users/").extend_path("/sigmavirus24") - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path='/users/sigmavirus24', query=None, fragment=None) - - >>> URIBuilder(path="/users/").extend_path("sigmavirus24") - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path='/users/sigmavirus24', query=None, fragment=None) - - >>> URIBuilder(path="/users").extend_path("sigmavirus24") - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path='/users/sigmavirus24', query=None, fragment=None) - - """ - existing_path = self.path or "" - path = "{}/{}".format(existing_path.rstrip("/"), path.lstrip("/")) - - return self.add_path(path) - - def add_query_from(self, query_items): - """Generate and add a query a dictionary or list of tuples. - - .. code-block:: python - - >>> URIBuilder().add_query_from({'a': 'b c'}) - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query='a=b+c', fragment=None) - - >>> URIBuilder().add_query_from([('a', 'b c')]) - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query='a=b+c', fragment=None) - - """ - query = normalizers.normalize_query(compat.urlencode(query_items)) - - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=self.path, - query=query, - fragment=self.fragment, - ) - - def extend_query_with(self, query_items): - """Extend the existing query string with the new query items. - - .. versionadded:: 1.5.0 - - .. code-block:: python - - >>> URIBuilder(query='a=b+c').extend_query_with({'a': 'b c'}) - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query='a=b+c&a=b+c', fragment=None) - - >>> URIBuilder(query='a=b+c').extend_query_with([('a', 'b c')]) - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query='a=b+c&a=b+c', fragment=None) - """ - original_query_items = compat.parse_qsl(self.query or "") - if not isinstance(query_items, list): - query_items = list(query_items.items()) - - return self.add_query_from(original_query_items + query_items) - - def add_query(self, query): - """Add a pre-formated query string to the URI. - - .. code-block:: python - - >>> URIBuilder().add_query('a=b&c=d') - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query='a=b&c=d', fragment=None) - - """ - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=self.path, - query=normalizers.normalize_query(query), - fragment=self.fragment, - ) - - def add_fragment(self, fragment): - """Add a fragment to the URI. - - .. code-block:: python - - >>> URIBuilder().add_fragment('section-2.6.1') - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query=None, fragment='section-2.6.1') - - """ - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=self.path, - query=self.query, - fragment=normalizers.normalize_fragment(fragment), - ) - - def finalize(self): - """Create a URIReference from our builder. - - .. code-block:: python - - >>> URIBuilder().add_scheme('https').add_host('github.com' - ... ).add_path('sigmavirus24/rfc3986').finalize().unsplit() - 'https://github.com/sigmavirus24/rfc3986' - - >>> URIBuilder().add_scheme('https').add_host('github.com' - ... ).add_path('sigmavirus24/rfc3986').add_credentials( - ... 'sigmavirus24', 'not-re@l').finalize().unsplit() - 'https://sigmavirus24:not-re%40l@github.com/sigmavirus24/rfc3986' - - """ - return uri.URIReference( - self.scheme, - normalizers.normalize_authority( - (self.userinfo, self.host, self.port) - ), - self.path, - self.query, - self.fragment, - ) - - def geturl(self): - """Generate the URL from this builder. - - .. versionadded:: 1.5.0 - - This is an alternative to calling :meth:`finalize` and keeping the - :class:`rfc3986.uri.URIReference` around. - """ - return self.finalize().unsplit() diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/compat.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/compat.py deleted file mode 100644 index 83e5c784..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/compat.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Compatibility module for Python 2 and 3 support.""" -import sys - -try: - from urllib.parse import quote as urlquote -except ImportError: # Python 2.x - from urllib import quote as urlquote - -try: - from urllib.parse import parse_qsl -except ImportError: # Python 2.x - from urlparse import parse_qsl - -try: - from urllib.parse import urlencode -except ImportError: # Python 2.x - from urllib import urlencode - -__all__ = ( - "to_bytes", - "to_str", - "urlquote", - "urlencode", - "parse_qsl", -) - -PY3 = (3, 0) <= sys.version_info < (4, 0) -PY2 = (2, 6) <= sys.version_info < (2, 8) - - -if PY3: - unicode = str # Python 3.x - - -def to_str(b, encoding="utf-8"): - """Ensure that b is text in the specified encoding.""" - if hasattr(b, "decode") and not isinstance(b, unicode): - b = b.decode(encoding) - return b - - -def to_bytes(s, encoding="utf-8"): - """Ensure that s is converted to bytes from the encoding.""" - if hasattr(s, "encode") and not isinstance(s, bytes): - s = s.encode(encoding) - return s diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/exceptions.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/exceptions.py deleted file mode 100644 index b117bc9c..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/exceptions.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -"""Exceptions module for rfc3986.""" - -from . import compat - - -class RFC3986Exception(Exception): - """Base class for all rfc3986 exception classes.""" - - pass - - -class InvalidAuthority(RFC3986Exception): - """Exception when the authority string is invalid.""" - - def __init__(self, authority): - """Initialize the exception with the invalid authority.""" - super(InvalidAuthority, self).__init__( - u"The authority ({0}) is not valid.".format( - compat.to_str(authority) - ) - ) - - -class InvalidPort(RFC3986Exception): - """Exception when the port is invalid.""" - - def __init__(self, port): - """Initialize the exception with the invalid port.""" - super(InvalidPort, self).__init__( - 'The port ("{0}") is not valid.'.format(port) - ) - - -class ResolutionError(RFC3986Exception): - """Exception to indicate a failure to resolve a URI.""" - - def __init__(self, uri): - """Initialize the error with the failed URI.""" - super(ResolutionError, self).__init__( - "{0} is not an absolute URI.".format(uri.unsplit()) - ) - - -class ValidationError(RFC3986Exception): - """Exception raised during Validation of a URI.""" - - pass - - -class MissingComponentError(ValidationError): - """Exception raised when a required component is missing.""" - - def __init__(self, uri, *component_names): - """Initialize the error with the missing component name.""" - verb = "was" - if len(component_names) > 1: - verb = "were" - - self.uri = uri - self.components = sorted(component_names) - components = ", ".join(self.components) - super(MissingComponentError, self).__init__( - "{} {} required but missing".format(components, verb), - uri, - self.components, - ) - - -class UnpermittedComponentError(ValidationError): - """Exception raised when a component has an unpermitted value.""" - - def __init__(self, component_name, component_value, allowed_values): - """Initialize the error with the unpermitted component.""" - super(UnpermittedComponentError, self).__init__( - "{} was required to be one of {!r} but was {!r}".format( - component_name, - list(sorted(allowed_values)), - component_value, - ), - component_name, - component_value, - allowed_values, - ) - self.component_name = component_name - self.component_value = component_value - self.allowed_values = allowed_values - - -class PasswordForbidden(ValidationError): - """Exception raised when a URL has a password in the userinfo section.""" - - def __init__(self, uri): - """Initialize the error with the URI that failed validation.""" - unsplit = getattr(uri, "unsplit", lambda: uri) - super(PasswordForbidden, self).__init__( - '"{}" contained a password when validation forbade it'.format( - unsplit() - ) - ) - self.uri = uri - - -class InvalidComponentsError(ValidationError): - """Exception raised when one or more components are invalid.""" - - def __init__(self, uri, *component_names): - """Initialize the error with the invalid component name(s).""" - verb = "was" - if len(component_names) > 1: - verb = "were" - - self.uri = uri - self.components = sorted(component_names) - components = ", ".join(self.components) - super(InvalidComponentsError, self).__init__( - "{} {} found to be invalid".format(components, verb), - uri, - self.components, - ) - - -class MissingDependencyError(RFC3986Exception): - """Exception raised when an IRI is encoded without the 'idna' module.""" diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/iri.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/iri.py deleted file mode 100644 index 540aa7bc..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/iri.py +++ /dev/null @@ -1,162 +0,0 @@ -"""Module containing the implementation of the IRIReference class.""" -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Copyright (c) 2015 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from collections import namedtuple - -from . import compat -from . import exceptions -from . import misc -from . import normalizers -from . import uri - - -try: - import idna -except ImportError: # pragma: no cover - idna = None - - -class IRIReference( - namedtuple("IRIReference", misc.URI_COMPONENTS), uri.URIMixin -): - """Immutable object representing a parsed IRI Reference. - - Can be encoded into an URIReference object via the procedure - specified in RFC 3987 Section 3.1 - - .. note:: - The IRI submodule is a new interface and may possibly change in - the future. Check for changes to the interface when upgrading. - """ - - slots = () - - def __new__( - cls, scheme, authority, path, query, fragment, encoding="utf-8" - ): - """Create a new IRIReference.""" - ref = super(IRIReference, cls).__new__( - cls, - scheme or None, - authority or None, - path or None, - query, - fragment, - ) - ref.encoding = encoding - return ref - - def __eq__(self, other): - """Compare this reference to another.""" - other_ref = other - if isinstance(other, tuple): - other_ref = self.__class__(*other) - elif not isinstance(other, IRIReference): - try: - other_ref = self.__class__.from_string(other) - except TypeError: - raise TypeError( - "Unable to compare {0}() to {1}()".format( - type(self).__name__, type(other).__name__ - ) - ) - - # See http://tools.ietf.org/html/rfc3986#section-6.2 - return tuple(self) == tuple(other_ref) - - def _match_subauthority(self): - return misc.ISUBAUTHORITY_MATCHER.match(self.authority) - - @classmethod - def from_string(cls, iri_string, encoding="utf-8"): - """Parse a IRI reference from the given unicode IRI string. - - :param str iri_string: Unicode IRI to be parsed into a reference. - :param str encoding: The encoding of the string provided - :returns: :class:`IRIReference` or subclass thereof - """ - iri_string = compat.to_str(iri_string, encoding) - - split_iri = misc.IRI_MATCHER.match(iri_string).groupdict() - return cls( - split_iri["scheme"], - split_iri["authority"], - normalizers.encode_component(split_iri["path"], encoding), - normalizers.encode_component(split_iri["query"], encoding), - normalizers.encode_component(split_iri["fragment"], encoding), - encoding, - ) - - def encode(self, idna_encoder=None): # noqa: C901 - """Encode an IRIReference into a URIReference instance. - - If the ``idna`` module is installed or the ``rfc3986[idna]`` - extra is used then unicode characters in the IRI host - component will be encoded with IDNA2008. - - :param idna_encoder: - Function that encodes each part of the host component - If not given will raise an exception if the IRI - contains a host component. - :rtype: uri.URIReference - :returns: A URI reference - """ - authority = self.authority - if authority: - if idna_encoder is None: - if idna is None: # pragma: no cover - raise exceptions.MissingDependencyError( - "Could not import the 'idna' module " - "and the IRI hostname requires encoding" - ) - - def idna_encoder(name): - if any(ord(c) > 128 for c in name): - try: - return idna.encode( - name.lower(), strict=True, std3_rules=True - ) - except idna.IDNAError: - raise exceptions.InvalidAuthority(self.authority) - return name - - authority = "" - if self.host: - authority = ".".join( - [ - compat.to_str(idna_encoder(part)) - for part in self.host.split(".") - ] - ) - - if self.userinfo is not None: - authority = ( - normalizers.encode_component(self.userinfo, self.encoding) - + "@" - + authority - ) - - if self.port is not None: - authority += ":" + str(self.port) - - return uri.URIReference( - self.scheme, - authority, - path=self.path, - query=self.query, - fragment=self.fragment, - encoding=self.encoding, - ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/misc.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/misc.py deleted file mode 100644 index 338b1879..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/misc.py +++ /dev/null @@ -1,135 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Module containing compiled regular expressions and constants. - -This module contains important constants, patterns, and compiled regular -expressions for parsing and validating URIs and their components. -""" - -import re - -from . import abnf_regexp - -# These are enumerated for the named tuple used as a superclass of -# URIReference -URI_COMPONENTS = ["scheme", "authority", "path", "query", "fragment"] - -important_characters = { - "generic_delimiters": abnf_regexp.GENERIC_DELIMITERS, - "sub_delimiters": abnf_regexp.SUB_DELIMITERS, - # We need to escape the '*' in this case - "re_sub_delimiters": abnf_regexp.SUB_DELIMITERS_RE, - "unreserved_chars": abnf_regexp.UNRESERVED_CHARS, - # We need to escape the '-' in this case: - "re_unreserved": abnf_regexp.UNRESERVED_RE, -} - -# For details about delimiters and reserved characters, see: -# http://tools.ietf.org/html/rfc3986#section-2.2 -GENERIC_DELIMITERS = abnf_regexp.GENERIC_DELIMITERS_SET -SUB_DELIMITERS = abnf_regexp.SUB_DELIMITERS_SET -RESERVED_CHARS = abnf_regexp.RESERVED_CHARS_SET -# For details about unreserved characters, see: -# http://tools.ietf.org/html/rfc3986#section-2.3 -UNRESERVED_CHARS = abnf_regexp.UNRESERVED_CHARS_SET -NON_PCT_ENCODED = abnf_regexp.NON_PCT_ENCODED_SET - -URI_MATCHER = re.compile(abnf_regexp.URL_PARSING_RE) - -SUBAUTHORITY_MATCHER = re.compile( - ( - "^(?:(?P{0})@)?" # userinfo - "(?P{1})" # host - ":?(?P{2})?$" # port - ).format( - abnf_regexp.USERINFO_RE, abnf_regexp.HOST_PATTERN, abnf_regexp.PORT_RE - ) -) - - -HOST_MATCHER = re.compile("^" + abnf_regexp.HOST_RE + "$") -IPv4_MATCHER = re.compile("^" + abnf_regexp.IPv4_RE + "$") -IPv6_MATCHER = re.compile(r"^\[" + abnf_regexp.IPv6_ADDRZ_RFC4007_RE + r"\]$") - -# Used by host validator -IPv6_NO_RFC4007_MATCHER = re.compile( - r"^\[%s\]$" % (abnf_regexp.IPv6_ADDRZ_RE) -) - -# Matcher used to validate path components -PATH_MATCHER = re.compile(abnf_regexp.PATH_RE) - - -# ################################## -# Query and Fragment Matcher Section -# ################################## - -QUERY_MATCHER = re.compile(abnf_regexp.QUERY_RE) - -FRAGMENT_MATCHER = QUERY_MATCHER - -# Scheme validation, see: http://tools.ietf.org/html/rfc3986#section-3.1 -SCHEME_MATCHER = re.compile("^{0}$".format(abnf_regexp.SCHEME_RE)) - -RELATIVE_REF_MATCHER = re.compile( - r"^%s(\?%s)?(#%s)?$" - % ( - abnf_regexp.RELATIVE_PART_RE, - abnf_regexp.QUERY_RE, - abnf_regexp.FRAGMENT_RE, - ) -) - -# See http://tools.ietf.org/html/rfc3986#section-4.3 -ABSOLUTE_URI_MATCHER = re.compile( - r"^%s:%s(\?%s)?$" - % ( - abnf_regexp.COMPONENT_PATTERN_DICT["scheme"], - abnf_regexp.HIER_PART_RE, - abnf_regexp.QUERY_RE[1:-1], - ) -) - -# ############### -# IRIs / RFC 3987 -# ############### - -IRI_MATCHER = re.compile(abnf_regexp.URL_PARSING_RE, re.UNICODE) - -ISUBAUTHORITY_MATCHER = re.compile( - ( - u"^(?:(?P{0})@)?" # iuserinfo - u"(?P{1})" # ihost - u":?(?P{2})?$" # port - ).format( - abnf_regexp.IUSERINFO_RE, abnf_regexp.IHOST_RE, abnf_regexp.PORT_RE - ), - re.UNICODE, -) - - -# Path merger as defined in http://tools.ietf.org/html/rfc3986#section-5.2.3 -def merge_paths(base_uri, relative_path): - """Merge a base URI's path with a relative URI's path.""" - if base_uri.path is None and base_uri.authority is not None: - return "/" + relative_path - else: - path = base_uri.path or "" - index = path.rfind("/") - return path[:index] + "/" + relative_path - - -UseExisting = object() diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/normalizers.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/normalizers.py deleted file mode 100644 index 0d702b6d..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/normalizers.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module with functions to normalize components.""" -import re - -from . import compat -from . import misc - - -def normalize_scheme(scheme): - """Normalize the scheme component.""" - return scheme.lower() - - -def normalize_authority(authority): - """Normalize an authority tuple to a string.""" - userinfo, host, port = authority - result = "" - if userinfo: - result += normalize_percent_characters(userinfo) + "@" - if host: - result += normalize_host(host) - if port: - result += ":" + port - return result - - -def normalize_username(username): - """Normalize a username to make it safe to include in userinfo.""" - return compat.urlquote(username) - - -def normalize_password(password): - """Normalize a password to make safe for userinfo.""" - return compat.urlquote(password) - - -def normalize_host(host): - """Normalize a host string.""" - if misc.IPv6_MATCHER.match(host): - percent = host.find("%") - if percent != -1: - percent_25 = host.find("%25") - - # Replace RFC 4007 IPv6 Zone ID delimiter '%' with '%25' - # from RFC 6874. If the host is '[%25]' then we - # assume RFC 4007 and normalize to '[%2525]' - if ( - percent_25 == -1 - or percent < percent_25 - or (percent == percent_25 and percent_25 == len(host) - 4) - ): - host = host.replace("%", "%25", 1) - - # Don't normalize the casing of the Zone ID - return host[:percent].lower() + host[percent:] - - return host.lower() - - -def normalize_path(path): - """Normalize the path string.""" - if not path: - return path - - path = normalize_percent_characters(path) - return remove_dot_segments(path) - - -def normalize_query(query): - """Normalize the query string.""" - if not query: - return query - return normalize_percent_characters(query) - - -def normalize_fragment(fragment): - """Normalize the fragment string.""" - if not fragment: - return fragment - return normalize_percent_characters(fragment) - - -PERCENT_MATCHER = re.compile("%[A-Fa-f0-9]{2}") - - -def normalize_percent_characters(s): - """All percent characters should be upper-cased. - - For example, ``"%3afoo%DF%ab"`` should be turned into ``"%3Afoo%DF%AB"``. - """ - matches = set(PERCENT_MATCHER.findall(s)) - for m in matches: - if not m.isupper(): - s = s.replace(m, m.upper()) - return s - - -def remove_dot_segments(s): - """Remove dot segments from the string. - - See also Section 5.2.4 of :rfc:`3986`. - """ - # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code - segments = s.split("/") # Turn the path into a list of segments - output = [] # Initialize the variable to use to store output - - for segment in segments: - # '.' is the current directory, so ignore it, it is superfluous - if segment == ".": - continue - # Anything other than '..', should be appended to the output - elif segment != "..": - output.append(segment) - # In this case segment == '..', if we can, we should pop the last - # element - elif output: - output.pop() - - # If the path starts with '/' and the output is empty or the first string - # is non-empty - if s.startswith("/") and (not output or output[0]): - output.insert(0, "") - - # If the path starts with '/.' or '/..' ensure we add one more empty - # string to add a trailing '/' - if s.endswith(("/.", "/..")): - output.append("") - - return "/".join(output) - - -def encode_component(uri_component, encoding): - """Encode the specific component in the provided encoding.""" - if uri_component is None: - return uri_component - - # Try to see if the component we're encoding is already percent-encoded - # so we can skip all '%' characters but still encode all others. - percent_encodings = len( - PERCENT_MATCHER.findall(compat.to_str(uri_component, encoding)) - ) - - uri_bytes = compat.to_bytes(uri_component, encoding) - is_percent_encoded = percent_encodings == uri_bytes.count(b"%") - - encoded_uri = bytearray() - - for i in range(0, len(uri_bytes)): - # Will return a single character bytestring on both Python 2 & 3 - byte = uri_bytes[i : i + 1] - byte_ord = ord(byte) - if (is_percent_encoded and byte == b"%") or ( - byte_ord < 128 and byte.decode() in misc.NON_PCT_ENCODED - ): - encoded_uri.extend(byte) - continue - encoded_uri.extend("%{0:02x}".format(byte_ord).encode().upper()) - - return encoded_uri.decode(encoding) diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/parseresult.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/parseresult.py deleted file mode 100644 index 8887e8f1..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/parseresult.py +++ /dev/null @@ -1,479 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2015 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module containing the urlparse compatibility logic.""" -from collections import namedtuple - -from . import compat -from . import exceptions -from . import misc -from . import normalizers -from . import uri - -__all__ = ("ParseResult", "ParseResultBytes") - -PARSED_COMPONENTS = ( - "scheme", - "userinfo", - "host", - "port", - "path", - "query", - "fragment", -) - - -class ParseResultMixin(object): - def _generate_authority(self, attributes): - # I swear I did not align the comparisons below. That's just how they - # happened to align based on pep8 and attribute lengths. - userinfo, host, port = ( - attributes[p] for p in ("userinfo", "host", "port") - ) - if ( - self.userinfo != userinfo - or self.host != host - or self.port != port - ): - if port: - port = "{0}".format(port) - return normalizers.normalize_authority( - ( - compat.to_str(userinfo, self.encoding), - compat.to_str(host, self.encoding), - port, - ) - ) - if isinstance(self.authority, bytes): - return self.authority.decode("utf-8") - return self.authority - - def geturl(self): - """Shim to match the standard library method.""" - return self.unsplit() - - @property - def hostname(self): - """Shim to match the standard library.""" - return self.host - - @property - def netloc(self): - """Shim to match the standard library.""" - return self.authority - - @property - def params(self): - """Shim to match the standard library.""" - return self.query - - -class ParseResult( - namedtuple("ParseResult", PARSED_COMPONENTS), ParseResultMixin -): - """Implementation of urlparse compatibility class. - - This uses the URIReference logic to handle compatibility with the - urlparse.ParseResult class. - """ - - slots = () - - def __new__( - cls, - scheme, - userinfo, - host, - port, - path, - query, - fragment, - uri_ref, - encoding="utf-8", - ): - """Create a new ParseResult.""" - parse_result = super(ParseResult, cls).__new__( - cls, - scheme or None, - userinfo or None, - host, - port or None, - path or None, - query, - fragment, - ) - parse_result.encoding = encoding - parse_result.reference = uri_ref - return parse_result - - @classmethod - def from_parts( - cls, - scheme=None, - userinfo=None, - host=None, - port=None, - path=None, - query=None, - fragment=None, - encoding="utf-8", - ): - """Create a ParseResult instance from its parts.""" - authority = "" - if userinfo is not None: - authority += userinfo + "@" - if host is not None: - authority += host - if port is not None: - authority += ":{0}".format(port) - uri_ref = uri.URIReference( - scheme=scheme, - authority=authority, - path=path, - query=query, - fragment=fragment, - encoding=encoding, - ).normalize() - userinfo, host, port = authority_from(uri_ref, strict=True) - return cls( - scheme=uri_ref.scheme, - userinfo=userinfo, - host=host, - port=port, - path=uri_ref.path, - query=uri_ref.query, - fragment=uri_ref.fragment, - uri_ref=uri_ref, - encoding=encoding, - ) - - @classmethod - def from_string( - cls, uri_string, encoding="utf-8", strict=True, lazy_normalize=True - ): - """Parse a URI from the given unicode URI string. - - :param str uri_string: Unicode URI to be parsed into a reference. - :param str encoding: The encoding of the string provided - :param bool strict: Parse strictly according to :rfc:`3986` if True. - If False, parse similarly to the standard library's urlparse - function. - :returns: :class:`ParseResult` or subclass thereof - """ - reference = uri.URIReference.from_string(uri_string, encoding) - if not lazy_normalize: - reference = reference.normalize() - userinfo, host, port = authority_from(reference, strict) - - return cls( - scheme=reference.scheme, - userinfo=userinfo, - host=host, - port=port, - path=reference.path, - query=reference.query, - fragment=reference.fragment, - uri_ref=reference, - encoding=encoding, - ) - - @property - def authority(self): - """Return the normalized authority.""" - return self.reference.authority - - def copy_with( - self, - scheme=misc.UseExisting, - userinfo=misc.UseExisting, - host=misc.UseExisting, - port=misc.UseExisting, - path=misc.UseExisting, - query=misc.UseExisting, - fragment=misc.UseExisting, - ): - """Create a copy of this instance replacing with specified parts.""" - attributes = zip( - PARSED_COMPONENTS, - (scheme, userinfo, host, port, path, query, fragment), - ) - attrs_dict = {} - for name, value in attributes: - if value is misc.UseExisting: - value = getattr(self, name) - attrs_dict[name] = value - authority = self._generate_authority(attrs_dict) - ref = self.reference.copy_with( - scheme=attrs_dict["scheme"], - authority=authority, - path=attrs_dict["path"], - query=attrs_dict["query"], - fragment=attrs_dict["fragment"], - ) - return ParseResult(uri_ref=ref, encoding=self.encoding, **attrs_dict) - - def encode(self, encoding=None): - """Convert to an instance of ParseResultBytes.""" - encoding = encoding or self.encoding - attrs = dict( - zip( - PARSED_COMPONENTS, - ( - attr.encode(encoding) if hasattr(attr, "encode") else attr - for attr in self - ), - ) - ) - return ParseResultBytes( - uri_ref=self.reference, encoding=encoding, **attrs - ) - - def unsplit(self, use_idna=False): - """Create a URI string from the components. - - :returns: The parsed URI reconstituted as a string. - :rtype: str - """ - parse_result = self - if use_idna and self.host: - hostbytes = self.host.encode("idna") - host = hostbytes.decode(self.encoding) - parse_result = self.copy_with(host=host) - return parse_result.reference.unsplit() - - -class ParseResultBytes( - namedtuple("ParseResultBytes", PARSED_COMPONENTS), ParseResultMixin -): - """Compatibility shim for the urlparse.ParseResultBytes object.""" - - def __new__( - cls, - scheme, - userinfo, - host, - port, - path, - query, - fragment, - uri_ref, - encoding="utf-8", - lazy_normalize=True, - ): - """Create a new ParseResultBytes instance.""" - parse_result = super(ParseResultBytes, cls).__new__( - cls, - scheme or None, - userinfo or None, - host, - port or None, - path or None, - query or None, - fragment or None, - ) - parse_result.encoding = encoding - parse_result.reference = uri_ref - parse_result.lazy_normalize = lazy_normalize - return parse_result - - @classmethod - def from_parts( - cls, - scheme=None, - userinfo=None, - host=None, - port=None, - path=None, - query=None, - fragment=None, - encoding="utf-8", - lazy_normalize=True, - ): - """Create a ParseResult instance from its parts.""" - authority = "" - if userinfo is not None: - authority += userinfo + "@" - if host is not None: - authority += host - if port is not None: - authority += ":{0}".format(int(port)) - uri_ref = uri.URIReference( - scheme=scheme, - authority=authority, - path=path, - query=query, - fragment=fragment, - encoding=encoding, - ) - if not lazy_normalize: - uri_ref = uri_ref.normalize() - to_bytes = compat.to_bytes - userinfo, host, port = authority_from(uri_ref, strict=True) - return cls( - scheme=to_bytes(scheme, encoding), - userinfo=to_bytes(userinfo, encoding), - host=to_bytes(host, encoding), - port=port, - path=to_bytes(path, encoding), - query=to_bytes(query, encoding), - fragment=to_bytes(fragment, encoding), - uri_ref=uri_ref, - encoding=encoding, - lazy_normalize=lazy_normalize, - ) - - @classmethod - def from_string( - cls, uri_string, encoding="utf-8", strict=True, lazy_normalize=True - ): - """Parse a URI from the given unicode URI string. - - :param str uri_string: Unicode URI to be parsed into a reference. - :param str encoding: The encoding of the string provided - :param bool strict: Parse strictly according to :rfc:`3986` if True. - If False, parse similarly to the standard library's urlparse - function. - :returns: :class:`ParseResultBytes` or subclass thereof - """ - reference = uri.URIReference.from_string(uri_string, encoding) - if not lazy_normalize: - reference = reference.normalize() - userinfo, host, port = authority_from(reference, strict) - - to_bytes = compat.to_bytes - return cls( - scheme=to_bytes(reference.scheme, encoding), - userinfo=to_bytes(userinfo, encoding), - host=to_bytes(host, encoding), - port=port, - path=to_bytes(reference.path, encoding), - query=to_bytes(reference.query, encoding), - fragment=to_bytes(reference.fragment, encoding), - uri_ref=reference, - encoding=encoding, - lazy_normalize=lazy_normalize, - ) - - @property - def authority(self): - """Return the normalized authority.""" - return self.reference.authority.encode(self.encoding) - - def copy_with( - self, - scheme=misc.UseExisting, - userinfo=misc.UseExisting, - host=misc.UseExisting, - port=misc.UseExisting, - path=misc.UseExisting, - query=misc.UseExisting, - fragment=misc.UseExisting, - lazy_normalize=True, - ): - """Create a copy of this instance replacing with specified parts.""" - attributes = zip( - PARSED_COMPONENTS, - (scheme, userinfo, host, port, path, query, fragment), - ) - attrs_dict = {} - for name, value in attributes: - if value is misc.UseExisting: - value = getattr(self, name) - if not isinstance(value, bytes) and hasattr(value, "encode"): - value = value.encode(self.encoding) - attrs_dict[name] = value - authority = self._generate_authority(attrs_dict) - to_str = compat.to_str - ref = self.reference.copy_with( - scheme=to_str(attrs_dict["scheme"], self.encoding), - authority=to_str(authority, self.encoding), - path=to_str(attrs_dict["path"], self.encoding), - query=to_str(attrs_dict["query"], self.encoding), - fragment=to_str(attrs_dict["fragment"], self.encoding), - ) - if not lazy_normalize: - ref = ref.normalize() - return ParseResultBytes( - uri_ref=ref, - encoding=self.encoding, - lazy_normalize=lazy_normalize, - **attrs_dict - ) - - def unsplit(self, use_idna=False): - """Create a URI bytes object from the components. - - :returns: The parsed URI reconstituted as a string. - :rtype: bytes - """ - parse_result = self - if use_idna and self.host: - # self.host is bytes, to encode to idna, we need to decode it - # first - host = self.host.decode(self.encoding) - hostbytes = host.encode("idna") - parse_result = self.copy_with(host=hostbytes) - if self.lazy_normalize: - parse_result = parse_result.copy_with(lazy_normalize=False) - uri = parse_result.reference.unsplit() - return uri.encode(self.encoding) - - -def split_authority(authority): - # Initialize our expected return values - userinfo = host = port = None - # Initialize an extra var we may need to use - extra_host = None - # Set-up rest in case there is no userinfo portion - rest = authority - - if "@" in authority: - userinfo, rest = authority.rsplit("@", 1) - - # Handle IPv6 host addresses - if rest.startswith("["): - host, rest = rest.split("]", 1) - host += "]" - - if ":" in rest: - extra_host, port = rest.split(":", 1) - elif not host and rest: - host = rest - - if extra_host and not host: - host = extra_host - - return userinfo, host, port - - -def authority_from(reference, strict): - try: - subauthority = reference.authority_info() - except exceptions.InvalidAuthority: - if strict: - raise - userinfo, host, port = split_authority(reference.authority) - else: - # Thanks to Richard Barrell for this idea: - # https://twitter.com/0x2ba22e11/status/617338811975139328 - userinfo, host, port = ( - subauthority.get(p) for p in ("userinfo", "host", "port") - ) - - if port: - try: - port = int(port) - except ValueError: - raise exceptions.InvalidPort(port) - return userinfo, host, port diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/uri.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/uri.py deleted file mode 100644 index 75c617d2..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/uri.py +++ /dev/null @@ -1,161 +0,0 @@ -"""Module containing the implementation of the URIReference class.""" -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Copyright (c) 2015 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from collections import namedtuple - -from . import compat -from . import misc -from . import normalizers -from ._mixin import URIMixin - - -class URIReference(namedtuple("URIReference", misc.URI_COMPONENTS), URIMixin): - """Immutable object representing a parsed URI Reference. - - .. note:: - - This class is not intended to be directly instantiated by the user. - - This object exposes attributes for the following components of a - URI: - - - scheme - - authority - - path - - query - - fragment - - .. attribute:: scheme - - The scheme that was parsed for the URI Reference. For example, - ``http``, ``https``, ``smtp``, ``imap``, etc. - - .. attribute:: authority - - Component of the URI that contains the user information, host, - and port sub-components. For example, - ``google.com``, ``127.0.0.1:5000``, ``username@[::1]``, - ``username:password@example.com:443``, etc. - - .. attribute:: path - - The path that was parsed for the given URI Reference. For example, - ``/``, ``/index.php``, etc. - - .. attribute:: query - - The query component for a given URI Reference. For example, ``a=b``, - ``a=b%20c``, ``a=b+c``, ``a=b,c=d,e=%20f``, etc. - - .. attribute:: fragment - - The fragment component of a URI. For example, ``section-3.1``. - - This class also provides extra attributes for easier access to information - like the subcomponents of the authority component. - - .. attribute:: userinfo - - The user information parsed from the authority. - - .. attribute:: host - - The hostname, IPv4, or IPv6 address parsed from the authority. - - .. attribute:: port - - The port parsed from the authority. - """ - - slots = () - - def __new__( - cls, scheme, authority, path, query, fragment, encoding="utf-8" - ): - """Create a new URIReference.""" - ref = super(URIReference, cls).__new__( - cls, - scheme or None, - authority or None, - path or None, - query, - fragment, - ) - ref.encoding = encoding - return ref - - __hash__ = tuple.__hash__ - - def __eq__(self, other): - """Compare this reference to another.""" - other_ref = other - if isinstance(other, tuple): - other_ref = URIReference(*other) - elif not isinstance(other, URIReference): - try: - other_ref = URIReference.from_string(other) - except TypeError: - raise TypeError( - "Unable to compare URIReference() to {0}()".format( - type(other).__name__ - ) - ) - - # See http://tools.ietf.org/html/rfc3986#section-6.2 - naive_equality = tuple(self) == tuple(other_ref) - return naive_equality or self.normalized_equality(other_ref) - - def normalize(self): - """Normalize this reference as described in Section 6.2.2. - - This is not an in-place normalization. Instead this creates a new - URIReference. - - :returns: A new reference object with normalized components. - :rtype: URIReference - """ - # See http://tools.ietf.org/html/rfc3986#section-6.2.2 for logic in - # this method. - return URIReference( - normalizers.normalize_scheme(self.scheme or ""), - normalizers.normalize_authority( - (self.userinfo, self.host, self.port) - ), - normalizers.normalize_path(self.path or ""), - normalizers.normalize_query(self.query), - normalizers.normalize_fragment(self.fragment), - self.encoding, - ) - - @classmethod - def from_string(cls, uri_string, encoding="utf-8"): - """Parse a URI reference from the given unicode URI string. - - :param str uri_string: Unicode URI to be parsed into a reference. - :param str encoding: The encoding of the string provided - :returns: :class:`URIReference` or subclass thereof - """ - uri_string = compat.to_str(uri_string, encoding) - - split_uri = misc.URI_MATCHER.match(uri_string).groupdict() - return cls( - split_uri["scheme"], - split_uri["authority"], - normalizers.encode_component(split_uri["path"], encoding), - normalizers.encode_component(split_uri["query"], encoding), - normalizers.encode_component(split_uri["fragment"], encoding), - encoding, - ) diff --git a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/validators.py b/IKEA_scraper/.venv/Lib/site-packages/rfc3986/validators.py deleted file mode 100644 index f3752488..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/rfc3986/validators.py +++ /dev/null @@ -1,447 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2017 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module containing the validation logic for rfc3986.""" -from . import exceptions -from . import misc -from . import normalizers - - -class Validator(object): - """Object used to configure validation of all objects in rfc3986. - - .. versionadded:: 1.0 - - Example usage:: - - >>> from rfc3986 import api, validators - >>> uri = api.uri_reference('https://github.com/') - >>> validator = validators.Validator().require_presence_of( - ... 'scheme', 'host', 'path', - ... ).allow_schemes( - ... 'http', 'https', - ... ).allow_hosts( - ... '127.0.0.1', 'github.com', - ... ) - >>> validator.validate(uri) - >>> invalid_uri = rfc3986.uri_reference('imap://mail.google.com') - >>> validator.validate(invalid_uri) - Traceback (most recent call last): - ... - rfc3986.exceptions.MissingComponentError: ('path was required but - missing', URIReference(scheme=u'imap', authority=u'mail.google.com', - path=None, query=None, fragment=None), ['path']) - - """ - - COMPONENT_NAMES = frozenset( - ["scheme", "userinfo", "host", "port", "path", "query", "fragment"] - ) - - def __init__(self): - """Initialize our default validations.""" - self.allowed_schemes = set() - self.allowed_hosts = set() - self.allowed_ports = set() - self.allow_password = True - self.required_components = { - "scheme": False, - "userinfo": False, - "host": False, - "port": False, - "path": False, - "query": False, - "fragment": False, - } - self.validated_components = self.required_components.copy() - - def allow_schemes(self, *schemes): - """Require the scheme to be one of the provided schemes. - - .. versionadded:: 1.0 - - :param schemes: - Schemes, without ``://`` that are allowed. - :returns: - The validator instance. - :rtype: - Validator - """ - for scheme in schemes: - self.allowed_schemes.add(normalizers.normalize_scheme(scheme)) - return self - - def allow_hosts(self, *hosts): - """Require the host to be one of the provided hosts. - - .. versionadded:: 1.0 - - :param hosts: - Hosts that are allowed. - :returns: - The validator instance. - :rtype: - Validator - """ - for host in hosts: - self.allowed_hosts.add(normalizers.normalize_host(host)) - return self - - def allow_ports(self, *ports): - """Require the port to be one of the provided ports. - - .. versionadded:: 1.0 - - :param ports: - Ports that are allowed. - :returns: - The validator instance. - :rtype: - Validator - """ - for port in ports: - port_int = int(port, base=10) - if 0 <= port_int <= 65535: - self.allowed_ports.add(port) - return self - - def allow_use_of_password(self): - """Allow passwords to be present in the URI. - - .. versionadded:: 1.0 - - :returns: - The validator instance. - :rtype: - Validator - """ - self.allow_password = True - return self - - def forbid_use_of_password(self): - """Prevent passwords from being included in the URI. - - .. versionadded:: 1.0 - - :returns: - The validator instance. - :rtype: - Validator - """ - self.allow_password = False - return self - - def check_validity_of(self, *components): - """Check the validity of the components provided. - - This can be specified repeatedly. - - .. versionadded:: 1.1 - - :param components: - Names of components from :attr:`Validator.COMPONENT_NAMES`. - :returns: - The validator instance. - :rtype: - Validator - """ - components = [c.lower() for c in components] - for component in components: - if component not in self.COMPONENT_NAMES: - raise ValueError( - '"{}" is not a valid component'.format(component) - ) - self.validated_components.update( - {component: True for component in components} - ) - return self - - def require_presence_of(self, *components): - """Require the components provided. - - This can be specified repeatedly. - - .. versionadded:: 1.0 - - :param components: - Names of components from :attr:`Validator.COMPONENT_NAMES`. - :returns: - The validator instance. - :rtype: - Validator - """ - components = [c.lower() for c in components] - for component in components: - if component not in self.COMPONENT_NAMES: - raise ValueError( - '"{}" is not a valid component'.format(component) - ) - self.required_components.update( - {component: True for component in components} - ) - return self - - def validate(self, uri): - """Check a URI for conditions specified on this validator. - - .. versionadded:: 1.0 - - :param uri: - Parsed URI to validate. - :type uri: - rfc3986.uri.URIReference - :raises MissingComponentError: - When a required component is missing. - :raises UnpermittedComponentError: - When a component is not one of those allowed. - :raises PasswordForbidden: - When a password is present in the userinfo component but is - not permitted by configuration. - :raises InvalidComponentsError: - When a component was found to be invalid. - """ - if not self.allow_password: - check_password(uri) - - required_components = [ - component - for component, required in self.required_components.items() - if required - ] - validated_components = [ - component - for component, required in self.validated_components.items() - if required - ] - if required_components: - ensure_required_components_exist(uri, required_components) - if validated_components: - ensure_components_are_valid(uri, validated_components) - - ensure_one_of(self.allowed_schemes, uri, "scheme") - ensure_one_of(self.allowed_hosts, uri, "host") - ensure_one_of(self.allowed_ports, uri, "port") - - -def check_password(uri): - """Assert that there is no password present in the uri.""" - userinfo = uri.userinfo - if not userinfo: - return - credentials = userinfo.split(":", 1) - if len(credentials) <= 1: - return - raise exceptions.PasswordForbidden(uri) - - -def ensure_one_of(allowed_values, uri, attribute): - """Assert that the uri's attribute is one of the allowed values.""" - value = getattr(uri, attribute) - if value is not None and allowed_values and value not in allowed_values: - raise exceptions.UnpermittedComponentError( - attribute, - value, - allowed_values, - ) - - -def ensure_required_components_exist(uri, required_components): - """Assert that all required components are present in the URI.""" - missing_components = sorted( - [ - component - for component in required_components - if getattr(uri, component) is None - ] - ) - if missing_components: - raise exceptions.MissingComponentError(uri, *missing_components) - - -def is_valid(value, matcher, require): - """Determine if a value is valid based on the provided matcher. - - :param str value: - Value to validate. - :param matcher: - Compiled regular expression to use to validate the value. - :param require: - Whether or not the value is required. - """ - if require: - return value is not None and matcher.match(value) - - # require is False and value is not None - return value is None or matcher.match(value) - - -def authority_is_valid(authority, host=None, require=False): - """Determine if the authority string is valid. - - :param str authority: - The authority to validate. - :param str host: - (optional) The host portion of the authority to validate. - :param bool require: - (optional) Specify if authority must not be None. - :returns: - ``True`` if valid, ``False`` otherwise - :rtype: - bool - """ - validated = is_valid(authority, misc.SUBAUTHORITY_MATCHER, require) - if validated and host is not None: - return host_is_valid(host, require) - return validated - - -def host_is_valid(host, require=False): - """Determine if the host string is valid. - - :param str host: - The host to validate. - :param bool require: - (optional) Specify if host must not be None. - :returns: - ``True`` if valid, ``False`` otherwise - :rtype: - bool - """ - validated = is_valid(host, misc.HOST_MATCHER, require) - if validated and host is not None and misc.IPv4_MATCHER.match(host): - return valid_ipv4_host_address(host) - elif validated and host is not None and misc.IPv6_MATCHER.match(host): - return misc.IPv6_NO_RFC4007_MATCHER.match(host) is not None - return validated - - -def scheme_is_valid(scheme, require=False): - """Determine if the scheme is valid. - - :param str scheme: - The scheme string to validate. - :param bool require: - (optional) Set to ``True`` to require the presence of a scheme. - :returns: - ``True`` if the scheme is valid. ``False`` otherwise. - :rtype: - bool - """ - return is_valid(scheme, misc.SCHEME_MATCHER, require) - - -def path_is_valid(path, require=False): - """Determine if the path component is valid. - - :param str path: - The path string to validate. - :param bool require: - (optional) Set to ``True`` to require the presence of a path. - :returns: - ``True`` if the path is valid. ``False`` otherwise. - :rtype: - bool - """ - return is_valid(path, misc.PATH_MATCHER, require) - - -def query_is_valid(query, require=False): - """Determine if the query component is valid. - - :param str query: - The query string to validate. - :param bool require: - (optional) Set to ``True`` to require the presence of a query. - :returns: - ``True`` if the query is valid. ``False`` otherwise. - :rtype: - bool - """ - return is_valid(query, misc.QUERY_MATCHER, require) - - -def fragment_is_valid(fragment, require=False): - """Determine if the fragment component is valid. - - :param str fragment: - The fragment string to validate. - :param bool require: - (optional) Set to ``True`` to require the presence of a fragment. - :returns: - ``True`` if the fragment is valid. ``False`` otherwise. - :rtype: - bool - """ - return is_valid(fragment, misc.FRAGMENT_MATCHER, require) - - -def valid_ipv4_host_address(host): - """Determine if the given host is a valid IPv4 address.""" - # If the host exists, and it might be IPv4, check each byte in the - # address. - return all([0 <= int(byte, base=10) <= 255 for byte in host.split(".")]) - - -_COMPONENT_VALIDATORS = { - "scheme": scheme_is_valid, - "path": path_is_valid, - "query": query_is_valid, - "fragment": fragment_is_valid, -} - -_SUBAUTHORITY_VALIDATORS = set(["userinfo", "host", "port"]) - - -def subauthority_component_is_valid(uri, component): - """Determine if the userinfo, host, and port are valid.""" - try: - subauthority_dict = uri.authority_info() - except exceptions.InvalidAuthority: - return False - - # If we can parse the authority into sub-components and we're not - # validating the port, we can assume it's valid. - if component == "host": - return host_is_valid(subauthority_dict["host"]) - elif component != "port": - return True - - try: - port = int(subauthority_dict["port"]) - except TypeError: - # If the port wasn't provided it'll be None and int(None) raises a - # TypeError - return True - - return 0 <= port <= 65535 - - -def ensure_components_are_valid(uri, validated_components): - """Assert that all components are valid in the URI.""" - invalid_components = set([]) - for component in validated_components: - if component in _SUBAUTHORITY_VALIDATORS: - if not subauthority_component_is_valid(uri, component): - invalid_components.add(component) - # Python's peephole optimizer means that while this continue *is* - # actually executed, coverage.py cannot detect that. See also, - # https://bitbucket.org/ned/coveragepy/issues/198/continue-marked-as-not-covered - continue # nocov: Python 2.7, 3.3, 3.4 - - validator = _COMPONENT_VALIDATORS[component] - if not validator(getattr(uri, component)): - invalid_components.add(component) - - if invalid_components: - raise exceptions.InvalidComponentsError(uri, *invalid_components) diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/__init__.cpython-39.pyc index 493e947bc2fe4fc50f0fb6180ab5205e9d610b84..fcdc6256a9154ea51e04d9de3c13c8bb7386cac0 100644 GIT binary patch delta 27 hcmZ4Gyvmt7k(ZZ?0SLH_yf$*1u`{}Dc4E(v0svFf1+V}B delta 27 hcmZ4Gyvmt7k(ZZ?0SNdmJ8a}OV`p^P?8KfS1pr&721oz^ diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-39.pyc index d04e1994fd7777acdf42f33905cd86425ffe4c9b..132324140cf1846994451be61ed0c335006e389e 100644 GIT binary patch delta 26 gcmZ3$vVesk(ZZ?0SLH_yf$*5U}SXLe1*}Q4FFDi1{(kX delta 27 hcmbO)FkgT>k(ZZ?0SNdmJ8a}W!N};c`3j>q8vs^L2D1PF diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/archive_util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/archive_util.cpython-39.pyc index c32e045068950572c401b078b0a8bc9a28f44fcf..fafbdf8e1d35ea62f79afea55b2ca2bd28b96acb 100644 GIT binary patch delta 27 hcmdm>yFr&bk(ZZ?0SLH_yf$(NF)_Mrj$;ZE0RU0L1)=}| delta 27 hcmdm>yFr&bk(ZZ?0SNdmJ8a|*Vq$dJ9LE$S0svW+208!$ diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/build_meta.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/build_meta.cpython-39.pyc index 864d09f247cfd0b00dfb13b09033e44405ce5282..dcd6505430b5ed94d1b231274f2f7afa7efe8956 100644 GIT binary patch delta 27 hcmaFu_S%g*k(ZZ?0SLH_yf$)AWM_2SJeU2PGyrD_2UP$7 delta 27 hcmaFu_S%g*k(ZZ?0SNdmJ8a~h$j<1pc`o}oX#j5A2kig= diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/config.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/config.cpython-39.pyc index 28efc48f05520ecf0faf390e612cadbd146eadca..7afb9d9662bab6ed19c3c06a9ccbfd2ae705bbe2 100644 GIT binary patch delta 29 jcmex5oAK*xM(#vjUM>b8;5PEw$gRW7=(gE{d9N1$c~A#o delta 29 jcmex5oAK*xM(#vjUM>b8;JfUwkz0qE(Pgs*^Ik6ifg=a` diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/dep_util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/dep_util.cpython-39.pyc index 30b983730f79358b70beb88d71be5edf504c9fa6..172e25a1d1e3d04cd9a512cb20d64267d3b14bf1 100644 GIT binary patch delta 26 gcmcc2cA1Skk(ZZ?0SLH_yf$(dGBLVMu4TFg08IY|C;$Ke delta 26 gcmcc2cA1Skk(ZZ?0SNdmJ8a}GWMXugT+4I~08}~#zyJUM diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/depends.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/depends.cpython-39.pyc index 2fe6588551076a5a3dd41fc453dac69ece9da5d5..eb97bc739bd4e79bac9cc13bda5c092cd38cd5bf 100644 GIT binary patch delta 27 hcmeyZ@mqsCk(ZZ?0SLH_yf$**U}ALJ{Df(`AOL4s2Ydhk delta 27 hcmeyZ@mqsCk(ZZ?0SNdmJ8a~>!NlmY`3ci>K>%+o2owMS diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/dist.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/dist.cpython-39.pyc index 5579d43bbfbe267eafdd5cf99005bb3dd3ad4dbf..c10792845a17493358bc192c0562b1fff04c9806 100644 GIT binary patch delta 29 jcmeC1&D1xWi93;(mx}=ixQ)Cvax1bjx^32FP3!;wVs8dz delta 29 jcmeC1&D1xWi93;(mx}=i_%1ta{6xBvhE diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/extension.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/extension.cpython-39.pyc index c56b300f82c89a6e3c03ed760619d4055aa0db0a..0145e7b9266b0af0e199269c0e46239cd005ce04 100644 GIT binary patch delta 27 hcmbQlKZ&0^k(ZZ?0SLH_yf$(#U}SXLyoT`^D*#H;21x(_ delta 27 hcmbQlKZ&0^k(ZZ?0SNdmJ8a}$z{u#bc@5(;Rsd3^2H^kz diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/glob.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/glob.cpython-39.pyc index 7f620760604b88b303f70cbc3249870e06e21fea..5fd7832cc382d2edf07c252d2e75e371ed58d371 100644 GIT binary patch delta 27 hcmaDM^FoF@k(ZZ?0SLH_yf$)2Ff+PsPGM%@1^`)v1*ZT2 delta 27 hcmaDM^FoF@k(ZZ?0SNdmJ8a~RU}kjLoWjh)4FF+R20s7* diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/installer.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/installer.cpython-39.pyc index aa4368f8a8936e7b237843349f55752d3a7c74ad..2ee594499034fbf237bc36e25ab557176980918e 100644 GIT binary patch delta 27 hcmX>rdRCM>k(ZZ?0SLH_yf$*zGBUbt?qqb~1OQa?1?K<& delta 27 hcmX>rdRCM>k(ZZ?0SNdmJ8a~xWn^^O+{x&|2>@Ki27dqm diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/launch.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/launch.cpython-39.pyc index 470b06e5e6efd4f0c160ea972e931c1b9dc4f11d..63272d8619541564f670638f95a3fbfd14afe954 100644 GIT binary patch delta 26 gcmey*_MeSAk(ZZ?0SLH_yf$(#W@2=kyq@U-09UsL-T(jq delta 26 gcmey*_MeSAk(ZZ?0SNdmJ8a}$%*5z2c|Fqw0ABJ3b^rhX diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-39.pyc index ac03888bdbdbf15d0cf86df848864c6d77794ea1..71859257a12cd5f7dbfbd32fc7c980a82cfdbd93 100644 GIT binary patch delta 27 gcmeAa?G)usb8;5PEw$i0k}(QWf4*7*wog1HE? delta 29 kcmcb3j_Kk#ChkODUM>b8;JfUwk$V{{qs!(^tn(KF0E&zWN&o-= diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/namespaces.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/namespaces.cpython-39.pyc index e79369461c637423660047ed87e6bb5927e344cc..1a9d6048f04943faaf9255beea00b9a516267e35 100644 GIT binary patch delta 27 hcmeB@>5}125}12b8;5PEw$nD9-=(ahOO|cRHj+Y1g delta 29 jcmezNkMY|-M(#vjUM>b8;JfUwk=v7v(PeWen_?vZmTCx; diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/py34compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/py34compat.cpython-39.pyc index a1cc89f9ec3723dd90259e6be86ee8b8c89227e6..c7792aa2b45e905a088c3cbab276a7b7b1ff5363 100644 GIT binary patch delta 24 ecmcb`e2bYok(ZZ?0SLH_ye4wrVRW1L;u8Qy)CT+j delta 24 ecmcb`e2bYok(ZZ?0SNdmJ51!h!{{>c#U}tv-3OEa diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/sandbox.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/sandbox.cpython-39.pyc index ed2368d582fc94b5e9766fc92abd12ea31e14f2f..a46bb7bc517fd1e78764366eb9d84c52f91540cb 100644 GIT binary patch delta 79 zcmbPHJ)@dCk(ZZ?0SLH_yf$(#W@dETyq?*GfAT*eNs&;Xa8VSHxW$>0SzJZIXjBY rxw0f9Kd&eXsI4dzNNiRRE@Ea(nmk#|oGl3?=r=i0Q+V@Zv8`$V9@`%6 diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/unicode_utils.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/__pycache__/unicode_utils.cpython-39.pyc index c10ef0665cfc28a969918d177ad0ed06927609fb..4fb489af7ff5a1226beb710f7fdb0e8ef851f6b5 100644 GIT binary patch delta 27 hcmcb@afO3Bk(ZZ?0SLH_yf$(hFfzJrwqcZD1^`cv1rGoK delta 27 hcmcb@afO3Bk(ZZ?0SNdmJ8a}OU}SXJY{MwQ3;F*3SM_G2sq07nxAL;wH) delta 26 gcmX@Ye1w@hk(ZZ?0SNdmJ8a~3Vq|og?8jIJ08UN?+yDRo diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-39.pyc index f04f936a5be14266f995b5cdfdc5996c908f31da..d2db9c28afda7b737c3ed3b7a8a64c3ed647098c 100644 GIT binary patch delta 27 hcmaE#{XUyJk(ZZ?0SLH_yf$)2vogAEPG{{f003*q2L=ED delta 27 hcmaE#{XUyJk(ZZ?0SNdmJ8a~RW@U8QoX*-|0048F2c7@` diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-39.pyc index 8257fb03ba6ca57a8054a88ad1594d4aed518f12..6499062596767f24aacafa8abcde66dc8e7a12b4 100644 GIT binary patch delta 27 hcmaEF{N9*5k(ZZ?0SLH_yf$*bVq$dL{Eg|S7yxL(2n7HD delta 27 hcmaEF{N9*5k(ZZ?0SNdmJ8a~B#l+~c`5V(uF#vFt2%P`` diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-39.pyc index dc68155fdb44869d107f8be191e30efdabb40be9..748141fb5b43a3696e30754179159d7117c0c87b 100644 GIT binary patch delta 27 hcmbPcJk6Lpk(ZZ?0SLH_yf$(xurj)B)?v*O0RT&F1vCHv delta 27 hcmbPcJk6Lpk(ZZ?0SNdmJ8a}uU}bdKtizfm0svD$1Ua+%g=DZkshYlBxh)*#;m0 delta 29 jcmeBbW$J2W;!fn{xgS2jBnz diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/config.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/config.cpython-39.pyc index d7e8fb245ae0528dd060738c8a416be7e918571c..a7f790b967f5fdb6c067ce45c1a9e6aee5730050 100644 GIT binary patch delta 27 hcmew>{a2bhk(ZZ?0SLH_yf$(NGBdhuj%8lJ1pr=h23!CD delta 27 hcmew>{a2bhk(ZZ?0SNdmJ8a|*WM*{P9Lv0b3jk(C2J`>` diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/core.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/core.cpython-39.pyc index b5f425d3e31fcff1dab3516ceeae6986d2b91df3..2cadf8d31f5eb686669ff21a12d39ade35408310 100644 GIT binary patch delta 27 hcmdmFvdM%yk(ZZ?0SLH_yf$(NFf+Psj$ytg1^`rp1~>o! delta 27 hcmdmFvdM%yk(ZZ?0SNdmJ8a|*U}kjL9K(D~3;<1|k(ZZ?0SLH_yf$+8voN}Cp3Smd764%?2LJ#7 delta 27 hcmccQa><1|k(ZZ?0SNdmJ8b0cXJK^NJey^^EC6Wz2bcf= diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/debug.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/debug.cpython-39.pyc index 961292f401645a6820ebf560accd8c452516337b..103576805b523d277c1353de57dbd25fbb549c10 100644 GIT binary patch delta 24 ecmeyt_=Ax`&O4bk(ZZ?0SLH_yf$+4u`#-BmSVds003Lu1{nYV delta 27 hcmaE>`&O4bk(ZZ?0SNdmJ8b0UV`FsLEX8(N003jJ2C)DD diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/dist.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/dist.cpython-39.pyc index 11139a07407d9f0e79001d764d306bc29951c28a..ed913b402d06aa89631678d8c48070e9c04a9e42 100644 GIT binary patch delta 29 icmZqgWoqwb;!fn{Ua-0IAXZkvsnLz)3zAqFu3 delta 29 jcmZqgWoqwb;!fn{?q diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/extension.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/extension.cpython-39.pyc index 9d1696f9decc658f0bbe476e6c1f4c94a7e4099a..b8bd43e3dfb0f55b8e1a2ada7c417041593059d7 100644 GIT binary patch delta 27 hcmdmKw$qF|k(ZZ?0SLH_yf$*r;AeE(yo7%$Hvn1k2BrW2 delta 27 hcmdmKw$qF|k(ZZ?0SNdmJ8a~h!O!Tjc?thiZUAA$2R;A* diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-39.pyc index ef1211a2a3e3cf2ffc079907c61b9873998d4392..1e71a7532730ff19d15dae248262e0e35475d970 100644 GIT binary patch delta 27 hcmdlQyfv6Rk(ZZ?0SLH_yf$(xvN5`C)@AEZ1^`%G1>*n! delta 27 hcmdlQyfv6Rk(ZZ?0SNdmJ8a}uWMg#MtjpG+3;dayo=Nk(ZZ?0SLH_yf$*DurRu9E?~K>3IJgL2Iv3) delta 27 hcmX>dayo=Nk(ZZ?0SNdmJ8a}mVPSOHT)=W$6#!_`2Y>(o diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/log.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/log.cpython-39.pyc index eb99488d3fa25c901bc1495bc124835245cfa7c1..b6f5d83f0ba90f6b4da680f74ff556c665d23284 100644 GIT binary patch delta 27 hcmdllv|orjk(ZZ?0SLH_yf$(#WMp*Pyq0kiI{;Jj23Y_A delta 27 hcmdllv|orjk(ZZ?0SNdmJ8a}$$jIojc`f54b^u$(2Jrv@ diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-39.pyc index 59f2fa89385b77ce6669972f0d531ff0dc4ae520..fc45b52c8335acb4170df825c95927199de7c014 100644 GIT binary patch delta 106 zcmbQ!$vCHzkvox>mx}=ixQ)Cva!+Apblbdu^@pg;E#{oeq$qYEQIJ@Yaf>}OFFB_) zCACNtsC4rd=@;y5xjmx}=i_%1takrY%bEU;uZ!za&CT-p#{eqn>52&Ij ock?3US&WQ%n{8DKxq#Gq{kJ@fd6NZYg(q*Yc>)xeYRk?J0FUV#?*IS* diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-39.pyc index b62b41704915d996a0971ad2b107e46406ed2024..fb76e276db748e704886c79f872ba529a1f6e83a 100644 GIT binary patch delta 27 hcmZ2pyu6q@k(ZZ?0SLH_yf$*%vM{=B_GF1O1pr*w1|t9f delta 27 hcmZ2pyu6q@k(ZZ?0SNdmJ8a~(WnpyL?8y>m3IJrQ2D<P1OQdP1#$oY delta 27 hcmeys@_~grk(ZZ?0SNdmJ8b0kWMp*N9Lgxo2moD@1_}TG diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-39.pyc index 9f1525dd21f7603fa0a8adbf1257acf8102dcc55..486ce811c7734436a09717321d8929cd414f4698 100644 GIT binary patch delta 24 ecmZ3?yqK9gk(ZZ?0SLH_ye4wLVsxAMZ7l#j9R_6p delta 24 ecmZ3?yqK9gk(ZZ?0SNdmJ51z$#pp8e+gboaCIvc3zA-k(ZZ?0SLH_yf$*nvopGF)@D~>0RT|M1sDJT delta 27 hcmX>vc3zA-k(ZZ?0SNdmJ8a~ZXJ>TTtj(^%0svT-1+V}B diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-39.pyc index 9b0fe255ec3cab3078bc50e66a09302b93881ffe..d05c6a996861d3bd3e974a19520e664c691c5ee5 100644 GIT binary patch delta 27 hcmeyE@G*fqk(ZZ?0SLH_yf$(NurRu9j$ski0RU)*24w&M delta 27 hcmeyE@G*fqk(ZZ?0SNdmJ8a|*U}1FG9K#~20|0PY2K@j4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-39.pyc index a3d777807fcae39059e0c2d5bef9e2169cf9e0ff..f8fc20a3316298f7f975133614343bfcaef73266 100644 GIT binary patch delta 27 hcmZ4MwAP6`k(ZZ?0SLH_yf$*57GQMSd|e<+003MA2Gjrm delta 27 hcmZ4MwAP6`k(ZZ?0SNdmJ8a}WEx_oq`MN-u003jw2W$WU diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-39.pyc index d832a387371d6f5b9e801e63dd50ba2bc3c6440b..afb1e460795dbb5a3226283b535d2e6a17d4c351 100644 GIT binary patch delta 27 hcmdmBy1|q?k(ZZ?0SLH_yf$(turs=C&S7^E1^`qd1<3#a delta 27 hcmdmBy1|q?k(ZZ?0SNdmJ8a}mU}tpMoWt%S3;mx}=ixQ)Cva&O{fblbd-^Q$EQZfytj delta 29 jcmdno&bYaqkvox>mx}=i_%1ta diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/version.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/version.cpython-39.pyc index 111258c86887fa1832a74e6a3194e4c25bda7ccb..2e1912fb4051da7d985593129afb45b48abc16f4 100644 GIT binary patch delta 27 hcmaE8`OuO(k(ZZ?0SLH_yf$*bW@U8S{GIic7yxG`2krm> delta 27 hcmaE8`OuO(k(ZZ?0SNdmJ8a~B&C2Mq`8(??F#vA)2!;Rv diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-39.pyc index 3f9150c37c74ee382be4ea067b8248a1021b13cc..45615b9ea6418e2928a139218507be9c8441fc80 100644 GIT binary patch delta 27 hcmdm~u~UOPk(ZZ?0SLH_yf$*rWny&Oypm~xAOKe6273Si delta 27 hcmdm~u~UOPk(ZZ?0SNdmJ8a~h%f#ric_q^XK>%L22NM7Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-39.pyc index 395a28c1b6eda4498d3ff0331cdef107c3e26fdc..6f62848ca78eeb524538259c48a4dc36d0c5c8dd 100644 GIT binary patch delta 26 gcmeBY>1W|i1W|ipb5e#ok(ZZ?0SLH_yf$+8Gcmetp3St58vs{K27dqm delta 27 hcmX>pb5e#ok(ZZ?0SNdmJ8b0cXJT~OJez49HvnHB2NwVU diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-39.pyc index c56da488d1ff1d378880a2d1b3856f7f7d98fea8..538f41b6e5f3774574e5bc6a04ca255647acdce4 100644 GIT binary patch delta 27 hcmdlXvqOeEk(ZZ?0SLH_yf$*bWo2~R{FBw50{~av2CV=9 delta 27 hcmdlXvqOeEk(ZZ?0SNdmJ8a~B%gX4o`6sJA2LNBO2Soq? diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_msi.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_msi.cpython-39.pyc index b7288c2fcbec6d48cf860038c7a14ae216dca467..bfb3718e634eca219333ffd0590d355e8e069fd0 100644 GIT binary patch delta 29 jcmaDii}BqoM(#vjUM>b8;5PEw$j!vU=(d@UCBYK_bjSvw delta 29 jcmaDii}BqoM(#vjUM>b8;JfUwk(-Hy(Pc9qOM)i=e47V3 diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-39.pyc index 3c13f7a8b3ff7990d83b38a55355fbeae9644841..d30eac6057971d60649dae008e78ab7fadc761cb 100644 GIT binary patch delta 26 gcmeww|23XFk(ZZ?0SLH_yf$*bytj3Wq2>@0O1?~U< diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-39.pyc index 27338e6914fedb927c4e3e63bba6c6cfb7c61dfd..056a01b2ce7585bb9a8dd6d7a34f26c01a0273cb 100644 GIT binary patch delta 27 hcmca9cTz2Pyyn diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-39.pyc index 51f09e15524f241592d0b74daab41d7a9a6867e3..b8225fe77c65d4fb85e8961b52d97e5f334b0430 100644 GIT binary patch delta 27 hcmeyO`bCvHk(ZZ?0SLH_yf$**Vq|pN{EU%L5CCLU2H^kz delta 27 hcmeyO`bCvHk(ZZ?0SNdmJ8a~>#mMNg`57ahAOLJ92YCPh diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-39.pyc index d497ddc9662bae518476944bb936e119cc79bb82..a11b0e2c9945ad7d4b0de01bbe05f12966e71517 100644 GIT binary patch delta 27 hcmdm9zrCJ2k(ZZ?0SLH_yf$+GU}ALJ%)-3c1^{S{2Pyyn delta 27 hcmdm9zrCJ2k(ZZ?0SNdmJ8b0s!NlmYnT2_?4FGUp2f_dV diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-39.pyc index 27069963754ab9c8ebeb8af818228c77be353ae2..9455c291f8073b25a4aa94ce5051798dc924d498 100644 GIT binary patch delta 27 hcmeww_%)C_k(ZZ?0SLH_yf$)&vM{=BPGp&)0sv>92G9Ti delta 27 hcmeww_%)C_k(ZZ?0SNdmJ8a|*WnpyLoX9do1psey2WS8Q diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-39.pyc index 5a4026260837df41e38980cdc6f728e7ae9343ad..db05ec68efd7be280c809d9f2af649c3d359705e 100644 GIT binary patch delta 27 hcmbQIG*5{;k(ZZ?0SLH_yf$*jGc&qv&Su`s3jj@H1>OJv delta 27 hcmbQIG*5{;k(ZZ?0SNdmJ8a~RXJ&NSoXxzM7XVc@26g}d diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-39.pyc index b9978a4072a2ea9140f02656e6d15dda085758d8..38ae9d1a1b632b77b47f4b31a22390f815455ca4 100644 GIT binary patch delta 27 hcmaE;_E3#Gk(ZZ?0SLH_yf$)YGBLVsE@gTn003OG2D$(M delta 27 hcmaE;_E3#Gk(ZZ?0SNdmJ8b06WMXvLT*~xD003l$2T}k4 diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-39.pyc index e8d3ac5a8457e70059f325f3cde97bed853627b1..14f660cfb8688373ef94e2d0875db0d31ded9314 100644 GIT binary patch delta 27 hcmca6a7}=fiq=fiqaa@zH2l)U1 delta 27 hcmX?7c%+a!k(ZZ?0SNdmJ8a}W%*^Pr`8@Mi6994>2$28) diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-39.pyc index 97ee651e367a70caea2b8a088cbe1b414eedfd01..3b693a5527e872c9da96dd43aefbddf772ca97cf 100644 GIT binary patch delta 27 hcmZqIY}e#YE0037B2POaj diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-39.pyc index 264490553cda1a2757bc67c8199a08a1b41bf3e8..13c30e1ae58d3080547ce20858836a9bab84b23d 100644 GIT binary patch delta 24 ecmdnSxQ&rJk(ZZ?0SLH_ye4wnGP+Il%mn~ChXm~a delta 24 ecmdnSxQ&rJk(ZZ?0SNdmJ51!ZWptV7nF|0wkOhSR diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-39.pyc index f68825ad7ffaf583bfd3e00c3514dddadc8dcc30..cfb1b47d176b39620dce20d2db3f0f75c10b0d7c 100644 GIT binary patch delta 27 hcmexS|D&Eek(ZZ?0SLH_yf$)surRu94q;hh4FGV(2R{G+ delta 27 hcmexS|D&Eek(ZZ?0SNdmJ8b0kU}1FG9Ky218UT2h2iE`q diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-39.pyc index 052573c61c91030c1e83fc334b1dbcb24f40a7b0..2d289f88a01dec4e2a0729cbd4f5cc3c8b6b6a59 100644 GIT binary patch delta 37 scmeydgy+W+9_~b5UM>b8;5PEw$bCkJ(XIK0O#2NP#_cy`m==5m0Ncb2hyVZp delta 37 scmeydgy+W+9_~b5UM>b8;JfUwk^77cqf7G*nf4npjN5O>FfI5B0O(f@AOHXW diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-39.pyc index 353400bb9db51888f6bf8a1e54f5e75eab506048..32d60e7597c30d32bfb287af644e3d70eb33f657 100644 GIT binary patch delta 24 dcmZo?YG>k3k3b8;5PEw$j!#b=+-R6w_S*jaoKzTl_dxv delta 33 ncmdmSn{CH!Hts}TUM>b8;JfUwk(-T=(WP04Z@Um5Ua+%jy8ZksjO9@ql_URDNY delta 29 jcmeC^VeIH(b%7 delta 26 gcmZ3$vVes?}|23G(8 delta 27 hcmca0c0r6gk(ZZ?0SNdmJ8a}mVq|pLoX7Zx698Rt2JZj> diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/_typing.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/_typing.cpython-39.pyc index cbe4a7f14b3ca7632f0827dd44d7813d0e4e95b5..7c1fa0fd42fd4d32de9a992c6dfde9adad96771d 100644 GIT binary patch delta 26 gcmX@leV&^;k(ZZ?0SLH_yf$+GU}1Ed%))va08jk}G5`Po delta 26 gcmX@leV&^;k(ZZ?0SNdmJ8b0s!NTY=nT7Q<09QB$$^ZZW diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-39.pyc index 954b09e567fd97bfc7a4eb5b5716dbc38afd5676..79af13f7cdcb1c740e0c2ff6f062488fbd199ec9 100644 GIT binary patch delta 27 hcmccOam9l>k(ZZ?0SLH_yf$(_V`X&P{E0P54gh8+2WS8Q delta 27 hcmccOam9l>k(ZZ?0SNdmJ8a~B#>(ij`4elB8~|b8;5PEw$Zf&Q=(gE~S>6`_b>0TV delta 29 jcmaF7fbsDHM(#vjUM>b8;JfUwk=ufq(Pgs>v%D_=eX$2z diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-39.pyc index ced061a39efb4f08704f71b3305da96c798105ef..2630aef04640f0f7931266f6dca966837d54c261 100644 GIT binary patch delta 70 zcmaFW#`vm@kvox>mx}=ixQ)Cva(`fAbld!gX^W}y8lX_oG9Yn_wbq5uE@ delta 70 zcmaFW#`vm@kvox>mx}=i_%1ta|K=(70_(-u=@IYtJCqGdqwB6%R|7HhGwr9s6l W_Qb@ZeD3;-(a2h{)o diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/build_py.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/build_py.cpython-39.pyc index d36812cdb7f5b9e15556916b0fe5286f21e37dbf..72de58ae03b5dc2bd50360adef670d760e26c6c8 100644 GIT binary patch delta 27 hcmdntxWkbGBdhu_GNx53IJ1i1|$Fg delta 27 hcmdmFw8@A&k(ZZ?0SNdmJ8a~3WM*{P?92RA6aZUH2D|_O diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/dist_info.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/dist_info.cpython-39.pyc index bd796873a9dbe8873c6da0ac4b8a8efd8ffcf924..ef8d2ae76c8220643bd317c5df39d2114043e008 100644 GIT binary patch delta 27 hcmaFM^_Gh}k(ZZ?0SLH_yf$**WMp*P{FJeS830~;2L}KE delta 27 hcmaFM^_Gh}k(ZZ?0SNdmJ8a~>$;jxk`6*)uGXQ2z2cG}{ diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/easy_install.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/easy_install.cpython-39.pyc index b6fa651e77a5b719aa5f9fe58cfba59ddd36924d..c22901ee02ac4b6624a44250243ffc83f5207f65 100644 GIT binary patch delta 29 jcmdn>fqB;lX6{5@UM>b8;5PEw$eqW*=(f3vfqB;lX6{5@UM>b8;JfUwkvorr(PeWL$AR|%im?f2 diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/egg_info.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/egg_info.cpython-39.pyc index 712540dce87774db27b1d50124a7542c795730c5..ca7c280f424d314d0b659e847a619830f999246a 100644 GIT binary patch delta 29 jcmcbzn(@kNM(#vjUM>b8;5PEw$lbus=(f3s-NO$6c@qbI delta 29 jcmcbzn(@kNM(#vjUM>b8;JfUwk-LGN(PeWFyN4eDfaVAm diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/install.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/install.cpython-39.pyc index b2f782e822bda06b182d3335485b7ff792353e55..abcfb4595591f5b35a7a4d32042b2b3eb0327c15 100644 GIT binary patch delta 27 hcmdldzfYb!k(ZZ?0SLH_yf$*TF)_Mrp2VcX3jkCv1>FDu delta 27 hcmdldzfYb!k(ZZ?0SNdmJ8a}`V`6mKJc&t%7XVxW26X@c diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-39.pyc index ea726679fd9a304840c6d84ce7bffd3167d6b20a..d09957602b57f6c8259cddd80df74c2b143da2da 100644 GIT binary patch delta 27 hcmew=^i_yEk(ZZ?0SLH_yf$**V`OyO{ED%g9ROkW2RHx# delta 27 hcmew=^i_yEk(ZZ?0SNdmJ8a~>$H?fi`4wX~I{<0P2hacj diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/install_lib.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/install_lib.cpython-39.pyc index efedc47dd3c2bb1c729da8ddf8041f2b22c7146a..6cd0009b9b6170ae1680edbe5bda55c07c5b4099 100644 GIT binary patch delta 27 hcmZ3Wut0%3k(ZZ?0SLH_yf$*5W@L2Re4Wvg4**g621x(_ delta 27 hcmZ3Wut0%3k(ZZ?0SNdmJ8a}W&B*Ao`8uN~9{^d+2H^kz diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/install_scripts.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/install_scripts.cpython-39.pyc index 672d933d5691f3babd9e23bf2ffd1980f9a4b95e..d1c3b4b09a9add83c7339c19929a315d3f5728ce 100644 GIT binary patch delta 27 hcmew$^g)O_k(ZZ?0SLH_yf$(_XJmBS{F$+q9ROiV2QmNv delta 27 hcmew$^g)O_k(ZZ?0SNdmJ8a~B&dBJp`7>iJI{;}O2g(2d diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/py36compat.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/py36compat.cpython-39.pyc index aafcdcacb74efd74afbb3ce6fbf9bc160cf38744..bae188d24864711bb9f75025e43841a508dbf5c6 100644 GIT binary patch delta 27 hcmaE^{9Ktkk(ZZ?0SLH_yf$)IvogAEZf8y40RUY@23i0B delta 27 hcmaE^{9Ktkk(ZZ?0SNdmJ8a~xW@U8Q+|HW70{~?g2J!#^ diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/register.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/register.cpython-39.pyc index b735e92da84b985472631216d3813bb11ee3ba80..cd023e645312dbac1b36a7ff7de17f1808d2b534 100644 GIT binary patch delta 27 hcmX@kcASknk(ZZ?0SLH_yf$)QV`OyO{D?7?5dc+;28aLv delta 27 hcmX@kcASknk(ZZ?0SNdmJ8a~>#>nWh`4M9(BLH1r2Ot0d diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/rotate.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/rotate.cpython-39.pyc index b92678c0f8f142e1c4d6078e4b22ddf44cbaba82..2ac274d8336a46be11727f61b6903788bc7344d7 100644 GIT binary patch delta 27 hcmX>kd`Or(k(ZZ?0SLH_yf$*DFfqDqE?^2`2LMqs1*rf4 delta 27 hcmX>kd`Or(k(ZZ?0SNdmJ8a}mVPbUIT)-5>4ggsO20;J- diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/saveopts.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/saveopts.cpython-39.pyc index c75205dd9a153e4f921203aa0f71da9a1cd1fbc8..774d50888d8be36cfc677ccd3d498bbf8910c346 100644 GIT binary patch delta 27 hcmbQrK9!w2k(ZZ?0SLH_yf$*%FfqDq_F(d51OP*y1l#}s delta 27 hcmbQrK9!w2k(ZZ?0SNdmJ8a~(VPbUI?7`&A2mniR1#|!a diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/sdist.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/sdist.cpython-39.pyc index 3f200422f0cbb4dbae76f7432c1a753c485463e2..27cf6a98dad96a061fcbcdff67cf3e8501f27250 100644 GIT binary patch delta 27 hcmdmGw9AM)k(ZZ?0SLH_yf$*rVPtgMyn=C(H~?7w29*E+ delta 27 hcmdmGw9AM)k(ZZ?0SNdmJ8a~h!^r5ec?IJnaR6Y^2Q2^q diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/setopt.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/setopt.cpython-39.pyc index 5bf36b02626f277f38c307215904b6ff9c63bdf5..991d40511adaea2eedc6a4a53a000f6307d66ff3 100644 GIT binary patch delta 27 hcmdm}yiu7uk(ZZ?0SLH_yf$(xGBdhu)@5$t0{~6#1zZ3C delta 27 hcmdm}yiu7uk(ZZ?0SNdmJ8a}uWM*{PtjpZO2LM&U1@r&_ diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/test.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/test.cpython-39.pyc index 6c6047e4297db2c3d2789742f03f4bc4125efa5f..9ce4ecb2e3f3fb88dfbef3bd8e3e5e36ba6b17ce 100644 GIT binary patch delta 27 hcmX@?bl8bIk(ZZ?0SLH_yf$(#U}ALJyoPDI8~|QI2HgMv delta 27 hcmX@?bl8bIk(ZZ?0SNdmJ8a}$z{KdXc@5KaIRIuA2Xz1d diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/upload.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/upload.cpython-39.pyc index 052f59025c66b48188aa94f10f369caecf923606..add0cd8dbbc4634e435ecc39b489afc5d44a6829 100644 GIT binary patch delta 27 hcmZ3(wuX&6k(ZZ?0SLH_yf$)QU}SXLe1|cB5dcq^1~C8t delta 27 hcmZ3(wuX&6k(ZZ?0SNdmJ8a~>z{u#b`3_?MBLG)x2FU;b diff --git a/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/upload_docs.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/setuptools/command/__pycache__/upload_docs.cpython-39.pyc index 57c2be7e511bff1daa8de6c38981405b06970262..e151cb2d560ab7768436941aaef2846793cbafd1 100644 GIT binary patch delta 27 hcmeA+=r-U^@JZ1?B(% diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/INSTALLER b/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/LICENSE.txt b/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/LICENSE.txt deleted file mode 100644 index d51d0a59..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/LICENSE.txt +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2012, Matt Davis -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -- The name Matt Davis 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 HOLDER 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/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/METADATA b/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/METADATA deleted file mode 100644 index ecae5637..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/METADATA +++ /dev/null @@ -1,54 +0,0 @@ -Metadata-Version: 2.1 -Name: snakeviz -Version: 2.1.0 -Summary: A web-based viewer for Python profiler output -Home-page: https://github.com/jiffyclub/snakeviz -Author: Matt Davis -Author-email: jiffyclub@gmail.com -License: UNKNOWN -Platform: UNKNOWN -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Natural Language :: English -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: JavaScript -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Topic :: Software Development -Requires-Dist: tornado (>=2.0) - -SnakeViz -======== - -.. image:: https://travis-ci.org/jiffyclub/snakeviz.svg?branch=master - :target: https://travis-ci.org/jiffyclub/snakeviz - :alt: Build Status - -.. image:: https://img.shields.io/pypi/v/snakeviz.svg - :target: https://pypi.python.org/pypi/snakeviz/ - :alt: Latest Version - -.. image:: https://img.shields.io/pypi/pyversions/snakeviz.svg - :target: https://pypi.python.org/pypi/snakeviz/ - :alt: Supported Python versions - -.. image:: https://img.shields.io/pypi/format/snakeviz.svg - :target: https://pypi.python.org/pypi/snakeviz/ - :alt: Wheel Status - -About ------ - -SnakeViz is a viewer for Python profiling data that runs as a web -application in your browser. It is inspired by the wxPython profile viewer -`RunSnakeRun `_. - -View the docs at https://jiffyclub.github.io/snakeviz/. - - diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/RECORD b/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/RECORD deleted file mode 100644 index a99cc927..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/RECORD +++ /dev/null @@ -1,42 +0,0 @@ -../../Scripts/snakeviz.exe,sha256=E25Nlf3SH6oxkfWQazux5ik2_kIn60_zqX4MLVtDCBM,106362 -snakeviz-2.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -snakeviz-2.1.0.dist-info/LICENSE.txt,sha256=qmcxFmwt3Y0oz6JJI6x9BZaLqVIYpMmMVeSWCA5GEIY,1435 -snakeviz-2.1.0.dist-info/METADATA,sha256=nH9V_ykS3JP1xzIr7rwzvH5DDVDc9Rhye_GT7lnsgEs,1803 -snakeviz-2.1.0.dist-info/RECORD,, -snakeviz-2.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -snakeviz-2.1.0.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 -snakeviz-2.1.0.dist-info/entry_points.txt,sha256=5oBaD_Ogznwnn62svzZtB3eGJN31fRksmaRptEpbWmo,48 -snakeviz-2.1.0.dist-info/top_level.txt,sha256=0U59somjmv_W7Qhd6V68_U2vqvRB41BznGI5v231eOg,9 -snakeviz/__init__.py,sha256=6uO3LvY1jBNv9mop8EB3BY24M78HYRhT1cKpSP--nQE,57 -snakeviz/__main__.py,sha256=QlLlrtqqBpg5KVrQDv9IBLX40pr-uCOSbfJD6r1cVl4,192 -snakeviz/__pycache__/__init__.cpython-39.pyc,, -snakeviz/__pycache__/__main__.cpython-39.pyc,, -snakeviz/__pycache__/cli.cpython-39.pyc,, -snakeviz/__pycache__/ipymagic.cpython-39.pyc,, -snakeviz/__pycache__/main.cpython-39.pyc,, -snakeviz/__pycache__/stats.cpython-39.pyc,, -snakeviz/__pycache__/version.cpython-39.pyc,, -snakeviz/cli.py,sha256=DbMlG5vBvxB5WVgr_--LrCH0uH_5D9pHeP2fUI6vkyE,5807 -snakeviz/ipymagic.py,sha256=H2NBO7TnUpi4fBk9oTD8GKY7VSTizAV8dBKsMYaHIXw,5331 -snakeviz/main.py,sha256=XJLdAMMYOU3Juq8EzMrqfBtD8PWPTj-BQ9X6CUF6iYI,2057 -snakeviz/static/drawsvg.js,sha256=6twwQvtwyioI2UrsEWyG3lbpUgwrwhb_UgH3ikr_VwI,11519 -snakeviz/static/favicon.ico,sha256=g-8VWAjphDxRDmpNKi_wLDSduXei9HvJAJ627jgSDd0,1406 -snakeviz/static/images/sort_asc.png,sha256=7mAQuwqNF-WDBxNqD78LGW2UmrbFDrZtH_jwp9Kk1Is,1118 -snakeviz/static/images/sort_both.png,sha256=Yk8KRxolNcR1Th9pdLDmTucNaQdzg0bioR0L_yAli4w,1136 -snakeviz/static/images/sort_desc.png,sha256=JtqOfq90agjewpKJd74hqmchJIRUChIEK4aqLZBLgOg,1127 -snakeviz/static/snakeviz.css,sha256=eUkdZ0AIUrPe4JNP9vMjxM4fUHY9Q7CmHt8rinQd6-o,3535 -snakeviz/static/snakeviz.js,sha256=UC8jLsgWrI1SKke34-mdxwnU-qb2SqN6HAii7q-zxuc,6756 -snakeviz/static/sunburst.js,sha256=BWp-VQzSRtV7uheoOu5mDYB0kgZ9VJmZ0NYPb-gb9K4,7134 -snakeviz/static/vendor/d3.min.js,sha256=9xcmPfcbFPsVGTGtCpaVc4-5gSSna7cj4bnPuRUrej4,146528 -snakeviz/static/vendor/d3.v3.min.js,sha256=dsOXGNHAo_syFnazt-KTBsCQeRmlcW1XKL0bCK4Baec,151725 -snakeviz/static/vendor/immutable.min.js,sha256=13JFytp-tj8jsxr6GQOVLCgcYfMUo2Paw4jVrnXLUPE,57032 -snakeviz/static/vendor/jquery-1.11.1.min.js,sha256=VAvG3sHdS5LqTT-5A_aeq_bZGa_Uj04xKxY8KM_w9EE,95786 -snakeviz/static/vendor/jquery-3.2.1.min.js,sha256=hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4,86659 -snakeviz/static/vendor/jquery.dataTables.min.css,sha256=TntJ2hIwyiYc8GIhWzIt-PvYBfQE4VfxJnn-ea5kcJs,14112 -snakeviz/static/vendor/jquery.dataTables.min.js,sha256=j007R7R6ijEWPa1df7FeJ6AFbQeww0xgif2SJWZOhHw,83268 -snakeviz/static/vendor/lodash.compat.min.js,sha256=6PdfTAOQP1gs7G1n26wraUgKrcOQRoia2u03ez8l3k8,31341 -snakeviz/static/vendor/lodash.min.js,sha256=8E6QUcFg1KTnpEU8TFGhpTGHw5fJqB9vCms3OhAYLqw,71419 -snakeviz/stats.py,sha256=v-y4nDgq7J3qIeqJHgefER9Og9sU0a0u3extDgNA784,2175 -snakeviz/templates/dir.html,sha256=GgjIQUqYljyDWTc9RsKQhTBvC5FaYa3JaKEGdhN4cf8,1757 -snakeviz/templates/viz.html,sha256=qjM7jybFw5u36O-ZQa4btEBsW5B4mhz7BHsAa9u4B9s,11473 -snakeviz/version.py,sha256=mXVYcHKOsY0tyDTVlMC-ix5C2xixEY9XlC0Ruqj1svI,31 diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/REQUESTED b/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/REQUESTED deleted file mode 100644 index e69de29b..00000000 diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/WHEEL b/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/WHEEL deleted file mode 100644 index ef99c6cf..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.34.2) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/entry_points.txt b/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/entry_points.txt deleted file mode 100644 index 646cccea..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[console_scripts] -snakeviz = snakeviz.cli:main - diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/top_level.txt b/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/top_level.txt deleted file mode 100644 index 2eab9bab..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz-2.1.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -snakeviz diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__init__.py b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__init__.py deleted file mode 100644 index 4b9b92b0..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .version import __version__ -from .ipymagic import * diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__main__.py b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__main__.py deleted file mode 100644 index 78f58cd5..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__main__.py +++ /dev/null @@ -1,7 +0,0 @@ -import sys -from .cli import main - -if __name__ == "__main__": - # __main__.py is ugly and confusing, monkey patch executable to say snakeviz - sys.argv[0] = "snakeviz" - sys.exit(main()) diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index addadead573b039cb65ed5b500d2883f355e9c6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 240 zcmYjL%L>9U5KO9K@p1PTDyU~gL_rUth@vM6EU^h1Y?G4ILj5CusaH?p9|(epcyM56 zcV=LBX|q{F7SH#D_HDmA@ej|6u`ScG#1O*~it!#}H+zw{L#(t#LHU7g9N?l3ka2B< zk^olX_9`e9)t{x^vb`^oJf=qx-jJ?X<4dp2bU@bmDOHkaDw&GOHasa6k@;da0TXJP ya80@yml;`#12H1yorH#GdgO)}NzXhJ*B*e7A_eFsdEpOZ#V!#ax!;Vt-M}A>=s+F- diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/__main__.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/__main__.cpython-39.pyc deleted file mode 100644 index 823fa2712d7bfa502ef84d8df83f7bd561bece51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 302 zcmYjL!Ab)$6nx2UODOh3_Fx4MJxCD?dJsjF-j+a!n@1aWH@hV3;(GN*^ypvs9l7>Y z`~yKSDHI%dGYrgQMoy;_2>AY8%CDf?X#OJ!<|3S%2U4I&1vx0Hl8V$crvxxjX-Vy= z8X-KT3KoFyK0^8iAB2Sb3bOGo{KDOi1kQ+0YpIQALPQlJXU@nHd;OY?ec}e^lcLf# z7RQj0H45QVY1h3^@kMu^VB_XJ{XATr@%v%ZHHKShR8#X+v1yu$U*B9Ug)6LV(ehc3 srsuc%kvrYtaVv{buF>&B^T}b%tQ|aC)Qx(s@I3ByED$3{l+g+K1Af#|#sB~S diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/cli.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/cli.cpython-39.pyc deleted file mode 100644 index 4278d9994e4a6cbe111ee1c5a6bde25fc6f82c65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4668 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 Z1Pe1}*0RS;b{SWZWi7zPyZKDM@NX38xorRd diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/main.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/main.cpython-39.pyc deleted file mode 100644 index 8ca70ba2228cff1fdf237da8aad9116bca3995a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1962 zcmZuxOOG5i5VqYtJv}{-Y&Mh4gFNOCAQQoaLnI`G&_+oFfv`bY1i~8B>K%J$dbVF{ zd$QV5?uQ^bt}hX@kN?%gFk+;VlfY?sURedVa#4iL0o|GXVF ze1v{6gV!6_&^mPaI|zmtP7uZLCkaU%>fp-eQg^-rRwt>Y9`!K#8f8~p#OwQ?Vq`u$ z=T~#zpp3j%?Q77$`fS4AWwoT0wrM-<&<;i%PfsmYtUS$Emza4=@*i7$Nth2`;|G_X z`53W)HJ>8ZdTDxjab<}XSC=Mkyovg!p2OYIMjz|irizp_%I+*z{5b}DpXfkETL}+Ez9)4s zm3bCQvyOV^7msK|@w7-H#pRcMmo_VFSVU?<+s9LOsB4UG&Bodt&*NfbPJO)*7_38= zmq2if10@VI@)S{rIn0GWWDz3vbnsO?|0K#-!o|q!J8mv09`rlVbIhD*GL4)GIQAzGqooq;Fim(C$p4I`QJ z%r)pkOzy^f^-exZSTD;}Pw3Xy!tx}66i-m54Ni0 zjnx2_{{t^me+}psub)9tXaRXQXfdn|V$Q;~5)fi|35YQQStny){TL7{$zAkqap0Ej z!ecHVdw2KN@%qwTl7m|5y6C_=s9S5jtihVB^jPhEuv(jMZBM}F8C&Tr8l`u1Hk?|T zDm*#UFlP4_a3NrI;6iiJDjkT)e`el_2Jj%5zZ3M1+U6wR>qR{Pj*nC>_In1$I2#Xw zlO=O97-$3~=gMfCYdm;?Z@$3mb00QUydm1?mNU9(G@dCDbGgxPizZ}D*Ns=05Dtt) z%b5Hu7pbL?JI&)v2T+qj$-P)jM8_=fVwuF*j`pIW0Q!j2#^{>bh8mrvh3xxc^~7EM z=tyzdE;IDi{`M?Mj7A|S3FW_EnT=b^Z$mfBIdRr#r$D?7UA_eZ)dFD2rI)_zW21Gj zPg>Xq-uS?oi?2KfnDc7heT_LMHL%gIX+O022tyr&VVbiU6ji8OVYoYsY*1k+3?uES zRS^FQ$B^yik>;B4v1G74@3K?gxZ%}8G1?Tz-HQc#CK<0s-t((UQqj!>eZCGdAlf*cmywa zo>2#QAZ{4Ho?#Qus8z55Rzm;n7agJ7}|w?PT@e_7T3hZPtf87j)_AS|YU@CsnN ZN+8i>#p&WMCYb!;`P~}<>4G)De*r>^0ki-B diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/stats.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/stats.cpython-39.pyc deleted file mode 100644 index 577db3890c075fa40ad035265323291de49832b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2735 zcmb_eTW=gi7OtwkOwV|1vLVXiaM=dJDzjRKu!NV$L>mF(vWr2A#6xS)sMB5JX}hO; zQdM@a(=8qx1iYaA3FAjgJnx^_f6%WyS^Kimz9Av=of?lX2@)^#sBWiDojSMg)Wpln z9ft3}Ki`eN3K;v57Uw^K#oy61bty}E&L%wKoaQ1Ik%Q66-H8`@mgeUEq!qO=_fr2c zi-NS31{m9^xW{_!BS>LA-UMm3lj*E1*0J!Cahw&HbiW*%Nj{W1iKjB*#C!5}F_NP1 zqG=a98?5FP+hj9-z}{nD{BIy?Q9DMYeC8N;)0_E~NX05U;251%hTg@>+2^&J@=d1_ z-?Q4Q9O6L_jxC{5)0$JjfZ~V zIqiAy7SO2foa1R0XP@9%s`xCZd{Cj+hNyz7Q?;w5%B{SO)&ZRVV5Q=4XR!C5PKfUV zSx6Nd8OC9rX%m*CP@CB3Fe^r-CFyWfs?dyOsEc?@?qqu>945Y>%YMg-c|T6Za{&*t zJP+@aJS|lw^<1LLiVd3Hp0g)$p6k$*W@xgBJe>@uQVnS@OtvTUt;OVQYn0`3m}i9? zj<$L%jSpidv1vr98+RI;aTDB+wJhR^Y#eP= zF0n?QwXktU6B7jsJELG>P1Ie`$gZfnpwsG*sjHCu)B1b22cPYZO<4?7T%_e>a4#8` zWj^@mAMf8C>O>*Y)u6v4i=Dwgv-<-LD_)<*$yU4}^`>M>2A}p@fwo8q`AI< zjKlgfF_h%dhk6!sRPGI2OmgtDXbz1ym8Dd^GZ;{xf_HWU%kp zH*CaHpyqKv7$bynma$p@Z(`M zmAA@L9~>T}AhWSTVfY&8JKb%cp6}T63%;dQ_LQXV8vB-+)@Cpx%q?4-JL!tW@-vVL zeA^o@t+59;Oeg&VBtpkCIkj&(W@*+BdF-YttAsf@)H65eLL1X|MA069i&CuUm_GD2NWq!|N0VNy}7s4_fPGnr@kU+F0cXe1unUWYl5@HF4Cy-U%lQAX45D1>7 zm|jC?=J7;C5tEa8Nil&P&iaLPpfsTN79D*FUB$k*ia_&PAkh4KIB+CBM>0GRDZ9rG z`MOQ=L#Gk_o9Z$SD7y8KM?SO$YV5Z9BWO)~Z39K>%c;8aHkSWKV|%wYby*DOxxJQ` zK%2hPA1XP`<3tY0@ct?J^mtD+Zki=VQS#!=;Hi26vvXH1Ul4H%o0=*J<9jdv=7mrB zgIsC-@d_sJ$F=kRF!0DeKkpN@3bsSuxKxJ^9rZkxkw~`CcAn5vy@skAN7ipqy-p^Lg{ zrV+W_A=S>O6tg9UL|x1)Jj-kq9;o<9ULh?Hg?bH~^W;*L!t>x#LAA+b_4<%jB<#Xf z6zJ2d=qN&V8C8taH8Xa=&aP2CY$JhOO0=G^p;94ezjoV4pr6F4x1yG?LcNdkWC8hT z=^XxTYN|hxs8^|@O0DQ0j9R8{1s$FtX%uPNERR$<8KUkhdWsu=C(gH}?sewJUIt6# z7ZxOE5Q{{y6$M3Uuh)%lLz3dbQrjcb@MLa+jiyCk=Pb4U3W2(hj`?^boIudy5#ZP5 z{_!R862?my|KeS>l#U2Qz&k?S#ED*~=?w8=Q&k%d6*;?UmAX$)tTnJ{lN|;RoVLbA tE2dOMoR(d-+jq#yJLl=s;5Nb9q)fMSd50>QCX{!fL6>xW^%uq}gjfIo diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/version.cpython-39.pyc b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/__pycache__/version.cpython-39.pyc deleted file mode 100644 index 2367d81675d06d56e113b23f2de036f5ce642e38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 205 zcmYe~<>g`kg4cf?6Xk*QV-N=!FabFZKwQiNBvKey7@`=W7*iO788n%ySdH`y^$h$p znQn2%$CsrR6=&w>#mC=bhcZ_(6fpxefr(!ME>4C$p8QV diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/cli.py b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/cli.py deleted file mode 100644 index b33a9b8a..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/cli.py +++ /dev/null @@ -1,169 +0,0 @@ -""" -This module contains the command line interface for snakeviz. - -""" -from __future__ import print_function - -import argparse -import os -import random -import socket -import sys -import threading -import webbrowser -from pstats import Stats - -try: - from urllib.parse import quote -except ImportError: - from urllib import quote - -from . import version - - -# As seen in IPython: -# https://github.com/ipython/ipython/blob/8be7f9abd97eafb493817371d70101d28640919c/IPython/html/notebookapp.py -# See the IPython license at: -# https://github.com/ipython/ipython/blob/master/COPYING.rst. -def random_ports(port, n): - """Generate a list of n random ports near the given port. - The first 5 ports will be sequential, and the remaining n-5 will be - randomly selected in the range [port-2*n, port+2*n]. - """ - for i in range(min(5, n)): - yield port + i - for i in range(n-5): - yield max(1, port + random.randint(-2*n, 2*n)) - - -class SVArgumentParser(argparse.ArgumentParser): - def error(self, message): - message = message + '\n\n' + self.format_help() - args = {'prog': self.prog, 'message': message} - self.exit(2, '%(prog)s: error: %(message)s' % args) - - -def build_parser(): - parser = SVArgumentParser( - description='Start SnakeViz to view a Python profile.') - - parser.add_argument('filename', help='Python profile to view') - - parser.add_argument('-v', '--version', action='version', - version=('%(prog)s ' + version.version)) - - parser.add_argument('-H', '--hostname', metavar='ADDR', default='127.0.0.1', - help='hostname to bind to (default: %(default)s)') - - parser.add_argument('-p', '--port', type=int, metavar='PORT', default=8080, - help='port to bind to; if this port is already in use a ' - 'free port will be selected automatically ' - '(default: %(default)s)') - - parser.add_argument('-b', '--browser', metavar='BROWSER_PATH', - help='name of webbrowser to launch as described in ' - 'the documentation of Python\'s webbrowser module: ' - 'https://docs.python.org/3/library/webbrowser.html') - - parser.add_argument('-s', '--server', action="store_true", default=False, - help='start SnakeViz in server-only mode--' - 'no attempt will be made to open a browser') - - return parser - - -def main(argv=None): - parser = build_parser() - args = parser.parse_args(argv) - - if args.browser and args.server: - parser.error("options --browser and --server are mutually exclusive") - - filename = os.path.abspath(args.filename) - if not os.path.exists(filename): - parser.error('the path %s does not exist' % filename) - - if not os.path.isdir(filename): - try: - open(filename) - except IOError as e: - parser.error('the file %s could not be opened: %s' - % (filename, str(e))) - - try: - Stats(filename) - except Exception: - parser.error(('The file %s is not a valid profile. ' % filename) + - 'Generate profiles using: \n\n' - '\tpython -m cProfile -o my_program.prof my_program.py\n\n' - 'Note that snakeviz must be run under the same ' - 'version of Python as was used to create the profile.\n') - - filename = quote(filename, safe='') - - hostname = args.hostname - port = args.port - - if not 0 <= port <= 65535: - parser.error('invalid port number %d: use a port between 0 and 65535' - % port) - - # Before starting tornado set the eventloop policy for windows and python 3.8 compatibility - # https://github.com/tornadoweb/tornado/issues/2608 - if sys.platform == 'win32' and sys.version_info[:2] == (3, 8): - import asyncio - asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) - - # Go ahead and import the tornado app and start it; we do an inline import - # here to avoid the extra overhead when just running the cli for --help and - # the like - - from .main import app - import tornado.ioloop - - # As seen in IPython: - # https://github.com/ipython/ipython/blob/8be7f9abd97eafb493817371d70101d28640919c/IPython/html/notebookapp.py - # See the IPython license at: - # https://github.com/ipython/ipython/blob/master/COPYING.rst. - for p in random_ports(port, 10): - try: - app.listen(p, address=hostname) - except socket.error as e: - print('Port {0} in use, trying another.'.format(p)) - else: - port = p - break - else: - print('No available port found.') - return 1 - - url = "http://{0}:{1}/snakeviz/{2}".format(hostname, port, filename) - print(('snakeviz web server started on %s:%d; enter Ctrl-C to exit' % - (hostname, port))) - print(url) - - if not args.server: - try: - browser = webbrowser.get(args.browser) - except webbrowser.Error as e: - parser.error('no web browser found: %s' % e) - - # Launch the browser in a separate thread to avoid blocking the - # ioloop from starting - def bt(): - browser.open(url, new=2) - threading.Thread(target=bt).start() - - try: - tornado.ioloop.IOLoop.instance().start() - except KeyboardInterrupt: - # TODO: Cheap KeyboardInterrupt handler for now; iPython has some nicer - # stuff for handling SIGINT and SIGTERM that might be worth borrowing - tornado.ioloop.IOLoop.instance().stop() - print('\nBye!') - - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/ipymagic.py b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/ipymagic.py deleted file mode 100644 index 144042f3..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/ipymagic.py +++ /dev/null @@ -1,172 +0,0 @@ -from __future__ import print_function - -import errno -import subprocess -import sys -import tempfile -import time -import uuid - -try: - from urllib.parse import quote -except ImportError: - from urllib import quote - -__all__ = ["load_ipython_extension"] - - -JUPYTER_HTML_TEMPLATE = """ - - -""" - - -# Users may be using snakeviz in an environment where IPython is not -# installed, this try/except makes sure that snakeviz is operational -# in that case. -try: - from IPython.core.magic import Magics, magics_class, line_cell_magic - from IPython.display import display, HTML -except ImportError: - pass -else: - - @magics_class - class SnakevizMagic(Magics): - @line_cell_magic - def snakeviz(self, line, cell=None): - """ - Profile code and display the profile in Snakeviz. - Works as a line or cell magic. - - Usage, in line mode: - %snakeviz [options] statement - - Usage, in cell mode: - %%snakeviz [options] [statement] - code... - code... - - Options: - - -t/--new-tab - If running the snakeviz magic in the Jupyter Notebook, - use this flag to open snakeviz visualization in a new tab - instead of embedded within the notebook. - - Note that this will briefly open a server with host 0.0.0.0, - which in some situations may present a slight security risk as - 0.0.0.0 means that the server will be available on all network - interfaces (if they are not blocked by something like a firewall). - - """ - # get location for saved profile - filename = tempfile.NamedTemporaryFile().name - - # parse options - opts, line = self.parse_options(line, "t", "new-tab", posix=False) - - # call signature for prun - line = "-q -D " + filename + " " + line - - # generate the stats file using IPython's prun magic - ip = get_ipython() - - if cell: - ip.run_cell_magic("prun", line, cell) - else: - ip.run_line_magic("prun", line) - - # start up a Snakeviz server - if _check_ipynb() and not ("t" in opts or "new-tab" in opts): - print("Embedding SnakeViz in this document...") - sv = open_snakeviz_and_display_in_notebook(filename) - else: - print("Opening SnakeViz in a new tab...") - sv = subprocess.Popen( - [sys.executable, "-m", "snakeviz", filename] - ) - # give time for the Snakeviz page to load then shut down the server - time.sleep(3) - sv.terminate() - - -def load_ipython_extension(ipython): - """Called when user runs %load_ext snakeviz""" - ipython.register_magics(SnakevizMagic) - - -def _check_ipynb(): - """ - Returns True if IPython is running as the backend for a - Jupyter Notebook. - - """ - cfg = get_ipython().config - return "connection_file" in cfg["IPKernelApp"] - - -def open_snakeviz_and_display_in_notebook(filename): - def _find_free_port(): - import socket - from contextlib import closing - - with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: - # snakeviz frequently gets called many times in a short period. - # This line tells the kernel it's okay to reuse TIME-WAIT sockets, - # which means snakeviz will use the same socket on successive runs, - # which makes life with snakeviz-over-SSH much easier. - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - # Try a default range of five ports, then use whatever's free. - ports = list(range(8080, 8085)) + [0] - for port in ports: - try: - s.bind(("", port)) - except socket.error as e: - if e.errno == errno.EADDRINUSE: - pass - else: - raise - else: - return s.getsockname()[1] - - port = str(_find_free_port()) - - def _start_and_wait_when_ready(): - import os - - environ = os.environ.copy() - environ["PYTHONUNBUFFERED"] = "TRUE" - sv = subprocess.Popen( - [ - sys.executable, - "-m", - "snakeviz", - "-s", - "-H", - "0.0.0.0", - "-p", - port, - filename, - ], - stdout=subprocess.PIPE, - universal_newlines=True, - env=environ, - ) - while True: - line = sv.stdout.readline() - if line.strip().startswith("snakeviz web server started"): - break - return sv - - sv = _start_and_wait_when_ready() - path = "/snakeviz/%s" % quote(filename, safe="") - display( - HTML( - JUPYTER_HTML_TEMPLATE.format( - port=port, path=path, uuid=uuid.uuid1() - ) - ) - ) - return sv diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/main.py b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/main.py deleted file mode 100644 index e0595c30..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/main.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -import os.path -from pstats import Stats -import json - -try: - from urllib.parse import quote -except ImportError: - from urllib import quote - -import tornado.ioloop -import tornado.web - -from .stats import table_rows, json_stats - -settings = { - 'static_path': os.path.join(os.path.dirname(__file__), 'static'), - 'template_path': os.path.join(os.path.dirname(__file__), 'templates'), - 'debug': True, - 'gzip': True -} - - -class VizHandler(tornado.web.RequestHandler): - def get(self, profile_name): - abspath = os.path.abspath(profile_name) - if os.path.isdir(abspath): - self._list_dir(abspath) - else: - try: - s = Stats(profile_name) - except: - raise RuntimeError('Could not read %s.' % profile_name) - self.render( - 'viz.html', profile_name=profile_name, - table_rows=table_rows(s), callees=json_stats(s)) - - def _list_dir(self, path): - """ - Show a directory listing. - - """ - entries = os.listdir(path) - dir_entries = [[[ - '..', - quote(os.path.normpath(os.path.join(path, '..')), safe='') - ]]] - for name in entries: - if name.startswith('.'): - # skip invisible files/directories - continue - fullname = os.path.join(path, name) - displayname = linkname = name - # Append / for directories or @ for symbolic links - if os.path.isdir(fullname): - displayname += '/' - if os.path.islink(fullname): - displayname += '@' - dir_entries.append( - [[displayname, quote(os.path.join(path, linkname), safe='')]]) - - self.render( - 'dir.html', dir_name=path, dir_entries=json.dumps(dir_entries)) - - -handlers = [(r'/snakeviz/(.*)', VizHandler)] - -app = tornado.web.Application(handlers, **settings) - -if __name__ == '__main__': - app.listen(8080) - tornado.ioloop.IOLoop.instance().start() diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/drawsvg.js b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/drawsvg.js deleted file mode 100644 index 068a4670..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/drawsvg.js +++ /dev/null @@ -1,363 +0,0 @@ -// This contains the code that renders and controls the visualization. - -var get_sunburst_render_params = function get_sunburst_render_params() { - // 80% of the smallest window dimension - var width = 0.8 * Math.min(window.innerHeight, window.innerWidth); - var height = width; - var radius = width / 2; - var partition = d3.layout.partition() - .size([2 * Math.PI, radius * radius]) - .value(function(d) { return d.time; }); - // By default D3 makes the y size proportional to some area, - // so y is a transformation from ~area to a linear scale - // so that all arcs have the same radial size. - var y = d3.scale.linear().domain([0, radius * radius]).range([0, radius]); - var arc = d3.svg.arc() - .startAngle(function(d) { - return Math.max(0, Math.min(2 * Math.PI, d.x)); - }) - .endAngle(function(d) { - return Math.max(0, Math.min(2 * Math.PI, d.x + d.dx)); - }) - .innerRadius(function(d) { return y(d.y); }) - .outerRadius(function(d) { return y(d.y + d.dy); }); - return { - "width": width, - "height": height, - "radius": radius, - "transform": "translate(" + radius + "," + radius + ")", - "partition": partition, - "arc": arc - }; -}; - -var get_icicle_render_params = function get_icicle_render_params() { - var width = window.innerWidth * 0.75; - var height = window.innerHeight * 0.8; - var leftMargin = 90; - var topMargin = 60; - var partition = d3.layout.partition() - .size([width - leftMargin, height - topMargin]) - .value(function(d) { return d.time; }); - return { - "width": width, - "height": height, - "leftMargin": leftMargin, - "topMargin": topMargin, - "transform": "translate(" + leftMargin + "," + topMargin + ")", - "partition": partition - }; -}; - -var get_render_params = function get_render_params(style) { - if (style === "sunburst") { - return get_sunburst_render_params(); - } else if (style === "icicle") { - return get_icicle_render_params(); - } else { - throw new Error("Unknown rendering style '" + style + "'."); - } -}; - -// Colors. -var scale = d3.scale.category20c(); - -// should make it so that a given function is always the same color -var color = function color(d) { - return scale(d.name); -}; - - -var make_vis_obj = function make_vis_obj (style) { - var params = get_render_params(style); - return d3.select("#chart") - .style('margin-left', 'auto') - .style('margin-right', 'auto') - .append("svg:svg") - .attr("width", params["width"]) - .attr("height", params["height"]) - .append("svg:g") - .attr("id", "container") - .attr("transform", params["transform"]); -}; -var vis = make_vis_obj("sunburst"); - - -var reset_vis = function reset_vis (style) { - // Remove the current figure - d3.select('svg').remove(); - - // Make and draw the new svg container - vis = make_vis_obj(style); -}; - -// This is the function that runs whenever the user clicks on an SVG -// element to trigger zooming. -var click = function click(d) { - // check whether we need to do anything - // (e.g. that the user hasn't clicked on the original root node) - if (d.name === sv_root_func_name) { - return; - } - - var stack_last = _.last(sv_call_stack); - if (d.name === stack_last) { - // need to go up a level in the call stack - sv_call_stack.pop(); - var new_root = _.last(sv_call_stack); - } else { - var new_root = d.name; - - // need to construct a new call stack - // go up the tree until we hit the tip of the call stack - var this_node = d; - var local_stack = [new_root]; - while (this_node.parent != null) { - if (this_node.parent.name === stack_last) { - // extend the call stack with what we've accumulated - local_stack.reverse(); - sv_call_stack = sv_call_stack.concat(local_stack); - break; - } else { - local_stack.push(this_node.parent.name); - this_node = this_node.parent; - } - } - } - - //figure out the new parent name - if (sv_call_stack.length === 1) { - var new_parent_name = null; - } else { - var new_parent_name = _.first(_.last(sv_call_stack, 2)); - } - - // Create new JSON for drawing a vis from a new root - sv_draw_vis(new_root, new_parent_name); - sv_update_call_stack_list(); - - // Activate the reset button if we aren't already at the root node - // And deactivate it if this is the root node - if (new_root !== sv_root_func_name) { - $('#resetbutton-zoom').prop('disabled', false); - } else { - $('#resetbutton-zoom').prop('disabled', true); - } -}; - -var sv_info_tpl = _.template( - ['
Name:
', - '
<%- name %>
', - '
Cumulative Time:
', - '
<%= cumulative %> s (<%= cumulative_percent %> %)
', - '
File:
', - '
<%- file %>
', - '
Line:
', - '
<%= line %>
', - '
Directory:
', - '
<%- directory %>
' - ].join('\n')); - -var sv_update_info_div = function sv_update_info_div (d) { - var re = /^(.*):(\d+)\((.*)\)$/; - var result = re.exec(d.name); - var file = result[1]; - var directory = ''; - var slash = file.lastIndexOf('/'); - if (slash !== -1) { - directory = file.slice(0, slash + 1); - file = file.slice(slash + 1); - } - var info = { - 'file': file, - 'directory': directory, - 'line': result[2], - 'name': result[3], - 'cumulative': d.cumulative.toPrecision(3), - 'cumulative_percent': (d.cumulative / sv_total_time * 100).toFixed(2) - }; - - var style = $('#sv-style-select').val(); - var div = $('#sv-info-div'); - div.html(sv_info_tpl(info)); - - var radius = get_sunburst_render_params()["radius"]; - if ((style === "sunburst") & (!div.hasClass('sunburst'))) { - div - .addClass('sunburst') - .removeClass('icicle') - .height(radius * 1.5) - .width(($('body').width() - (2 * radius)) / 2.1); - } else if ((style === "icicle") & (!div.hasClass('icicle'))) { - div - .addClass('icicle') - .removeClass('sunburst') - .height(radius * 1.5) - .width(200); - } -}; - - -var apply_mouseover = function apply_mouseover (selection) { - selection.on('mouseover', function (d, i) { - // select all the nodes that represent this exact function - // and highlight them by darkening their color - var thisname = d.name; - var thispath = selection.filter(function(d, i) { - return d.name === thisname; - }); - var thiscolor = d3.rgb('#ff00ff'); - thispath.style('fill', thiscolor.toString()); - sv_update_info_div(d); - sv_show_info_div(); - }) - .on('mouseout', function(d, i){ - // reset nodes to their original color - var thisname = d.name; - var thispath = selection.filter(function(d, i) { - return d.name === thisname;}); - thispath.style('fill', color(d)); - }); -}; - - -// This is having D3 do its thing. -var drawSunburst = function drawSunburst(json) { - var params = get_render_params("sunburst"); - - // For efficiency, filter nodes to keep only those large enough to see. - var nodes = params["partition"].nodes(json).filter(function(d) { - return (d.dx > 0.005); // 0.005 radians = 0.29 degrees. - }); - - // Bounding circle underneath the sunburst, to make it easier to detect - // when the mouse leaves the parent g. - vis.append("svg:circle") - .attr("r", params["radius"]) - .style("opacity", 0); - - var path = vis.data([json]).selectAll("path") - .data(nodes) - .enter().append("svg:path") - .attr("id", function(d, i) { return "path-" + i; }) - .attr("d", params["arc"]) - .attr("fill-rule", "evenodd") - .style("fill", color) - .style("stroke", "#fff") - .on('click', click) - .call(apply_mouseover); -}; - -var drawIcicle = function drawIcicle(json) { - params = get_render_params("icicle"); - var nodes = params["partition"].nodes(json).filter(function(d) { - return (d.dx > 0.5); // at least half-a-pixel wide to be visible. - }); - var x = d3.scale.linear() - .domain([0, nodes[0].dx]) - .range([0, params["width"] - params["leftMargin"]]); - var y = d3.scale.linear() - .domain([0, nodes[0].dy * $('#sv-depth-select').val()]) - .range([0, params["height"] - params["topMargin"]]); - - var rect = vis.data([json]).selectAll("rect") - .data(nodes) - .enter().append("rect") - .attr("id", function(d, i) { return "path-" + i; }) - .attr("x", function(d) { return x(d.x); }) - .attr("y", function(d) { return y(d.y); }) - .attr("width", function(d) { return x(d.dx); }) - .attr("height", function(d) { return y(d.dy); }) - .attr("fill-rule", "evenodd") - .attr("fill", color) - .attr("stroke", "#FFF") - .on('click', click) - .call(apply_mouseover); - - var labels = vis.data([json]).selectAll("text") - .data(nodes) - .enter().append("text") - .attr("x", function(d) { return x(d.x + (d.dx / 2.0)); }) - .attr("y", function(d) { return y(d.y + (d.dy / 2.0)); }) - .attr("width", function(d) { return x(d.dx); }) - .attr("height", function(d) { return y(d.dy); }) - .attr("font-family", "sans-serif") - .attr("font-size", "15px") - .attr("fill", "black") - .attr("text-anchor", "middle") - .attr("pointer-events", "none"); - - // Append the function name - labels.append("tspan") - .text(function(d) { return d.display_name; }) - .attr("text-anchor", "middle") - .attr("x", function(d) { return x(d.x + (d.dx / 2.0)); }); - // Append the time - labels.append("tspan") - .text(function(d) { return d.cumulative.toPrecision(3) + " s"; }) - .attr("text-anchor", "middle") - .attr("x", function(d) { return x(d.x + (d.dx / 2.0)); }) - .attr("dy", "1.2em"); - - // Remove labels that don't fit - d3.selectAll("text") - .each(function(d, a, b) { - // var text = d3.selectd(this); - var bbox = this.getBBox(); - if (bbox.width > x(d.dx)) { - this.remove(); - } - }); -}; - -// Clear and redraw the visualization -var redraw_vis = function redraw_vis(json) { - var style = $('#sv-style-select').val(); - reset_vis(style); - if (style === "sunburst") { - drawSunburst(json); - } else if (style === "icicle") { - drawIcicle(json); - } - d3.select('#container') - .on('mouseenter', sv_show_info_div) - .on('mouseleave', sv_hide_info_div); -}; - - -// Reset the visualization to its original state starting from the -// main root function. -var resetVis = function resetViz() { - sv_draw_vis(sv_root_func_name); - - // Reset the call stack - sv_call_stack = [sv_root_func_name]; - sv_update_call_stack_list(); - - $('#resetbutton-zoom').prop('disabled', true); -}; -$('#resetbutton-zoom').on('click', resetVis); - - -var resetRoot = function resetRoot() { - // originally set in the setup code in viz.html - sv_root_func_name = sv_root_func_name__cached; - resetVis(); - $('#resetbutton-root').prop('disabled', true); -}; -$('#resetbutton-root').on('click', resetRoot); - - -// The handler for when the user changes the depth selection dropdown. -var sv_selects_changed = function sv_selects_changed() { - sv_cycle_worker(); - var parent_name = null; - if (sv_call_stack.length > 1) { - parent_name = sv_call_stack[sv_call_stack.length - 2]; - } - sv_hide_error_msg(); - sv_draw_vis(_.last(sv_call_stack), parent_name); -}; -d3.select('#sv-style-select').on('change', sv_selects_changed); -d3.select('#sv-depth-select').on('change', sv_selects_changed); -d3.select('#sv-cutoff-select').on('change', sv_selects_changed); diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/favicon.ico b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/favicon.ico deleted file mode 100644 index d64343c801dbe93fd3f06dd9b9f059db20b44247..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1406 zcmbW1Wz-xs7)IX$CB=(1I7L(33GNWwA-F?|JHd+vcL?q+Da3=Sk+1DqNrLWG+8>$%(YTmC8p^m=_s+l^>7{B z)`=~hRHY>QAkil2suiCbX%#aIuSO}27M+WP9;UO>G+tbUTj2I^9hs3#lcgm=tOHgr;YxE&oLnYxjt_fm|O6r*U(da@FH7T40xc&R~2N>Pl5 z+tHzgSz!h;RV%p*qHB@Z&`~p2%pKkuylK37@*Lb2F9oLelG-SJWpCm8XZk5-7FG>X z8#-kADZKSC9s4Za8qOoa?cqAS8O|cYE%ZpN8@v^~W%3fQrTbdmg%UBcnhy`pECUvbI07$ui-o*%pRu0UBg*Km<48!zr@Vo zuHY_{mwJgEOv~KRFXJuXr-N(ZM((l3U4Y%=Cz7dg*V7?s2`&8$>j`fjZyn5*j)wE7 za06UVuHxQx+}8>>kgeIL$ac7E=&6}GytVXb@KWGLS0 z?wDITHk?J|9%tP3Fdgn1&LhGtaC`hE@(k_@Jre7dbwjs|w}6`triB@~#~F74Zcm2} zH<3(@yPof#l)QHKhEu(L!DiDwden+zJ$2lwCVTyyjpBm8 z+;zaBf84v(3?E&#?aZHF{qPaXkNM=WtBiZ&?(_X{>)s3fI^j#%Px|Uv8_4~KE!*Lso%M9i|Nas_Z__Cs1F{#+!xpE zG{@IB>^AR@x9_{~Z+DMa{KIDWuuretVb*2UV@Izv_S47D^L@M50zcom|EcTfSI%62 ziZ>5gYP5%v8{_f!F5Y^^k1yYDmgi1dbAlI7TX&KXO+nb*`VfFD}IA!gL@7QmV-|snSiBTqhuMt6P_}u4rcI3idKFP2SpU%ZJIE?RL`X zK?Oyo=*5GG2SxDYK=7akJqV&hrl{aWJa`y*5xh+1%i2y4V}gO?edPc9{r;a9vjc}) zn|Cxb4AYwFmvVG%_ui)U^y_4!ujsO!qzYuv8YUIR!Aw%KiWp=JrG#@>(I!s4#N7H->?w+cxsH2#GA};A>g8lyFDGPKh!5)vuP_{)}*83+N zJUBU!S0_i+E{*Lu1iGsNB``2iK-CyCU7?y_mv{xb_pUh>ESZqe1Y2{eAZLMSIT%EO zFrdOH1W^=3p>Qk~I{J+k#s5zQ@j{%aIA!l^GQjJ zqA1Uc2%!{8qBKfMNh#9DCnKS_*uZ8?mnf!+8@f8xtz#prVg=E`3bCBLWsNmDAX~PG z<(4fQh=UOzE2?gKXRkc9XeI3Er?HlHECVd%SI}3`hy1_du3@$R$r(qT;k@Sft63UX zv;)2Ea_iH>^6+4jPK-lGM{Zw37Tz>~~zlHzO61x51(V4jcaKrcIVDG$-d>)z}S|7f!xxYhfUE}Kj zug_h&HZN}go22$5Ym1}P8~vYNx7-~$TWFJ;_nh!wFYSAQJF{CCo=xpK8^7?iY1^!H haOA^1D_`VC7fU=jcT diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/images/sort_both.png b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/images/sort_both.png deleted file mode 100644 index 18670406bc01ab2721781822dd6478917745ff54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1136 zcmaJ>O=#0l98WD1Hz^GK+C=e@fhgE~b#2$Ux^~T`1v5)mw1NlIe}zC z+ge9alrMQeN|SYi`>tC{zIG}!O_oO7k;UC8kBf>8sknx65F`zy2d1H-4fel=trX>@ z^-LCL<%6P%3`TJ=Ov$hao1$9VN|vJbLJV@SM>nJN{L>dS(6uOiBq(#Tm4F5Pz>p2Q zhq^NAP_G)%=(c^JwImV&17Zb~j6Ty5OHq1RS0sD)n5Dro1ouYi-$7;N6i6T&f*`~B zRW8JV5YO;|=5RQ?2M8R`v7Es2f}anI0YT(Au=3Evo2})=wA8uci&#;*fUzaAY_V8m ziU9`MJuDxIL|hF)@DqgJ88op{@|#XmML~j&YU>u(kqKNyC5HxZlqQk>PQkENWld+L zOr&6JNwHX-;oOueKw17j)G$`j4o<^A@%~fT$qZVMO+yC_*eYpUzR7iEi3uAj7}*(w z`YKgS6%a;F0a+l?9R#wX>ZWTi<7HV)nhsV>6(*%9O%xbi*F?TK!383rh#(|*p6}q} zd?z25;!?0(hzA2Li3(Rj>VN@FT;Xbexbdo7cN7eZc$T28pMYAYjSR4yvZz;&C0tc+ zg{xJMrKKvDCBd+6WB+P&<%mp=yImbyVyq56G|9BvWUP^I>ms=lb4e+lDSgg;Us`JO zKB6{wH+j~F#-A4FY3K3qm~Z6m@V6}oQ%8?p-E$dw`#0C$PJfmCV8)v}3>Ydha%`fZ zJk~G*M^A3LGk$Td;R`icF67R~`sBOHv)Hlqlc%$jy~9_oZJcNyWxkbb_O9u#|7hLF z-<-NMLzh3S0YA@8gd1Pt(Df|3@16Y-n=aSvsF@AkI`ioeFg>&H3bXU&vBnE6gIChkL+(Ey+0iB4Z$Eze7t_CX>Hq)$ diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/images/sort_desc.png b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/images/sort_desc.png deleted file mode 100644 index def071ed5afd264a036f6d9e75856366fd6ad153..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1127 zcmbVMOK8+U7*1U&zKRu5sR)h{1;yRWWV^4}ShvZpU2*HWU2!iy(qy)cZ89;Lb+`3m zMbruv!GjkO!3qksP*5)lD)k}=Dp*ht-n@8G5m8XoN!zU+ih_Y;=AZe$?|)|~*Ri8v z(dtDU$2DZy)jV65`|pB!_H}d7Cv0h=sUqzpC0fy3%q0!dg+a#Bx^W(BM*oq=xP{{a zC9_bZ#q2IgCss)FbwX9kVQ7wPX{|b%-is;d!ri7V^Y8E8=YeU+{JuyQW*r6hnC$~D z?i}bS=mWia!r)uCftISo2rNuBP__DOPpZoN6tBeg{;|M=DHYl)^V3chvpJv;7lTL$ z26Y&PAc{gL+#HL=wg3?#C_qs_Vi3iouqZ(YW*(kdbB&UeSJN}Lm?ZN(lsb|iR4SEF zB^)Adw}29fgwG+0L8cM(`faLJgSNN6#-L(PcTI+l@K3y+Xf(g*^61+0|J+O6zN2mb?UNGh6GU@A{1+eF%d@N2(^XdVmhis(y25|iAr;gV=io5OsYy0 zB}Gv|2&GUGrBPB%s*yG^841Ug8a88lRI_zlvuiTDGuXsmv6A9qjS{y&NMEf3ay^6+ zuZK85>5PD^rkl1e`{kLAR>iJ)6dP%mSYRr@k~xQcDE=$%X{_--ITM&Og5Ml}G)wJ> zb)dhUZG9%p4iC23#JFrUCcmwHz{cugMoku~ue-kg{Mj0~%`FeCcz9jAdg}QET-kSG za`+2B_+lRTaeAVz>E`F1pN7h>B=BbGqcz13d%ywZR&4OjkNNrF_U}#EcXDGa@V52B z>JnIW7#s%CHi diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/snakeviz.css b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/snakeviz.css deleted file mode 100644 index 7b8af0a4..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/snakeviz.css +++ /dev/null @@ -1,228 +0,0 @@ -body { - padding: 20px; -} - -button { - font-family: monospace; - font-size: 20px; - background: white; - padding: 10px 20px 10px 20px; - border: 2px solid; - -webkit-border-radius: 28px; - -moz-border-radius: 28px; - border-radius: 28px; - color: #444444; - border-color: #444444; -} - -button:hover { - background: #C9F0F2; -} - -button:disabled { - color: #cccccc; - border-color: #cccccc; -} - -button:disabled:hover { - background: white; -} - -.btn-active { - background: #5CBDED; -} - -#resetbuttons { - position: absolute; - top: 60px; -} - -.button-div { - margin-bottom: 10px; -} - -#snakeviz-text { - position: absolute; - top: -20px; -} - -#snakeviz-text > a { - color: #cccccc; - font-family: monospace; - text-decoration: none; -} - -.sv-footer { - text-align: right; -} - -.footer-link { - color: #cccccc; - font-family: monospace; -} - -select { - font-family: monospace; - font-size: 20px; - background: white; - padding: 10px 20px 10px 20px; -} - -#sv-style-label { - font-family: monospace; - position: absolute; - top: 180px; -} - -#sv-depth-label { - font-family: monospace; - position: absolute; - top: 220px; -} - -#sv-cutoff-label { - font-family: monospace; - position: absolute; - top: 260px; -} - -#sv-info-div { - position: absolute; - top: 300px; - display: none; - overflow: hidden; -} - -.sv-info-label { - font-weight: bold; -} - -.sv-info-item { - font-family: monospace; - word-wrap: break-word; -} - -#sv-call-stack { - position: absolute; - right: 0; - padding-right: 10px; - font-family: monospace; - text-align: right; -} - -#sv-call-stack-list { - text-align: left; - overflow-y: scroll; - border: 2px solid gray; - background-color: white; - margin-top: 5px; - display: none; -} - -#sv-call-stack-list div { - cursor: pointer; - padding: 0 10px 0 10px; -} - -#sv-call-stack-list div:hover { - background-color: #C9F0F2; -} - -#sv-call-stack-list div span { - display: table-cell; -} - -#sv-error-div { - position: absolute; - display: none; -} - -.sv-error-msg { - color: #ecf0f1; - background: #e74c3c; - border: 3px solid #95a5a6; - border-radius: 28px; - -webkit-border-radius: 28px; - -moz-border-radius: 28px; - padding: 10px; -} - -.sv-error-msg a { - text-decoration: none; - color: #C9F0F2; -} - -.sv-error-msg a:hover { - text-decoration: underline; - color: #5CBDED; -} - -.sv-error-msg p { - padding: 0 20px 0 20px; -} - -.sv-error-close { - background: #c0392b; - text-align: center; - padding: 4px; - margin: 0 20px 20px 20px; - border-radius: 10px; -} - -.sv-error-close:hover { - background: #a52112; -} - -.data-table-hover { - background: #C9F0F2; -} - -/* Spinner CSS from http://tobiasahlin.com/spinkit/ */ -.spinner { - display: inline-block; - width: 100px; - text-align: center; -} - -.spinner > div { - width: 18px; - height: 18px; - background-color: #333; - - border-radius: 100%; - display: inline-block; - -webkit-animation: bouncedelay 1.4s infinite ease-in-out; - animation: bouncedelay 1.4s infinite ease-in-out; - /* Prevent first frame from flickering when animation starts */ - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.spinner .bounce1 { - -webkit-animation-delay: -0.32s; - animation-delay: -0.32s; -} - -.spinner .bounce2 { - -webkit-animation-delay: -0.16s; - animation-delay: -0.16s; -} - -@-webkit-keyframes bouncedelay { - 0%, 80%, 100% { -webkit-transform: scale(0.0) } - 40% { -webkit-transform: scale(1.0) } -} - -@keyframes bouncedelay { - 0%, 80%, 100% { - transform: scale(0.0); - -webkit-transform: scale(0.0); - } 40% { - transform: scale(1.0); - -webkit-transform: scale(1.0); - } -} - -.dir-listing { - margin-top: 20px; -} diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/snakeviz.js b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/snakeviz.js deleted file mode 100644 index e42d03b4..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/snakeviz.js +++ /dev/null @@ -1,228 +0,0 @@ -// Look for something that calls other functions, -// but is never called itself. -var sv_find_root = function sv_find_root (stats) { - var callers = Immutable.Set.fromKeys(stats); - var callees = Immutable.Set(); - - for (var key in stats) { - callees = callees.union(Immutable.Set.fromKeys(stats[key]['children'])); - } - - var diff = callers.subtract(callees); - if (diff.size !== 0) { - // hopefully there's only one thing left... - var possible_roots = diff.toJS(); - } else { - var possible_roots = _.keys(stats); - } - - // if more than one potential root found, fall back on finding the thing - // with the most cummulative time - return _.maxBy(possible_roots, function (s) { - return stats[s]['stats'][3]; - }); -}; - - -// Returns the hierarchy depth value from the depth element -// This value is used to prune elements when building the call tree: -// if a child's cumulative time is less than this fraction of the parent -// then the program skips the descent into that child. -var sv_hierarchy_cutoff = function sv_hierarchy_cutoff() { - return parseFloat($('#sv-cutoff-select').val()); -}; - - -// Configures the call stack button's settings and appearance -// for when the call stack is hidden. -var sv_call_stack_btn_for_show = function sv_call_stack_btn_for_show() { - var btn = $('#sv-call-stack-btn'); - btn.on('click', sv_show_call_stack); - btn.removeClass('btn-active'); -}; - - -// Configures the call stack button's settings and appearance -// for when the call stack is visible. -var sv_call_stack_btn_for_hide = function sv_call_stack_btn_for_hide() { - var btn = $('#sv-call-stack-btn'); - btn.on('click', sv_hide_call_stack); - btn.addClass('btn-active'); -}; - - -// Items on the call stack can include directory names that we want -// to remove for display in the call stack list. -var sv_item_name = function sv_item_name (name) { - var slash = name.lastIndexOf('/'); - var rename = name; - if (slash !== -1) { - rename = name.slice(slash + 1); - } - return rename; -}; - - -// Builds a list of div elements, each of which contain a number and -// a function description: file name:line number(function name) -var sv_call_tpl = _.template('
<%= i %>. <%- name %>
'); -var sv_call_stack_list = function sv_call_stack_list(call_stack) { - var calls = []; - // the call stack list comes in ordered from root -> leaf, - // but we want to display it leaf -> root, so we iterate over call_stack - // in reverse here. - for (var i = call_stack.length - 1; i >= 0; i--) { - (function () { - var index = i; - var name = call_stack[i]; - var parent_name = (i > 0) ? call_stack[i-1] : null; - calls.push($(sv_call_tpl( - {'name': sv_item_name(name), 'i': index} - )).click(function () { - sv_draw_vis(name, parent_name); - sv_call_stack = sv_call_stack.slice(0, index+1); - sv_update_call_stack_list(); - if (name !== sv_root_func_name) { - $('#resetbutton-zoom').prop('disabled', false); - } else { - $('#resetbutton-zoom').prop('disabled', true); - } - })); - })() - } - return calls; -}; - - -// update the displayed call stack list -var sv_update_call_stack_list = function sv_update_call_stack_list() { - var calls = sv_call_stack_list(sv_call_stack); - var div = $('#sv-call-stack-list'); - div.children().remove(); - div.append(calls); - return div; -}; - - -// make the call stack list visible -var sv_show_call_stack = function sv_show_call_stack() { - sv_call_stack_btn_for_hide(); - var div = $('#sv-call-stack-list'); - div.css('max-height', get_sunburst_render_params()["radius"] * 1.5); - div.show(); -}; - - -// hide the call stack list -var sv_hide_call_stack = function sv_hide_call_stack() { - var div = $('#sv-call-stack-list'); - div.hide(); - sv_call_stack_btn_for_show(); -}; - - -// show the information div -var sv_show_info_div = function sv_show_info_div() { - $('#sv-info-div').show(); -}; - - -// hide the information div -var sv_hide_info_div = function sv_hide_info_div() { - $('#sv-info-div').hide(); -}; - - -// Show the "app is working" indicator -var sv_show_working = function sv_show_working() { - $('#working-spinner').show(); -}; - - -// Hide the "app is working" indicator -var sv_hide_working = function sv_hide_working() { - $('#working-spinner').hide(); -}; - - -// Make the worker and sv_draw_vis function -var sv_make_worker = function sv_make_worker() { - var URL = URL || window.URL || window.webkitURL; - var blob = new Blob( - [$('#hierarchy-worker').text()], {'type': 'text/javascript'}); - var blobURL = URL.createObjectURL(blob); - var sv_worker = new Worker(blobURL); - - sv_worker.onmessage = function (event) { - var json = JSON.parse(event.data); - if (cache_key != null) { - sv_json_cache[cache_key] = json; - } - redraw_vis(json); - _.defer(sv_hide_working); - }; - - sv_worker.onerror = function (event) { - sv_show_error_msg(); - console.log(event); - sv_cycle_worker(); - sv_hide_working(); - }; - - sv_end_worker = function () { - sv_worker.terminate(); - URL.revokeObjectURL(blobURL); - sv_hide_working(); - }; - - return sv_worker; -}; - - -var sv_cycle_worker = function sv_cycle_worker() { - sv_end_worker(); - sv_worker = sv_make_worker(); -}; - - -var sv_draw_vis = function sv_draw_vis(root_name, parent_name) { - sv_show_working(); - var message = { - 'depth': sv_hierarchy_depth(), - 'cutoff': sv_hierarchy_cutoff(), - 'name': root_name, - 'parent_name': parent_name, - 'url': window.location.origin - }; - - cache_key = JSON.stringify(message); - if (_.has(sv_json_cache, cache_key)) { - redraw_vis(sv_json_cache[cache_key]); - sv_hide_working(); - } else { - sv_worker.postMessage(message); - } -}; - - -// An error message for when the worker fails building the call tree -var sv_show_error_msg = function sv_show_error_msg() { - var radius = get_sunburst_render_params()["radius"]; - $('#sv-error-div') - .css('top', window.innerHeight / 2 - radius) - .css('left', window.innerWidth / 2 - radius) - .width(radius * 2) - .show(); -}; - - -var sv_hide_error_msg = function sv_hide_error_msg() { - $('#sv-error-div').hide(); -}; -$('#sv-error-close-div').on('click', sv_hide_error_msg); diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/sunburst.js b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/sunburst.js deleted file mode 100644 index a51b4924..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/sunburst.js +++ /dev/null @@ -1,233 +0,0 @@ -// This contains the code that renders and controls -// the sunburst visualization. - - -// 80% of the smallest window dimension -var width = 0.8 * Math.min(window.innerHeight, window.innerWidth), - height = width, - radius = width / 2, - scale = d3.scale.category20c(); // colors - - -// should make it so that a given function is always the same color -var color = function color(d) { - return scale(d.name); -}; - - -var make_vis_obj = function make_vis_obj () { - return d3.select("#chart") - .style('margin-left', 'auto') - .style('margin-right', 'auto') - .append("svg:svg") - .attr("width", width) - .attr("height", height) - .append("svg:g") - .attr("id", "container") - .attr("transform", "translate(" + radius + "," + radius + ")"); -}; -var vis = make_vis_obj(); - - -var reset_vis = function reset_vis () { - // Remove the current figure - d3.select('svg').remove(); - - // Make and draw the new svg container - vis = make_vis_obj(); -}; - - -var partition = d3.layout.partition() - .size([2 * Math.PI, radius * radius]) - .value(function(d) { return d.size; }); - - -// By default D3 makes the y size proportional to some area, -// so y is a transformation from ~area to a linear scale -// so that all arcs have the same radial size. -var y = d3.scale.linear().domain([0, radius * radius]).range([0, radius]); -var arc = d3.svg.arc() - .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, d.x)); }) - .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, d.x + d.dx)); }) - .innerRadius(function(d) { return y(d.y); }) - .outerRadius(function(d) { return y(d.y + d.dy); }); - - -// This is the function that runs whenever the user clicks on an SVG -// element to trigger zooming. -var click = function click(d) { - // check whether we need to do anything - // (e.g. that the user hasn't clicked on the original root node) - if (d.name === sv_root_func_name) { - return; - } - - var stack_last = _.last(sv_call_stack); - if (d.name === stack_last) { - // need to go up a level in the call stack - sv_call_stack.pop(); - var new_root = _.last(sv_call_stack); - } else { - var new_root = d.name; - - // need to construct a new call stack - // go up the tree until we hit the tip of the call stack - var this_node = d; - var local_stack = [new_root]; - while (this_node.parent != null) { - if (this_node.parent.name === stack_last) { - // extend the call stack with what we've accumulated - local_stack.reverse(); - sv_call_stack = sv_call_stack.concat(local_stack); - break; - } else { - local_stack.push(this_node.parent.name); - this_node = this_node.parent; - } - } - } - - //figure out the new parent name - if (sv_call_stack.length === 1) { - var new_parent_name = null; - } else { - var new_parent_name = _.first(_.last(sv_call_stack, 2)); - } - - // Create new JSON for drawing a vis from a new root - sv_draw_vis(new_root, new_parent_name); - sv_update_call_stack_list(); - - // Activate the reset button if we aren't already at the root node - // And deactivate it if this is the root node - if (new_root !== sv_root_func_name) { - d3.select('#resetbutton').node().removeAttribute('disabled'); - } else { - d3.select('#resetbutton').property('disabled', 'True'); - } -}; - -var sv_info_tpl = _.template( - ['
Name:
', - '
<%- name %>
', - '
Cumulative Time:
', - '
<%= cumulative %> s (<%= cumulative_percent %> %)
', - '
File:
', - '
<%- file %>
', - '
Line:
', - '
<%= line %>
', - '
Directory:
', - '
<%- directory %>
' - ].join('\n')); - -var sv_update_info_div = function sv_update_info_div (d) { - var re = /^(.*):(\d+)\((.*)\)$/; - var result = re.exec(d.name); - var file = result[1]; - var directory = ''; - var slash = file.lastIndexOf('/'); - if (slash !== -1) { - directory = file.slice(0, slash + 1); - file = file.slice(slash + 1); - } - var info = { - 'file': file, - 'directory': directory, - 'line': result[2], - 'name': result[3], - 'cumulative': d.cumulative.toPrecision(3), - 'cumulative_percent': (d.cumulative / sv_total_time * 100).toFixed(2) - }; - $('#sv-info-div') - .html(sv_info_tpl(info)) - .height(radius * 1.5) - .width(($('body').width() - (2 * radius)) / 2.1); -}; - - -var apply_mouseover = function apply_mouseover (selection) { - selection.on('mouseover', function (d, i) { - // select all the nodes that represent this exact function - // and highlight them by darkening their color - var thisname = d.name; - var thispath = selection.filter(function(d, i) { - return d.name === thisname;}) - var thiscolor = d3.rgb('#ff00ff'); - thispath.style('fill', thiscolor.toString()); - sv_update_info_div(d); - }) - .on('mouseout', function(d, i){ - // reset nodes to their original color - var thisname = d.name; - var thispath = selection.filter(function(d, i) { - return d.name === thisname;}); - thispath.style('fill', color(d)); - }); -}; - - -// This is having D3 do its thing. -var drawSunburst = function drawSunburst(json) { - // Bounding circle underneath the sunburst, to make it easier to detect - // when the mouse leaves the parent g. - vis.append("svg:circle") - .attr("r", radius) - .style("opacity", 0); - - // For efficiency, filter nodes to keep only those large enough to see. - var nodes = partition.nodes(json) - .filter(function(d) { - return (d.dx > 0.005); // 0.005 radians = 0.29 degrees - }); - - var path = vis.data([json]).selectAll("path") - .data(nodes) - .enter().append("svg:path") - .attr("id", function(d, i) { return "path-" + i; }) - .attr("d", arc) - .attr("fill-rule", "evenodd") - .style("fill", color) - .style("stroke", "#fff") - .on('click', click) - .call(apply_mouseover); - - d3.select('#container') - .on('mouseenter', sv_show_info_div) - .on('mouseleave', sv_hide_info_div); -}; - - -// Clear and redraw the visualization -var redraw_vis = function redraw_vis(json) { - reset_vis(); - drawSunburst(json); -}; - - -// Reset the visualization to its original state starting from the -// main root function. -var resetVis = function resetViz() { - sv_draw_vis(sv_root_func_name); - - // Reset the call stack - sv_call_stack = [sv_root_func_name]; - sv_update_call_stack_list(); - - d3.select('#resetbutton').property('disabled', 'True'); -}; -d3.select('#resetbutton').on('click', resetVis); - - -// The handler for when the user changes the depth selection dropdown. -var sv_selects_changed = function sv_selects_changed() { - sv_cycle_worker(); - var parent_name = null; - if (sv_call_stack.length > 1) { - parent_name = sv_call_stack[sv_call_stack.length - 2]; - } - sv_hide_error_msg(); - sv_draw_vis(_.last(sv_call_stack), parent_name); -}; -d3.select('#sv-depth-select').on('change', sv_selects_changed); -d3.select('#sv-cutoff-select').on('change', sv_selects_changed); diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/d3.min.js b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/d3.min.js deleted file mode 100644 index d7cfb702..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null===n?0/0:+n}function e(n){return!isNaN(n)}function r(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function u(n){return n.length}function i(n){for(var t=1;n*t%1;)t*=10;return t}function o(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function a(){this._=Object.create(null)}function c(n){return(n+="")===la||n[0]===sa?sa+n:n}function l(n){return(n+="")[0]===sa?n.slice(1):n}function s(n){return c(n)in this._}function f(n){return(n=c(n))in this._&&delete this._[n]}function h(){var n=[];for(var t in this._)n.push(l(t));return n}function g(){var n=0;for(var t in this._)++n;return n}function p(){for(var n in this._)return!1;return!0}function v(){this._=Object.create(null)}function d(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function m(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=fa.length;r>e;++e){var u=fa[e]+t;if(u in n)return u}}function y(){}function x(){}function M(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function H(n){return ga(n,Ma),n}function O(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var l=ba.get(n);return l&&(n=l,c=V),a?t?u:r:t?y:i}function Z(n,t){return function(e){var r=Bo.event;Bo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Bo.event=r}}}function V(n,t){var e=Z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function X(){var n=".dragsuppress-"+ ++Sa,t="click"+n,e=Bo.select(Qo).on("touchmove"+n,_).on("dragstart"+n,_).on("selectstart"+n,_);if(wa){var r=Ko.style,u=r[wa];r[wa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),wa&&(r[wa]=u),i&&(e.on(t,function(){_(),o()},!0),setTimeout(o,0))}}function $(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>ka&&(Qo.scrollX||Qo.scrollY)){e=Bo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();ka=!(u.f||u.e),e.remove()}return ka?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function B(){return Bo.event.changedTouches[0].identifier}function W(){return Bo.event.target}function J(){return Qo}function G(n){return n>0?1:0>n?-1:0}function K(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function Q(n){return n>1?0:-1>n?Ea:Math.acos(n)}function nt(n){return n>1?Ca:-1>n?-Ca:Math.asin(n)}function tt(n){return((n=Math.exp(n))-1/n)/2}function et(n){return((n=Math.exp(n))+1/n)/2}function rt(n){return((n=Math.exp(2*n))-1)/(n+1)}function ut(n){return(n=Math.sin(n/2))*n}function it(){}function ot(n,t,e){return this instanceof ot?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ot?new ot(n.h,n.s,n.l):Mt(""+n,_t,ot):new ot(n,t,e)}function at(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new dt(u(n+120),u(n),u(n-120))}function ct(n,t,e){return this instanceof ct?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof ct?new ct(n.h,n.c,n.l):n instanceof st?ht(n.l,n.a,n.b):ht((n=bt((n=Bo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new ct(n,t,e)}function lt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new st(e,Math.cos(n*=La)*t,Math.sin(n)*t)}function st(n,t,e){return this instanceof st?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof st?new st(n.l,n.a,n.b):n instanceof ct?lt(n.h,n.c,n.l):bt((n=dt(n)).r,n.g,n.b):new st(n,t,e)}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Ya,r=gt(r)*Ia,i=gt(i)*Za,new dt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?new ct(Math.atan2(e,t)*Ta,Math.sqrt(t*t+e*e),n):new ct(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n,t,e){return this instanceof dt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof dt?new dt(n.r,n.g,n.b):Mt(""+n,dt,at):new dt(n,t,e)}function mt(n){return new dt(n>>16,255&n>>8,255&n)}function yt(n){return mt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function Mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(St(u[0]),St(u[1]),St(u[2]))}return(i=$a.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new ot(r,u,c)}function bt(n,t,e){n=wt(n),t=wt(t),e=wt(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Ya),u=pt((.2126729*n+.7151522*t+.072175*e)/Ia),i=pt((.0193339*n+.119192*t+.9503041*e)/Za);return st(116*u-16,500*(r-u),200*(u-i))}function wt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function St(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function kt(n){return"function"==typeof n?n:function(){return n}}function Et(n){return n}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Ct(t,e,n,r)}}function Ct(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Bo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!Qo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Bo.event;Bo.event=n;try{o.progress.call(i,c)}finally{Bo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Jo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Bo.rebind(i,o,"on"),null==r?i:i.get(Nt(r))}function Nt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function Lt(){var n=Tt(),t=qt()-n;t>24?(isFinite(t)&&(clearTimeout(Ga),Ga=setTimeout(Lt,t)),Ja=0):(Ja=1,Qa(Lt))}function Tt(){var n=Date.now();for(Ka=Ba;Ka;)n>=Ka.t&&(Ka.f=Ka.c(n-Ka.t)),Ka=Ka.n;return n}function qt(){for(var n,t=Ba,e=1/0;t;)t.f?t=n?n.n=t.n:Ba=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:Et;return function(n){var e=tc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=ec.get(g)||Ut;var x=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=Bo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var M,_,b=n.lastIndexOf(".");if(0>b){var w=y?n.lastIndexOf("e"):-1;0>w?(M=n,_=""):(M=n.substring(0,w),_=n.substring(w))}else M=n.substring(0,b),_=t+n.substring(b+1);!l&&f&&(M=i(M,1/0));var S=v.length+M.length+_.length+(x?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return x&&(M=i(k+M,k.length?s-_.length:1/0)),u+=v,n=M+_,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(x?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new uc(e-1)),1),e}function i(n,e){return t(n=new uc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{uc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{uc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{uc=jt;var r=new jt;return r._=t,n(r,e)._}finally{uc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in oc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.slice(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function l(n,t,r){return e(n,C.X.toString(),t,r)}function s(n,t,e){var r=x.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{uc=jt;var t=new uc;return t._=n,r(t)}finally{uc=Date}}var r=t(n);return e.parse=function(n){try{uc=jt;var t=r.parse(n);return t&&t._}finally{uc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var x=Bo.map(),M=It(v),_=Zt(v),b=It(d),w=Zt(d),S=It(m),k=Zt(m),E=It(y),A=Zt(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Yt(n.getDate(),t,2)},e:function(n,t){return Yt(n.getDate(),t,2)},H:function(n,t){return Yt(n.getHours(),t,2)},I:function(n,t){return Yt(n.getHours()%12||12,t,2)},j:function(n,t){return Yt(1+rc.dayOfYear(n),t,3)},L:function(n,t){return Yt(n.getMilliseconds(),t,3)},m:function(n,t){return Yt(n.getMonth()+1,t,2)},M:function(n,t){return Yt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Yt(n.getSeconds(),t,2)},U:function(n,t){return Yt(rc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Yt(rc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Yt(n.getFullYear()%100,t,2)},Y:function(n,t){return Yt(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function Yt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function It(n){return new RegExp("^(?:"+n.map(Bo.requote).join("|")+")","i")}function Zt(n){for(var t=new a,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=0|ca(t)/60,u=ca(t)%60;return e+Yt(r,"0",2)+Yt(u,"0",2)}function oe(n,t,e){cc.lastIndex=0;var r=cc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);pc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;vc.point=function(o,a){vc.point=n,r=(t=o)*La,u=Math.cos(a=(e=a)*La/2+Ea/4),i=Math.sin(a)},vc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function xe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function Me(n){return[Math.atan2(n[1],n[0]),nt(n[2])]}function _e(n,t){return ca(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ze(e,n,null,!0),l=new ze(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new ze(r,n,null,!1),l=new ze(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),Ne(i),Ne(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Ne(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=Bo.merge(g);var n=je(m,p);g.length?(_||(i.polygonStart(),_=!0),Ce(g,Re,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=qe(),M=t(x),_=!1;return y}}function Te(n){return n.length>1}function qe(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:y,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Re(n,t){return((n=n.x)[0]<0?n[1]-Ca-Na:Ca-n[1])-((t=t.x)[0]<0?t[1]-Ca-Na:Ca-t[1])}function De(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Ea:-Ea,c=ca(i-e);ca(c-Ea)0?Ca:-Ca),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Ea&&(ca(e-u)Na?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Ue(n,t,e,r){var u;if(null==n)u=e*Ca,r.point(-Ea,u),r.point(0,u),r.point(Ea,u),r.point(Ea,0),r.point(Ea,-u),r.point(0,-u),r.point(-Ea,-u),r.point(-Ea,0),r.point(-Ea,u);else if(ca(n[0]-t[0])>Na){var i=n[0]a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Ea/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+Ea/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Ea,k=p*x;if(pc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*Aa:_,S^h>=e^m>=e){var E=de(pe(f),pe(n));xe(E);var A=de(u,E);xe(A);var C=(S^_>=0?-1:1)*nt(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Na>i||Na>i&&0>pc)^1&o}function Fe(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Ea:-Ea),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(_e(e,g)||_e(p,g))&&(p[0]+=Na,p[1]+=Na,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&_e(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),x=m*m-y*(ve(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ye(d,(-m-M)/y);if(me(_,p),_=Me(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ca(A-Ea)A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ca(_[0]-w)Ea^(w<=_[0]&&_[0]<=S)){var z=ye(d,(-m+M)/y);return me(z,p),[_,Me(z)]}}}function u(t,e){var r=o?n:Ea-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ca(i)>Na,c=gr(n,6*La);return Le(t,e,c,o?[0,-n]:[-Ea,n-Ea])}function He(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Oe(n,t,e,r){function u(r,u){return ca(r[0]-n)0?0:3:ca(r[0]-e)0?2:1:ca(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&K(l,i,n)>0&&++t:i[1]<=r&&K(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Nc,Math.min(Nc,n)),t=Math.max(-Nc,Math.min(Nc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=qe(),C=He(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Bo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return N}}function Ye(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ie(n){var t=0,e=Ea/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Ea/180,e=n[1]*Ea/180):[180*(t/Ea),180*(e/Ea)]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,nt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Lc+=u*n-r*t,r=n,u=t}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,t=r=i,e=u=o},Pc.lineEnd=function(){n(t,e)}}function Xe(n,t){Tc>n&&(Tc=n),n>Rc&&(Rc=n),qc>t&&(qc=t),t>Dc&&(Dc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){yc+=n,xc+=t,++Mc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);_c+=o*(t+n)/2,bc+=o*(e+r)/2,wc+=o,We(t=n,e=r)}var t,e;jc.point=function(r,u){jc.point=n,We(t=r,e=u)}}function Ge(){jc.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);_c+=o*(r+n)/2,bc+=o*(u+t)/2,wc+=o,o=u*n-r*t,Sc+=o*(r+n),kc+=o*(u+t),Ec+=3*o,We(r=n,u=t)}var t,e,r,u;jc.point=function(i,o){jc.point=n,We(t=r=i,e=u=o)},jc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,Aa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:y};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function s(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=l+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ca(ca(w)-1)i||ca((y*z+x*L)/M-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*La),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Ta,e*Ta])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*La,n[1]*La),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Ta,n[1]*Ta]}function r(){a=Ye(o=lr(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Cc,_=Et,b=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(M(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Cc):Fe((b=+n)*La),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Oe(n[0][0],n[0][1],n[1][0],n[1][1]):Et,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*La,d=n[1]%360*La,r()):[v*Ta,d*Ta]},t.rotate=function(n){return arguments.length?(m=n[0]%360*La,y=n[1]%360*La,x=n.length>2?n[2]%360*La:0,r()):[m*Ta,y*Ta,x*Ta]},Bo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*La,e*La)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>Ea?n-Aa:-Ea>n?n+Aa:n,t]}function lr(n,t,e){return n?t||e?Ye(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>Ea?t-Aa:-Ea>t?t+Aa:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),nt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),nt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*Aa)):(u=n+o*Aa,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=Me([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,xe(e);var r=Q(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Na)%(2*Math.PI)}function vr(n,t,e){var r=Bo.range(n,t-Na,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=Bo.range(n,t-Na,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function xr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(ut(r-t)+u*o*ut(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ta,Math.atan2(o,Math.sqrt(r*r+u*u))*Ta]}:function(){return[n*Ta,t*Ta]};return p.distance=h,p}function Mr(){function n(n,u){var i=Math.sin(u*=La),o=Math.cos(u),a=ca((n*=La)-t),c=Math.cos(a);Fc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Hc.point=function(u,i){t=u*La,e=Math.sin(i*=La),r=Math.cos(i),Hc.point=n},Hc.lineEnd=function(){Hc.point=Hc.lineEnd=y}}function _r(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function br(n,t){function e(n,t){o>0?-Ca+Na>t&&(t=-Ca+Na):t>Ca-Na&&(t=Ca-Na);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Ea/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=G(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ca]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ca(u)u;u++){for(;r>1&&K(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function Lr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Tr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function qr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=Kc.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Wc.remove(n),Kc.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ca(e-c.circle.x)s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Wc._;a;)if(r=Fr(a,o)-i,r>Na)a=a.L;else{if(u=i-Hr(a,o),!(u>Na)){r>-Na?(t=a.P,e=a):u>-Na?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Wc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Wc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),Vr(e),void 0;if(!e)return c.edge=Jr(t.site,c.site),void 0;Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+s,y:(h*x-v*y)/m+f};Kr(e.edge,l,p,M),c.edge=Jr(l,n,null,M),e.edge=Jr(n,p,null,M),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Yr(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Bc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ca(r-t)>Na||ca(u-e)>Na)&&(a.splice(o,0,new Qr(Gr(i.site,s,ca(r-f)Na?{x:f,y:ca(t-f)Na?{x:ca(e-p)Na?{x:h,y:ca(t-h)Na?{x:ca(e-g)=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=Qc.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Gc._;x;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:pu(e,r)})),i=el.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function du(n,t){for(var e,r=Bo.interpolators.length;--r>=0&&!(e=Bo.interpolators[r](n,t)););return e}function mu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(du(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function yu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function Mu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function bu(n){return n*n*n}function wu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Su(n){return function(t){return Math.pow(t,n)}}function ku(n){return 1-Math.cos(n*Ca)}function Eu(n){return Math.pow(2,10*(n-1))}function Au(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Aa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Aa/t)}}function Nu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function zu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=Bo.hcl(n),t=Bo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return lt(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=Bo.hsl(n),t=Bo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return at(e+i*n,r+o*n,u+a*n)+""}}function qu(n,t){n=Bo.lab(n),t=Bo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ft(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Du(n){var t=[n.a,n.b],e=[n.c,n.d],r=Uu(t),u=Pu(t,e),i=Uu(ju(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:pu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:pu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:pu(g[0],p[0])},{i:e-2,x:pu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i=0;)e.push(u[r])}function Ku(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++oe;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function li(n){return n.reduce(si,0)}function si(n,t){return n+t[1]}function fi(n,t){return hi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function hi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function gi(n){return[Bo.min(n),Bo.max(n)]}function pi(n,t){return n.value-t.value}function vi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function di(n,t){n._pack_next=t,t._pack_prev=n}function mi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function yi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],bi(r,u,i),t(i),vi(r,i),r._pack_prev=i,vi(i,u),u=r._pack_next,o=3;l>o;o++){bi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(mi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!mi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Mi)}}function xi(n){n._pack_next=n._pack_prev=n}function Mi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function Ni(n){return 1+Bo.max(n,function(n){return n.y})}function zi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function qi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ri(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Di(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Pi(n){return n.rangeExtent?n.rangeExtent():Di(n.range())}function Ui(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function ji(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Fi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:gl}function Hi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Hi:Ui,c=r?Ou:Hu;return o=u(n,t,c,e),a=u(t,n,c,du),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Ru)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Vi(n,t)},i.tickFormat=function(t,e){return Xi(n,t,e)},i.nice=function(t){return Ii(n,t),u()},i.copy=function(){return Oi(n,t,e,r)},u()}function Yi(n,t){return Bo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Ii(n,t){return ji(n,Fi(Zi(n,t)[2]))}function Zi(n,t){null==t&&(t=10);var e=Di(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Vi(n,t){return Bo.range.apply(Bo,Zi(n,t))}function Xi(n,t,e){var r=Zi(n,t);if(e){var u=tc.exec(e);if(u.shift(),"s"===u[8]){var i=Bo.formatPrefix(Math.max(ca(r[0]),ca(r[1])));return u[7]||(u[7]="."+$i(i.scale(r[2]))),u[8]="f",e=Bo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Bi(u[8],r)),e=u.join("")}else e=",."+$i(r[2])+"f";return Bo.format(e)}function $i(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Bi(n,t){var e=$i(t[2]);return n in pl?Math.abs(e-$i(Math.max(ca(t[0]),ca(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Wi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=ji(r.map(u),e?Math:dl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Di(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return vl;arguments.length<2?t=vl:"function"!=typeof t&&(t=Bo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Wi(n.copy(),t,e,r)},Yi(o,n)}function Ji(n,t,e){function r(t){return n(u(t))}var u=Gi(t),i=Gi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Vi(e,n)},r.tickFormat=function(n,t){return Xi(e,n,t)},r.nice=function(n){return r.domain(Ii(e,n))},r.exponent=function(o){return arguments.length?(u=Gi(t=o),i=Gi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Ji(n.copy(),t,e)},Yi(r,n)}function Gi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ki(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Bo.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new a;for(var i,o=-1,c=r.length;++on?[0/0,0/0]:[n>0?a[n-1]:r[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return no(n,t,e)},u()}function to(n,t){function e(e){return e>=e?t[Bo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return to(n,t)},e}function eo(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Vi(n,t)},t.tickFormat=function(t,e){return Xi(n,t,e)},t.copy=function(){return eo(n)},t}function ro(n){return n.innerRadius}function uo(n){return n.outerRadius}function io(n){return n.startAngle}function oo(n){return n.endAngle}function ao(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=kt(e),p=kt(r);++f1&&u.push("H",r[0]),u.join("")}function fo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Co(n){return n.length<3?co(n):n[0]+mo(n,Ao(n))}function No(n){for(var t,e,r,u=-1,i=n.length;++ue?l():(u.active=e,i.event&&i.event.start.call(n,s,t),i.tween.forEach(function(e,r){(r=r.call(n,s,t))&&v.push(r) -}),Bo.timer(function(){return p.c=c(r||1)?Ae:c,1},0,o),void 0)}function c(r){if(u.active!==e)return l();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a);return o>=1?(i.event&&i.event.end.call(n,s,t),l()):void 0}function l(){return--u.count?delete u[e]:delete n.__transition__,1}var s=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ka,v=[];return p.t=h+o,r>=h?a(r-h):(p.c=a,void 0)},0,o)}}function Oo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Yo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Io(n){return n.toISOString()}function Zo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Bo.bisect(Ol,u);return i==Ol.length?[t.year,Zi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Ol[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Vo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Vo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Di(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Vo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Zo(n.copy(),t,e)},Yi(r,n)}function Vo(n){return new Date(n)}function Xo(n){return JSON.parse(n.responseText)}function $o(n){var t=Go.createRange();return t.selectNode(Go.body),t.createContextualFragment(n.responseText)}var Bo={version:"3.4.13"};Date.now||(Date.now=function(){return+new Date});var Wo=[].slice,Jo=function(n){return Wo.call(n)},Go=document,Ko=Go.documentElement,Qo=window;try{Jo(Ko.childNodes)[0].nodeType}catch(na){Jo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Go.createElement("div").style.setProperty("opacity",0,"")}catch(ta){var ea=Qo.Element.prototype,ra=ea.setAttribute,ua=ea.setAttributeNS,ia=Qo.CSSStyleDeclaration.prototype,oa=ia.setProperty;ea.setAttribute=function(n,t){ra.call(this,n,t+"")},ea.setAttributeNS=function(n,t,e){ua.call(this,n,t,e+"")},ia.setProperty=function(n,t,e){oa.call(this,n,t+"",e)}}Bo.ascending=n,Bo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Bo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ur&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r)}return e},Bo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ue&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ue&&(e=r)}return e},Bo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=e);)e=u=void 0;for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=e);)e=void 0;for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},Bo.sum=function(n,t){var r,u=0,i=n.length,o=-1;if(1===arguments.length)for(;++or?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Bo.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=Bo.min(arguments,u),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ca=Math.abs;Bo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,u=[],o=i(ca(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)u.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,s,f,h,g=-1,p=o.length,v=i[c++],d=new a;++g=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Bo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Bo.set=function(n){var t=new v;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},o(v,{has:s,add:function(n){return this._[c(n+="")]=!0,n},remove:f,values:h,size:g,empty:p,forEach:function(n){for(var t in this._)n.call(this,l(t))}}),Bo.behavior={},Bo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Bo.event=null,Bo.requote=function(n){return n.replace(ha,"\\$&")};var ha=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ga={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},pa=function(n,t){return t.querySelector(n)},va=function(n,t){return t.querySelectorAll(n)},da=Ko.matches||Ko[m(Ko,"matchesSelector")],ma=function(n,t){return da.call(n,t)};"function"==typeof Sizzle&&(pa=function(n,t){return Sizzle(n,t)[0]||null},va=Sizzle,ma=Sizzle.matchesSelector),Bo.selection=function(){return _a};var ya=Bo.selection.prototype=[];ya.select=function(n){var t,e,r,u,i=[];n=k(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),xa.hasOwnProperty(e)?{space:xa[e],local:n}:n}},ya.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Bo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(A(t,n[t]));return this}return this.each(A(n,t))},ya.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=z(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(q(e,n[e],t));return this}if(2>r)return Qo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(q(n,t,e))},ya.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},ya.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},ya.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},ya.append=function(n){return n=D(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},ya.insert=function(n,t){return n=D(n),t=k(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},ya.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},ya.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new a,y=new Array(o);for(r=-1;++rr;++r)p[r]=P(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),l.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return S(u)},ya.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},ya.sort=function(n){n=j.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},ya.size=function(){var n=0;return F(this,function(){++n}),n};var Ma=[];Bo.selection.enter=H,Bo.selection.enter.prototype=Ma,Ma.append=ya.append,Ma.empty=ya.empty,Ma.node=ya.node,Ma.call=ya.call,Ma.size=ya.size,Ma.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(I(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(I(n,t,e))};var ba=Bo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ba.forEach(function(n){"on"+n in Go&&ba.remove(n)});var wa="onselectstart"in Go?null:m(Ko.style,"userSelect"),Sa=0;Bo.mouse=function(n){return $(n,b())};var ka=/WebKit/.test(Qo.navigator.userAgent)?-1:0;Bo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=b().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return $(n,r)},Bo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Bo.event.target===f),g({type:"dragend"}))}var l,s=this,f=Bo.event.target,h=s.parentNode,g=e.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Bo.select(u()).on(i+d,a).on(o+d,c),y=X(),x=t(h,v);r?(l=r.apply(s,arguments),l=[l.x-x[0],l.y-x[1]]):l=[0,0],g({type:"dragstart"})}}var e=w(n,"drag","dragstart","dragend"),r=null,u=t(y,Bo.mouse,J,"mousemove","mouseup"),i=t(B,Bo.touch,W,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Bo.rebind(n,e,"on")},Bo.touches=function(n,t){return arguments.length<2&&(t=b().touches),t?Jo(t).map(function(t){var e=$(n,t);return e.identifier=t.identifier,e}):[]};var Ea=Math.PI,Aa=2*Ea,Ca=Ea/2,Na=1e-6,za=Na*Na,La=Ea/180,Ta=180/Ea,qa=Math.SQRT2,Ra=2,Da=4;Bo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=et(v),o=i/(Ra*h)*(e*rt(qa*t+v)-tt(v));return[r+o*l,u+o*s,i*e/et(qa*t+v)]}return[r+n*l,u+n*s,i*Math.exp(qa*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Da*f)/(2*i*Ra*h),p=(c*c-i*i-Da*f)/(2*c*Ra*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/qa;return e.duration=1e3*y,e},Bo.behavior.zoom=function(){function n(n){n.on(A,l).on(ja+".zoom",f).on("dblclick.zoom",h).on(z,s)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){x&&x.domain(y.range().map(function(n){return(n-S.x)/S.k}).map(y.invert)),b&&b.domain(M.range().map(function(n){return(n-S.y)/S.k}).map(M.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function l(){function n(){s=1,u(Bo.mouse(r),h),a(l)}function e(){f.on(C,null).on(N,null),g(s&&Bo.event.target===i),c(l)}var r=this,i=Bo.event.target,l=L.of(r,arguments),s=0,f=Bo.select(Qo).on(C,n).on(N,e),h=t(Bo.mouse(r)),g=X();Y.call(r),o(l)}function s(){function n(){var n=Bo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Bo.event.target;Bo.select(t).on(x,i).on(M,f),b.push(t);for(var e=Bo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var l=n(),s=Date.now();if(1===l.length){if(500>s-m){var h=l[0],g=v[h.identifier];r(2*S.k),u(h,g),_(),a(p)}m=s}else if(l.length>1){var h=l[0],y=l[1],w=h[0]-y[0],k=h[1]-y[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Bo.touches(g),c=0,l=o.length;l>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=d&&Math.sqrt(s/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Bo.event.touches.length){for(var t=Bo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Bo.selectAll(b).on(y,null),w.on(A,l).on(z,s),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,y=".zoom-"+Bo.event.changedTouches[0].identifier,x="touchmove"+y,M="touchend"+y,b=[],w=Bo.select(g),k=X();Y.call(g),e(),o(p),w.on(A,null).on(z,e)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Bo.mouse(this)),Y.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),_(),r(Math.pow(2,.002*Pa())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Bo.mouse(this),i=t(e),l=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Bo.event.shiftKey?Math.ceil(l)-1:Math.floor(l)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,y,x,M,b,S={x:0,y:0,k:1},k=[960,500],E=Ua,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=w(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Cl?Bo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Bo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Ua:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(x=t,y=t.copy(),S={x:0,y:0,k:1},n):x},n.y=function(t){return arguments.length?(b=t,M=t.copy(),S={x:0,y:0,k:1},n):b},Bo.rebind(n,L,"on")};var Pa,Ua=[0,1/0],ja="onwheel"in Go?(Pa=function(){return-Bo.event.deltaY*(Bo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Go?(Pa=function(){return Bo.event.wheelDelta},"mousewheel"):(Pa=function(){return-Bo.event.detail},"MozMousePixelScroll");Bo.color=it,it.prototype.toString=function(){return this.rgb()+""},Bo.hsl=ot;var Fa=ot.prototype=new it;Fa.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,this.l/n)},Fa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,n*this.l)},Fa.rgb=function(){return at(this.h,this.s,this.l)},Bo.hcl=ct;var Ha=ct.prototype=new it;Ha.brighter=function(n){return new ct(this.h,this.c,Math.min(100,this.l+Oa*(arguments.length?n:1)))},Ha.darker=function(n){return new ct(this.h,this.c,Math.max(0,this.l-Oa*(arguments.length?n:1)))},Ha.rgb=function(){return lt(this.h,this.c,this.l).rgb()},Bo.lab=st;var Oa=18,Ya=.95047,Ia=1,Za=1.08883,Va=st.prototype=new it;Va.brighter=function(n){return new st(Math.min(100,this.l+Oa*(arguments.length?n:1)),this.a,this.b)},Va.darker=function(n){return new st(Math.max(0,this.l-Oa*(arguments.length?n:1)),this.a,this.b)},Va.rgb=function(){return ft(this.l,this.a,this.b)},Bo.rgb=dt;var Xa=dt.prototype=new it;Xa.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new dt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new dt(u,u,u)},Xa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new dt(n*this.r,n*this.g,n*this.b)},Xa.hsl=function(){return _t(this.r,this.g,this.b)},Xa.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var $a=Bo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});$a.forEach(function(n,t){$a.set(n,mt(t))}),Bo.functor=kt,Bo.xhr=At(Et),Bo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Ct(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new v,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Bo.csv=Bo.dsv(",","text/csv"),Bo.tsv=Bo.dsv(" ","text/tab-separated-values");var Ba,Wa,Ja,Ga,Ka,Qa=Qo[m(Qo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Bo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Wa?Wa.n=i:Ba=i,Wa=i,Ja||(Ga=clearTimeout(Ga),Ja=1,Qa(Lt))},Bo.timer.flush=function(){Tt(),qt()},Bo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var nc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);Bo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Bo.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),nc[8+e/3]};var tc=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,ec=Bo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Bo.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),rc=Bo.time={},uc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){ic.setUTCDate.apply(this._,arguments)},setDay:function(){ic.setUTCDay.apply(this._,arguments)},setFullYear:function(){ic.setUTCFullYear.apply(this._,arguments)},setHours:function(){ic.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){ic.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){ic.setUTCMinutes.apply(this._,arguments)},setMonth:function(){ic.setUTCMonth.apply(this._,arguments)},setSeconds:function(){ic.setUTCSeconds.apply(this._,arguments)},setTime:function(){ic.setTime.apply(this._,arguments)}};var ic=Date.prototype;rc.year=Ft(function(n){return n=rc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),rc.years=rc.year.range,rc.years.utc=rc.year.utc.range,rc.day=Ft(function(n){var t=new uc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),rc.days=rc.day.range,rc.days.utc=rc.day.utc.range,rc.dayOfYear=function(n){var t=rc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=rc[n]=Ft(function(n){return(n=rc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=rc.year(n).getDay();return Math.floor((rc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});rc[n+"s"]=e.range,rc[n+"s"].utc=e.utc.range,rc[n+"OfYear"]=function(n){var e=rc.year(n).getDay();return Math.floor((rc.dayOfYear(n)+(e+t)%7)/7)}}),rc.week=rc.sunday,rc.weeks=rc.sunday.range,rc.weeks.utc=rc.sunday.utc.range,rc.weekOfYear=rc.sundayOfYear;var oc={"-":"",_:" ",0:"0"},ac=/^\s*\d+/,cc=/^%/;Bo.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var lc=Bo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Bo.format=lc.numberFormat,Bo.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,sc),le(sc.s,this.s,this),this.s?this.t+=sc.t:this.s=sc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var sc=new ce;Bo.geo.stream=function(n,t){n&&fc.hasOwnProperty(n.type)?fc[n.type](n,t):se(n,t)};var fc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Ea+n:n,vc.lineStart=vc.lineEnd=vc.point=y}};Bo.geo.bounds=function(){function n(n,t){x.push(M=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*La,e*La]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);xe(o),o=Me(o);var c=t-p,l=c>0?1:-1,v=o[0]*Ta*l,d=ca(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Ta;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Ta;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=s,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ca(r)>180?r+(r>0?360:-360):r}else v=n,d=e;vc.point(n,e),t(n,e)}function i(){vc.lineStart()}function o(){u(v,d),vc.lineEnd(),ca(y)>Na&&(s=-(h=180)),M[0]=s,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:npc?(s=-(h=180),f=-(g=90)):y>Na?g=90:-Na>y&&(f=-90),M[0]=s,M[1]=h}};return function(n){g=h=-(s=f=1/0),x=[],Bo.geo.stream(n,_); -var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return x=M=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),Bo.geo.centroid=function(n){dc=mc=yc=xc=Mc=_c=bc=wc=Sc=kc=Ec=0,Bo.geo.stream(n,Ac);var t=Sc,e=kc,r=Ec,u=t*t+e*e+r*r;return za>u&&(t=_c,e=bc,r=wc,Na>mc&&(t=yc,e=xc,r=Mc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Ta,nt(r/Math.sqrt(u))*Ta]};var dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc,Ec,Ac={sphere:y,point:be,lineStart:Se,lineEnd:ke,polygonStart:function(){Ac.lineStart=Ee},polygonEnd:function(){Ac.lineStart=Se}},Cc=Le(Ae,De,Ue,[-Ea,-Ea/2]),Nc=1e9;Bo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Oe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Bo.geo.conicEqualArea=function(){return Ie(Ze)}).raw=Ze,Bo.geo.albers=function(){return Bo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Bo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Bo.geo.albers(),o=Bo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Bo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Na,f+.12*l+Na],[s-.214*l-Na,f+.234*l-Na]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Na,f+.166*l+Na],[s-.115*l-Na,f+.234*l-Na]]).stream(c).point,n},n.scale(1070)};var zc,Lc,Tc,qc,Rc,Dc,Pc={point:y,lineStart:y,lineEnd:y,polygonStart:function(){Lc=0,Pc.lineStart=Ve},polygonEnd:function(){Pc.lineStart=Pc.lineEnd=Pc.point=y,zc+=ca(Lc/2)}},Uc={point:Xe,lineStart:y,lineEnd:y,polygonStart:y,polygonEnd:y},jc={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){jc.lineStart=Ke},polygonEnd:function(){jc.point=We,jc.lineStart=Je,jc.lineEnd=Ge}};Bo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Bo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return zc=0,Bo.geo.stream(n,u(Pc)),zc},n.centroid=function(n){return yc=xc=Mc=_c=bc=wc=Sc=kc=Ec=0,Bo.geo.stream(n,u(jc)),Ec?[Sc/Ec,kc/Ec]:wc?[_c/wc,bc/wc]:Mc?[yc/Mc,xc/Mc]:[0/0,0/0]},n.bounds=function(n){return Rc=Dc=-(Tc=qc=1/0),Bo.geo.stream(n,u(Uc)),[[Tc,qc],[Rc,Dc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):Et,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Bo.geo.albersUsa()).context(null)},Bo.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Bo.geo.projection=ur,Bo.geo.projectionMutator=ir,(Bo.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,Bo.geo.rotation=function(n){function t(t){return t=n(t[0]*La,t[1]*La),t[0]*=Ta,t[1]*=Ta,t}return n=lr(n[0]%360*La,n[1]*La,n.length>2?n[2]*La:0),t.invert=function(t){return t=n.invert(t[0]*La,t[1]*La),t[0]*=Ta,t[1]*=Ta,t},t},cr.invert=ar,Bo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*La,-n[1]*La,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ta,n[1]*=Ta}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*La,u*La),n):t},n.precision=function(r){return arguments.length?(e=gr(t*La,(u=+r)*La),n):u},n.angle(90)},Bo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*La,u=n[1]*La,i=t[1]*La,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},Bo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Bo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Bo.range(Math.ceil(l/m)*m,c,m).map(g)).concat(Bo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ca(n%d)>Na}).map(s)).concat(Bo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ca(n%m)>Na}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Na],[180,90-Na]]).minorExtent([[-180,-80-Na],[180,80+Na]])},Bo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return Bo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Bo.geo.interpolate=function(n,t){return xr(n[0]*La,n[1]*La,t[0]*La,t[1]*La)},Bo.geo.length=function(n){return Fc=0,Bo.geo.stream(n,Hc),Fc};var Fc,Hc={sphere:y,point:y,lineStart:Mr,lineEnd:y,polygonStart:y,polygonEnd:y},Oc=_r(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Bo.geo.azimuthalEqualArea=function(){return ur(Oc)}).raw=Oc;var Yc=_r(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},Et);(Bo.geo.azimuthalEquidistant=function(){return ur(Yc)}).raw=Yc,(Bo.geo.conicConformal=function(){return Ie(br)}).raw=br,(Bo.geo.conicEquidistant=function(){return Ie(wr)}).raw=wr;var Ic=_r(function(n){return 1/n},Math.atan);(Bo.geo.gnomonic=function(){return ur(Ic)}).raw=Ic,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ca]},(Bo.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Zc=_r(function(){return 1},Math.asin);(Bo.geo.orthographic=function(){return ur(Zc)}).raw=Zc;var Vc=_r(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Bo.geo.stereographic=function(){return ur(Vc)}).raw=Vc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ca]},(Bo.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,Bo.geom={},Bo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=kt(e),i=kt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Nr(a),s=Nr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Na)*Na,y:Math.round(o(n,t)/Na)*Na,i:t}})}var r=Ar,u=Cr,i=r,o=u,a=nl;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Ir),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c=l,h=r>=s,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,x=kt(a),M=kt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var _=+x(s=n[g],g),b=+M(s,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=ul.get(e)||rl,r=il.get(r)||Et,yu(r(e.apply(null,Wo.call(arguments,1))))},Bo.interpolateHcl=Lu,Bo.interpolateHsl=Tu,Bo.interpolateLab=qu,Bo.interpolateRound=Ru,Bo.transform=function(n){var t=Go.createElementNS(Bo.ns.prefix.svg,"g");return(Bo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Du(e?e.matrix:ol)})(n)},Du.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var ol={a:1,b:0,c:0,d:1,e:0,f:0};Bo.interpolateTransform=Fu,Bo.layout={},Bo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=Bo.event.x,n.py=Bo.event.y,a.resume()}var e,r,u,i,o,a={},c=Bo.dispatch("start","tick","end"),l=[1,1],s=.9,f=al,h=cl,g=-30,p=ll,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=l[0]/2,M=l[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Wu(t=Bo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Bo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;l>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Bo.behavior.drag().origin(Et).on("dragstart.force",Vu).on("drag.force",t).on("dragend.force",Xu)),arguments.length?(this.on("mouseover.force",$u).on("mouseout.force",Bu).call(e),void 0):e},Bo.rebind(a,c,"on")};var al=20,cl=1,ll=1/0;Bo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Ku(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ti,e=Qu,r=ni;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Gu(t,function(n){n.children&&(n.value=0)}),Ku(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Bo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++lp;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=Et,e=oi,r=ai,u=ii,i=ri,o=ui;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:fl.get(t)||oi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:hl.get(t)||ai,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var fl=Bo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ci),i=n.map(li),o=Bo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return Bo.range(n.length).reverse()},"default":oi}),hl=Bo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ai});Bo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[Bo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=gi,u=fi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=kt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return hi(n,t)}:kt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Bo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Ku(a,function(n){n.r=+s(n.value)}),Ku(a,yi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Ku(a,function(n){n.r+=f}),Ku(a,yi),Ku(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=Bo.layout.hierarchy().sort(pi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Ju(n,e)},Bo.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Ku(h,e),h.parent.m=-h.z,Gu(h,r),l)Gu(f,i);else{var g=f,p=f,v=f;Gu(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Gu(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ai(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=ki(o),u=Si(u),o&&u;)c=Si(c),i=ki(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ei(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!ki(i)&&(i.t=o,i.m+=f-s),u&&!Si(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Bo.layout.hierarchy().sort(null).value(null),a=wi,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Ju(n,o)},Bo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Ku(c,function(n){var t=n.children;t&&t.length?(n.x=zi(t),n.y=Ni(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Ku(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Bo.layout.hierarchy().sort(null).value(null),e=wi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Ju(n,t)},Bo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Bo.random.normal.apply(Bo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Bo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Bo.scale={};var gl={floor:Et,ceil:Et};Bo.scale.linear=function(){return Oi([0,1],[0,1],du,!1)};var pl={s:1,g:1,p:1,r:1,e:1};Bo.scale.log=function(){return Wi(Bo.scale.linear().domain([0,1]),10,!0,[1,10])};var vl=Bo.format(".0e"),dl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Bo.scale.pow=function(){return Ji(Bo.scale.linear(),1,[0,1])},Bo.scale.sqrt=function(){return Bo.scale.pow().exponent(.5)},Bo.scale.ordinal=function(){return Ki([],{t:"range",a:[[]]})},Bo.scale.category10=function(){return Bo.scale.ordinal().range(ml)},Bo.scale.category20=function(){return Bo.scale.ordinal().range(yl)},Bo.scale.category20b=function(){return Bo.scale.ordinal().range(xl)},Bo.scale.category20c=function(){return Bo.scale.ordinal().range(Ml)};var ml=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(yt),yl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(yt),xl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(yt),Ml=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(yt);Bo.scale.quantile=function(){return Qi([],[]) -},Bo.scale.quantize=function(){return no(0,1,[0,1])},Bo.scale.threshold=function(){return to([.5],[0,1])},Bo.scale.identity=function(){return eo([0,1])},Bo.svg={},Bo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+_l,a=u.apply(this,arguments)+_l,c=(o>a&&(c=o,o=a,a=c),a-o),l=Ea>c?"0":"1",s=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=bl?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*s+","+i*f+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+l+",0 "+n*s+","+n*f+"Z":"M"+i*s+","+i*f+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=ro,e=uo,r=io,u=oo;return n.innerRadius=function(e){return arguments.length?(t=kt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=kt(t),n):e},n.startAngle=function(t){return arguments.length?(r=kt(t),n):r},n.endAngle=function(t){return arguments.length?(u=kt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+_l;return[Math.cos(i)*n,Math.sin(i)*n]},n};var _l=-Ca,bl=Aa-Na;Bo.svg.line=function(){return ao(Et)};var wl=Bo.map({linear:co,"linear-closed":lo,step:so,"step-before":fo,"step-after":ho,basis:xo,"basis-open":Mo,"basis-closed":_o,bundle:bo,cardinal:vo,"cardinal-open":go,"cardinal-closed":po,monotone:Co});wl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Sl=[0,2/3,1/3,0],kl=[0,1/3,2/3,0],El=[0,1/6,2/3,1/6];Bo.svg.line.radial=function(){var n=ao(No);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},fo.reverse=ho,ho.reverse=fo,Bo.svg.area=function(){return zo(Et)},Bo.svg.area.radial=function(){var n=zo(No);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Bo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+_l,s=l.call(n,u,r)+_l;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Ea)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Lo,c=io,l=oo;return n.radius=function(t){return arguments.length?(a=kt(t),n):a},n.source=function(t){return arguments.length?(i=kt(t),n):i},n.target=function(t){return arguments.length?(o=kt(t),n):o},n.startAngle=function(t){return arguments.length?(c=kt(t),n):c},n.endAngle=function(t){return arguments.length?(l=kt(t),n):l},n},Bo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=To;return n.source=function(e){return arguments.length?(t=kt(e),n):t},n.target=function(t){return arguments.length?(e=kt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Bo.svg.diagonal.radial=function(){var n=Bo.svg.diagonal(),t=To,e=n.projection;return n.projection=function(n){return arguments.length?e(qo(t=n)):t},n},Bo.svg.symbol=function(){function n(n,r){return(Al.get(t.call(this,n,r))||Po)(e.call(this,n,r))}var t=Do,e=Ro;return n.type=function(e){return arguments.length?(t=kt(e),n):t},n.size=function(t){return arguments.length?(e=kt(t),n):e},n};var Al=Bo.map({circle:Po,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/zl),e=t*zl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/zl),e=t*zl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Bo.svg.symbolTypes=Al.keys();var Cl,Nl,zl=Math.sqrt(3),Ll=Math.tan(30*La),Tl=[],ql=0;Tl.call=ya.call,Tl.empty=ya.empty,Tl.node=ya.node,Tl.size=ya.size,Bo.transition=function(n){return arguments.length?Cl?n.transition():n:_a.transition()},Bo.transition.prototype=Tl,Tl.select=function(n){var t,e,r,u=this.id,i=[];n=k(n);for(var o=-1,a=this.length;++oi;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Uo(u,this.id)},Tl.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):F(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Tl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Fu:du,a=Bo.ns.qualify(n);return jo(this,"attr."+n,t,a.local?i:u)},Tl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Bo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Tl.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Qo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=du(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return jo(this,"style."+n,t,u)},Tl.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Qo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Tl.text=function(n){return jo(this,"text",n,Fo)},Tl.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Tl.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Bo.ease.apply(Bo,arguments)),F(this,function(e){e.__transition__[t].ease=n}))},Tl.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:F(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Tl.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:F(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Tl.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Nl,u=Cl;Cl=e,F(this,function(t,r,u){Nl=t.__transition__[e],n.call(t,t.__data__,r,u)}),Nl=r,Cl=u}else F(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Bo.dispatch("start","end"))).on(n,t)});return this},Tl.transition=function(){for(var n,t,e,r,u=this.id,i=++ql,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],l=0,s=t.length;s>l;l++)(e=t[l])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Ho(e,l,i,r)),n.push(e)}return Uo(o,i)},Bo.svg.axis=function(){function n(n){n.each(function(){var n,l=Bo.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):Et:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Na),d=Bo.transition(p.exit()).style("opacity",Na).remove(),m=Bo.transition(p.order()).style("opacity",1),y=Math.max(u,0)+o,x=Pi(f),M=l.selectAll(".domain").data([0]),_=(M.enter().append("path").attr("class","domain"),Bo.transition(M));v.append("line"),v.append("text");var b,w,S,k,E=v.select("line"),A=m.select("line"),C=p.select("text").text(g),N=v.select("text"),z=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Oo,b="x",S="y",w="x2",k="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Yo,b="y",S="x",w="y2",k="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),E.attr(k,L*u),N.attr(S,L*y),A.attr(w,0).attr(k,L*u),z.attr(b,0).attr(S,L*y),f.rangeBand){var T=f,q=T.rangeBand()/2;s=f=function(n){return T(n)+q}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=Bo.scale.linear(),r=Rl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Dl?t+"":Rl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Rl="bottom",Dl={top:1,right:1,bottom:1,left:1};Bo.svg.brush=function(){function n(i){i.each(function(){var i=Bo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,Et);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Pl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var s,f=Bo.transition(i),h=Bo.transition(o);c&&(s=Pi(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Pi(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Bo.event.keyCode&&(C||(y=null,z[0]-=s[1],z[1]-=f[1],C=2),_())}function p(){32==Bo.event.keyCode&&2==C&&(z[0]+=s[1],z[1]+=f[1],C=0,_())}function v(){var n=Bo.mouse(M),u=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(Bo.event.altKey?(y||(y=[(s[0]+s[1])/2,(f[0]+f[1])/2]),z[0]=s[+(n[0]p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Bo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var y,x,M=this,b=Bo.select(Bo.event.target),w=a.of(M,arguments),S=Bo.select(M),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&l,C=b.classed("extent"),N=X(),z=Bo.mouse(M),L=Bo.select(Qo).on("keydown.brush",u).on("keyup.brush",p);if(Bo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=s[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);x=[s[1-T]-z[0],f[1-q]-z[1]],z[0]=s[T],z[1]=f[q]}else Bo.event.altKey&&(y=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Bo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=w(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],f=[0,0],h=!0,g=!0,p=Ul[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Cl?Bo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=mu(s,t.x),r=mu(f,t.y);return i=o=null,function(u){s=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Ul[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,p=Ul[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(h=!!t[0],g=!!t[1]):c?h=!!t:l&&(g=!!t),n):c&&l?[h,g]:c?h:l?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],l&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),l&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(h=u,u=a,a=h))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&f[0]==f[1]},Bo.rebind(n,a,"on")};var Pl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ul=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],jl=rc.format=lc.timeFormat,Fl=jl.utc,Hl=Fl("%Y-%m-%dT%H:%M:%S.%LZ");jl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Io:Hl,Io.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Io.toString=Hl.toString,rc.second=Ft(function(n){return new uc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),rc.seconds=rc.second.range,rc.seconds.utc=rc.second.utc.range,rc.minute=Ft(function(n){return new uc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),rc.minutes=rc.minute.range,rc.minutes.utc=rc.minute.utc.range,rc.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new uc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),rc.hours=rc.hour.range,rc.hours.utc=rc.hour.utc.range,rc.month=Ft(function(n){return n=rc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),rc.months=rc.month.range,rc.months.utc=rc.month.utc.range;var Ol=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Yl=[[rc.second,1],[rc.second,5],[rc.second,15],[rc.second,30],[rc.minute,1],[rc.minute,5],[rc.minute,15],[rc.minute,30],[rc.hour,1],[rc.hour,3],[rc.hour,6],[rc.hour,12],[rc.day,1],[rc.day,2],[rc.week,1],[rc.month,1],[rc.month,3],[rc.year,1]],Il=jl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ae]]),Zl={range:function(n,t,e){return Bo.range(Math.ceil(n/e)*e,+t,e).map(Vo)},floor:Et,ceil:Et};Yl.year=rc.year,rc.scale=function(){return Zo(Bo.scale.linear(),Yl,Il)};var Vl=Yl.map(function(n){return[n[0].utc,n[1]]}),Xl=Fl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ae]]);Vl.year=rc.year.utc,rc.scale.utc=function(){return Zo(Bo.scale.linear(),Vl,Xl)},Bo.text=At(function(n){return n.responseText}),Bo.json=function(n,t){return Ct(n,"application/json",Xo,t)},Bo.html=function(n,t){return Ct(n,"text/html",$o,t)},Bo.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Bo):"object"==typeof module&&module.exports&&(module.exports=Bo),this.d3=Bo}(); \ No newline at end of file diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/d3.v3.min.js b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/d3.v3.min.js deleted file mode 100644 index 16648730..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/d3.v3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ -r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], -shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; -if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/immutable.min.js b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/immutable.min.js deleted file mode 100644 index 18ffb77b..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/immutable.min.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Immutable=e()}(this,function(){"use strict";function t(t,e){e&&(t.prototype=Object.create(e.prototype)),t.prototype.constructor=t}function e(t){return o(t)?t:O(t)}function r(t){return u(t)?t:x(t)}function n(t){return s(t)?t:k(t)}function i(t){return o(t)&&!a(t)?t:A(t)}function o(t){return!(!t||!t[ar])}function u(t){return!(!t||!t[hr])}function s(t){return!(!t||!t[fr])}function a(t){return u(t)||s(t)}function h(t){return!(!t||!t[cr])}function f(t){return t.value=!1,t}function c(t){t&&(t.value=!0)}function _(){}function p(t,e){e=e||0;for(var r=Math.max(0,t.length-e),n=Array(r),i=0;r>i;i++)n[i]=t[i+e];return n}function v(t){return void 0===t.size&&(t.size=t.__iterate(y)),t.size}function l(t,e){if("number"!=typeof e){var r=e>>>0;if(""+r!==e||4294967295===r)return NaN;e=r}return 0>e?v(t)+e:e}function y(){return!0}function d(t,e,r){return(0===t||void 0!==r&&-r>=t)&&(void 0===e||void 0!==r&&e>=r)}function m(t,e){return w(t,e,0)}function g(t,e){return w(t,e,e)}function w(t,e,r){return void 0===t?r:0>t?Math.max(0,e+t):void 0===e?t:Math.min(e,t)}function S(t){this.next=t}function z(t,e,r,n){var i=0===t?e:1===t?r:[e,r];return n?n.value=i:n={value:i,done:!1},n}function I(){return{value:void 0,done:!0}}function b(t){return!!M(t)}function q(t){return t&&"function"==typeof t.next}function D(t){var e=M(t);return e&&e.call(t)}function M(t){var e=t&&(zr&&t[zr]||t[Ir]);return"function"==typeof e?e:void 0}function E(t){return t&&"number"==typeof t.length}function O(t){return null===t||void 0===t?T():o(t)?t.toSeq():C(t)}function x(t){return null===t||void 0===t?T().toKeyedSeq():o(t)?u(t)?t.toSeq():t.fromEntrySeq():B(t)}function k(t){return null===t||void 0===t?T():o(t)?u(t)?t.entrySeq():t.toIndexedSeq():W(t)}function A(t){return(null===t||void 0===t?T():o(t)?u(t)?t.entrySeq():t:W(t)).toSetSeq()}function j(t){this._array=t,this.size=t.length}function R(t){var e=Object.keys(t);this._object=t,this._keys=e, -this.size=e.length}function U(t){this._iterable=t,this.size=t.length||t.size}function K(t){this._iterator=t,this._iteratorCache=[]}function L(t){return!(!t||!t[qr])}function T(){return Dr||(Dr=new j([]))}function B(t){var e=Array.isArray(t)?new j(t).fromEntrySeq():q(t)?new K(t).fromEntrySeq():b(t)?new U(t).fromEntrySeq():"object"==typeof t?new R(t):void 0;if(!e)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+t);return e}function W(t){var e=J(t);if(!e)throw new TypeError("Expected Array or iterable object of values: "+t);return e}function C(t){var e=J(t)||"object"==typeof t&&new R(t);if(!e)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+t);return e}function J(t){return E(t)?new j(t):q(t)?new K(t):b(t)?new U(t):void 0}function N(t,e,r,n){var i=t._cache;if(i){for(var o=i.length-1,u=0;o>=u;u++){var s=i[r?o-u:u];if(e(s[1],n?s[0]:u,t)===!1)return u+1}return u}return t.__iterateUncached(e,r)}function P(t,e,r,n){var i=t._cache;if(i){var o=i.length-1,u=0;return new S(function(){var t=i[r?o-u:u];return u++>o?I():z(e,n?t[0]:u-1,t[1])})}return t.__iteratorUncached(e,r)}function H(t,e){return e?V(e,t,"",{"":t}):Y(t)}function V(t,e,r,n){return Array.isArray(e)?t.call(n,r,k(e).map(function(r,n){return V(t,r,n,e)})):Q(e)?t.call(n,r,x(e).map(function(r,n){return V(t,r,n,e)})):e}function Y(t){return Array.isArray(t)?k(t).map(Y).toList():Q(t)?x(t).map(Y).toMap():t}function Q(t){return t&&(t.constructor===Object||void 0===t.constructor)}function X(t,e){if(t===e||t!==t&&e!==e)return!0;if(!t||!e)return!1;if("function"==typeof t.valueOf&&"function"==typeof e.valueOf){if(t=t.valueOf(),e=e.valueOf(),t===e||t!==t&&e!==e)return!0;if(!t||!e)return!1}return"function"==typeof t.equals&&"function"==typeof e.equals&&t.equals(e)?!0:!1}function F(t,e){if(t===e)return!0;if(!o(e)||void 0!==t.size&&void 0!==e.size&&t.size!==e.size||void 0!==t.__hash&&void 0!==e.__hash&&t.__hash!==e.__hash||u(t)!==u(e)||s(t)!==s(e)||h(t)!==h(e))return!1;if(0===t.size&&0===e.size)return!0; -var r=!a(t);if(h(t)){var n=t.entries();return e.every(function(t,e){var i=n.next().value;return i&&X(i[1],t)&&(r||X(i[0],e))})&&n.next().done}var i=!1;if(void 0===t.size)if(void 0===e.size)"function"==typeof t.cacheResult&&t.cacheResult();else{i=!0;var f=t;t=e,e=f}var c=!0,_=e.__iterate(function(e,n){return(r?t.has(e):i?X(e,t.get(n,yr)):X(t.get(n,yr),e))?void 0:(c=!1,!1)});return c&&t.size===_}function G(t,e){if(!(this instanceof G))return new G(t,e);if(this._value=t,this.size=void 0===e?1/0:Math.max(0,e),0===this.size){if(Mr)return Mr;Mr=this}}function Z(t,e){if(!t)throw Error(e)}function $(t,e,r){if(!(this instanceof $))return new $(t,e,r);if(Z(0!==r,"Cannot step a Range by 0"),t=t||0,void 0===e&&(e=1/0),r=void 0===r?1:Math.abs(r),t>e&&(r=-r),this._start=t,this._end=e,this._step=r,this.size=Math.max(0,Math.ceil((e-t)/r-1)+1),0===this.size){if(Er)return Er;Er=this}}function tt(){throw TypeError("Abstract")}function et(){}function rt(){}function nt(){}function it(t){return t>>>1&1073741824|3221225471&t}function ot(t){if(t===!1||null===t||void 0===t)return 0;if("function"==typeof t.valueOf&&(t=t.valueOf(),t===!1||null===t||void 0===t))return 0;if(t===!0)return 1;var e=typeof t;if("number"===e){if(t!==t||t===1/0)return 0;var r=0|t;for(r!==t&&(r^=4294967295*t);t>4294967295;)t/=4294967295,r^=t;return it(r)}if("string"===e)return t.length>Kr?ut(t):st(t);if("function"==typeof t.hashCode)return t.hashCode();if("object"===e)return at(t);if("function"==typeof t.toString)return st(""+t);throw Error("Value type "+e+" cannot be hashed.")}function ut(t){var e=Br[t];return void 0===e&&(e=st(t),Tr===Lr&&(Tr=0,Br={}),Tr++,Br[t]=e),e}function st(t){for(var e=0,r=0;t.length>r;r++)e=31*e+t.charCodeAt(r)|0;return it(e)}function at(t){var e;if(jr&&(e=Or.get(t),void 0!==e))return e;if(e=t[Ur],void 0!==e)return e;if(!Ar){if(e=t.propertyIsEnumerable&&t.propertyIsEnumerable[Ur],void 0!==e)return e;if(e=ht(t),void 0!==e)return e}if(e=++Rr,1073741824&Rr&&(Rr=0),jr)Or.set(t,e);else{if(void 0!==kr&&kr(t)===!1)throw Error("Non-extensible objects are not allowed as keys."); -if(Ar)Object.defineProperty(t,Ur,{enumerable:!1,configurable:!1,writable:!1,value:e});else if(void 0!==t.propertyIsEnumerable&&t.propertyIsEnumerable===t.constructor.prototype.propertyIsEnumerable)t.propertyIsEnumerable=function(){return this.constructor.prototype.propertyIsEnumerable.apply(this,arguments)},t.propertyIsEnumerable[Ur]=e;else{if(void 0===t.nodeType)throw Error("Unable to set a non-enumerable property on object.");t[Ur]=e}}return e}function ht(t){if(t&&t.nodeType>0)switch(t.nodeType){case 1:return t.uniqueID;case 9:return t.documentElement&&t.documentElement.uniqueID}}function ft(t){Z(t!==1/0,"Cannot perform this action with an infinite size.")}function ct(t){return null===t||void 0===t?zt():_t(t)&&!h(t)?t:zt().withMutations(function(e){var n=r(t);ft(n.size),n.forEach(function(t,r){return e.set(r,t)})})}function _t(t){return!(!t||!t[Wr])}function pt(t,e){this.ownerID=t,this.entries=e}function vt(t,e,r){this.ownerID=t,this.bitmap=e,this.nodes=r}function lt(t,e,r){this.ownerID=t,this.count=e,this.nodes=r}function yt(t,e,r){this.ownerID=t,this.keyHash=e,this.entries=r}function dt(t,e,r){this.ownerID=t,this.keyHash=e,this.entry=r}function mt(t,e,r){this._type=e,this._reverse=r,this._stack=t._root&&wt(t._root)}function gt(t,e){return z(t,e[0],e[1])}function wt(t,e){return{node:t,index:0,__prev:e}}function St(t,e,r,n){var i=Object.create(Cr);return i.size=t,i._root=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function zt(){return Jr||(Jr=St(0))}function It(t,e,r){var n,i;if(t._root){var o=f(dr),u=f(mr);if(n=bt(t._root,t.__ownerID,0,void 0,e,r,o,u),!u.value)return t;i=t.size+(o.value?r===yr?-1:1:0)}else{if(r===yr)return t;i=1,n=new pt(t.__ownerID,[[e,r]])}return t.__ownerID?(t.size=i,t._root=n,t.__hash=void 0,t.__altered=!0,t):n?St(i,n):zt()}function bt(t,e,r,n,i,o,u,s){return t?t.update(e,r,n,i,o,u,s):o===yr?t:(c(s),c(u),new dt(e,n,[i,o]))}function qt(t){return t.constructor===dt||t.constructor===yt}function Dt(t,e,r,n,i){if(t.keyHash===n)return new yt(e,n,[t.entry,i]);var o,u=(0===r?t.keyHash:t.keyHash>>>r)&lr,s=(0===r?n:n>>>r)&lr,a=u===s?[Dt(t,e,r+pr,n,i)]:(o=new dt(e,n,i), -s>u?[t,o]:[o,t]);return new vt(e,1<o;o++){var u=e[o];i=i.update(t,0,void 0,u[0],u[1])}return i}function Et(t,e,r,n){for(var i=0,o=0,u=Array(r),s=0,a=1,h=e.length;h>s;s++,a<<=1){var f=e[s];void 0!==f&&s!==n&&(i|=a,u[o++]=f)}return new vt(t,i,u)}function Ot(t,e,r,n,i){for(var o=0,u=Array(vr),s=0;0!==r;s++,r>>>=1)u[s]=1&r?e[o++]:void 0;return u[n]=i,new lt(t,o+1,u)}function xt(t,e,n){for(var i=[],u=0;n.length>u;u++){var s=n[u],a=r(s);o(s)||(a=a.map(function(t){return H(t)})),i.push(a)}return jt(t,e,i)}function kt(t,e,r){return t&&t.mergeDeep&&o(e)?t.mergeDeep(e):X(t,e)?t:e}function At(t){return function(e,r,n){if(e&&e.mergeDeepWith&&o(r))return e.mergeDeepWith(t,r);var i=t(e,r,n);return X(e,i)?e:i}}function jt(t,e,r){return r=r.filter(function(t){return 0!==t.size}),0===r.length?t:0!==t.size||t.__ownerID||1!==r.length?t.withMutations(function(t){for(var n=e?function(r,n){t.update(n,yr,function(t){return t===yr?r:e(t,r,n)})}:function(e,r){t.set(r,e)},i=0;r.length>i;i++)r[i].forEach(n)}):t.constructor(r[0])}function Rt(t,e,r,n){var i=t===yr,o=e.next();if(o.done){var u=i?r:t,s=n(u);return s===u?t:s}Z(i||t&&t.set,"invalid keyPath");var a=o.value,h=i?yr:t.get(a,yr),f=Rt(h,e,r,n);return f===h?t:f===yr?t.remove(a):(i?zt():t).set(a,f)}function Ut(t){return t-=t>>1&1431655765,t=(858993459&t)+(t>>2&858993459),t=t+(t>>4)&252645135,t+=t>>8,t+=t>>16,127&t}function Kt(t,e,r,n){var i=n?t:p(t);return i[e]=r,i}function Lt(t,e,r,n){var i=t.length+1;if(n&&e+1===i)return t[e]=r,t;for(var o=Array(i),u=0,s=0;i>s;s++)s===e?(o[s]=r,u=-1):o[s]=t[s+u];return o}function Tt(t,e,r){var n=t.length-1;if(r&&e===n)return t.pop(),t;for(var i=Array(n),o=0,u=0;n>u;u++)u===e&&(o=1),i[u]=t[u+o];return i}function Bt(t){var e=Pt();if(null===t||void 0===t)return e;if(Wt(t))return t;var r=n(t),i=r.size;return 0===i?e:(ft(i),i>0&&vr>i?Nt(0,i,pr,null,new Ct(r.toArray())):e.withMutations(function(t){t.setSize(i),r.forEach(function(e,r){return t.set(r,e)})}))}function Wt(t){ -return!(!t||!t[Vr])}function Ct(t,e){this.array=t,this.ownerID=e}function Jt(t,e){function r(t,e,r){return 0===e?n(t,r):i(t,e,r)}function n(t,r){var n=r===s?a&&a.array:t&&t.array,i=r>o?0:o-r,h=u-r;return h>vr&&(h=vr),function(){if(i===h)return Xr;var t=e?--h:i++;return n&&n[t]}}function i(t,n,i){var s,a=t&&t.array,h=i>o?0:o-i>>n,f=(u-i>>n)+1;return f>vr&&(f=vr),function(){for(;;){if(s){var t=s();if(t!==Xr)return t;s=null}if(h===f)return Xr;var o=e?--f:h++;s=r(a&&a[o],n-pr,i+(o<=t.size||0>e)return t.withMutations(function(t){0>e?Xt(t,e).set(0,r):Xt(t,0,e+1).set(e,r)});e+=t._origin;var n=t._tail,i=t._root,o=f(mr);return e>=Gt(t._capacity)?n=Vt(n,t.__ownerID,0,e,r,o):i=Vt(i,t.__ownerID,t._level,e,r,o),o.value?t.__ownerID?(t._root=i,t._tail=n,t.__hash=void 0,t.__altered=!0,t):Nt(t._origin,t._capacity,t._level,i,n):t}function Vt(t,e,r,n,i,o){var u=n>>>r&lr,s=t&&t.array.length>u;if(!s&&void 0===i)return t;var a;if(r>0){var h=t&&t.array[u],f=Vt(h,e,r-pr,n,i,o);return f===h?t:(a=Yt(t,e),a.array[u]=f,a)}return s&&t.array[u]===i?t:(c(o),a=Yt(t,e),void 0===i&&u===a.array.length-1?a.array.pop():a.array[u]=i,a)}function Yt(t,e){return e&&t&&e===t.ownerID?t:new Ct(t?t.array.slice():[],e)}function Qt(t,e){if(e>=Gt(t._capacity))return t._tail;if(1<e){for(var r=t._root,n=t._level;r&&n>0;)r=r.array[e>>>n&lr],n-=pr;return r}}function Xt(t,e,r){void 0!==e&&(e=0|e),void 0!==r&&(r=0|r);var n=t.__ownerID||new _,i=t._origin,o=t._capacity,u=i+e,s=void 0===r?o:0>r?o+r:i+r;if(u===i&&s===o)return t;if(u>=s)return t.clear();for(var a=t._level,h=t._root,f=0;0>u+f;)h=new Ct(h&&h.array.length?[void 0,h]:[],n),a+=pr,f+=1<=1<p?Qt(t,s-1):p>c?new Ct([],n):v;if(v&&p>c&&o>u&&v.array.length){h=Yt(h,n);for(var y=h,d=a;d>pr;d-=pr){var m=c>>>d&lr;y=y.array[m]=Yt(y.array[m],n)}y.array[c>>>pr&lr]=v}if(o>s&&(l=l&&l.removeAfter(n,0,s)),u>=p)u-=p,s-=p,a=pr,h=null,l=l&&l.removeBefore(n,0,u);else if(u>i||c>p){for(f=0;h;){var g=u>>>a&lr;if(g!==p>>>a&lr)break;g&&(f+=(1<i&&(h=h.removeBefore(n,a,u-f)),h&&c>p&&(h=h.removeAfter(n,a,p-f)),f&&(u-=f,s-=f)}return t.__ownerID?(t.size=s-u,t._origin=u,t._capacity=s,t._level=a,t._root=h,t._tail=l,t.__hash=void 0,t.__altered=!0,t):Nt(u,s,a,h,l)}function Ft(t,e,r){for(var i=[],u=0,s=0;r.length>s;s++){var a=r[s],h=n(a);h.size>u&&(u=h.size),o(a)||(h=h.map(function(t){return H(t)})),i.push(h)}return u>t.size&&(t=t.setSize(u)),jt(t,e,i)}function Gt(t){return vr>t?0:t-1>>>pr<=vr&&u.size>=2*o.size?(i=u.filter(function(t,e){return void 0!==t&&s!==e}),n=i.toKeyedSeq().map(function(t){return t[0]}).flip().toMap(),t.__ownerID&&(n.__ownerID=i.__ownerID=t.__ownerID)):(n=o.remove(e),i=s===u.size-1?u.pop():u.set(s,void 0))}else if(a){if(r===u.get(s)[1])return t;n=o,i=u.set(s,[e,r])}else n=o.set(e,u.size),i=u.set(u.size,[e,r]);return t.__ownerID?(t.size=n.size,t._map=n,t._list=i,t.__hash=void 0,t):te(n,i)}function ne(t,e){this._iter=t,this._useKeys=e,this.size=t.size}function ie(t){this._iter=t,this.size=t.size}function oe(t){this._iter=t,this.size=t.size}function ue(t){this._iter=t,this.size=t.size}function se(t){var e=Ee(t);return e._iter=t,e.size=t.size,e.flip=function(){return t},e.reverse=function(){var e=t.reverse.apply(this); -return e.flip=function(){return t.reverse()},e},e.has=function(e){return t.includes(e)},e.includes=function(e){return t.has(e)},e.cacheResult=Oe,e.__iterateUncached=function(e,r){var n=this;return t.__iterate(function(t,r){return e(r,t,n)!==!1},r)},e.__iteratorUncached=function(e,r){if(e===Sr){var n=t.__iterator(e,r);return new S(function(){var t=n.next();if(!t.done){var e=t.value[0];t.value[0]=t.value[1],t.value[1]=e}return t})}return t.__iterator(e===wr?gr:wr,r)},e}function ae(t,e,r){var n=Ee(t);return n.size=t.size,n.has=function(e){return t.has(e)},n.get=function(n,i){var o=t.get(n,yr);return o===yr?i:e.call(r,o,n,t)},n.__iterateUncached=function(n,i){var o=this;return t.__iterate(function(t,i,u){return n(e.call(r,t,i,u),i,o)!==!1},i)},n.__iteratorUncached=function(n,i){var o=t.__iterator(Sr,i);return new S(function(){var i=o.next();if(i.done)return i;var u=i.value,s=u[0];return z(n,s,e.call(r,u[1],s,t),i)})},n}function he(t,e){var r=Ee(t);return r._iter=t,r.size=t.size,r.reverse=function(){return t},t.flip&&(r.flip=function(){var e=se(t);return e.reverse=function(){return t.flip()},e}),r.get=function(r,n){return t.get(e?r:-1-r,n)},r.has=function(r){return t.has(e?r:-1-r)},r.includes=function(e){return t.includes(e)},r.cacheResult=Oe,r.__iterate=function(e,r){var n=this;return t.__iterate(function(t,r){return e(t,r,n)},!r)},r.__iterator=function(e,r){return t.__iterator(e,!r)},r}function fe(t,e,r,n){var i=Ee(t);return n&&(i.has=function(n){var i=t.get(n,yr);return i!==yr&&!!e.call(r,i,n,t)},i.get=function(n,i){var o=t.get(n,yr);return o!==yr&&e.call(r,o,n,t)?o:i}),i.__iterateUncached=function(i,o){var u=this,s=0;return t.__iterate(function(t,o,a){return e.call(r,t,o,a)?(s++,i(t,n?o:s-1,u)):void 0},o),s},i.__iteratorUncached=function(i,o){var u=t.__iterator(Sr,o),s=0;return new S(function(){for(;;){var o=u.next();if(o.done)return o;var a=o.value,h=a[0],f=a[1];if(e.call(r,f,h,t))return z(i,n?h:s++,f,o)}})},i}function ce(t,e,r){var n=ct().asMutable();return t.__iterate(function(i,o){n.update(e.call(r,i,o,t),0,function(t){ -return t+1})}),n.asImmutable()}function _e(t,e,r){var n=u(t),i=(h(t)?Zt():ct()).asMutable();t.__iterate(function(o,u){i.update(e.call(r,o,u,t),function(t){return t=t||[],t.push(n?[u,o]:o),t})});var o=Me(t);return i.map(function(e){return be(t,o(e))})}function pe(t,e,r,n){var i=t.size;if(void 0!==e&&(e=0|e),void 0!==r&&(r=r===1/0?i:0|r),d(e,r,i))return t;var o=m(e,i),u=g(r,i);if(o!==o||u!==u)return pe(t.toSeq().cacheResult(),e,r,n);var s,a=u-o;a===a&&(s=0>a?0:a);var h=Ee(t);return h.size=0===s?s:t.size&&s||void 0,!n&&L(t)&&s>=0&&(h.get=function(e,r){return e=l(this,e),e>=0&&s>e?t.get(e+o,r):r}),h.__iterateUncached=function(e,r){var i=this;if(0===s)return 0;if(r)return this.cacheResult().__iterate(e,r);var u=0,a=!0,h=0;return t.__iterate(function(t,r){return a&&(a=u++s)return I();var t=i.next();return n||e===wr?t:e===gr?z(e,a-1,void 0,t):z(e,a-1,t.value[1],t)})},h}function ve(t,e,r){var n=Ee(t);return n.__iterateUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterate(n,i);var u=0;return t.__iterate(function(t,i,s){return e.call(r,t,i,s)&&++u&&n(t,i,o)}),u},n.__iteratorUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterator(n,i);var u=t.__iterator(Sr,i),s=!0;return new S(function(){if(!s)return I();var t=u.next();if(t.done)return t;var i=t.value,a=i[0],h=i[1];return e.call(r,h,a,o)?n===Sr?t:z(n,a,h,t):(s=!1,I())})},n}function le(t,e,r,n){var i=Ee(t);return i.__iterateUncached=function(i,o){var u=this;if(o)return this.cacheResult().__iterate(i,o);var s=!0,a=0;return t.__iterate(function(t,o,h){return s&&(s=e.call(r,t,o,h))?void 0:(a++,i(t,n?o:a-1,u))}),a},i.__iteratorUncached=function(i,o){var u=this;if(o)return this.cacheResult().__iterator(i,o);var s=t.__iterator(Sr,o),a=!0,h=0;return new S(function(){var t,o,f;do{if(t=s.next(),t.done)return n||i===wr?t:i===gr?z(i,h++,void 0,t):z(i,h++,t.value[1],t); -var c=t.value;o=c[0],f=c[1],a&&(a=e.call(r,f,o,u))}while(a);return i===Sr?t:z(i,o,f,t)})},i}function ye(t,e){var n=u(t),i=[t].concat(e).map(function(t){return o(t)?n&&(t=r(t)):t=n?B(t):W(Array.isArray(t)?t:[t]),t}).filter(function(t){return 0!==t.size});if(0===i.length)return t;if(1===i.length){var a=i[0];if(a===t||n&&u(a)||s(t)&&s(a))return a}var h=new j(i);return n?h=h.toKeyedSeq():s(t)||(h=h.toSetSeq()),h=h.flatten(!0),h.size=i.reduce(function(t,e){if(void 0!==t){var r=e.size;if(void 0!==r)return t+r}},0),h}function de(t,e,r){var n=Ee(t);return n.__iterateUncached=function(n,i){function u(t,h){var f=this;t.__iterate(function(t,i){return(!e||e>h)&&o(t)?u(t,h+1):n(t,r?i:s++,f)===!1&&(a=!0),!a},i)}var s=0,a=!1;return u(t,0),s},n.__iteratorUncached=function(n,i){var u=t.__iterator(n,i),s=[],a=0;return new S(function(){for(;u;){var t=u.next();if(t.done===!1){var h=t.value;if(n===Sr&&(h=h[1]),e&&!(e>s.length)||!o(h))return r?t:z(n,a++,h,t);s.push(u),u=h.__iterator(n,i)}else u=s.pop()}return I()})},n}function me(t,e,r){var n=Me(t);return t.toSeq().map(function(i,o){return n(e.call(r,i,o,t))}).flatten(!0)}function ge(t,e){var r=Ee(t);return r.size=t.size&&2*t.size-1,r.__iterateUncached=function(r,n){var i=this,o=0;return t.__iterate(function(t,n){return(!o||r(e,o++,i)!==!1)&&r(t,o++,i)!==!1},n),o},r.__iteratorUncached=function(r,n){var i,o=t.__iterator(wr,n),u=0;return new S(function(){return(!i||u%2)&&(i=o.next(),i.done)?i:u%2?z(r,u++,e):z(r,u++,i.value,i)})},r}function we(t,e,r){e||(e=xe);var n=u(t),i=0,o=t.toSeq().map(function(e,n){return[n,e,i++,r?r(e,n,t):e]}).toArray();return o.sort(function(t,r){return e(t[3],r[3])||t[2]-r[2]}).forEach(n?function(t,e){o[e].length=2}:function(t,e){o[e]=t[1]}),n?x(o):s(t)?k(o):A(o)}function Se(t,e,r){if(e||(e=xe),r){var n=t.toSeq().map(function(e,n){return[e,r(e,n,t)]}).reduce(function(t,r){return ze(e,t[1],r[1])?r:t});return n&&n[0]}return t.reduce(function(t,r){return ze(e,t,r)?r:t})}function ze(t,e,r){var n=t(r,e);return 0===n&&r!==e&&(void 0===r||null===r||r!==r)||n>0}function Ie(t,r,n){ -var i=Ee(t);return i.size=new j(n).map(function(t){return t.size}).min(),i.__iterate=function(t,e){for(var r,n=this.__iterator(wr,e),i=0;!(r=n.next()).done&&t(r.value,i++,this)!==!1;);return i},i.__iteratorUncached=function(t,i){var o=n.map(function(t){return t=e(t),D(i?t.reverse():t)}),u=0,s=!1;return new S(function(){var e;return s||(e=o.map(function(t){return t.next()}),s=e.some(function(t){return t.done})),s?I():z(t,u++,r.apply(null,e.map(function(t){return t.value})))})},i}function be(t,e){return L(t)?e:t.constructor(e)}function qe(t){if(t!==Object(t))throw new TypeError("Expected [K, V] tuple: "+t)}function De(t){return ft(t.size),v(t)}function Me(t){return u(t)?r:s(t)?n:i}function Ee(t){return Object.create((u(t)?x:s(t)?k:A).prototype)}function Oe(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):O.prototype.cacheResult.call(this)}function xe(t,e){return t>e?1:e>t?-1:0}function ke(t){var r=D(t);if(!r){if(!E(t))throw new TypeError("Expected iterable or array-like: "+t);r=D(e(t))}return r}function Ae(t,e){var r,n=function(o){if(o instanceof n)return o;if(!(this instanceof n))return new n(o);if(!r){r=!0;var u=Object.keys(t);Ue(i,u),i.size=u.length,i._name=e,i._keys=u,i._defaultValues=t}this._map=ct(o)},i=n.prototype=Object.create(Gr);return i.constructor=n,n}function je(t,e,r){var n=Object.create(Object.getPrototypeOf(t));return n._map=e,n.__ownerID=r,n}function Re(t){return t._name||t.constructor.name||"Record"}function Ue(t,e){try{e.forEach(Ke.bind(void 0,t))}catch(r){}}function Ke(t,e){Object.defineProperty(t,e,{get:function(){return this.get(e)},set:function(t){Z(this.__ownerID,"Cannot set on an immutable record."),this.set(e,t)}})}function Le(t){return null===t||void 0===t?Ce():Te(t)&&!h(t)?t:Ce().withMutations(function(e){var r=i(t);ft(r.size),r.forEach(function(t){return e.add(t)})})}function Te(t){return!(!t||!t[Zr])}function Be(t,e){return t.__ownerID?(t.size=e.size,t._map=e,t):e===t._map?t:0===e.size?t.__empty():t.__make(e)}function We(t,e){var r=Object.create($r); -return r.size=t?t.size:0,r._map=t,r.__ownerID=e,r}function Ce(){return tn||(tn=We(zt()))}function Je(t){return null===t||void 0===t?He():Ne(t)?t:He().withMutations(function(e){var r=i(t);ft(r.size),r.forEach(function(t){return e.add(t)})})}function Ne(t){return Te(t)&&h(t)}function Pe(t,e){var r=Object.create(en);return r.size=t?t.size:0,r._map=t,r.__ownerID=e,r}function He(){return rn||(rn=Pe(ee()))}function Ve(t){return null===t||void 0===t?Xe():Ye(t)?t:Xe().unshiftAll(t)}function Ye(t){return!(!t||!t[nn])}function Qe(t,e,r,n){var i=Object.create(on);return i.size=t,i._head=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function Xe(){return un||(un=Qe(0))}function Fe(t,e){var r=function(r){t.prototype[r]=e[r]};return Object.keys(e).forEach(r),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(e).forEach(r),t}function Ge(t,e){return e}function Ze(t,e){return[e,t]}function $e(t){return function(){return!t.apply(this,arguments)}}function tr(t){return function(){return-t.apply(this,arguments)}}function er(t){return"string"==typeof t?JSON.stringify(t):t+""}function rr(){return p(arguments)}function nr(t,e){return e>t?1:t>e?-1:0}function ir(t){if(t.size===1/0)return 0;var e=h(t),r=u(t),n=e?1:0,i=t.__iterate(r?e?function(t,e){n=31*n+ur(ot(t),ot(e))|0}:function(t,e){n=n+ur(ot(t),ot(e))|0}:e?function(t){n=31*n+ot(t)|0}:function(t){n=n+ot(t)|0});return or(i,n)}function or(t,e){return e=xr(e,3432918353),e=xr(e<<15|e>>>-15,461845907),e=xr(e<<13|e>>>-13,5),e=(e+3864292196|0)^t,e=xr(e^e>>>16,2246822507),e=xr(e^e>>>13,3266489909),e=it(e^e>>>16)}function ur(t,e){return t^e+2654435769+(t<<6)+(t>>2)|0}var sr=Array.prototype.slice;t(r,e),t(n,e),t(i,e),e.isIterable=o,e.isKeyed=u,e.isIndexed=s,e.isAssociative=a,e.isOrdered=h,e.Keyed=r,e.Indexed=n,e.Set=i;var ar="@@__IMMUTABLE_ITERABLE__@@",hr="@@__IMMUTABLE_KEYED__@@",fr="@@__IMMUTABLE_INDEXED__@@",cr="@@__IMMUTABLE_ORDERED__@@",_r="delete",pr=5,vr=1<=i;i++)if(t(r[e?n-i:i],i,this)===!1)return i+1;return i},j.prototype.__iterator=function(t,e){var r=this._array,n=r.length-1,i=0;return new S(function(){return i>n?I():z(t,i,r[e?n-i++:i++])})},t(R,x),R.prototype.get=function(t,e){return void 0===e||this.has(t)?this._object[t]:e},R.prototype.has=function(t){return this._object.hasOwnProperty(t)},R.prototype.__iterate=function(t,e){for(var r=this._object,n=this._keys,i=n.length-1,o=0;i>=o;o++){var u=n[e?i-o:o];if(t(r[u],u,this)===!1)return o+1}return o},R.prototype.__iterator=function(t,e){var r=this._object,n=this._keys,i=n.length-1,o=0;return new S(function(){var u=n[e?i-o:o];return o++>i?I():z(t,u,r[u])})},R.prototype[cr]=!0,t(U,k),U.prototype.__iterateUncached=function(t,e){if(e)return this.cacheResult().__iterate(t,e); -var r=this._iterable,n=D(r),i=0;if(q(n))for(var o;!(o=n.next()).done&&t(o.value,i++,this)!==!1;);return i},U.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterable,n=D(r);if(!q(n))return new S(I);var i=0;return new S(function(){var e=n.next();return e.done?e:z(t,i++,e.value)})},t(K,k),K.prototype.__iterateUncached=function(t,e){if(e)return this.cacheResult().__iterate(t,e);for(var r=this._iterator,n=this._iteratorCache,i=0;n.length>i;)if(t(n[i],i++,this)===!1)return i;for(var o;!(o=r.next()).done;){var u=o.value;if(n[i]=u,t(u,i++,this)===!1)break}return i},K.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterator,n=this._iteratorCache,i=0;return new S(function(){if(i>=n.length){var e=r.next();if(e.done)return e;n[i]=e.value}return z(t,i,n[i++])})};var Dr;t(G,k),G.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},G.prototype.get=function(t,e){return this.has(t)?this._value:e},G.prototype.includes=function(t){return X(this._value,t)},G.prototype.slice=function(t,e){var r=this.size;return d(t,e,r)?this:new G(this._value,g(e,r)-m(t,r))},G.prototype.reverse=function(){return this},G.prototype.indexOf=function(t){return X(this._value,t)?0:-1},G.prototype.lastIndexOf=function(t){return X(this._value,t)?this.size:-1},G.prototype.__iterate=function(t,e){for(var r=0;this.size>r;r++)if(t(this._value,r,this)===!1)return r+1;return r},G.prototype.__iterator=function(t,e){var r=this,n=0;return new S(function(){return r.size>n?z(t,n++,r._value):I()})},G.prototype.equals=function(t){return t instanceof G?X(this._value,t._value):F(t)};var Mr;t($,k),$.prototype.toString=function(){return 0===this.size?"Range []":"Range [ "+this._start+"..."+this._end+(1!==this._step?" by "+this._step:"")+" ]"},$.prototype.get=function(t,e){return this.has(t)?this._start+l(this,t)*this._step:e},$.prototype.includes=function(t){var e=(t-this._start)/this._step;return e>=0&&this.size>e&&e===Math.floor(e); -},$.prototype.slice=function(t,e){return d(t,e,this.size)?this:(t=m(t,this.size),e=g(e,this.size),t>=e?new $(0,0):new $(this.get(t,this._end),this.get(e,this._end),this._step))},$.prototype.indexOf=function(t){var e=t-this._start;if(e%this._step===0){var r=e/this._step;if(r>=0&&this.size>r)return r}return-1},$.prototype.lastIndexOf=function(t){return this.indexOf(t)},$.prototype.__iterate=function(t,e){for(var r=this.size-1,n=this._step,i=e?this._start+r*n:this._start,o=0;r>=o;o++){if(t(i,o,this)===!1)return o+1;i+=e?-n:n}return o},$.prototype.__iterator=function(t,e){var r=this.size-1,n=this._step,i=e?this._start+r*n:this._start,o=0;return new S(function(){var u=i;return i+=e?-n:n,o>r?I():z(t,o++,u)})},$.prototype.equals=function(t){return t instanceof $?this._start===t._start&&this._end===t._end&&this._step===t._step:F(this,t)};var Er;t(tt,e),t(et,tt),t(rt,tt),t(nt,tt),tt.Keyed=et,tt.Indexed=rt,tt.Set=nt;var Or,xr="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(t,e){t=0|t,e=0|e;var r=65535&t,n=65535&e;return r*n+((t>>>16)*n+r*(e>>>16)<<16>>>0)|0},kr=Object.isExtensible,Ar=function(){try{return Object.defineProperty({},"@",{}),!0}catch(t){return!1}}(),jr="function"==typeof WeakMap;jr&&(Or=new WeakMap);var Rr=0,Ur="__immutablehash__";"function"==typeof Symbol&&(Ur=Symbol(Ur));var Kr=16,Lr=255,Tr=0,Br={};t(ct,et),ct.of=function(){var t=sr.call(arguments,0);return zt().withMutations(function(e){for(var r=0;t.length>r;r+=2){if(r+1>=t.length)throw Error("Missing value for key: "+t[r]);e.set(t[r],t[r+1])}})},ct.prototype.toString=function(){return this.__toString("Map {","}")},ct.prototype.get=function(t,e){return this._root?this._root.get(0,void 0,t,e):e},ct.prototype.set=function(t,e){return It(this,t,e)},ct.prototype.setIn=function(t,e){return this.updateIn(t,yr,function(){return e})},ct.prototype.remove=function(t){return It(this,t,yr)},ct.prototype.deleteIn=function(t){return this.updateIn(t,function(){return yr})},ct.prototype.update=function(t,e,r){return 1===arguments.length?t(this):this.updateIn([t],e,r); -},ct.prototype.updateIn=function(t,e,r){r||(r=e,e=void 0);var n=Rt(this,ke(t),e,r);return n===yr?void 0:n},ct.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):zt()},ct.prototype.merge=function(){return xt(this,void 0,arguments)},ct.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return xt(this,t,e)},ct.prototype.mergeIn=function(t){var e=sr.call(arguments,1);return this.updateIn(t,zt(),function(t){return"function"==typeof t.merge?t.merge.apply(t,e):e[e.length-1]})},ct.prototype.mergeDeep=function(){return xt(this,kt,arguments)},ct.prototype.mergeDeepWith=function(t){var e=sr.call(arguments,1);return xt(this,At(t),e)},ct.prototype.mergeDeepIn=function(t){var e=sr.call(arguments,1);return this.updateIn(t,zt(),function(t){return"function"==typeof t.mergeDeep?t.mergeDeep.apply(t,e):e[e.length-1]})},ct.prototype.sort=function(t){return Zt(we(this,t))},ct.prototype.sortBy=function(t,e){return Zt(we(this,e,t))},ct.prototype.withMutations=function(t){var e=this.asMutable();return t(e),e.wasAltered()?e.__ensureOwner(this.__ownerID):this},ct.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new _)},ct.prototype.asImmutable=function(){return this.__ensureOwner()},ct.prototype.wasAltered=function(){return this.__altered},ct.prototype.__iterator=function(t,e){return new mt(this,t,e)},ct.prototype.__iterate=function(t,e){var r=this,n=0;return this._root&&this._root.iterate(function(e){return n++,t(e[1],e[0],r)},e),n},ct.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?St(this.size,this._root,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},ct.isMap=_t;var Wr="@@__IMMUTABLE_MAP__@@",Cr=ct.prototype;Cr[Wr]=!0,Cr[_r]=Cr.remove,Cr.removeIn=Cr.deleteIn,pt.prototype.get=function(t,e,r,n){for(var i=this.entries,o=0,u=i.length;u>o;o++)if(X(r,i[o][0]))return i[o][1];return n},pt.prototype.update=function(t,e,r,n,i,o,u){for(var s=i===yr,a=this.entries,h=0,f=a.length;f>h&&!X(n,a[h][0]);h++); -var _=f>h;if(_?a[h][1]===i:s)return this;if(c(u),(s||!_)&&c(o),!s||1!==a.length){if(!_&&!s&&a.length>=Nr)return Mt(t,a,n,i);var v=t&&t===this.ownerID,l=v?a:p(a);return _?s?h===f-1?l.pop():l[h]=l.pop():l[h]=[n,i]:l.push([n,i]),v?(this.entries=l,this):new pt(t,l)}},vt.prototype.get=function(t,e,r,n){void 0===e&&(e=ot(r));var i=1<<((0===t?e:e>>>t)&lr),o=this.bitmap;return 0===(o&i)?n:this.nodes[Ut(o&i-1)].get(t+pr,e,r,n)},vt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=(0===e?r:r>>>e)&lr,a=1<=Pr)return Ot(t,_,h,s,v);if(f&&!v&&2===_.length&&qt(_[1^c]))return _[1^c];if(f&&v&&1===_.length&&qt(v))return v;var l=t&&t===this.ownerID,y=f?v?h:h^a:h|a,d=f?v?Kt(_,c,v,l):Tt(_,c,l):Lt(_,c,v,l);return l?(this.bitmap=y,this.nodes=d,this):new vt(t,y,d)},lt.prototype.get=function(t,e,r,n){void 0===e&&(e=ot(r));var i=(0===t?e:e>>>t)&lr,o=this.nodes[i];return o?o.get(t+pr,e,r,n):n},lt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=(0===e?r:r>>>e)&lr,a=i===yr,h=this.nodes,f=h[s];if(a&&!f)return this;var c=bt(f,t,e+pr,r,n,i,o,u);if(c===f)return this;var _=this.count;if(f){if(!c&&(_--,Hr>_))return Et(t,h,_,s)}else _++;var p=t&&t===this.ownerID,v=Kt(h,s,c,p);return p?(this.count=_,this.nodes=v,this):new lt(t,_,v)},yt.prototype.get=function(t,e,r,n){for(var i=this.entries,o=0,u=i.length;u>o;o++)if(X(r,i[o][0]))return i[o][1];return n},yt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=i===yr;if(r!==this.keyHash)return s?this:(c(u),c(o),Dt(this,t,e,r,[n,i]));for(var a=this.entries,h=0,f=a.length;f>h&&!X(n,a[h][0]);h++);var _=f>h;if(_?a[h][1]===i:s)return this;if(c(u),(s||!_)&&c(o),s&&2===f)return new dt(t,this.keyHash,a[1^h]);var v=t&&t===this.ownerID,l=v?a:p(a);return _?s?h===f-1?l.pop():l[h]=l.pop():l[h]=[n,i]:l.push([n,i]),v?(this.entries=l,this):new yt(t,this.keyHash,l)},dt.prototype.get=function(t,e,r,n){return X(r,this.entry[0])?this.entry[1]:n; -},dt.prototype.update=function(t,e,r,n,i,o,u){var s=i===yr,a=X(n,this.entry[0]);return(a?i===this.entry[1]:s)?this:(c(u),s?void c(o):a?t&&t===this.ownerID?(this.entry[1]=i,this):new dt(t,this.keyHash,[n,i]):(c(o),Dt(this,t,e,ot(n),[n,i])))},pt.prototype.iterate=yt.prototype.iterate=function(t,e){for(var r=this.entries,n=0,i=r.length-1;i>=n;n++)if(t(r[e?i-n:n])===!1)return!1},vt.prototype.iterate=lt.prototype.iterate=function(t,e){for(var r=this.nodes,n=0,i=r.length-1;i>=n;n++){var o=r[e?i-n:n];if(o&&o.iterate(t,e)===!1)return!1}},dt.prototype.iterate=function(t,e){return t(this.entry)},t(mt,S),mt.prototype.next=function(){for(var t=this._type,e=this._stack;e;){var r,n=e.node,i=e.index++;if(n.entry){if(0===i)return gt(t,n.entry)}else if(n.entries){if(r=n.entries.length-1,r>=i)return gt(t,n.entries[this._reverse?r-i:i])}else if(r=n.nodes.length-1,r>=i){var o=n.nodes[this._reverse?r-i:i];if(o){if(o.entry)return gt(t,o.entry);e=this._stack=wt(o,e)}continue}e=this._stack=this._stack.__prev}return I()};var Jr,Nr=vr/4,Pr=vr/2,Hr=vr/4;t(Bt,rt),Bt.of=function(){return this(arguments)},Bt.prototype.toString=function(){return this.__toString("List [","]")},Bt.prototype.get=function(t,e){if(t=l(this,t),t>=0&&this.size>t){t+=this._origin;var r=Qt(this,t);return r&&r.array[t&lr]}return e},Bt.prototype.set=function(t,e){return Ht(this,t,e)},Bt.prototype.remove=function(t){return this.has(t)?0===t?this.shift():t===this.size-1?this.pop():this.splice(t,1):this},Bt.prototype.insert=function(t,e){return this.splice(t,0,e)},Bt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=pr,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):Pt()},Bt.prototype.push=function(){var t=arguments,e=this.size;return this.withMutations(function(r){Xt(r,0,e+t.length);for(var n=0;t.length>n;n++)r.set(e+n,t[n])})},Bt.prototype.pop=function(){return Xt(this,0,-1)},Bt.prototype.unshift=function(){var t=arguments;return this.withMutations(function(e){Xt(e,-t.length);for(var r=0;t.length>r;r++)e.set(r,t[r]); -})},Bt.prototype.shift=function(){return Xt(this,1)},Bt.prototype.merge=function(){return Ft(this,void 0,arguments)},Bt.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return Ft(this,t,e)},Bt.prototype.mergeDeep=function(){return Ft(this,kt,arguments)},Bt.prototype.mergeDeepWith=function(t){var e=sr.call(arguments,1);return Ft(this,At(t),e)},Bt.prototype.setSize=function(t){return Xt(this,0,t)},Bt.prototype.slice=function(t,e){var r=this.size;return d(t,e,r)?this:Xt(this,m(t,r),g(e,r))},Bt.prototype.__iterator=function(t,e){var r=0,n=Jt(this,e);return new S(function(){var e=n();return e===Xr?I():z(t,r++,e)})},Bt.prototype.__iterate=function(t,e){for(var r,n=0,i=Jt(this,e);(r=i())!==Xr&&t(r,n++,this)!==!1;);return n},Bt.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?Nt(this._origin,this._capacity,this._level,this._root,this._tail,t,this.__hash):(this.__ownerID=t,this)},Bt.isList=Wt;var Vr="@@__IMMUTABLE_LIST__@@",Yr=Bt.prototype;Yr[Vr]=!0,Yr[_r]=Yr.remove,Yr.setIn=Cr.setIn,Yr.deleteIn=Yr.removeIn=Cr.removeIn,Yr.update=Cr.update,Yr.updateIn=Cr.updateIn,Yr.mergeIn=Cr.mergeIn,Yr.mergeDeepIn=Cr.mergeDeepIn,Yr.withMutations=Cr.withMutations,Yr.asMutable=Cr.asMutable,Yr.asImmutable=Cr.asImmutable,Yr.wasAltered=Cr.wasAltered,Ct.prototype.removeBefore=function(t,e,r){if(r===e?1<>>e&lr;if(n>=this.array.length)return new Ct([],t);var i,o=0===n;if(e>0){var u=this.array[n];if(i=u&&u.removeBefore(t,e-pr,r),i===u&&o)return this}if(o&&!i)return this;var s=Yt(this,t);if(!o)for(var a=0;n>a;a++)s.array[a]=void 0;return i&&(s.array[n]=i),s},Ct.prototype.removeAfter=function(t,e,r){if(r===(e?1<>>e&lr;if(n>=this.array.length)return this;var i;if(e>0){var o=this.array[n];if(i=o&&o.removeAfter(t,e-pr,r),i===o&&n===this.array.length-1)return this}var u=Yt(this,t);return u.array.splice(n+1),i&&(u.array[n]=i),u};var Qr,Xr={};t(Zt,ct),Zt.of=function(){return this(arguments)},Zt.prototype.toString=function(){return this.__toString("OrderedMap {","}"); -},Zt.prototype.get=function(t,e){var r=this._map.get(t);return void 0!==r?this._list.get(r)[1]:e},Zt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._map.clear(),this._list.clear(),this):ee()},Zt.prototype.set=function(t,e){return re(this,t,e)},Zt.prototype.remove=function(t){return re(this,t,yr)},Zt.prototype.wasAltered=function(){return this._map.wasAltered()||this._list.wasAltered()},Zt.prototype.__iterate=function(t,e){var r=this;return this._list.__iterate(function(e){return e&&t(e[1],e[0],r)},e)},Zt.prototype.__iterator=function(t,e){return this._list.fromEntrySeq().__iterator(t,e)},Zt.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t),r=this._list.__ensureOwner(t);return t?te(e,r,t,this.__hash):(this.__ownerID=t,this._map=e,this._list=r,this)},Zt.isOrderedMap=$t,Zt.prototype[cr]=!0,Zt.prototype[_r]=Zt.prototype.remove;var Fr;t(ne,x),ne.prototype.get=function(t,e){return this._iter.get(t,e)},ne.prototype.has=function(t){return this._iter.has(t)},ne.prototype.valueSeq=function(){return this._iter.valueSeq()},ne.prototype.reverse=function(){var t=this,e=he(this,!0);return this._useKeys||(e.valueSeq=function(){return t._iter.toSeq().reverse()}),e},ne.prototype.map=function(t,e){var r=this,n=ae(this,t,e);return this._useKeys||(n.valueSeq=function(){return r._iter.toSeq().map(t,e)}),n},ne.prototype.__iterate=function(t,e){var r,n=this;return this._iter.__iterate(this._useKeys?function(e,r){return t(e,r,n)}:(r=e?De(this):0,function(i){return t(i,e?--r:r++,n)}),e)},ne.prototype.__iterator=function(t,e){if(this._useKeys)return this._iter.__iterator(t,e);var r=this._iter.__iterator(wr,e),n=e?De(this):0;return new S(function(){var i=r.next();return i.done?i:z(t,e?--n:n++,i.value,i)})},ne.prototype[cr]=!0,t(ie,k),ie.prototype.includes=function(t){return this._iter.includes(t)},ie.prototype.__iterate=function(t,e){var r=this,n=0;return this._iter.__iterate(function(e){return t(e,n++,r)},e)},ie.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e),n=0; -return new S(function(){var e=r.next();return e.done?e:z(t,n++,e.value,e)})},t(oe,A),oe.prototype.has=function(t){return this._iter.includes(t)},oe.prototype.__iterate=function(t,e){var r=this;return this._iter.__iterate(function(e){return t(e,e,r)},e)},oe.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e);return new S(function(){var e=r.next();return e.done?e:z(t,e.value,e.value,e)})},t(ue,x),ue.prototype.entrySeq=function(){return this._iter.toSeq()},ue.prototype.__iterate=function(t,e){var r=this;return this._iter.__iterate(function(e){if(e){qe(e);var n=o(e);return t(n?e.get(1):e[1],n?e.get(0):e[0],r)}},e)},ue.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e);return new S(function(){for(;;){var e=r.next();if(e.done)return e;var n=e.value;if(n){qe(n);var i=o(n);return z(t,i?n.get(0):n[0],i?n.get(1):n[1],e)}}})},ie.prototype.cacheResult=ne.prototype.cacheResult=oe.prototype.cacheResult=ue.prototype.cacheResult=Oe,t(Ae,et),Ae.prototype.toString=function(){return this.__toString(Re(this)+" {","}")},Ae.prototype.has=function(t){return this._defaultValues.hasOwnProperty(t)},Ae.prototype.get=function(t,e){if(!this.has(t))return e;var r=this._defaultValues[t];return this._map?this._map.get(t,r):r},Ae.prototype.clear=function(){if(this.__ownerID)return this._map&&this._map.clear(),this;var t=this.constructor;return t._empty||(t._empty=je(this,zt()))},Ae.prototype.set=function(t,e){if(!this.has(t))throw Error('Cannot set unknown key "'+t+'" on '+Re(this));if(this._map&&!this._map.has(t)){var r=this._defaultValues[t];if(e===r)return this}var n=this._map&&this._map.set(t,e);return this.__ownerID||n===this._map?this:je(this,n)},Ae.prototype.remove=function(t){if(!this.has(t))return this;var e=this._map&&this._map.remove(t);return this.__ownerID||e===this._map?this:je(this,e)},Ae.prototype.wasAltered=function(){return this._map.wasAltered()},Ae.prototype.__iterator=function(t,e){var n=this;return r(this._defaultValues).map(function(t,e){return n.get(e)}).__iterator(t,e)},Ae.prototype.__iterate=function(t,e){ -var n=this;return r(this._defaultValues).map(function(t,e){return n.get(e)}).__iterate(t,e)},Ae.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map&&this._map.__ensureOwner(t);return t?je(this,e,t):(this.__ownerID=t,this._map=e,this)};var Gr=Ae.prototype;Gr[_r]=Gr.remove,Gr.deleteIn=Gr.removeIn=Cr.removeIn,Gr.merge=Cr.merge,Gr.mergeWith=Cr.mergeWith,Gr.mergeIn=Cr.mergeIn,Gr.mergeDeep=Cr.mergeDeep,Gr.mergeDeepWith=Cr.mergeDeepWith,Gr.mergeDeepIn=Cr.mergeDeepIn,Gr.setIn=Cr.setIn,Gr.update=Cr.update,Gr.updateIn=Cr.updateIn,Gr.withMutations=Cr.withMutations,Gr.asMutable=Cr.asMutable,Gr.asImmutable=Cr.asImmutable,t(Le,nt),Le.of=function(){return this(arguments)},Le.fromKeys=function(t){return this(r(t).keySeq())},Le.prototype.toString=function(){return this.__toString("Set {","}")},Le.prototype.has=function(t){return this._map.has(t)},Le.prototype.add=function(t){return Be(this,this._map.set(t,!0))},Le.prototype.remove=function(t){return Be(this,this._map.remove(t))},Le.prototype.clear=function(){return Be(this,this._map.clear())},Le.prototype.union=function(){var t=sr.call(arguments,0);return t=t.filter(function(t){return 0!==t.size}),0===t.length?this:0!==this.size||this.__ownerID||1!==t.length?this.withMutations(function(e){for(var r=0;t.length>r;r++)i(t[r]).forEach(function(t){return e.add(t)})}):this.constructor(t[0])},Le.prototype.intersect=function(){var t=sr.call(arguments,0);if(0===t.length)return this;t=t.map(function(t){return i(t)});var e=this;return this.withMutations(function(r){e.forEach(function(e){t.every(function(t){return t.includes(e)})||r.remove(e)})})},Le.prototype.subtract=function(){var t=sr.call(arguments,0);if(0===t.length)return this;t=t.map(function(t){return i(t)});var e=this;return this.withMutations(function(r){e.forEach(function(e){t.some(function(t){return t.includes(e)})&&r.remove(e)})})},Le.prototype.merge=function(){return this.union.apply(this,arguments)},Le.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return this.union.apply(this,e)}, -Le.prototype.sort=function(t){return Je(we(this,t))},Le.prototype.sortBy=function(t,e){return Je(we(this,e,t))},Le.prototype.wasAltered=function(){return this._map.wasAltered()},Le.prototype.__iterate=function(t,e){var r=this;return this._map.__iterate(function(e,n){return t(n,n,r)},e)},Le.prototype.__iterator=function(t,e){return this._map.map(function(t,e){return e}).__iterator(t,e)},Le.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t);return t?this.__make(e,t):(this.__ownerID=t,this._map=e,this)},Le.isSet=Te;var Zr="@@__IMMUTABLE_SET__@@",$r=Le.prototype;$r[Zr]=!0,$r[_r]=$r.remove,$r.mergeDeep=$r.merge,$r.mergeDeepWith=$r.mergeWith,$r.withMutations=Cr.withMutations,$r.asMutable=Cr.asMutable,$r.asImmutable=Cr.asImmutable,$r.__empty=Ce,$r.__make=We;var tn;t(Je,Le),Je.of=function(){return this(arguments)},Je.fromKeys=function(t){return this(r(t).keySeq())},Je.prototype.toString=function(){return this.__toString("OrderedSet {","}")},Je.isOrderedSet=Ne;var en=Je.prototype;en[cr]=!0,en.__empty=He,en.__make=Pe;var rn;t(Ve,rt),Ve.of=function(){return this(arguments)},Ve.prototype.toString=function(){return this.__toString("Stack [","]")},Ve.prototype.get=function(t,e){var r=this._head;for(t=l(this,t);r&&t--;)r=r.next;return r?r.value:e},Ve.prototype.peek=function(){return this._head&&this._head.value},Ve.prototype.push=function(){if(0===arguments.length)return this;for(var t=this.size+arguments.length,e=this._head,r=arguments.length-1;r>=0;r--)e={value:arguments[r],next:e};return this.__ownerID?(this.size=t,this._head=e,this.__hash=void 0,this.__altered=!0,this):Qe(t,e)},Ve.prototype.pushAll=function(t){if(t=n(t),0===t.size)return this;ft(t.size);var e=this.size,r=this._head;return t.reverse().forEach(function(t){e++,r={value:t,next:r}}),this.__ownerID?(this.size=e,this._head=r,this.__hash=void 0,this.__altered=!0,this):Qe(e,r)},Ve.prototype.pop=function(){return this.slice(1)},Ve.prototype.unshift=function(){return this.push.apply(this,arguments)},Ve.prototype.unshiftAll=function(t){ -return this.pushAll(t)},Ve.prototype.shift=function(){return this.pop.apply(this,arguments)},Ve.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Xe()},Ve.prototype.slice=function(t,e){if(d(t,e,this.size))return this;var r=m(t,this.size),n=g(e,this.size);if(n!==this.size)return rt.prototype.slice.call(this,t,e);for(var i=this.size-r,o=this._head;r--;)o=o.next;return this.__ownerID?(this.size=i,this._head=o,this.__hash=void 0,this.__altered=!0,this):Qe(i,o)},Ve.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?Qe(this.size,this._head,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},Ve.prototype.__iterate=function(t,e){if(e)return this.reverse().__iterate(t);for(var r=0,n=this._head;n&&t(n.value,r++,this)!==!1;)n=n.next;return r},Ve.prototype.__iterator=function(t,e){if(e)return this.reverse().__iterator(t);var r=0,n=this._head;return new S(function(){if(n){var e=n.value;return n=n.next,z(t,r++,e)}return I()})},Ve.isStack=Ye;var nn="@@__IMMUTABLE_STACK__@@",on=Ve.prototype;on[nn]=!0,on.withMutations=Cr.withMutations,on.asMutable=Cr.asMutable,on.asImmutable=Cr.asImmutable,on.wasAltered=Cr.wasAltered;var un;e.Iterator=S,Fe(e,{toArray:function(){ft(this.size);var t=Array(this.size||0);return this.valueSeq().__iterate(function(e,r){t[r]=e}),t},toIndexedSeq:function(){return new ie(this)},toJS:function(){return this.toSeq().map(function(t){return t&&"function"==typeof t.toJS?t.toJS():t}).__toJS()},toJSON:function(){return this.toSeq().map(function(t){return t&&"function"==typeof t.toJSON?t.toJSON():t}).__toJS()},toKeyedSeq:function(){return new ne(this,!0)},toMap:function(){return ct(this.toKeyedSeq())},toObject:function(){ft(this.size);var t={};return this.__iterate(function(e,r){t[r]=e}),t},toOrderedMap:function(){return Zt(this.toKeyedSeq())},toOrderedSet:function(){return Je(u(this)?this.valueSeq():this)},toSet:function(){return Le(u(this)?this.valueSeq():this)},toSetSeq:function(){return new oe(this); -},toSeq:function(){return s(this)?this.toIndexedSeq():u(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Ve(u(this)?this.valueSeq():this)},toList:function(){return Bt(u(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(t,e){return 0===this.size?t+e:t+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+e},concat:function(){var t=sr.call(arguments,0);return be(this,ye(this,t))},includes:function(t){return this.some(function(e){return X(e,t)})},entries:function(){return this.__iterator(Sr)},every:function(t,e){ft(this.size);var r=!0;return this.__iterate(function(n,i,o){return t.call(e,n,i,o)?void 0:(r=!1,!1)}),r},filter:function(t,e){return be(this,fe(this,t,e,!0))},find:function(t,e,r){var n=this.findEntry(t,e);return n?n[1]:r},forEach:function(t,e){return ft(this.size),this.__iterate(e?t.bind(e):t)},join:function(t){ft(this.size),t=void 0!==t?""+t:",";var e="",r=!0;return this.__iterate(function(n){r?r=!1:e+=t,e+=null!==n&&void 0!==n?""+n:""}),e},keys:function(){return this.__iterator(gr)},map:function(t,e){return be(this,ae(this,t,e))},reduce:function(t,e,r){ft(this.size);var n,i;return arguments.length<2?i=!0:n=e,this.__iterate(function(e,o,u){i?(i=!1,n=e):n=t.call(r,n,e,o,u)}),n},reduceRight:function(t,e,r){var n=this.toKeyedSeq().reverse();return n.reduce.apply(n,arguments)},reverse:function(){return be(this,he(this,!0))},slice:function(t,e){return be(this,pe(this,t,e,!0))},some:function(t,e){return!this.every($e(t),e)},sort:function(t){return be(this,we(this,t))},values:function(){return this.__iterator(wr)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some(function(){return!0})},count:function(t,e){return v(t?this.toSeq().filter(t,e):this)},countBy:function(t,e){return ce(this,t,e)},equals:function(t){return F(this,t)},entrySeq:function(){var t=this;if(t._cache)return new j(t._cache);var e=t.toSeq().map(Ze).toIndexedSeq();return e.fromEntrySeq=function(){return t.toSeq()},e},filterNot:function(t,e){ -return this.filter($e(t),e)},findEntry:function(t,e,r){var n=r;return this.__iterate(function(r,i,o){return t.call(e,r,i,o)?(n=[i,r],!1):void 0}),n},findKey:function(t,e){var r=this.findEntry(t,e);return r&&r[0]},findLast:function(t,e,r){return this.toKeyedSeq().reverse().find(t,e,r)},findLastEntry:function(t,e,r){return this.toKeyedSeq().reverse().findEntry(t,e,r)},findLastKey:function(t,e){return this.toKeyedSeq().reverse().findKey(t,e)},first:function(){return this.find(y)},flatMap:function(t,e){return be(this,me(this,t,e))},flatten:function(t){return be(this,de(this,t,!0))},fromEntrySeq:function(){return new ue(this)},get:function(t,e){return this.find(function(e,r){return X(r,t)},void 0,e)},getIn:function(t,e){for(var r,n=this,i=ke(t);!(r=i.next()).done;){var o=r.value;if(n=n&&n.get?n.get(o,yr):yr,n===yr)return e}return n},groupBy:function(t,e){return _e(this,t,e)},has:function(t){return this.get(t,yr)!==yr},hasIn:function(t){return this.getIn(t,yr)!==yr},isSubset:function(t){return t="function"==typeof t.includes?t:e(t),this.every(function(e){return t.includes(e)})},isSuperset:function(t){return t="function"==typeof t.isSubset?t:e(t),t.isSubset(this)},keyOf:function(t){return this.findKey(function(e){return X(e,t)})},keySeq:function(){return this.toSeq().map(Ge).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(t){return this.toKeyedSeq().reverse().keyOf(t)},max:function(t){return Se(this,t)},maxBy:function(t,e){return Se(this,e,t)},min:function(t){return Se(this,t?tr(t):nr)},minBy:function(t,e){return Se(this,e?tr(e):nr,t)},rest:function(){return this.slice(1)},skip:function(t){return this.slice(Math.max(0,t))},skipLast:function(t){return be(this,this.toSeq().reverse().skip(t).reverse())},skipWhile:function(t,e){return be(this,le(this,t,e,!0))},skipUntil:function(t,e){return this.skipWhile($e(t),e)},sortBy:function(t,e){return be(this,we(this,e,t))},take:function(t){return this.slice(0,Math.max(0,t))},takeLast:function(t){return be(this,this.toSeq().reverse().take(t).reverse()); -},takeWhile:function(t,e){return be(this,ve(this,t,e))},takeUntil:function(t,e){return this.takeWhile($e(t),e)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=ir(this))}});var sn=e.prototype;sn[ar]=!0,sn[br]=sn.values,sn.__toJS=sn.toArray,sn.__toStringMapper=er,sn.inspect=sn.toSource=function(){return""+this},sn.chain=sn.flatMap,sn.contains=sn.includes,Fe(r,{flip:function(){return be(this,se(this))},mapEntries:function(t,e){var r=this,n=0;return be(this,this.toSeq().map(function(i,o){return t.call(e,[o,i],n++,r)}).fromEntrySeq())},mapKeys:function(t,e){var r=this;return be(this,this.toSeq().flip().map(function(n,i){return t.call(e,n,i,r)}).flip())}});var an=r.prototype;an[hr]=!0,an[br]=sn.entries,an.__toJS=sn.toObject,an.__toStringMapper=function(t,e){return JSON.stringify(e)+": "+er(t)},Fe(n,{toKeyedSeq:function(){return new ne(this,!1)},filter:function(t,e){return be(this,fe(this,t,e,!1))},findIndex:function(t,e){var r=this.findEntry(t,e);return r?r[0]:-1},indexOf:function(t){var e=this.keyOf(t);return void 0===e?-1:e},lastIndexOf:function(t){var e=this.lastKeyOf(t);return void 0===e?-1:e},reverse:function(){return be(this,he(this,!1))},slice:function(t,e){return be(this,pe(this,t,e,!1))},splice:function(t,e){var r=arguments.length;if(e=Math.max(0|e,0),0===r||2===r&&!e)return this;t=m(t,0>t?this.count():this.size);var n=this.slice(0,t);return be(this,1===r?n:n.concat(p(arguments,2),this.slice(t+e)))},findLastIndex:function(t,e){var r=this.findLastEntry(t,e);return r?r[0]:-1},first:function(){return this.get(0)},flatten:function(t){return be(this,de(this,t,!1))},get:function(t,e){return t=l(this,t),0>t||this.size===1/0||void 0!==this.size&&t>this.size?e:this.find(function(e,r){return r===t},void 0,e)},has:function(t){return t=l(this,t),t>=0&&(void 0!==this.size?this.size===1/0||this.size>t:-1!==this.indexOf(t))},interpose:function(t){return be(this,ge(this,t))},interleave:function(){var t=[this].concat(p(arguments)),e=Ie(this.toSeq(),k.of,t),r=e.flatten(!0);return e.size&&(r.size=e.size*t.length), -be(this,r)},keySeq:function(){return $(0,this.size)},last:function(){return this.get(-1)},skipWhile:function(t,e){return be(this,le(this,t,e,!1))},zip:function(){var t=[this].concat(p(arguments));return be(this,Ie(this,rr,t))},zipWith:function(t){var e=p(arguments);return e[0]=this,be(this,Ie(this,t,e))}}),n.prototype[fr]=!0,n.prototype[cr]=!0,Fe(i,{get:function(t,e){return this.has(t)?t:e},includes:function(t){return this.has(t)},keySeq:function(){return this.valueSeq()}}),i.prototype.has=sn.includes,i.prototype.contains=i.prototype.includes,Fe(x,r.prototype),Fe(k,n.prototype),Fe(A,i.prototype),Fe(et,r.prototype),Fe(rt,n.prototype),Fe(nt,i.prototype);var hn={Iterable:e,Seq:O,Collection:tt,Map:ct,OrderedMap:Zt,List:Bt,Stack:Ve,Set:Le,OrderedSet:Je,Record:Ae,Range:$,Repeat:G,is:X,fromJS:H};return hn}); \ No newline at end of file diff --git a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/jquery-1.11.1.min.js b/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/jquery-1.11.1.min.js deleted file mode 100644 index ab28a247..00000000 --- a/IKEA_scraper/.venv/Lib/site-packages/snakeviz/static/vendor/jquery-1.11.1.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="
","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h; -if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:k.htmlSerialize?[0,"",""]:[1,"X
","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("